From f50531ff45c61acfa4c1151d3e3a7c7edb3825a7 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 30 May 2024 10:53:56 +0800 Subject: [PATCH 001/112] admt: Configured ADMT plugin - Added logic for compatible - Changed Harmonic Calibration icon - Changed plugin description Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtplugin.cpp | 122 ++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 plugins/admt/src/admtplugin.cpp diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp new file mode 100644 index 0000000000..26dc28bc9c --- /dev/null +++ b/plugins/admt/src/admtplugin.cpp @@ -0,0 +1,122 @@ +#include "admtplugin.h" +#include "harmoniccalibration.h" + +#include +#include + +#include + +Q_LOGGING_CATEGORY(CAT_ADMTPLUGIN, "ADMTPlugin") +using namespace scopy::admt; + +bool ADMTPlugin::compatible(QString m_param, QString category) +{ + m_name = "ADMT4000"; + bool ret = false; + Connection *conn = ConnectionProvider::open(m_param); + + if(!conn) { + qWarning(CAT_ADMTPLUGIN) << "No context available for admt"; + return false; + } + + iio_device *admtDevice = iio_context_find_device(conn->context(), "admt4000"); + if(admtDevice) { + ret = true; + } + + ConnectionProvider::close(m_param); + + return ret; +} + +bool ADMTPlugin::loadPage() +{ + // Here you must write the code for the plugin info page + // Below is an example for an iio device + /*m_page = new QWidget(); + m_page->setLayout(new QVBoxLayout(m_page)); + m_page->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_infoPage = new InfoPage(m_page); + m_infoPage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + m_page->layout()->addWidget(m_infoPage); + m_page->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding)); + + auto cp = ContextProvider::GetInstance(); + struct iio_context *context = cp->open(m_param); + ssize_t attributeCount = iio_context_get_attrs_count(context); + for(int i = 0; i < attributeCount; ++i) { + const char *name; + const char *value; + int ret = iio_context_get_attr(context, i, &name, &value); + if(ret < 0) { + qWarning(CAT_ADMTPLUGIN) << "Could not read attribute with index:" << i; + continue; + } + + m_infoPage->update(name, value); + } + cp->close(m_param); + m_page->ensurePolished();*/ + return true; +} + +bool ADMTPlugin::loadIcon() +{ + SCOPY_PLUGIN_ICON(":/gui/icons/adalm.svg"); + return true; +} + +void ADMTPlugin::loadToolList() +{ + m_toolList.append( + SCOPY_NEW_TOOLMENUENTRY("harmoniccalibration", "Harmonic Calibration", ":/gui/icons/scopy-default/icons/tool_oscilloscope.svg")); +} + +void ADMTPlugin::unload() { /*delete m_infoPage;*/ } + +QString ADMTPlugin::description() { return "Plugin for ADMT Harmonic Calibration"; } + +bool ADMTPlugin::onConnect() +{ + // This method is called when you try to connect to a device and the plugin is + // compatible to that device + // In case of success the function must return true and false otherwise + + HarmonicCalibration *harmonicCalibration = new HarmonicCalibration(); + m_toolList[0]->setTool(harmonicCalibration); + m_toolList[0]->setEnabled(true); + m_toolList[0]->setRunBtnVisible(true); + return true; +} + +bool ADMTPlugin::onDisconnect() +{ + // This method is called when the disconnect button is pressed + // It must remove all connections that were established on the connection + for(auto &tool : m_toolList) { + tool->setEnabled(false); + tool->setRunning(false); + tool->setRunBtnVisible(false); + QWidget *w = tool->tool(); + if(w) { + tool->setTool(nullptr); + delete(w); + } + } + return true; +} + +void ADMTPlugin::initMetadata() +{ + loadMetadata( + R"plugin( + { + "priority":100, + "category":[ + "iio" + ], + "exclude":[""] + } +)plugin"); +} From b8fca81d2ce5b30f6ff8fc0baf9a4c4a0ae58306 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 3 Jun 2024 11:39:46 +0800 Subject: [PATCH 002/112] admt: Added test GUI textbox and button for rotation, count, and angle Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../include/admtplugin/harmoniccalibration.h | 43 +++++++++ plugins/admt/src/harmoniccalibration.cpp | 90 +++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 plugins/admt/include/admtplugin/harmoniccalibration.h create mode 100644 plugins/admt/src/harmoniccalibration.cpp diff --git a/plugins/admt/include/admtplugin/harmoniccalibration.h b/plugins/admt/include/admtplugin/harmoniccalibration.h new file mode 100644 index 0000000000..e6a073ca8f --- /dev/null +++ b/plugins/admt/include/admtplugin/harmoniccalibration.h @@ -0,0 +1,43 @@ +#ifndef HARMONICCALIBRATION_H +#define HARMONICCALIBRATION_H + +#include "scopy-admtplugin_export.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace scopy::admt { +class SCOPY_ADMTPLUGIN_EXPORT HarmonicCalibration : public QWidget +{ + Q_OBJECT +public: + HarmonicCalibration(QWidget *parent = nullptr); + ~HarmonicCalibration(); +private: + ToolTemplate *tool; + GearBtn *settingsButton; + InfoBtn *infoButton; + RunBtn *runButton; + QPushButton *getRotationButton, *getCountButton, *getAngleButton; + QLineEdit *rotationLineEdit, *countLineEdit, *angleLineEdit; + MenuHeaderWidget *header; + QWidget *leftWidget, *leftBody; + QVBoxLayout *leftLayout, *leftBodyLayout; + MenuSectionWidget *rotationSection, *countSection, *angleSection; + MenuCollapseSection *rotationCollapse, *countCollapse, *angleCollapse; + QScrollArea *scrollArea; +}; +} // namespace scopy::admt +#endif // HARMONICCALIBRATION_H diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp new file mode 100644 index 0000000000..5ad36d2e86 --- /dev/null +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -0,0 +1,90 @@ +#include "harmoniccalibration.h" + +#include + +using namespace scopy::admt; + +HarmonicCalibration::HarmonicCalibration(QWidget *parent) +{ + QHBoxLayout *lay = new QHBoxLayout(this); + lay->setMargin(0); + setLayout(lay); + tool = new ToolTemplate(this); + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(true); + tool->leftContainer()->setVisible(true); + tool->rightContainer()->setVisible(true); + tool->bottomContainer()->setVisible(true); + lay->addWidget(tool); + infoButton = new InfoBtn(this); + runButton = new RunBtn(this); + tool->addWidgetToTopContainerHelper(infoButton, TTA_LEFT); + tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); + + leftWidget = new QWidget(this); + leftLayout = new QVBoxLayout(this); + leftLayout->setMargin(0); + leftLayout->setSpacing(10); + leftWidget->setLayout(leftLayout); + tool->leftStack()->add("left", leftWidget); + + header = new MenuHeaderWidget("ADMT4000", QPen(StyleHelper::getColor("ScopyBlue")), leftWidget); + leftLayout->addWidget(header); + + scrollArea = new QScrollArea(leftWidget); + scrollArea->setWidgetResizable(true); + leftLayout->addWidget(scrollArea); + + leftBody = new QWidget(scrollArea); + leftBodyLayout = new QVBoxLayout(leftBody); + leftBodyLayout->setMargin(0); + leftBodyLayout->setSpacing(10); + leftBody->setLayout(leftBodyLayout); + + //leftLayout->addLayout(leftBodyLayout); + + + rotationSection = new MenuSectionWidget(leftWidget); + countSection = new MenuSectionWidget(leftWidget); + angleSection = new MenuSectionWidget(leftWidget); + + rotationCollapse = new MenuCollapseSection("ROTATION", MenuCollapseSection::MHCW_NONE, rotationSection); + countCollapse = new MenuCollapseSection("COUNT", MenuCollapseSection::MHCW_NONE, countSection); + angleCollapse = new MenuCollapseSection("ANGLE", MenuCollapseSection::MHCW_NONE, angleSection); + rotationCollapse->contentLayout()->setSpacing(10); + countCollapse->contentLayout()->setSpacing(10); + angleCollapse->contentLayout()->setSpacing(10); + + rotationLineEdit = new QLineEdit(rotationCollapse); + countLineEdit = new QLineEdit(countCollapse); + angleLineEdit = new QLineEdit(angleCollapse); + StyleHelper::MenuLineEdit(rotationLineEdit, "rotationEdit"); + StyleHelper::MenuLineEdit(countLineEdit, "countEdit"); + StyleHelper::MenuLineEdit(angleLineEdit, "angleEdit"); + + getRotationButton = new QPushButton("Get Rotation", rotationCollapse); + getCountButton = new QPushButton("Get Count", countCollapse); + getAngleButton = new QPushButton("Get Angle", angleCollapse); + StyleHelper::BlueButton(getRotationButton, "rotationButton"); + StyleHelper::BlueButton(getCountButton, "countButton"); + StyleHelper::BlueButton(getAngleButton, "angleButton"); + + rotationCollapse->contentLayout()->addWidget(rotationLineEdit); + rotationCollapse->contentLayout()->addWidget(getRotationButton); + rotationSection->contentLayout()->addWidget(rotationCollapse); + countCollapse->contentLayout()->addWidget(countLineEdit); + countCollapse->contentLayout()->addWidget(getCountButton); + countSection->contentLayout()->addWidget(countCollapse); + angleCollapse->contentLayout()->addWidget(angleLineEdit); + angleCollapse->contentLayout()->addWidget(getAngleButton); + angleSection->contentLayout()->addWidget(angleCollapse); + + leftBodyLayout->addWidget(rotationSection); + leftBodyLayout->addWidget(countSection); + leftBodyLayout->addWidget(angleSection); + + QStackedWidget *centralWidget = new QStackedWidget(this); + tool->addWidgetToCentralContainerHelper(centralWidget); +} + +HarmonicCalibration::~HarmonicCalibration() {} From 412b67d28abce05f62412f750be642be221361fc Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 6 Jun 2024 15:01:51 +0800 Subject: [PATCH 003/112] admt: Renamed plugin and include directories Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/.gitignore | 1 + plugins/admt/CMakeLists.txt | 70 +++++++++++++++++++ plugins/admt/include/admt/admtplugin.h | 31 ++++++++ .../harmoniccalibration.h | 4 +- 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 plugins/admt/.gitignore create mode 100644 plugins/admt/CMakeLists.txt create mode 100644 plugins/admt/include/admt/admtplugin.h rename plugins/admt/include/{admtplugin => admt}/harmoniccalibration.h (90%) diff --git a/plugins/admt/.gitignore b/plugins/admt/.gitignore new file mode 100644 index 0000000000..cf99da1b8f --- /dev/null +++ b/plugins/admt/.gitignore @@ -0,0 +1 @@ +include/admt/scopy-admt_export.h \ No newline at end of file diff --git a/plugins/admt/CMakeLists.txt b/plugins/admt/CMakeLists.txt new file mode 100644 index 0000000000..18678584b4 --- /dev/null +++ b/plugins/admt/CMakeLists.txt @@ -0,0 +1,70 @@ +cmake_minimum_required(VERSION 3.9) + +set(SCOPY_MODULE admt) + +message(STATUS "building plugin: " ${SCOPY_MODULE}) + +project(scopy-${SCOPY_MODULE} VERSION 0.1 LANGUAGES CXX) + +include(GenerateExportHeader) + +# TODO: split stylesheet/resources and add here TODO: export header files correctly + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/ui) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) + +file(GLOB SRC_LIST src/*.cpp src/*.cc) +file(GLOB HEADER_LIST include/${SCOPY_MODULE}/*.h include/${SCOPY_MODULE}/*.hpp) +file(GLOB UI_LIST ui/*.ui) + +set(ENABLE_TESTING ON) +if(ENABLE_TESTING) + add_subdirectory(test) +endif() + +set(PROJECT_SOURCES ${SRC_LIST} ${HEADER_LIST} ${UI_LIST}) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS REQUIRED Widgets Core) + +if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${SCOPY_PLUGIN_BUILD_PATH}) +elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Scopy.app/Contents/MacOS/plugins/plugins) +else() + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${SCOPY_PLUGIN_BUILD_PATH}) +endif() + +qt_add_resources(PROJECT_RESOURCES res/resources.qrc) +add_library(${PROJECT_NAME} SHARED ${PROJECT_SOURCES} ${PROJECT_RESOURCES}) + +generate_export_header( + ${PROJECT_NAME} EXPORT_FILE_NAME ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}/${PROJECT_NAME}_export.h +) + +target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}) + +target_include_directories(${PROJECT_NAME} PUBLIC scopy-pluginbase scopy-gui) + +target_link_libraries( + ${PROJECT_NAME} + PUBLIC Qt::Widgets + Qt::Core + scopy-pluginbase + scopy-gui + scopy-iioutil +) + +set(PLUGIN_NAME ${PROJECT_NAME} PARENT_SCOPE) +set(PLUGIN_DESCRIPTION "ADMT plugin" PARENT_SCOPE) + +install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${SCOPY_PLUGIN_INSTALL_DIR}) \ No newline at end of file diff --git a/plugins/admt/include/admt/admtplugin.h b/plugins/admt/include/admt/admtplugin.h new file mode 100644 index 0000000000..09f0ce35c1 --- /dev/null +++ b/plugins/admt/include/admt/admtplugin.h @@ -0,0 +1,31 @@ +#ifndef ADMTPLUGIN_H +#define ADMTPLUGIN_H + +#define SCOPY_PLUGIN_NAME ADMTPlugin + +#include "scopy-admt_export.h" +#include +#include +#include + +namespace scopy::admt { +class SCOPY_ADMT_EXPORT ADMTPlugin : public QObject, public PluginBase +{ + Q_OBJECT + SCOPY_PLUGIN; + +public: + bool compatible(QString m_param, QString category) override; + bool loadPage() override; + bool loadIcon() override; + void loadToolList() override; + void unload() override; + void initMetadata() override; + QString description() override; + +public Q_SLOTS: + bool onConnect() override; + bool onDisconnect() override; +}; +} // namespace scopy::admt +#endif // ADMTPLUGIN_H diff --git a/plugins/admt/include/admtplugin/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h similarity index 90% rename from plugins/admt/include/admtplugin/harmoniccalibration.h rename to plugins/admt/include/admt/harmoniccalibration.h index e6a073ca8f..a057a7e0c0 100644 --- a/plugins/admt/include/admtplugin/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -1,7 +1,7 @@ #ifndef HARMONICCALIBRATION_H #define HARMONICCALIBRATION_H -#include "scopy-admtplugin_export.h" +#include "scopy-admt_export.h" #include #include @@ -19,7 +19,7 @@ #include namespace scopy::admt { -class SCOPY_ADMTPLUGIN_EXPORT HarmonicCalibration : public QWidget +class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget { Q_OBJECT public: From 557997e88ba32c59431dc64895f18688c8d535e4 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 10 Jun 2024 12:19:39 +0800 Subject: [PATCH 004/112] admt: Connected button to output to text field Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 10 +++++- plugins/admt/src/admtplugin.cpp | 6 ++-- plugins/admt/src/harmoniccalibration.cpp | 35 ++++++++++++++++--- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index a057a7e0c0..bc4824cbdd 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -23,9 +24,16 @@ class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget { Q_OBJECT public: - HarmonicCalibration(QWidget *parent = nullptr); + HarmonicCalibration(struct iio_context *context, QWidget *parent = nullptr); ~HarmonicCalibration(); private: + void getRotationData(); + void getCountData(); + void getAngleData(); + QStringList getDeviceList(iio_context *context); + + iio_context *context; + ToolTemplate *tool; GearBtn *settingsButton; InfoBtn *infoButton; diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index 26dc28bc9c..ff38a08487 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -26,7 +26,7 @@ bool ADMTPlugin::compatible(QString m_param, QString category) } ConnectionProvider::close(m_param); - + return ret; } @@ -83,7 +83,9 @@ bool ADMTPlugin::onConnect() // compatible to that device // In case of success the function must return true and false otherwise - HarmonicCalibration *harmonicCalibration = new HarmonicCalibration(); + auto *cp = ConnectionProvider::GetInstance(); + Connection *conn = cp->open(m_param); + HarmonicCalibration *harmonicCalibration = new HarmonicCalibration(conn->context()); m_toolList[0]->setTool(harmonicCalibration); m_toolList[0]->setEnabled(true); m_toolList[0]->setRunBtnVisible(true); diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 5ad36d2e86..1a943795d0 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -4,8 +4,10 @@ using namespace scopy::admt; -HarmonicCalibration::HarmonicCalibration(QWidget *parent) +HarmonicCalibration::HarmonicCalibration(struct iio_context *context, QWidget *parent) { + this->context = context; + QHBoxLayout *lay = new QHBoxLayout(this); lay->setMargin(0); setLayout(lay); @@ -41,9 +43,6 @@ HarmonicCalibration::HarmonicCalibration(QWidget *parent) leftBodyLayout->setSpacing(10); leftBody->setLayout(leftBodyLayout); - //leftLayout->addLayout(leftBodyLayout); - - rotationSection = new MenuSectionWidget(leftWidget); countSection = new MenuSectionWidget(leftWidget); angleSection = new MenuSectionWidget(leftWidget); @@ -68,6 +67,9 @@ HarmonicCalibration::HarmonicCalibration(QWidget *parent) StyleHelper::BlueButton(getRotationButton, "rotationButton"); StyleHelper::BlueButton(getCountButton, "countButton"); StyleHelper::BlueButton(getAngleButton, "angleButton"); + QObject::connect(getRotationButton, &QPushButton::clicked, this, &HarmonicCalibration::getRotationData); + QObject::connect(getCountButton, &QPushButton::clicked, this, &HarmonicCalibration::getCountData); + QObject::connect(getAngleButton, &QPushButton::clicked, this, &HarmonicCalibration::getAngleData); rotationCollapse->contentLayout()->addWidget(rotationLineEdit); rotationCollapse->contentLayout()->addWidget(getRotationButton); @@ -88,3 +90,28 @@ HarmonicCalibration::HarmonicCalibration(QWidget *parent) } HarmonicCalibration::~HarmonicCalibration() {} + +void HarmonicCalibration::getRotationData() +{ + int devCount = iio_context_get_devices_count(context); + auto s = std::to_string(devCount); + QString qstr = QString::fromStdString(s); + rotationLineEdit->setText(qstr); +} + +void HarmonicCalibration::getCountData() +{ + countLineEdit->setText("test"); +} + +void HarmonicCalibration::getAngleData() +{ + angleLineEdit->setText("test"); +} + +QStringList HarmonicCalibration::getDeviceList(iio_context *context) +{ + QStringList deviceList; + int devCount = iio_context_get_devices_count(context); + return deviceList; +} \ No newline at end of file From ce5de5e95ad30551fff57f5d25f3c7e07e6ef9f8 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 13 Jun 2024 07:31:22 +0800 Subject: [PATCH 005/112] admt: Added GRTimePlotAddon Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/CMakeLists.txt | 2 + plugins/admt/include/admt/admtplugin.h | 144 +++++++++++++++++- .../admt/include/admt/harmoniccalibration.h | 14 +- plugins/admt/src/admtplugin.cpp | 87 ++++++++++- plugins/admt/src/harmoniccalibration.cpp | 46 ++++-- 5 files changed, 272 insertions(+), 21 deletions(-) diff --git a/plugins/admt/CMakeLists.txt b/plugins/admt/CMakeLists.txt index 18678584b4..f4929a0f86 100644 --- a/plugins/admt/CMakeLists.txt +++ b/plugins/admt/CMakeLists.txt @@ -62,6 +62,8 @@ target_link_libraries( scopy-pluginbase scopy-gui scopy-iioutil + scopy-gr-util + scopy-iio-widgets ) set(PLUGIN_NAME ${PROJECT_NAME} PARENT_SCOPE) diff --git a/plugins/admt/include/admt/admtplugin.h b/plugins/admt/include/admt/admtplugin.h index 09f0ce35c1..d5cc29709d 100644 --- a/plugins/admt/include/admt/admtplugin.h +++ b/plugins/admt/include/admt/admtplugin.h @@ -4,11 +4,146 @@ #define SCOPY_PLUGIN_NAME ADMTPlugin #include "scopy-admt_export.h" + +#include + +#include +#include #include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -namespace scopy::admt { +namespace scopy { +using namespace grutil; + +class SCOPY_ADMT_EXPORT ChannelIdProvider : public QObject +{ + Q_OBJECT +public: + ChannelIdProvider(QObject *parent) + : QObject(parent) + { + idx = 0; + } + virtual ~ChannelIdProvider() {} + + int next() { return idx++; } + QPen pen(int idx) { return QPen(StyleHelper::getColor("CH" + QString::number(idx))); } + + int idx; +}; + +class SCOPY_ADMT_EXPORT PlotProxy +{ +public: + virtual ToolAddon *getPlotAddon() = 0; + virtual ToolAddon *getPlotSettings() = 0; + virtual QList getDeviceAddons() = 0; + virtual QList getChannelAddons() = 0; + virtual QList getAddons() = 0; + + virtual void addDeviceAddon(ToolAddon *d) = 0; + virtual void removeDeviceAddon(ToolAddon *d) = 0; + virtual void addChannelAddon(ChannelAddon *c) = 0; + virtual void removeChannelAddon(ChannelAddon *c) = 0; + virtual void init() = 0; + + virtual ChannelIdProvider *getChannelIdProvider() = 0; +}; + +class SCOPY_ADMT_EXPORT GRTimePlotProxy : public QObject, public PlotProxy +{ + Q_OBJECT +public: + GRTimePlotProxy(QObject *parent = nullptr) + : QObject(parent) + { + chIdP = new ChannelIdProvider(this); + } + ~GRTimePlotProxy() {} + + void setPlotAddon(GRTimePlotAddon *p, GRTimePlotAddonSettings *s) + { + this->plotAddon = p; + this->plotSettingsAddon = s; + } + + void addDeviceAddon(ToolAddon *d) override { deviceAddons.append(d); } + + void removeDeviceAddon(ToolAddon *d) override { deviceAddons.removeAll(d); } + + void addChannelAddon(ChannelAddon *c) override { channelAddons.append(c); } + + void removeChannelAddon(ChannelAddon *c) override { channelAddons.removeAll(c); } + + ToolAddon *getPlotAddon() override { return plotAddon; } + + ToolAddon *getPlotSettings() override { return plotSettingsAddon; } + + QList getDeviceAddons() override { return deviceAddons; } + + QList getChannelAddons() override { return channelAddons; } + + QList getAddons() override + { + QList addons; + + addons.append(channelAddons); + addons.append(deviceAddons); + addons.append(plotSettingsAddon); + addons.append(plotAddon); + return addons; + } + + void init() override + { + for(auto *addon : getAddons()) { + if(dynamic_cast(addon)) { + auto GRAddon = dynamic_cast(addon); + connect(topBlock, &GRTopBlock::aboutToStart, this, [=]() { GRAddon->preFlowStart(); }); + connect(topBlock, &GRTopBlock::started, this, [=]() { GRAddon->postFlowStart(); }); + connect(topBlock, &GRTopBlock::aboutToStop, this, [=]() { GRAddon->preFlowStop(); }); + connect(topBlock, &GRTopBlock::stopped, this, [=]() { GRAddon->postFlowStop(); }); + connect(topBlock, &GRTopBlock::aboutToBuild, this, [=]() { GRAddon->preFlowBuild(); }); + connect(topBlock, &GRTopBlock::builtSignalPaths, this, + [=]() { GRAddon->postFlowBuild(); }); + connect(topBlock, &GRTopBlock::aboutToTeardown, this, + [=]() { GRAddon->preFlowTeardown(); }); + connect(topBlock, &GRTopBlock::teardownSignalPaths, this, + [=]() { GRAddon->postFlowTeardown(); }); + } + } + } + + ChannelIdProvider *getChannelIdProvider() override { return chIdP; } + + QString getPrefix() { return prefix; } + void setPrefix(QString p) { prefix = p; } + GRTopBlock *getTopBlock() const { return topBlock; } + void setTopBlock(GRTopBlock *newTopBlock) { topBlock = newTopBlock; } + +private: + GRTimePlotAddon *plotAddon; + GRTimePlotAddonSettings *plotSettingsAddon; + QList deviceAddons; + QList channelAddons; + GRTopBlock *topBlock; + ChannelIdProvider *chIdP; + + QString prefix; +}; + class SCOPY_ADMT_EXPORT ADMTPlugin : public QObject, public PluginBase { Q_OBJECT @@ -26,6 +161,13 @@ class SCOPY_ADMT_EXPORT ADMTPlugin : public QObject, public PluginBase public Q_SLOTS: bool onConnect() override; bool onDisconnect() override; + +private: + iio_context *m_ctx; + QWidget *harmonicCalibration; + QLineEdit *edit; + PlotProxy *createRecipe(iio_context *ctx); + GRTimePlotProxy *recipe; }; } // namespace scopy::admt #endif // ADMTPLUGIN_H diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index bc4824cbdd..09ffc74a41 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -19,12 +20,12 @@ #include #include -namespace scopy::admt { +namespace scopy { class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget { Q_OBJECT public: - HarmonicCalibration(struct iio_context *context, QWidget *parent = nullptr); + HarmonicCalibration(PlotProxy *proxy, QWidget *parent = nullptr); ~HarmonicCalibration(); private: void getRotationData(); @@ -32,8 +33,6 @@ class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget void getAngleData(); QStringList getDeviceList(iio_context *context); - iio_context *context; - ToolTemplate *tool; GearBtn *settingsButton; InfoBtn *infoButton; @@ -46,6 +45,13 @@ class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget MenuSectionWidget *rotationSection, *countSection, *angleSection; MenuCollapseSection *rotationCollapse, *countCollapse, *angleCollapse; QScrollArea *scrollArea; + + QPushButton *openLastMenuBtn; + PlotProxy *proxy; + GRTimePlotAddon *plotAddon; + GRTimePlotAddonSettings *plotAddonSettings; + QButtonGroup *rightMenuBtnGrp; + int uuid = 0; }; } // namespace scopy::admt #endif // HARMONICCALIBRATION_H diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index ff38a08487..5e9b170c6e 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -7,7 +7,8 @@ #include Q_LOGGING_CATEGORY(CAT_ADMTPLUGIN, "ADMTPlugin") -using namespace scopy::admt; +using namespace scopy; +using namespace scopy::grutil; bool ADMTPlugin::compatible(QString m_param, QString category) { @@ -77,19 +78,93 @@ void ADMTPlugin::unload() { /*delete m_infoPage;*/ } QString ADMTPlugin::description() { return "Plugin for ADMT Harmonic Calibration"; } +PlotProxy *ADMTPlugin::createRecipe(iio_context *ctx) +{ + QStringList deviceList; + QMap devChannelMap; + int devCount = iio_context_get_devices_count(ctx); + qDebug(CAT_ADMTPLUGIN) << " Found " << devCount << "devices"; + for(int i = 0; i < devCount; i++) { + iio_device *dev = iio_context_get_device(ctx, i); + QString dev_name = QString::fromLocal8Bit(iio_device_get_name(dev)); + + qDebug(CAT_ADMTPLUGIN) << "Looking for scanelements in " << dev_name; + if(dev_name == "m2k-logic-analyzer-rx") + continue; + QStringList channelList; + for(int j = 0; j < iio_device_get_channels_count(dev); j++) { + + struct iio_channel *chn = iio_device_get_channel(dev, j); + QString chn_name = QString::fromLocal8Bit(iio_channel_get_id(chn)); + qDebug(CAT_ADMTPLUGIN) << "Verify if " << chn_name << "is scan element"; + if(chn_name == "timestamp" /*|| chn_name == "accel_z" || chn_name =="accel_y"*/) + continue; + if(!iio_channel_is_output(chn) && iio_channel_is_scan_element(chn)) { + channelList.append(chn_name); + } + } + if(channelList.isEmpty()) + continue; + deviceList.append(dev_name); + devChannelMap.insert(dev_name, channelList); + } + + // should this be wrapped to a register function (?) + GRTopBlock *top = new grutil::GRTopBlock("Time", this); + + recipe = new GRTimePlotProxy(this); + QString plotRecipePrefix = "time_"; + recipe->setPrefix(plotRecipePrefix); + + GRTimePlotAddon *p = new GRTimePlotAddon(plotRecipePrefix, top, this); + GRTimePlotAddonSettings *s = new GRTimePlotAddonSettings(p, this); + + recipe->setPlotAddon(p, s); + + ChannelIdProvider *chIdProvider = recipe->getChannelIdProvider(); + for(const QString &iio_dev : deviceList) { + GRIIODeviceSource *gr_dev = new GRIIODeviceSource(m_ctx, iio_dev, iio_dev, 0x400, this); + + top->registerIIODeviceSource(gr_dev); + + GRDeviceAddon *d = new GRDeviceAddon(gr_dev, this); + connect(s, &GRTimePlotAddonSettings::bufferSizeChanged, d, &GRDeviceAddon::updateBufferSize); + recipe->addDeviceAddon(d); + + for(const QString &ch : devChannelMap.value(iio_dev, {})) { + int idx = chIdProvider->next(); + GRTimeChannelAddon *t = new GRTimeChannelAddon(ch, d, p, chIdProvider->pen(idx), this); + top->registerSignalPath(t->signalPath()); + recipe->addChannelAddon(t); + } + } + recipe->setTopBlock(top); + + qDebug(CAT_ADMTPLUGIN) << deviceList; + qDebug(CAT_ADMTPLUGIN) << devChannelMap; + + return recipe; +} + bool ADMTPlugin::onConnect() { // This method is called when you try to connect to a device and the plugin is // compatible to that device // In case of success the function must return true and false otherwise - auto *cp = ConnectionProvider::GetInstance(); - Connection *conn = cp->open(m_param); - HarmonicCalibration *harmonicCalibration = new HarmonicCalibration(conn->context()); - m_toolList[0]->setTool(harmonicCalibration); + Connection *conn = ConnectionProvider::GetInstance()->open(m_param); + if(conn == nullptr) + return false; + m_ctx = conn->context(); m_toolList[0]->setEnabled(true); m_toolList[0]->setRunBtnVisible(true); - return true; + + auto recipe = createRecipe(m_ctx); + + harmonicCalibration = new HarmonicCalibration(recipe); + m_toolList[0]->setTool(harmonicCalibration); + + return true; } bool ADMTPlugin::onDisconnect() diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 1a943795d0..e21c096611 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -2,12 +2,12 @@ #include -using namespace scopy::admt; +using namespace scopy; +using namespace scopy::grutil; -HarmonicCalibration::HarmonicCalibration(struct iio_context *context, QWidget *parent) +HarmonicCalibration::HarmonicCalibration(PlotProxy *proxy, QWidget *parent) { - this->context = context; - + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QHBoxLayout *lay = new QHBoxLayout(this); lay->setMargin(0); setLayout(lay); @@ -18,11 +18,40 @@ HarmonicCalibration::HarmonicCalibration(struct iio_context *context, QWidget *p tool->rightContainer()->setVisible(true); tool->bottomContainer()->setVisible(true); lay->addWidget(tool); + tool->setLeftContainerWidth(210); + tool->setRightContainerWidth(300); + tool->setTopContainerHeight(100); + tool->setBottomContainerHeight(90); + + openLastMenuBtn = new OpenLastMenuBtn(dynamic_cast(tool->rightContainer()), true, this); + rightMenuBtnGrp = dynamic_cast(openLastMenuBtn)->getButtonGroup(); + + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + + settingsButton = new GearBtn(this); infoButton = new InfoBtn(this); runButton = new RunBtn(this); + + tool->addWidgetToTopContainerMenuControlHelper(openLastMenuBtn, TTA_RIGHT); + tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); + tool->addWidgetToTopContainerHelper(infoButton, TTA_LEFT); tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); + plotAddon = dynamic_cast(proxy->getPlotAddon()); + tool->addWidgetToCentralContainerHelper(plotAddon->getWidget()); + + plotAddonSettings = dynamic_cast(proxy->getPlotSettings()); + rightMenuBtnGrp->addButton(settingsButton); + + QString settingsMenuId = plotAddonSettings->getName() + QString(uuid++); + tool->rightStack()->add(settingsMenuId, plotAddonSettings->getWidget()); + connect(settingsButton, &QPushButton::toggled, this, [=, this](bool b) { + if(b) + tool->requestMenu(settingsMenuId); + }); + leftWidget = new QWidget(this); leftLayout = new QVBoxLayout(this); leftLayout->setMargin(0); @@ -85,18 +114,15 @@ HarmonicCalibration::HarmonicCalibration(struct iio_context *context, QWidget *p leftBodyLayout->addWidget(countSection); leftBodyLayout->addWidget(angleSection); - QStackedWidget *centralWidget = new QStackedWidget(this); - tool->addWidgetToCentralContainerHelper(centralWidget); + // QStackedWidget *centralWidget = new QStackedWidget(this); + // tool->addWidgetToCentralContainerHelper(centralWidget); } HarmonicCalibration::~HarmonicCalibration() {} void HarmonicCalibration::getRotationData() { - int devCount = iio_context_get_devices_count(context); - auto s = std::to_string(devCount); - QString qstr = QString::fromStdString(s); - rotationLineEdit->setText(qstr); + rotationLineEdit->setText("test"); } void HarmonicCalibration::getCountData() From 17aa7642795246736029b6e23632cf9f7b82c030 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 14 Jun 2024 16:30:11 +0800 Subject: [PATCH 006/112] admt: Implemented channel control and init methods Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 68 ++- plugins/admt/src/harmoniccalibration.cpp | 402 ++++++++++++++---- 2 files changed, 371 insertions(+), 99 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 09ffc74a41..b8d00bbf59 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -19,39 +20,72 @@ #include #include #include +#include +#include +#include namespace scopy { -class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget +class MenuControlButton; +class CollapsableMenuControlButton; + +class HarmonicCalibration : public QWidget { Q_OBJECT public: HarmonicCalibration(PlotProxy *proxy, QWidget *parent = nullptr); ~HarmonicCalibration(); + void init(); + void deinit(); + void startAddons(); + void stopAddons(); + bool running() const; + void setRunning(bool newRunning); +public Q_SLOTS: + void run(bool); + void stop(); + void start(); + void restart(); + void showMeasurements(bool b); + void createSnapshotChannel(SnapshotProvider::SnapshotRecipe rec); + void deleteChannel(ChannelAddon *); + MenuControlButton *addChannel(ChannelAddon *channelAddon, QWidget *parent); + CollapsableMenuControlButton *addDevice(GRDeviceAddon *dev, QWidget *parent); +Q_SIGNALS: + void runningChanged(bool); private: - void getRotationData(); - void getCountData(); - void getAngleData(); - QStringList getDeviceList(iio_context *context); - + bool m_running; ToolTemplate *tool; GearBtn *settingsButton; InfoBtn *infoButton; RunBtn *runButton; - QPushButton *getRotationButton, *getCountButton, *getAngleButton; - QLineEdit *rotationLineEdit, *countLineEdit, *angleLineEdit; - MenuHeaderWidget *header; - QWidget *leftWidget, *leftBody; - QVBoxLayout *leftLayout, *leftBodyLayout; - MenuSectionWidget *rotationSection, *countSection, *angleSection; - MenuCollapseSection *rotationCollapse, *countCollapse, *angleCollapse; - QScrollArea *scrollArea; - - QPushButton *openLastMenuBtn; + + QPushButton *openLastMenuButton; PlotProxy *proxy; GRTimePlotAddon *plotAddon; GRTimePlotAddonSettings *plotAddonSettings; - QButtonGroup *rightMenuBtnGrp; + QButtonGroup *rightMenuButtonGroup; + + MenuControlButton *channelsButton; + VerticalChannelManager *verticalChannelManager; + QButtonGroup *channelGroup; + MapStackedWidget *channelStack; + MeasurementsPanel *measurePanel; + MeasurementSettings *measureSettings; + StatsPanel *statsPanel; + + void setupChannelsButtonHelper(MenuControlButton *channelsButton); + void setupMeasureButtonHelper(MenuControlButton *measureButton); + void setupChannelSnapshot(ChannelAddon *channelAddon); + void setupChannelMeasurement(ChannelAddon *channelAddon); + void setupChannelDelete(ChannelAddon *channelAddon); + void setupChannelMenuControlButtonHelper(MenuControlButton *menuControlButton, ChannelAddon *channelAddon); + void setupDeviceMenuControlButtonHelper(MenuControlButton *menuControlButton, GRDeviceAddon *channelAddon); + int uuid = 0; + const QString channelsMenuId = "channels"; + const QString measureMenuId = "measure"; + const QString statsMenuId = "stats"; + const QString verticalChannelManagerId = "vcm"; }; } // namespace scopy::admt #endif // HARMONICCALIBRATION_H diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index e21c096611..56a0153acd 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -6,6 +6,8 @@ using namespace scopy; using namespace scopy::grutil; HarmonicCalibration::HarmonicCalibration(PlotProxy *proxy, QWidget *parent) + : QWidget(parent) + , proxy(proxy) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QHBoxLayout *lay = new QHBoxLayout(this); @@ -23,8 +25,8 @@ HarmonicCalibration::HarmonicCalibration(PlotProxy *proxy, QWidget *parent) tool->setTopContainerHeight(100); tool->setBottomContainerHeight(90); - openLastMenuBtn = new OpenLastMenuBtn(dynamic_cast(tool->rightContainer()), true, this); - rightMenuBtnGrp = dynamic_cast(openLastMenuBtn)->getButtonGroup(); + openLastMenuButton = new OpenLastMenuBtn(dynamic_cast(tool->rightContainer()), true, this); + rightMenuButtonGroup = dynamic_cast(openLastMenuButton)->getButtonGroup(); tool->openBottomContainerHelper(false); tool->openTopContainerHelper(false); @@ -33,17 +35,14 @@ HarmonicCalibration::HarmonicCalibration(PlotProxy *proxy, QWidget *parent) infoButton = new InfoBtn(this); runButton = new RunBtn(this); - tool->addWidgetToTopContainerMenuControlHelper(openLastMenuBtn, TTA_RIGHT); - tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); - - tool->addWidgetToTopContainerHelper(infoButton, TTA_LEFT); - tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); + channelsButton = new MenuControlButton(this); + setupChannelsButtonHelper(channelsButton); plotAddon = dynamic_cast(proxy->getPlotAddon()); tool->addWidgetToCentralContainerHelper(plotAddon->getWidget()); plotAddonSettings = dynamic_cast(proxy->getPlotSettings()); - rightMenuBtnGrp->addButton(settingsButton); + rightMenuButtonGroup->addButton(settingsButton); QString settingsMenuId = plotAddonSettings->getName() + QString(uuid++); tool->rightStack()->add(settingsMenuId, plotAddonSettings->getWidget()); @@ -52,92 +51,331 @@ HarmonicCalibration::HarmonicCalibration(PlotProxy *proxy, QWidget *parent) tool->requestMenu(settingsMenuId); }); - leftWidget = new QWidget(this); - leftLayout = new QVBoxLayout(this); - leftLayout->setMargin(0); - leftLayout->setSpacing(10); - leftWidget->setLayout(leftLayout); - tool->leftStack()->add("left", leftWidget); - - header = new MenuHeaderWidget("ADMT4000", QPen(StyleHelper::getColor("ScopyBlue")), leftWidget); - leftLayout->addWidget(header); - - scrollArea = new QScrollArea(leftWidget); - scrollArea->setWidgetResizable(true); - leftLayout->addWidget(scrollArea); - - leftBody = new QWidget(scrollArea); - leftBodyLayout = new QVBoxLayout(leftBody); - leftBodyLayout->setMargin(0); - leftBodyLayout->setSpacing(10); - leftBody->setLayout(leftBodyLayout); - - rotationSection = new MenuSectionWidget(leftWidget); - countSection = new MenuSectionWidget(leftWidget); - angleSection = new MenuSectionWidget(leftWidget); - - rotationCollapse = new MenuCollapseSection("ROTATION", MenuCollapseSection::MHCW_NONE, rotationSection); - countCollapse = new MenuCollapseSection("COUNT", MenuCollapseSection::MHCW_NONE, countSection); - angleCollapse = new MenuCollapseSection("ANGLE", MenuCollapseSection::MHCW_NONE, angleSection); - rotationCollapse->contentLayout()->setSpacing(10); - countCollapse->contentLayout()->setSpacing(10); - angleCollapse->contentLayout()->setSpacing(10); - - rotationLineEdit = new QLineEdit(rotationCollapse); - countLineEdit = new QLineEdit(countCollapse); - angleLineEdit = new QLineEdit(angleCollapse); - StyleHelper::MenuLineEdit(rotationLineEdit, "rotationEdit"); - StyleHelper::MenuLineEdit(countLineEdit, "countEdit"); - StyleHelper::MenuLineEdit(angleLineEdit, "angleEdit"); - - getRotationButton = new QPushButton("Get Rotation", rotationCollapse); - getCountButton = new QPushButton("Get Count", countCollapse); - getAngleButton = new QPushButton("Get Angle", angleCollapse); - StyleHelper::BlueButton(getRotationButton, "rotationButton"); - StyleHelper::BlueButton(getCountButton, "countButton"); - StyleHelper::BlueButton(getAngleButton, "angleButton"); - QObject::connect(getRotationButton, &QPushButton::clicked, this, &HarmonicCalibration::getRotationData); - QObject::connect(getCountButton, &QPushButton::clicked, this, &HarmonicCalibration::getCountData); - QObject::connect(getAngleButton, &QPushButton::clicked, this, &HarmonicCalibration::getAngleData); - - rotationCollapse->contentLayout()->addWidget(rotationLineEdit); - rotationCollapse->contentLayout()->addWidget(getRotationButton); - rotationSection->contentLayout()->addWidget(rotationCollapse); - countCollapse->contentLayout()->addWidget(countLineEdit); - countCollapse->contentLayout()->addWidget(getCountButton); - countSection->contentLayout()->addWidget(countCollapse); - angleCollapse->contentLayout()->addWidget(angleLineEdit); - angleCollapse->contentLayout()->addWidget(getAngleButton); - angleSection->contentLayout()->addWidget(angleCollapse); - - leftBodyLayout->addWidget(rotationSection); - leftBodyLayout->addWidget(countSection); - leftBodyLayout->addWidget(angleSection); - - // QStackedWidget *centralWidget = new QStackedWidget(this); - // tool->addWidgetToCentralContainerHelper(centralWidget); + MenuControlButton *measure = new MenuControlButton(this); + setupMeasureButtonHelper(measure); + measurePanel = new MeasurementsPanel(this); + tool->topStack()->add(measureMenuId, measurePanel); + tool->openTopContainerHelper(false); + + statsPanel = new StatsPanel(this); + tool->bottomStack()->add(statsMenuId, statsPanel); + + measureSettings = new MeasurementSettings(this); + HoverWidget *measurePanelManagerHover = new HoverWidget(nullptr, measure, tool); + measurePanelManagerHover->setContent(measureSettings); + measurePanelManagerHover->setAnchorPos(HoverPosition::HP_TOPRIGHT); + measurePanelManagerHover->setContentPos(HoverPosition::HP_TOPLEFT); + connect(measure->button(), &QPushButton::toggled, this, [=, this](bool b) { + measurePanelManagerHover->setVisible(b); + measurePanelManagerHover->raise(); + }); + connect(measureSettings, &MeasurementSettings::enableMeasurementPanel, tool->topCentral(), + &QWidget::setVisible); + connect(measureSettings, &MeasurementSettings::enableStatsPanel, tool->bottomCentral(), &QWidget::setVisible); + + connect(measureSettings, &MeasurementSettings::sortMeasurements, measurePanel, &MeasurementsPanel::sort); + connect(measureSettings, &MeasurementSettings::sortStats, statsPanel, &StatsPanel::sort); + + tool->addWidgetToTopContainerMenuControlHelper(openLastMenuButton, TTA_RIGHT); + tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); + + tool->addWidgetToTopContainerHelper(infoButton, TTA_LEFT); + tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); + + tool->addWidgetToBottomContainerHelper(channelsButton, TTA_LEFT); + tool->addWidgetToBottomContainerHelper(measure, TTA_RIGHT); + + connect(channelsButton, &QPushButton::toggled, dynamic_cast(tool->leftContainer()), + &MenuHAnim::toggleMenu); + + // Left Channel Manager + verticalChannelManager = new VerticalChannelManager(this); + tool->leftStack()->add(verticalChannelManagerId, verticalChannelManager); + + channelGroup = new QButtonGroup(this); + for(auto d : proxy->getDeviceAddons()) { + GRDeviceAddon *dev = dynamic_cast(d); + if(!dev) + continue; + CollapsableMenuControlButton *devButton = addDevice(dev, verticalChannelManager); + verticalChannelManager->add(devButton); + + for(TimeChannelAddon *channelAddon : dev->getRegisteredChannels()) { + auto menuControlButton = addChannel(channelAddon, devButton); + devButton->add(menuControlButton); + } + } + + connect(runButton, &QPushButton::toggled, this, &HarmonicCalibration::setRunning); + connect(this, &HarmonicCalibration::runningChanged, this, &HarmonicCalibration::run); + connect(this, &HarmonicCalibration::runningChanged, runButton, &QAbstractButton::setChecked); + connect(plotAddon, &GRTimePlotAddon::requestStop, this, &HarmonicCalibration::stop, Qt::QueuedConnection); + connect(measure, &MenuControlButton::toggled, this, &HarmonicCalibration::showMeasurements); + + channelsButton->button()->setChecked(true); + channelGroup->buttons()[1]->setChecked(true); + + init(); } HarmonicCalibration::~HarmonicCalibration() {} -void HarmonicCalibration::getRotationData() +void HarmonicCalibration::setupChannelsButtonHelper(MenuControlButton *channelsButton) { - rotationLineEdit->setText("test"); + channelsButton->setName("Channels"); + channelsButton->setOpenMenuChecksThis(true); + channelsButton->setDoubleClickToOpenMenu(true); + channelsButton->checkBox()->setVisible(false); + channelsButton->setChecked(true); + channelStack = new MapStackedWidget(this); + tool->rightStack()->add(channelsMenuId, channelStack); + connect(channelsButton->button(), &QAbstractButton::toggled, this, [=, this](bool b) { + if(b) + tool->requestMenu(channelsMenuId); + }); + rightMenuButtonGroup->addButton(channelsButton->button()); } -void HarmonicCalibration::getCountData() +void HarmonicCalibration::setupMeasureButtonHelper(MenuControlButton *measureButton) { - countLineEdit->setText("test"); + measureButton->setName("Measure"); + measureButton->setOpenMenuChecksThis(true); + measureButton->setDoubleClickToOpenMenu(true); + measureButton->checkBox()->setVisible(false); } -void HarmonicCalibration::getAngleData() +void HarmonicCalibration::setupChannelMenuControlButtonHelper(MenuControlButton *menuControlButton, ChannelAddon *channelAddon) { - angleLineEdit->setText("test"); + menuControlButton->setName(channelAddon->getName()); + menuControlButton->setCheckBoxStyle(MenuControlButton::CS_CIRCLE); + menuControlButton->setOpenMenuChecksThis(true); + menuControlButton->setDoubleClickToOpenMenu(true); + menuControlButton->setColor(channelAddon->pen().color()); + menuControlButton->button()->setVisible(false); + menuControlButton->setCheckable(true); + + connect(menuControlButton->checkBox(), &QCheckBox::toggled, this, [=, this](bool b) { + if(b) + channelAddon->enable(); + else + channelAddon->disable(); + }); + menuControlButton->checkBox()->setChecked(true); +} + +void HarmonicCalibration::setupChannelSnapshot(ChannelAddon *channelAddon) +{ + auto snapshotChannel = dynamic_cast(channelAddon); + if(!snapshotChannel) + return; + connect(channelAddon, SIGNAL(addNewSnapshot(SnapshotProvider::SnapshotRecipe)), this, + SLOT(createSnapshotChannel(SnapshotProvider::SnapshotRecipe))); +} + +void HarmonicCalibration::setupChannelMeasurement(ChannelAddon *channelAddon) +{ + auto chMeasureableChannel = dynamic_cast(channelAddon); + if(!chMeasureableChannel) + return; + auto chMeasureManager = chMeasureableChannel->getMeasureManager(); + if(!chMeasureManager) + return; + if(measureSettings) { + connect(chMeasureManager, &MeasureManagerInterface::enableMeasurement, measurePanel, + &MeasurementsPanel::addMeasurement); + connect(chMeasureManager, &MeasureManagerInterface::disableMeasurement, measurePanel, + &MeasurementsPanel::removeMeasurement); + connect(measureSettings, &MeasurementSettings::toggleAllMeasurements, chMeasureManager, + &MeasureManagerInterface::toggleAllMeasurement); + connect(measureSettings, &MeasurementSettings::toggleAllStats, chMeasureManager, + &MeasureManagerInterface::toggleAllStats); + connect(chMeasureManager, &MeasureManagerInterface::enableStat, statsPanel, &StatsPanel::addStat); + connect(chMeasureManager, &MeasureManagerInterface::disableStat, statsPanel, &StatsPanel::removeStat); + } +} + +void HarmonicCalibration::setupChannelDelete(ChannelAddon *channelAddon) +{ + connect(channelAddon, SIGNAL(requestDeleteChannel(ChannelAddon *)), this, SLOT(deleteChannel(ChannelAddon *))); } -QStringList HarmonicCalibration::getDeviceList(iio_context *context) +void HarmonicCalibration::deleteChannel(ChannelAddon *ch) { - QStringList deviceList; - int devCount = iio_context_get_devices_count(context); - return deviceList; + + MenuControlButton *last = nullptr; + for(auto c : proxy->getChannelAddons()) { + auto ca = dynamic_cast(c); + if(ca == ch && last) { + last->animateClick(1); + } + + last = dynamic_cast(ca->getMenuControlWidget()); + } + proxy->removeChannelAddon(ch); + + ch->onStop(); + ch->disable(); + plotAddon->onChannelRemoved(ch); + plotAddonSettings->onChannelRemoved(ch); + ch->onDeinit(); + delete ch->getMenuControlWidget(); + delete ch; +} + +MenuControlButton *HarmonicCalibration::addChannel(ChannelAddon *channelAddon, QWidget *parent) +{ + MenuControlButton *menuControlButton = new MenuControlButton(parent); + channelAddon->setMenuControlWidget(menuControlButton); + channelGroup->addButton(menuControlButton); + + QString id = channelAddon->getName() + QString::number(uuid++); + setupChannelMenuControlButtonHelper(menuControlButton, channelAddon); + + channelStack->add(id, channelAddon->getWidget()); + + connect(menuControlButton, &QAbstractButton::clicked, this, [=, this](bool b) { + if(b) { + if(!channelsButton->button()->isChecked()) { + // Workaround because QButtonGroup and setChecked do not interact programatically + channelsButton->button()->animateClick(1); + } + + plotAddon->plot()->selectChannel(channelAddon->plotCh()); + channelStack->show(id); + } + }); + + setupChannelSnapshot(channelAddon); + setupChannelMeasurement(channelAddon); + setupChannelDelete(channelAddon); + plotAddon->onChannelAdded(channelAddon); + plotAddonSettings->onChannelAdded(channelAddon); + return menuControlButton; +} + +void HarmonicCalibration::setupDeviceMenuControlButtonHelper(MenuControlButton *deviceMenuControlButton, GRDeviceAddon *deviceAddon) +{ + deviceMenuControlButton->setName(deviceAddon->getName()); + deviceMenuControlButton->setCheckable(true); + deviceMenuControlButton->button()->setVisible(false); + deviceMenuControlButton->setOpenMenuChecksThis(true); + deviceMenuControlButton->setDoubleClickToOpenMenu(true); +} + +CollapsableMenuControlButton *HarmonicCalibration::addDevice(GRDeviceAddon *dev, QWidget *parent) +{ + auto devButton = new CollapsableMenuControlButton(parent); + setupDeviceMenuControlButtonHelper(devButton->getControlBtn(), dev); + channelGroup->addButton(devButton->getControlBtn()); + QString id = dev->getName() + QString::number(uuid++); + channelStack->add(id, dev->getWidget()); + connect(devButton->getControlBtn(), &QPushButton::toggled, this, [=, this](bool b) { + if(b) { + tool->requestMenu(channelsMenuId); + channelStack->show(id); + } + }); + return devButton; +} + +void HarmonicCalibration::init() +{ + auto addons = proxy->getAddons(); + proxy->init(); + //initCursors(); + for(auto addon : addons) { + addon->onInit(); + } +} + +void HarmonicCalibration::deinit() +{ + auto addons = proxy->getAddons(); + + for(auto addon : addons) { + addon->onDeinit(); + } +} + +void HarmonicCalibration::restart() +{ + if(m_running) { + run(false); + run(true); + } +} + +void HarmonicCalibration::showMeasurements(bool b) +{ + if(b) { + tool->requestMenu(measureMenuId); + tool->requestMenu(statsMenuId); + } + tool->openTopContainerHelper(b); + tool->openBottomContainerHelper(b); +} + +void HarmonicCalibration::createSnapshotChannel(SnapshotProvider::SnapshotRecipe rec) +{ + // proxy->getChannelAddons().append(new ch) + qInfo() << "Creating snapshot from recipe" << rec.name; + + ChannelIdProvider *chidp = proxy->getChannelIdProvider(); + int idx = chidp->next(); + ImportChannelAddon *ch = new ImportChannelAddon("REF-" + rec.name + "-" + QString::number(idx), plotAddon, + chidp->pen(idx), this); + proxy->addChannelAddon(ch); + ch->setData(rec.x, rec.y); + auto btn = addChannel(ch, verticalChannelManager); + verticalChannelManager->add(btn); + ch->onInit(); + btn->animateClick(1); +} + +bool HarmonicCalibration::running() const { return m_running; } + +void HarmonicCalibration::setRunning(bool newRunning) +{ + if(m_running == newRunning) + return; + m_running = newRunning; + Q_EMIT runningChanged(newRunning); +} + +void HarmonicCalibration::start() { run(true); } + +void HarmonicCalibration::stop() { run(false); } + +void HarmonicCalibration::startAddons() +{ + auto addons = proxy->getAddons(); + + for(auto addon : addons) { + addon->onStart(); + } +} +void HarmonicCalibration::stopAddons() +{ + auto addons = proxy->getAddons(); + + for(auto addon : addons) { + addon->onStop(); + } +} + +void HarmonicCalibration::run(bool b) +{ + qInfo() << b; + QElapsedTimer tim; + tim.start(); + + if(!b) { + runButton->setChecked(false); + } + + if(b) { + startAddons(); + } else { + stopAddons(); + } } \ No newline at end of file From 671e0b15e7549d6811e8e044f6d6b3028116baaa Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 18 Jun 2024 09:51:15 +0800 Subject: [PATCH 007/112] admt: Update CMakeList - Reverted C++ standard from 20 to 17 Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/.gitignore | 3 ++- plugins/admt/CMakeLists.txt | 18 +++++++++++++++--- .../include/admt/scopy-admt_config.h.cmakein | 10 ++++++++++ plugins/admt/src/harmoniccalibration.cpp | 12 ++++++------ 4 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 plugins/admt/include/admt/scopy-admt_config.h.cmakein diff --git a/plugins/admt/.gitignore b/plugins/admt/.gitignore index cf99da1b8f..a4793c0f9c 100644 --- a/plugins/admt/.gitignore +++ b/plugins/admt/.gitignore @@ -1 +1,2 @@ -include/admt/scopy-admt_export.h \ No newline at end of file +include/admt/scopy-admt_export.h +include/admt/scopy-admt_config.h \ No newline at end of file diff --git a/plugins/admt/CMakeLists.txt b/plugins/admt/CMakeLists.txt index f4929a0f86..88570b24b0 100644 --- a/plugins/admt/CMakeLists.txt +++ b/plugins/admt/CMakeLists.txt @@ -6,11 +6,14 @@ message(STATUS "building plugin: " ${SCOPY_MODULE}) project(scopy-${SCOPY_MODULE} VERSION 0.1 LANGUAGES CXX) +set(PLUGIN_DISPLAY_NAME "ADMT") +set(PLUGIN_DESCRIPTION "Plugin for ADMT Harmonic Calibration") + include(GenerateExportHeader) # TODO: split stylesheet/resources and add here TODO: export header files correctly -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/ui) @@ -50,6 +53,11 @@ generate_export_header( ${PROJECT_NAME} EXPORT_FILE_NAME ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}/${PROJECT_NAME}_export.h ) +configure_file( + include/${SCOPY_MODULE}/scopy-${SCOPY_MODULE}_config.h.cmakein + ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}/scopy-${SCOPY_MODULE}_config.h @ONLY +) + target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}) @@ -66,7 +74,11 @@ target_link_libraries( scopy-iio-widgets ) -set(PLUGIN_NAME ${PROJECT_NAME} PARENT_SCOPE) -set(PLUGIN_DESCRIPTION "ADMT plugin" PARENT_SCOPE) +if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + set(INSTALLER_DESCRIPTION "${PLUGIN_DISPLAY_NAME} ${PLUGIN_DESCRIPTION}") + configureinstallersettings(${SCOPY_MODULE} ${INSTALLER_DESCRIPTION} TRUE) +endif() + +set(ADMT_TARGET_NAME ${PROJECT_NAME} PARENT_SCOPE) install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${SCOPY_PLUGIN_INSTALL_DIR}) \ No newline at end of file diff --git a/plugins/admt/include/admt/scopy-admt_config.h.cmakein b/plugins/admt/include/admt/scopy-admt_config.h.cmakein new file mode 100644 index 0000000000..8e4f35c573 --- /dev/null +++ b/plugins/admt/include/admt/scopy-admt_config.h.cmakein @@ -0,0 +1,10 @@ +#ifndef SCOPY_ADMT_CONFIG_H_CMAKEIN +#define SCOPY_ADMT_CONFIG_H_CMAKEIN + +#define ADMT_PLUGIN_DISPLAY_NAME "@PLUGIN_DISPLAY_NAME@" +#define ADMT_PLUGIN_SCOPY_MODULE "@SCOPY_MODULE@" +#define ADMT_PLUGIN_DESCRIPTION "@PLUGIN_DESCRIPTION@" + +#cmakedefine ENABLE_SCOPYJS + +#endif // SCOPY_ADMT_CONFIG_H_CMAKEIN \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 56a0153acd..5ea2ffd110 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -46,7 +46,7 @@ HarmonicCalibration::HarmonicCalibration(PlotProxy *proxy, QWidget *parent) QString settingsMenuId = plotAddonSettings->getName() + QString(uuid++); tool->rightStack()->add(settingsMenuId, plotAddonSettings->getWidget()); - connect(settingsButton, &QPushButton::toggled, this, [=, this](bool b) { + connect(settingsButton, &QPushButton::toggled, this, [=](bool b) { if(b) tool->requestMenu(settingsMenuId); }); @@ -65,7 +65,7 @@ HarmonicCalibration::HarmonicCalibration(PlotProxy *proxy, QWidget *parent) measurePanelManagerHover->setContent(measureSettings); measurePanelManagerHover->setAnchorPos(HoverPosition::HP_TOPRIGHT); measurePanelManagerHover->setContentPos(HoverPosition::HP_TOPLEFT); - connect(measure->button(), &QPushButton::toggled, this, [=, this](bool b) { + connect(measure->button(), &QPushButton::toggled, this, [=](bool b) { measurePanelManagerHover->setVisible(b); measurePanelManagerHover->raise(); }); @@ -129,7 +129,7 @@ void HarmonicCalibration::setupChannelsButtonHelper(MenuControlButton *channelsB channelsButton->setChecked(true); channelStack = new MapStackedWidget(this); tool->rightStack()->add(channelsMenuId, channelStack); - connect(channelsButton->button(), &QAbstractButton::toggled, this, [=, this](bool b) { + connect(channelsButton->button(), &QAbstractButton::toggled, this, [=](bool b) { if(b) tool->requestMenu(channelsMenuId); }); @@ -154,7 +154,7 @@ void HarmonicCalibration::setupChannelMenuControlButtonHelper(MenuControlButton menuControlButton->button()->setVisible(false); menuControlButton->setCheckable(true); - connect(menuControlButton->checkBox(), &QCheckBox::toggled, this, [=, this](bool b) { + connect(menuControlButton->checkBox(), &QCheckBox::toggled, this, [=](bool b) { if(b) channelAddon->enable(); else @@ -233,7 +233,7 @@ MenuControlButton *HarmonicCalibration::addChannel(ChannelAddon *channelAddon, Q channelStack->add(id, channelAddon->getWidget()); - connect(menuControlButton, &QAbstractButton::clicked, this, [=, this](bool b) { + connect(menuControlButton, &QAbstractButton::clicked, this, [=](bool b) { if(b) { if(!channelsButton->button()->isChecked()) { // Workaround because QButtonGroup and setChecked do not interact programatically @@ -269,7 +269,7 @@ CollapsableMenuControlButton *HarmonicCalibration::addDevice(GRDeviceAddon *dev, channelGroup->addButton(devButton->getControlBtn()); QString id = dev->getName() + QString::number(uuid++); channelStack->add(id, dev->getWidget()); - connect(devButton->getControlBtn(), &QPushButton::toggled, this, [=, this](bool b) { + connect(devButton->getControlBtn(), &QPushButton::toggled, this, [=](bool b) { if(b) { tool->requestMenu(channelsMenuId); channelStack->show(id); From 65741a1fd1340a559f22568b05dd51deb3df8c08 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 26 Jun 2024 09:07:19 +0800 Subject: [PATCH 008/112] admt: Added historical graph Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 4 +++ plugins/admt/src/harmoniccalibration.cpp | 32 +++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index b8d00bbf59..7a4bda8351 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -2,6 +2,7 @@ #define HARMONICCALIBRATION_H #include "scopy-admt_export.h" +#include "sismograph.hpp" #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include #include @@ -73,6 +75,8 @@ public Q_SLOTS: MeasurementSettings *measureSettings; StatsPanel *statsPanel; + Sismograph *dataGraph, *tempGraph; + void setupChannelsButtonHelper(MenuControlButton *channelsButton); void setupMeasureButtonHelper(MenuControlButton *measureButton); void setupChannelSnapshot(ChannelAddon *channelAddon); diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 5ea2ffd110..9284bc0ddd 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -39,7 +39,7 @@ HarmonicCalibration::HarmonicCalibration(PlotProxy *proxy, QWidget *parent) setupChannelsButtonHelper(channelsButton); plotAddon = dynamic_cast(proxy->getPlotAddon()); - tool->addWidgetToCentralContainerHelper(plotAddon->getWidget()); + // tool->addWidgetToCentralContainerHelper(plotAddon->getWidget()); plotAddonSettings = dynamic_cast(proxy->getPlotSettings()); rightMenuButtonGroup->addButton(settingsButton); @@ -54,8 +54,8 @@ HarmonicCalibration::HarmonicCalibration(PlotProxy *proxy, QWidget *parent) MenuControlButton *measure = new MenuControlButton(this); setupMeasureButtonHelper(measure); measurePanel = new MeasurementsPanel(this); - tool->topStack()->add(measureMenuId, measurePanel); - tool->openTopContainerHelper(false); + //tool->topStack()->add(measureMenuId, measurePanel); + //tool->openTopContainerHelper(false); statsPanel = new StatsPanel(this); tool->bottomStack()->add(statsMenuId, statsPanel); @@ -92,6 +92,32 @@ HarmonicCalibration::HarmonicCalibration(PlotProxy *proxy, QWidget *parent) verticalChannelManager = new VerticalChannelManager(this); tool->leftStack()->add(verticalChannelManagerId, verticalChannelManager); + QWidget *historicalGraphWidget = new QWidget(); + QVBoxLayout *historicalGraphLayout = new QVBoxLayout(this); + + dataGraph = new Sismograph(this); + dataGraph->setColor(QColor("#ff7200")); + dataGraph->setAutoscale(false); + dataGraph->addScale(-1.0, 1.0, 5, 5); + dataGraph->addScale(-5.0, 5.0, 10, 2); + dataGraph->addScale(-25.0, 25.0, 10, 5); + dataGraph->setUnitOfMeasure("Voltage", "V"); + + tempGraph = new Sismograph(this); + tempGraph->setColor(QColor("#9013fe")); + tempGraph->setAutoscale(false); + tempGraph->addScale(-1.0, 1.0, 5, 5); + tempGraph->addScale(-5.0, 5.0, 10, 2); + tempGraph->addScale(-25.0, 25.0, 10, 5); + tempGraph->setUnitOfMeasure("Voltage", "V"); + + historicalGraphLayout->addWidget(dataGraph); + historicalGraphLayout->addWidget(tempGraph); + + historicalGraphWidget->setLayout(historicalGraphLayout); + + tool->addWidgetToCentralContainerHelper(historicalGraphWidget); + channelGroup = new QButtonGroup(this); for(auto d : proxy->getDeviceAddons()) { GRDeviceAddon *dev = dynamic_cast(d); From 2f4d1bf7062a7a86a22d3902505a819ab82d991a Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 9 Jul 2024 11:03:43 +0800 Subject: [PATCH 009/112] admt: Implemented GUI interface and controller Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 46 ++ plugins/admt/include/admt/admtplugin.h | 7 +- .../admt/include/admt/harmoniccalibration.h | 73 +- plugins/admt/src/admtcontroller.cpp | 178 +++++ plugins/admt/src/admtplugin.cpp | 13 +- plugins/admt/src/harmoniccalibration.cpp | 666 +++++++++--------- 6 files changed, 620 insertions(+), 363 deletions(-) create mode 100644 plugins/admt/include/admt/admtcontroller.h create mode 100644 plugins/admt/src/admtcontroller.cpp diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h new file mode 100644 index 0000000000..dfa6e1976e --- /dev/null +++ b/plugins/admt/include/admt/admtcontroller.h @@ -0,0 +1,46 @@ +#ifndef ADMTCONTROLLER_H +#define ADMTCONTROLLER_H + +#include +#include + +#include +#include + +#include + +namespace scopy::admt { +class ADMTController : public QObject +{ + Q_OBJECT +public: + ADMTController(QString uri, QObject *parent = nullptr); + ~ADMTController(); + + enum Channel + { + ROTATION, + ANGLE, + COUNT, + TEMPERATURE, + CHANNEL_COUNT + }; + + const char* ChannelIds[CHANNEL_COUNT] = {"rot", "angl", "count", "temp"}; + + const char* getChannelId(Channel channel); + + void connectADMT(); + void disconnectADMT(); + QString getChannelValue(); + int getChannelIndex(const char *channelName); + double getChannelValue(const char *channelName, int bufferSize); +private: + iio_context *m_iioCtx; + iio_buffer *m_iioBuffer; + Connection *m_conn; + QString uri; +}; +} // namespace scopy::admt + +#endif // ADMTCONTROLLER_H \ No newline at end of file diff --git a/plugins/admt/include/admt/admtplugin.h b/plugins/admt/include/admt/admtplugin.h index d5cc29709d..add9ec0dc6 100644 --- a/plugins/admt/include/admt/admtplugin.h +++ b/plugins/admt/include/admt/admtplugin.h @@ -4,6 +4,7 @@ #define SCOPY_PLUGIN_NAME ADMTPlugin #include "scopy-admt_export.h" +#include "admtcontroller.h" #include @@ -24,8 +25,8 @@ #include #include -namespace scopy { -using namespace grutil; +namespace scopy::admt { +using namespace scopy::grutil; class SCOPY_ADMT_EXPORT ChannelIdProvider : public QObject { @@ -168,6 +169,8 @@ public Q_SLOTS: QLineEdit *edit; PlotProxy *createRecipe(iio_context *ctx); GRTimePlotProxy *recipe; + + ADMTController *m_admtController; }; } // namespace scopy::admt #endif // ADMTPLUGIN_H diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 7a4bda8351..7d029d564d 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -4,7 +4,6 @@ #include "scopy-admt_export.h" #include "sismograph.hpp" -#include #include #include #include @@ -13,33 +12,31 @@ #include #include #include -#include +#include +#include +#include -#include #include +#include +#include +#include #include #include #include #include #include #include -#include -#include +#include +#include -namespace scopy { -class MenuControlButton; -class CollapsableMenuControlButton; +namespace scopy::admt { class HarmonicCalibration : public QWidget { Q_OBJECT public: - HarmonicCalibration(PlotProxy *proxy, QWidget *parent = nullptr); + HarmonicCalibration(ADMTController *m_admtController, QWidget *parent = nullptr); ~HarmonicCalibration(); - void init(); - void deinit(); - void startAddons(); - void stopAddons(); bool running() const; void setRunning(bool newRunning); public Q_SLOTS: @@ -47,49 +44,47 @@ public Q_SLOTS: void stop(); void start(); void restart(); - void showMeasurements(bool b); - void createSnapshotChannel(SnapshotProvider::SnapshotRecipe rec); - void deleteChannel(ChannelAddon *); - MenuControlButton *addChannel(ChannelAddon *channelAddon, QWidget *parent); - CollapsableMenuControlButton *addDevice(GRDeviceAddon *dev, QWidget *parent); + void timerTask(); Q_SIGNALS: void runningChanged(bool); private: + ADMTController *m_admtController; + iio_context *m_ctx; bool m_running; ToolTemplate *tool; GearBtn *settingsButton; InfoBtn *infoButton; RunBtn *runButton; + double rotation, angle, count, temp; + QPushButton *openLastMenuButton; - PlotProxy *proxy; - GRTimePlotAddon *plotAddon; - GRTimePlotAddonSettings *plotAddonSettings; QButtonGroup *rightMenuButtonGroup; - MenuControlButton *channelsButton; - VerticalChannelManager *verticalChannelManager; - QButtonGroup *channelGroup; - MapStackedWidget *channelStack; - MeasurementsPanel *measurePanel; - MeasurementSettings *measureSettings; - StatsPanel *statsPanel; + QLineEdit *sampleRateLineEdit, *bufferSizeLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit; + QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel; Sismograph *dataGraph, *tempGraph; - void setupChannelsButtonHelper(MenuControlButton *channelsButton); - void setupMeasureButtonHelper(MenuControlButton *measureButton); - void setupChannelSnapshot(ChannelAddon *channelAddon); - void setupChannelMeasurement(ChannelAddon *channelAddon); - void setupChannelDelete(ChannelAddon *channelAddon); - void setupChannelMenuControlButtonHelper(MenuControlButton *menuControlButton, ChannelAddon *channelAddon); - void setupDeviceMenuControlButtonHelper(MenuControlButton *menuControlButton, GRDeviceAddon *channelAddon); + MenuHeaderWidget *header; + + MenuSectionWidget *rightMenuSectionWidget; + MenuCollapseSection *rotationCollapse, *angleCollapse, *countCollapse, *tempCollapse; + MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo; + + void updateChannelValues(); + void updateLineEditValues(); + void updateGeneralSettingEnabled(bool value); + void connectLineEditToNumber(QLineEdit* lineEdit, int& variable); + void connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph); + void connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph); + void changeGraphColorByChannelName(Sismograph* graph, const char* channelName); + void connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph); + + QTimer *timer; int uuid = 0; - const QString channelsMenuId = "channels"; - const QString measureMenuId = "measure"; - const QString statsMenuId = "stats"; - const QString verticalChannelManagerId = "vcm"; + const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; }; } // namespace scopy::admt #endif // HARMONICCALIBRATION_H diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp new file mode 100644 index 0000000000..d84a148277 --- /dev/null +++ b/plugins/admt/src/admtcontroller.cpp @@ -0,0 +1,178 @@ +#include "admtcontroller.h" + +#include + +#include +#include +#include +#include +#include + +static const size_t maxAttrSize = 512; + +using namespace scopy::admt; +using namespace std; + +ADMTController::ADMTController(QString uri, QObject *parent) + :QObject(parent) + , uri(uri) +{ + +} + +ADMTController::~ADMTController() {} + +void ADMTController::connectADMT() +{ + m_conn = ConnectionProvider::open(uri); + m_iioCtx = m_conn->context(); +} + +void ADMTController::disconnectADMT() +{ + if(!m_conn || !m_iioCtx){ + return; + } + + ConnectionProvider::close(uri); + m_conn = nullptr; + m_iioCtx = nullptr; + +} + +const char* ADMTController::getChannelId(Channel channel) +{ + if(channel >= 0 && channel < CHANNEL_COUNT){ + return ChannelIds[channel]; + } + return "Unknown"; +} + +int ADMTController::getChannelIndex(const char *channelName) +{ + iio_device *admtDevice = iio_context_find_device(m_iioCtx, "admt4000"); + int channelCount = iio_device_get_channels_count(admtDevice); + iio_channel *channel; + std::string message = ""; + for(int i = 0; i < channelCount; i++){ + channel = iio_device_get_channel(admtDevice, i); + const char *deviceChannel = iio_channel_get_id(channel); + + std::string strDeviceChannel = std::string(deviceChannel); + std::string strChannelName = std::string(channelName); + + if(deviceChannel != nullptr && strDeviceChannel == strChannelName){ + message = message + "[" + std::to_string(i) + "]" + std::string(deviceChannel) + ", "; + return iio_channel_get_index(channel); + } + else { + channel = NULL; + } + } + return -1; +} + +double ADMTController::getChannelValue(const char *channelName, int bufferSize = 1) +{ + double value; + char converted[bufferSize] = ""; + + int deviceCount = iio_context_get_devices_count(m_iioCtx); + //if(deviceCount < 1) return QString("No devices found"); + + iio_device *admtDevice = iio_context_find_device(m_iioCtx, "admt4000"); + //if(admtDevice == NULL) return QString("No ADMT4000 device"); + + int channelCount = iio_device_get_channels_count(admtDevice); + //if(channelCount < 1) return QString("No channels found."); + + iio_channel *channel; + std::string message = ""; + for(int i = 0; i < channelCount; i++){ + channel = iio_device_get_channel(admtDevice, i); + const char *deviceChannel = iio_channel_get_id(channel); + + if(deviceChannel != nullptr && std::string(deviceChannel) == std::string(channelName)){ + message = message + "[" + std::to_string(i) + "]" + std::string(deviceChannel) + ", "; + break; + } + else { + channel = NULL; + } + } + if(channel == NULL) { + //return QString::fromStdString(message); + } + iio_channel_enable(channel); + + double scale = 1.0; + int offsetAttrVal = 0; + const char *scaleAttrName = "scale"; + const char *offsetAttrName = "offset"; + const char *scaleAttr = iio_channel_find_attr(channel, scaleAttrName); + //if(scaleAttr == NULL) return QString("No scale attribute"); + const char *offsetAttr = iio_channel_find_attr(channel, offsetAttrName); + //if(offsetAttr == NULL) return QString("No offset attribute"); + + double *scaleVal = new double(1); + int scaleRet = iio_channel_attr_read_double(channel, scaleAttr, scaleVal); + //if(scaleRet != 0) return QString("Cannot read scale attribute"); + scale = *scaleVal; + + char *offsetDst = new char[maxAttrSize]; + iio_channel_attr_read(channel, offsetAttr, offsetDst, maxAttrSize); + offsetAttrVal = std::atoi(offsetDst); + + iio_buffer *iioBuffer = iio_device_create_buffer(admtDevice, bufferSize, false); + //if(!iioBuffer) return QString("Cannot create buffer."); + + ssize_t numBytesRead; + int8_t *pointerData, *pointerEnd; + void *buffer; + ptrdiff_t pointerIncrement; + + numBytesRead = iio_buffer_refill(iioBuffer); + //if(numBytesRead < 1) return QString("Cannot refill buffer."); + + pointerIncrement = reinterpret_cast(iio_buffer_step(iioBuffer)); + pointerEnd = static_cast(iio_buffer_end(iioBuffer)); + + const struct iio_data_format *format = iio_channel_get_data_format(channel); + const struct iio_data_format channelFormat = *format; + unsigned int repeat = channelFormat.repeat; + uint8_t bitLength = static_cast(channelFormat.bits); + size_t offset = static_cast(channelFormat.shift); + + QString result; + std::list rawSamples; + // std::list unsignedSamples; + std::list castSamples; + + size_t sample, bytes; + + size_t sampleSize = channelFormat.length / 8 * repeat; + //if(sampleSize == 0) return QString("Sample size is zero."); + + buffer = malloc(sampleSize * bufferSize); + //if(!buffer) return QString("Cannot allocate memory for buffer."); + + bytes = iio_channel_read(channel, iioBuffer, buffer, sampleSize * bufferSize); + for(sample = 0; sample < bytes / sampleSize; ++sample) + { + for(int j = 0; j < repeat; ++j) + { + if(channelFormat.length / 8 == sizeof(int16_t)) + { + rawSamples.push_back(*((int8_t*)buffer)); + int16_t rawValue = ((int16_t*)buffer)[sample+j]; + castSamples.push_back(rawValue); + value = (rawValue - static_cast(offsetAttrVal)) * scale; + result = QString::number(value); + } + } + } + + message = message + result.toStdString(); + iio_buffer_destroy(iioBuffer); + return value; //QString::fromStdString(message); +} \ No newline at end of file diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index 5e9b170c6e..0fe8fdc29a 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -1,4 +1,5 @@ #include "admtplugin.h" +#include "admtcontroller.h" #include "harmoniccalibration.h" #include @@ -7,7 +8,7 @@ #include Q_LOGGING_CATEGORY(CAT_ADMTPLUGIN, "ADMTPlugin") -using namespace scopy; +using namespace scopy::admt; using namespace scopy::grutil; bool ADMTPlugin::compatible(QString m_param, QString category) @@ -27,7 +28,7 @@ bool ADMTPlugin::compatible(QString m_param, QString category) } ConnectionProvider::close(m_param); - + ret = true; return ret; } @@ -159,9 +160,11 @@ bool ADMTPlugin::onConnect() m_toolList[0]->setEnabled(true); m_toolList[0]->setRunBtnVisible(true); - auto recipe = createRecipe(m_ctx); + //auto recipe = createRecipe(m_ctx); - harmonicCalibration = new HarmonicCalibration(recipe); + m_admtController = new ADMTController(m_param, this); + m_admtController->connectADMT(); + harmonicCalibration = new HarmonicCalibration(m_admtController); m_toolList[0]->setTool(harmonicCalibration); return true; @@ -181,6 +184,8 @@ bool ADMTPlugin::onDisconnect() delete(w); } } + + m_admtController->disconnectADMT(); return true; } diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 9284bc0ddd..b053710068 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -2,406 +2,436 @@ #include +static int sampleRate = 50; +static int bufferSize = 1; +static int dataGraphSamples = 100; +static int tempGraphSamples = 100; +static bool running = false; +static double *dataGraphValue; + using namespace scopy; +using namespace scopy::admt; using namespace scopy::grutil; -HarmonicCalibration::HarmonicCalibration(PlotProxy *proxy, QWidget *parent) +HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidget *parent) : QWidget(parent) - , proxy(proxy) + , m_admtController(m_admtController) { + rotationChannelName = m_admtController->getChannelId(ADMTController::Channel::ROTATION); + angleChannelName = m_admtController->getChannelId(ADMTController::Channel::ANGLE); + countChannelName = m_admtController->getChannelId(ADMTController::Channel::COUNT); + temperatureChannelName = m_admtController->getChannelId(ADMTController::Channel::TEMPERATURE); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QHBoxLayout *lay = new QHBoxLayout(this); - lay->setMargin(0); - setLayout(lay); tool = new ToolTemplate(this); - tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - tool->topContainer()->setVisible(true); - tool->leftContainer()->setVisible(true); - tool->rightContainer()->setVisible(true); - tool->bottomContainer()->setVisible(true); + setLayout(lay); + lay->setMargin(0); lay->addWidget(tool); - tool->setLeftContainerWidth(210); - tool->setRightContainerWidth(300); - tool->setTopContainerHeight(100); - tool->setBottomContainerHeight(90); - + openLastMenuButton = new OpenLastMenuBtn(dynamic_cast(tool->rightContainer()), true, this); rightMenuButtonGroup = dynamic_cast(openLastMenuButton)->getButtonGroup(); - - tool->openBottomContainerHelper(false); - tool->openTopContainerHelper(false); settingsButton = new GearBtn(this); infoButton = new InfoBtn(this); runButton = new RunBtn(this); - channelsButton = new MenuControlButton(this); - setupChannelsButtonHelper(channelsButton); - - plotAddon = dynamic_cast(proxy->getPlotAddon()); - // tool->addWidgetToCentralContainerHelper(plotAddon->getWidget()); - - plotAddonSettings = dynamic_cast(proxy->getPlotSettings()); rightMenuButtonGroup->addButton(settingsButton); - QString settingsMenuId = plotAddonSettings->getName() + QString(uuid++); - tool->rightStack()->add(settingsMenuId, plotAddonSettings->getWidget()); - connect(settingsButton, &QPushButton::toggled, this, [=](bool b) { - if(b) - tool->requestMenu(settingsMenuId); - }); - - MenuControlButton *measure = new MenuControlButton(this); - setupMeasureButtonHelper(measure); - measurePanel = new MeasurementsPanel(this); - //tool->topStack()->add(measureMenuId, measurePanel); - //tool->openTopContainerHelper(false); - - statsPanel = new StatsPanel(this); - tool->bottomStack()->add(statsMenuId, statsPanel); - - measureSettings = new MeasurementSettings(this); - HoverWidget *measurePanelManagerHover = new HoverWidget(nullptr, measure, tool); - measurePanelManagerHover->setContent(measureSettings); - measurePanelManagerHover->setAnchorPos(HoverPosition::HP_TOPRIGHT); - measurePanelManagerHover->setContentPos(HoverPosition::HP_TOPLEFT); - connect(measure->button(), &QPushButton::toggled, this, [=](bool b) { - measurePanelManagerHover->setVisible(b); - measurePanelManagerHover->raise(); - }); - connect(measureSettings, &MeasurementSettings::enableMeasurementPanel, tool->topCentral(), - &QWidget::setVisible); - connect(measureSettings, &MeasurementSettings::enableStatsPanel, tool->bottomCentral(), &QWidget::setVisible); - - connect(measureSettings, &MeasurementSettings::sortMeasurements, measurePanel, &MeasurementsPanel::sort); - connect(measureSettings, &MeasurementSettings::sortStats, statsPanel, &StatsPanel::sort); - - tool->addWidgetToTopContainerMenuControlHelper(openLastMenuButton, TTA_RIGHT); - tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); - - tool->addWidgetToTopContainerHelper(infoButton, TTA_LEFT); - tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); - - tool->addWidgetToBottomContainerHelper(channelsButton, TTA_LEFT); - tool->addWidgetToBottomContainerHelper(measure, TTA_RIGHT); - - connect(channelsButton, &QPushButton::toggled, dynamic_cast(tool->leftContainer()), - &MenuHAnim::toggleMenu); - - // Left Channel Manager - verticalChannelManager = new VerticalChannelManager(this); - tool->leftStack()->add(verticalChannelManagerId, verticalChannelManager); + // Raw Data Widget + QScrollArea *rawDataScroll = new QScrollArea(this); + rawDataScroll->setWidgetResizable(true); + QWidget *rawDataWidget = new QWidget(rawDataScroll); + rawDataScroll->setWidget(rawDataWidget); + QVBoxLayout *rawDataLayout = new QVBoxLayout(rawDataWidget); + rawDataLayout->setMargin(0); + // rawDataLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed)); + rawDataWidget->setLayout(rawDataLayout); + + MenuSectionWidget *rotationWidget = new MenuSectionWidget(rawDataWidget); + MenuSectionWidget *angleWidget = new MenuSectionWidget(rawDataWidget); + MenuSectionWidget *countWidget = new MenuSectionWidget(rawDataWidget); + MenuSectionWidget *tempWidget = new MenuSectionWidget(rawDataWidget); + rotationWidget->contentLayout()->setSpacing(10); + angleWidget->contentLayout()->setSpacing(10); + countWidget->contentLayout()->setSpacing(10); + tempWidget->contentLayout()->setSpacing(10); + MenuCollapseSection *rotationSection = new MenuCollapseSection("Rotation", MenuCollapseSection::MHCW_NONE, rotationWidget); + MenuCollapseSection *angleSection = new MenuCollapseSection("Angle", MenuCollapseSection::MHCW_NONE, angleWidget); + MenuCollapseSection *countSection = new MenuCollapseSection("Count", MenuCollapseSection::MHCW_NONE, countWidget); + MenuCollapseSection *tempSection = new MenuCollapseSection("Temperature", MenuCollapseSection::MHCW_NONE, tempWidget); + rotationSection->contentLayout()->setSpacing(10); + angleSection->contentLayout()->setSpacing(10); + countSection->contentLayout()->setSpacing(10); + tempSection->contentLayout()->setSpacing(10); + + rotationWidget->contentLayout()->addWidget(rotationSection); + angleWidget->contentLayout()->addWidget(angleSection); + countWidget->contentLayout()->addWidget(countSection); + tempWidget->contentLayout()->addWidget(tempSection); + + rawDataLayout->addWidget(rotationWidget); + rawDataLayout->addWidget(angleWidget); + rawDataLayout->addWidget(countWidget); + rawDataLayout->addWidget(tempWidget); + rawDataLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + rotationValueLabel = new QLabel(rotationSection); + StyleHelper::MenuControlLabel(rotationValueLabel, "rotationValueLabel"); + angleValueLabel = new QLabel(angleSection); + StyleHelper::MenuControlLabel(angleValueLabel, "angleValueLabel"); + countValueLabel = new QLabel(countSection); + StyleHelper::MenuControlLabel(countValueLabel, "countValueLabel"); + tempValueLabel = new QLabel(tempSection); + StyleHelper::MenuControlLabel(tempValueLabel, "tempValueLabel"); + + updateChannelValues(); + updateLineEditValues(); + + rotationSection->contentLayout()->addWidget(rotationValueLabel); + angleSection->contentLayout()->addWidget(angleValueLabel); + countSection->contentLayout()->addWidget(countValueLabel); + tempSection->contentLayout()->addWidget(tempValueLabel); QWidget *historicalGraphWidget = new QWidget(); QVBoxLayout *historicalGraphLayout = new QVBoxLayout(this); + QLabel *dataGraphLabel = new QLabel(historicalGraphWidget); + dataGraphLabel->setText("Phase"); + StyleHelper::MenuSmallLabel(dataGraphLabel, "dataGraphLabel"); + dataGraph = new Sismograph(this); dataGraph->setColor(QColor("#ff7200")); + dataGraph->setPlotAxisXTitle("Degree (°)"); + dataGraph->setPlotDirection(Sismograph::LEFT_TO_RIGHT); + dataGraph->setUnitOfMeasure("Degree", "°"); dataGraph->setAutoscale(false); - dataGraph->addScale(-1.0, 1.0, 5, 5); - dataGraph->addScale(-5.0, 5.0, 10, 2); - dataGraph->addScale(-25.0, 25.0, 10, 5); - dataGraph->setUnitOfMeasure("Voltage", "V"); + dataGraph->addScale(-30.0, 390.0, 15, 5); + dataGraph->setNumSamples(dataGraphSamples); + dataGraphValue = &rotation; + dataGraph->plot(*dataGraphValue); + + QLabel *tempGraphLabel = new QLabel(historicalGraphWidget); + tempGraphLabel->setText("Temperature"); + StyleHelper::MenuSmallLabel(tempGraphLabel, "tempGraphLabel"); tempGraph = new Sismograph(this); - tempGraph->setColor(QColor("#9013fe")); + changeGraphColorByChannelName(tempGraph, temperatureChannelName); + tempGraph->setPlotAxisXTitle("Celsius (°C)"); + tempGraph->setPlotDirection(Sismograph::LEFT_TO_RIGHT); + tempGraph->setUnitOfMeasure("Celsius", "°C"); tempGraph->setAutoscale(false); - tempGraph->addScale(-1.0, 1.0, 5, 5); - tempGraph->addScale(-5.0, 5.0, 10, 2); - tempGraph->addScale(-25.0, 25.0, 10, 5); - tempGraph->setUnitOfMeasure("Voltage", "V"); + tempGraph->addScale(0.0, 100.0, 25, 5); + tempGraph->setNumSamples(tempGraphSamples); + tempGraph->plot(temp); + historicalGraphLayout->addWidget(dataGraphLabel); historicalGraphLayout->addWidget(dataGraph); + historicalGraphLayout->addWidget(tempGraphLabel); historicalGraphLayout->addWidget(tempGraph); historicalGraphWidget->setLayout(historicalGraphLayout); - tool->addWidgetToCentralContainerHelper(historicalGraphWidget); + // General Setting + QScrollArea *generalSettingScroll = new QScrollArea(this); + generalSettingScroll->setWidgetResizable(true); + QWidget *generalSettingWidget = new QWidget(generalSettingScroll); + generalSettingScroll->setWidget(generalSettingWidget); + QVBoxLayout *generalSettingLayout = new QVBoxLayout(generalSettingWidget); + generalSettingLayout->setMargin(0); + generalSettingWidget->setLayout(generalSettingLayout); + + header = new MenuHeaderWidget("ADMT4000", QPen(StyleHelper::getColor("ScopyBlue")), this); + + // General Setting Widget + MenuSectionWidget *generalWidget = new MenuSectionWidget(generalSettingWidget); + generalWidget->contentLayout()->setSpacing(10); + MenuCollapseSection *generalSection = new MenuCollapseSection("Data Acquisition", MenuCollapseSection::MHCW_NONE, generalWidget); + generalSection->contentLayout()->setSpacing(10); + generalWidget->contentLayout()->addWidget(generalSection); + + // Sample Rate + QLabel *sampleRateLabel = new QLabel(generalSection); + sampleRateLabel->setText("Sample Rate (Update Freq.)"); + StyleHelper::MenuSmallLabel(sampleRateLabel, "sampleRateLabel"); + sampleRateLineEdit = new QLineEdit(generalSection); + sampleRateLineEdit->setText(QString::number(sampleRate)); + + connectLineEditToNumber(sampleRateLineEdit, sampleRate); + + generalSection->contentLayout()->addWidget(sampleRateLabel); + generalSection->contentLayout()->addWidget(sampleRateLineEdit); + + // Buffer Size + QLabel *bufferSizeLabel = new QLabel(generalSection); + bufferSizeLabel->setText("Buffer Sample Size"); + StyleHelper::MenuSmallLabel(bufferSizeLabel, "bufferSizeLabel"); + bufferSizeLineEdit = new QLineEdit(generalSection); + bufferSizeLineEdit->setText(QString::number(bufferSize)); + + connectLineEditToNumber(bufferSizeLineEdit, bufferSize); + + generalSection->contentLayout()->addWidget(bufferSizeLabel); + generalSection->contentLayout()->addWidget(bufferSizeLineEdit); + + // Data Graph Setting Widget + MenuSectionWidget *dataGraphWidget = new MenuSectionWidget(generalSettingWidget); + dataGraphWidget->contentLayout()->setSpacing(10); + MenuCollapseSection *dataGraphSection = new MenuCollapseSection("Data Graph", MenuCollapseSection::MHCW_NONE, dataGraphWidget); + dataGraphSection->contentLayout()->setSpacing(10); + + // Graph Channel + m_dataGraphChannelMenuCombo = new MenuCombo("Graph Channel", dataGraphSection); + auto dataGraphChannelCombo = m_dataGraphChannelMenuCombo->combo(); + dataGraphChannelCombo->addItem("Rotation", QVariant::fromValue(reinterpret_cast(const_cast(rotationChannelName)))); + dataGraphChannelCombo->addItem("Angle", QVariant::fromValue(reinterpret_cast(const_cast(angleChannelName)))); + dataGraphChannelCombo->addItem("Count", QVariant::fromValue(reinterpret_cast(const_cast(countChannelName)))); + + connectMenuComboToGraphChannel(m_dataGraphChannelMenuCombo, dataGraph); + + dataGraphSection->contentLayout()->addWidget(m_dataGraphChannelMenuCombo); + + // Graph Samples + QLabel *dataGraphSamplesLabel = new QLabel(generalSection); + dataGraphSamplesLabel->setText("Graph Samples"); + StyleHelper::MenuSmallLabel(dataGraphSamplesLabel, "dataGraphSamplesLabel"); + dataGraphSamplesLineEdit = new QLineEdit(generalSection); + dataGraphSamplesLineEdit->setText(QString::number(dataGraphSamples)); + + connectLineEditToGraphSamples(dataGraphSamplesLineEdit, dataGraphSamples, dataGraph); + + dataGraphSection->contentLayout()->addWidget(dataGraphSamplesLabel); + dataGraphSection->contentLayout()->addWidget(dataGraphSamplesLineEdit); + + // Graph Direction + m_dataGraphDirectionMenuCombo = new MenuCombo("Graph Direction", dataGraphSection); + auto dataGraphDirectionCombo = m_dataGraphDirectionMenuCombo->combo(); + dataGraphDirectionCombo->addItem("Left to right", Sismograph::LEFT_TO_RIGHT); + dataGraphDirectionCombo->addItem("Right to left", Sismograph::RIGHT_TO_LEFT); + dataGraphSection->contentLayout()->addWidget(m_dataGraphDirectionMenuCombo); + + dataGraphWidget->contentLayout()->addWidget(dataGraphSection); + + connectMenuComboToGraphDirection(m_dataGraphDirectionMenuCombo, dataGraph); + + // Temperature Graph + MenuSectionWidget *tempGraphWidget = new MenuSectionWidget(generalSettingWidget); + tempGraphWidget->contentLayout()->setSpacing(10); + MenuCollapseSection *tempGraphSection = new MenuCollapseSection("Temperature Graph", MenuCollapseSection::MHCW_NONE, tempGraphWidget); + tempGraphSection->contentLayout()->setSpacing(10); + + // Graph Samples + QLabel *tempGraphSamplesLabel = new QLabel(generalSection); + tempGraphSamplesLabel->setText("Graph Samples"); + StyleHelper::MenuSmallLabel(tempGraphSamplesLabel, "tempGraphSamplesLabel"); + tempGraphSamplesLineEdit = new QLineEdit(generalSection); + tempGraphSamplesLineEdit->setText(QString::number(tempGraphSamples)); + tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLabel); + tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLineEdit); + + connectLineEditToGraphSamples(tempGraphSamplesLineEdit, tempGraphSamples, tempGraph); + + // Graph Direction + m_tempGraphDirectionMenuCombo = new MenuCombo("Graph Direction", tempGraphSection); + auto tempGraphDirectionCombo = m_tempGraphDirectionMenuCombo->combo(); + tempGraphDirectionCombo->addItem("Left to right", Sismograph::LEFT_TO_RIGHT); + tempGraphDirectionCombo->addItem("Right to left", Sismograph::RIGHT_TO_LEFT); + tempGraphSection->contentLayout()->addWidget(m_tempGraphDirectionMenuCombo); + tempGraphWidget->contentLayout()->addWidget(tempGraphSection); + + connectMenuComboToGraphDirection(m_tempGraphDirectionMenuCombo, tempGraph); + + generalSettingLayout->addWidget(header); + generalSettingLayout->addSpacerItem(new QSpacerItem(0, 3, QSizePolicy::Fixed, QSizePolicy::Fixed)); + generalSettingLayout->addWidget(generalWidget); + generalSettingLayout->addWidget(dataGraphWidget); + generalSettingLayout->addWidget(tempGraphWidget); + generalSettingLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); - channelGroup = new QButtonGroup(this); - for(auto d : proxy->getDeviceAddons()) { - GRDeviceAddon *dev = dynamic_cast(d); - if(!dev) - continue; - CollapsableMenuControlButton *devButton = addDevice(dev, verticalChannelManager); - verticalChannelManager->add(devButton); - - for(TimeChannelAddon *channelAddon : dev->getRegisteredChannels()) { - auto menuControlButton = addChannel(channelAddon, devButton); - devButton->add(menuControlButton); - } - } + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(true); + tool->leftContainer()->setVisible(true); + tool->rightContainer()->setVisible(true); + tool->bottomContainer()->setVisible(true); + tool->setLeftContainerWidth(210); + tool->setRightContainerWidth(300); + tool->setTopContainerHeight(100); + tool->setBottomContainerHeight(90); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + tool->addWidgetToTopContainerMenuControlHelper(openLastMenuButton, TTA_RIGHT); + tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); + tool->addWidgetToTopContainerHelper(infoButton, TTA_LEFT); + tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); + // tool->leftStack()->add("rawDataWidget", rawDataWidget); + tool->leftStack()->add("rawDataScroll", rawDataScroll); + tool->rightStack()->add("generalSettingScroll", generalSettingScroll); + tool->addWidgetToCentralContainerHelper(historicalGraphWidget); connect(runButton, &QPushButton::toggled, this, &HarmonicCalibration::setRunning); connect(this, &HarmonicCalibration::runningChanged, this, &HarmonicCalibration::run); connect(this, &HarmonicCalibration::runningChanged, runButton, &QAbstractButton::setChecked); - connect(plotAddon, &GRTimePlotAddon::requestStop, this, &HarmonicCalibration::stop, Qt::QueuedConnection); - connect(measure, &MenuControlButton::toggled, this, &HarmonicCalibration::showMeasurements); - channelsButton->button()->setChecked(true); - channelGroup->buttons()[1]->setChecked(true); - - init(); + timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, &HarmonicCalibration::timerTask); } HarmonicCalibration::~HarmonicCalibration() {} -void HarmonicCalibration::setupChannelsButtonHelper(MenuControlButton *channelsButton) -{ - channelsButton->setName("Channels"); - channelsButton->setOpenMenuChecksThis(true); - channelsButton->setDoubleClickToOpenMenu(true); - channelsButton->checkBox()->setVisible(false); - channelsButton->setChecked(true); - channelStack = new MapStackedWidget(this); - tool->rightStack()->add(channelsMenuId, channelStack); - connect(channelsButton->button(), &QAbstractButton::toggled, this, [=](bool b) { - if(b) - tool->requestMenu(channelsMenuId); - }); - rightMenuButtonGroup->addButton(channelsButton->button()); -} - -void HarmonicCalibration::setupMeasureButtonHelper(MenuControlButton *measureButton) +void HarmonicCalibration::restart() { - measureButton->setName("Measure"); - measureButton->setOpenMenuChecksThis(true); - measureButton->setDoubleClickToOpenMenu(true); - measureButton->checkBox()->setVisible(false); + if(m_running) { + run(false); + run(true); + } } -void HarmonicCalibration::setupChannelMenuControlButtonHelper(MenuControlButton *menuControlButton, ChannelAddon *channelAddon) -{ - menuControlButton->setName(channelAddon->getName()); - menuControlButton->setCheckBoxStyle(MenuControlButton::CS_CIRCLE); - menuControlButton->setOpenMenuChecksThis(true); - menuControlButton->setDoubleClickToOpenMenu(true); - menuControlButton->setColor(channelAddon->pen().color()); - menuControlButton->button()->setVisible(false); - menuControlButton->setCheckable(true); - - connect(menuControlButton->checkBox(), &QCheckBox::toggled, this, [=](bool b) { - if(b) - channelAddon->enable(); - else - channelAddon->disable(); - }); - menuControlButton->checkBox()->setChecked(true); -} +bool HarmonicCalibration::running() const { return m_running; } -void HarmonicCalibration::setupChannelSnapshot(ChannelAddon *channelAddon) +void HarmonicCalibration::setRunning(bool newRunning) { - auto snapshotChannel = dynamic_cast(channelAddon); - if(!snapshotChannel) + if(m_running == newRunning) return; - connect(channelAddon, SIGNAL(addNewSnapshot(SnapshotProvider::SnapshotRecipe)), this, - SLOT(createSnapshotChannel(SnapshotProvider::SnapshotRecipe))); + m_running = newRunning; + Q_EMIT runningChanged(newRunning); } -void HarmonicCalibration::setupChannelMeasurement(ChannelAddon *channelAddon) -{ - auto chMeasureableChannel = dynamic_cast(channelAddon); - if(!chMeasureableChannel) - return; - auto chMeasureManager = chMeasureableChannel->getMeasureManager(); - if(!chMeasureManager) - return; - if(measureSettings) { - connect(chMeasureManager, &MeasureManagerInterface::enableMeasurement, measurePanel, - &MeasurementsPanel::addMeasurement); - connect(chMeasureManager, &MeasureManagerInterface::disableMeasurement, measurePanel, - &MeasurementsPanel::removeMeasurement); - connect(measureSettings, &MeasurementSettings::toggleAllMeasurements, chMeasureManager, - &MeasureManagerInterface::toggleAllMeasurement); - connect(measureSettings, &MeasurementSettings::toggleAllStats, chMeasureManager, - &MeasureManagerInterface::toggleAllStats); - connect(chMeasureManager, &MeasureManagerInterface::enableStat, statsPanel, &StatsPanel::addStat); - connect(chMeasureManager, &MeasureManagerInterface::disableStat, statsPanel, &StatsPanel::removeStat); - } -} +void HarmonicCalibration::start() { run(true); } -void HarmonicCalibration::setupChannelDelete(ChannelAddon *channelAddon) -{ - connect(channelAddon, SIGNAL(requestDeleteChannel(ChannelAddon *)), this, SLOT(deleteChannel(ChannelAddon *))); -} +void HarmonicCalibration::stop() { run(false); } -void HarmonicCalibration::deleteChannel(ChannelAddon *ch) +void HarmonicCalibration::run(bool b) { + qInfo() << b; + QElapsedTimer tim; + tim.start(); - MenuControlButton *last = nullptr; - for(auto c : proxy->getChannelAddons()) { - auto ca = dynamic_cast(c); - if(ca == ch && last) { - last->animateClick(1); - } - - last = dynamic_cast(ca->getMenuControlWidget()); + if(!b) { + runButton->setChecked(false); + timer->stop(); + } + else{ + timer->start(sampleRate); } - proxy->removeChannelAddon(ch); - - ch->onStop(); - ch->disable(); - plotAddon->onChannelRemoved(ch); - plotAddonSettings->onChannelRemoved(ch); - ch->onDeinit(); - delete ch->getMenuControlWidget(); - delete ch; -} - -MenuControlButton *HarmonicCalibration::addChannel(ChannelAddon *channelAddon, QWidget *parent) -{ - MenuControlButton *menuControlButton = new MenuControlButton(parent); - channelAddon->setMenuControlWidget(menuControlButton); - channelGroup->addButton(menuControlButton); - - QString id = channelAddon->getName() + QString::number(uuid++); - setupChannelMenuControlButtonHelper(menuControlButton, channelAddon); - - channelStack->add(id, channelAddon->getWidget()); - - connect(menuControlButton, &QAbstractButton::clicked, this, [=](bool b) { - if(b) { - if(!channelsButton->button()->isChecked()) { - // Workaround because QButtonGroup and setChecked do not interact programatically - channelsButton->button()->animateClick(1); - } - - plotAddon->plot()->selectChannel(channelAddon->plotCh()); - channelStack->show(id); - } - }); - setupChannelSnapshot(channelAddon); - setupChannelMeasurement(channelAddon); - setupChannelDelete(channelAddon); - plotAddon->onChannelAdded(channelAddon); - plotAddonSettings->onChannelAdded(channelAddon); - return menuControlButton; + updateGeneralSettingEnabled(!b); } -void HarmonicCalibration::setupDeviceMenuControlButtonHelper(MenuControlButton *deviceMenuControlButton, GRDeviceAddon *deviceAddon) -{ - deviceMenuControlButton->setName(deviceAddon->getName()); - deviceMenuControlButton->setCheckable(true); - deviceMenuControlButton->button()->setVisible(false); - deviceMenuControlButton->setOpenMenuChecksThis(true); - deviceMenuControlButton->setDoubleClickToOpenMenu(true); -} +void HarmonicCalibration::timerTask(){ + updateChannelValues(); + updateLineEditValues(); -CollapsableMenuControlButton *HarmonicCalibration::addDevice(GRDeviceAddon *dev, QWidget *parent) -{ - auto devButton = new CollapsableMenuControlButton(parent); - setupDeviceMenuControlButtonHelper(devButton->getControlBtn(), dev); - channelGroup->addButton(devButton->getControlBtn()); - QString id = dev->getName() + QString::number(uuid++); - channelStack->add(id, dev->getWidget()); - connect(devButton->getControlBtn(), &QPushButton::toggled, this, [=](bool b) { - if(b) { - tool->requestMenu(channelsMenuId); - channelStack->show(id); - } - }); - return devButton; + dataGraph->plot(*dataGraphValue); + tempGraph->plot(temp); } -void HarmonicCalibration::init() -{ - auto addons = proxy->getAddons(); - proxy->init(); - //initCursors(); - for(auto addon : addons) { - addon->onInit(); - } +void HarmonicCalibration::updateChannelValues(){ + rotation = m_admtController->getChannelValue(rotationChannelName, bufferSize); + angle = m_admtController->getChannelValue(angleChannelName, bufferSize); + count = m_admtController->getChannelValue(countChannelName, bufferSize); + temp = m_admtController->getChannelValue(temperatureChannelName, bufferSize); } -void HarmonicCalibration::deinit() -{ - auto addons = proxy->getAddons(); - - for(auto addon : addons) { - addon->onDeinit(); - } +void HarmonicCalibration::updateLineEditValues(){ + rotationValueLabel->setText(QString::number(rotation) + "°"); + angleValueLabel->setText(QString::number(angle) + "°"); + countValueLabel->setText(QString::number(count)); + tempValueLabel->setText(QString::number(temp) + " °C"); } -void HarmonicCalibration::restart() +void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { - if(m_running) { - run(false); - run(true); - } + sampleRateLineEdit->setEnabled(value); + bufferSizeLineEdit->setEnabled(value); + dataGraphSamplesLineEdit->setEnabled(value); + tempGraphSamplesLineEdit->setEnabled(value); + m_dataGraphDirectionMenuCombo->setEnabled(value); + m_tempGraphDirectionMenuCombo->setEnabled(value); } -void HarmonicCalibration::showMeasurements(bool b) +void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable) { - if(b) { - tool->requestMenu(measureMenuId); - tool->requestMenu(statsMenuId); - } - tool->openTopContainerHelper(b); - tool->openBottomContainerHelper(b); + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { + bool ok; + int value = lineEdit->text().toInt(&ok); + if (ok) { + variable = value; + } else { + lineEdit->setText(QString::number(variable)); + } + }); } -void HarmonicCalibration::createSnapshotChannel(SnapshotProvider::SnapshotRecipe rec) +void HarmonicCalibration::connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph) { - // proxy->getChannelAddons().append(new ch) - qInfo() << "Creating snapshot from recipe" << rec.name; - - ChannelIdProvider *chidp = proxy->getChannelIdProvider(); - int idx = chidp->next(); - ImportChannelAddon *ch = new ImportChannelAddon("REF-" + rec.name + "-" + QString::number(idx), plotAddon, - chidp->pen(idx), this); - proxy->addChannelAddon(ch); - ch->setData(rec.x, rec.y); - auto btn = addChannel(ch, verticalChannelManager); - verticalChannelManager->add(btn); - ch->onInit(); - btn->animateClick(1); + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, graph]() { + bool ok; + int value = lineEdit->text().toInt(&ok); + if (ok) { + variable = value; + graph->setNumSamples(variable); + } else { + lineEdit->setText(QString::number(variable)); + } + }); } -bool HarmonicCalibration::running() const { return m_running; } - -void HarmonicCalibration::setRunning(bool newRunning) +void HarmonicCalibration::connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph) { - if(m_running == newRunning) - return; - m_running = newRunning; - Q_EMIT runningChanged(newRunning); + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [combo, graph]() { + int value = qvariant_cast(combo->currentData()); + switch(value) + { + case Sismograph::LEFT_TO_RIGHT: + graph->setPlotDirection(Sismograph::LEFT_TO_RIGHT); + graph->reset(); + break; + case Sismograph::RIGHT_TO_LEFT: + graph->setPlotDirection(Sismograph::RIGHT_TO_LEFT); + graph->reset(); + break; + } + }); } -void HarmonicCalibration::start() { run(true); } - -void HarmonicCalibration::stop() { run(false); } - -void HarmonicCalibration::startAddons() +void HarmonicCalibration::changeGraphColorByChannelName(Sismograph* graph, const char* channelName) { - auto addons = proxy->getAddons(); - - for(auto addon : addons) { - addon->onStart(); - } -} -void HarmonicCalibration::stopAddons() -{ - auto addons = proxy->getAddons(); - - for(auto addon : addons) { - addon->onStop(); + int index = m_admtController->getChannelIndex(channelName); + if(index > -1){ + graph->setColor(StyleHelper::getColor( QString::fromStdString("CH" + std::to_string(index) ))); } } -void HarmonicCalibration::run(bool b) +void HarmonicCalibration::connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph) { - qInfo() << b; - QElapsedTimer tim; - tim.start(); - - if(!b) { - runButton->setChecked(false); - } - - if(b) { - startAddons(); - } else { - stopAddons(); - } + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [this, combo, graph]() { + int currentIndex = combo->currentIndex(); + QVariant currentData = combo->currentData(); + char *value = reinterpret_cast(currentData.value()); + switch(currentIndex) + { + case ADMTController::Channel::ROTATION: + dataGraphValue = &rotation; + graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); + graph->addScale(-30.0, 390.0, 15, 5); + graph->setUnitOfMeasure("Degree", "°"); + break; + case ADMTController::Channel::ANGLE: + dataGraphValue = ∠ + graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); + graph->addScale(-30.0, 390.0, 15, 5); + graph->setUnitOfMeasure("Degree", "°"); + break; + case ADMTController::Channel::COUNT: + dataGraphValue = &count; + graph->setAxisTitle(QwtAxis::YLeft, tr("Count")); + graph->addScale(-1.0, 20.0, 5, 1); + graph->setUnitOfMeasure("Count", ""); + break; + } + changeGraphColorByChannelName(graph, value); + graph->reset(); + }); } \ No newline at end of file From 6f27ed089f5be6d34c7d229271a792e249840689 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 9 Jul 2024 16:29:47 +0800 Subject: [PATCH 010/112] admt: Fixed axis scales when changing displayed graph - Changed data graph color to defined method - Removed redundant plot direction declaration Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/harmoniccalibration.cpp | 31 ++++++++++++------------ 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index b053710068..f7427e73b6 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -101,12 +101,11 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg StyleHelper::MenuSmallLabel(dataGraphLabel, "dataGraphLabel"); dataGraph = new Sismograph(this); - dataGraph->setColor(QColor("#ff7200")); + changeGraphColorByChannelName(dataGraph, rotationChannelName); dataGraph->setPlotAxisXTitle("Degree (°)"); - dataGraph->setPlotDirection(Sismograph::LEFT_TO_RIGHT); dataGraph->setUnitOfMeasure("Degree", "°"); dataGraph->setAutoscale(false); - dataGraph->addScale(-30.0, 390.0, 15, 5); + dataGraph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); dataGraph->setNumSamples(dataGraphSamples); dataGraphValue = &rotation; dataGraph->plot(*dataGraphValue); @@ -118,7 +117,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg tempGraph = new Sismograph(this); changeGraphColorByChannelName(tempGraph, temperatureChannelName); tempGraph->setPlotAxisXTitle("Celsius (°C)"); - tempGraph->setPlotDirection(Sismograph::LEFT_TO_RIGHT); tempGraph->setUnitOfMeasure("Celsius", "°C"); tempGraph->setAutoscale(false); tempGraph->addScale(0.0, 100.0, 25, 5); @@ -181,7 +179,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg dataGraphSection->contentLayout()->setSpacing(10); // Graph Channel - m_dataGraphChannelMenuCombo = new MenuCombo("Graph Channel", dataGraphSection); + m_dataGraphChannelMenuCombo = new MenuCombo("Channel", dataGraphSection); auto dataGraphChannelCombo = m_dataGraphChannelMenuCombo->combo(); dataGraphChannelCombo->addItem("Rotation", QVariant::fromValue(reinterpret_cast(const_cast(rotationChannelName)))); dataGraphChannelCombo->addItem("Angle", QVariant::fromValue(reinterpret_cast(const_cast(angleChannelName)))); @@ -193,7 +191,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg // Graph Samples QLabel *dataGraphSamplesLabel = new QLabel(generalSection); - dataGraphSamplesLabel->setText("Graph Samples"); + dataGraphSamplesLabel->setText("Samples"); StyleHelper::MenuSmallLabel(dataGraphSamplesLabel, "dataGraphSamplesLabel"); dataGraphSamplesLineEdit = new QLineEdit(generalSection); dataGraphSamplesLineEdit->setText(QString::number(dataGraphSamples)); @@ -204,7 +202,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg dataGraphSection->contentLayout()->addWidget(dataGraphSamplesLineEdit); // Graph Direction - m_dataGraphDirectionMenuCombo = new MenuCombo("Graph Direction", dataGraphSection); + m_dataGraphDirectionMenuCombo = new MenuCombo("Direction", dataGraphSection); auto dataGraphDirectionCombo = m_dataGraphDirectionMenuCombo->combo(); dataGraphDirectionCombo->addItem("Left to right", Sismograph::LEFT_TO_RIGHT); dataGraphDirectionCombo->addItem("Right to left", Sismograph::RIGHT_TO_LEFT); @@ -222,7 +220,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg // Graph Samples QLabel *tempGraphSamplesLabel = new QLabel(generalSection); - tempGraphSamplesLabel->setText("Graph Samples"); + tempGraphSamplesLabel->setText("Samples"); StyleHelper::MenuSmallLabel(tempGraphSamplesLabel, "tempGraphSamplesLabel"); tempGraphSamplesLineEdit = new QLineEdit(generalSection); tempGraphSamplesLineEdit->setText(QString::number(tempGraphSamples)); @@ -232,7 +230,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg connectLineEditToGraphSamples(tempGraphSamplesLineEdit, tempGraphSamples, tempGraph); // Graph Direction - m_tempGraphDirectionMenuCombo = new MenuCombo("Graph Direction", tempGraphSection); + m_tempGraphDirectionMenuCombo = new MenuCombo("Direction", tempGraphSection); auto tempGraphDirectionCombo = m_tempGraphDirectionMenuCombo->combo(); tempGraphDirectionCombo->addItem("Left to right", Sismograph::LEFT_TO_RIGHT); tempGraphDirectionCombo->addItem("Right to left", Sismograph::RIGHT_TO_LEFT); @@ -414,21 +412,24 @@ void HarmonicCalibration::connectMenuComboToGraphChannel(MenuCombo* menuCombo, S { case ADMTController::Channel::ROTATION: dataGraphValue = &rotation; - graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); - graph->addScale(-30.0, 390.0, 15, 5); graph->setUnitOfMeasure("Degree", "°"); + graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); + graph->setNumSamples(dataGraphSamples); + graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); break; case ADMTController::Channel::ANGLE: dataGraphValue = ∠ - graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); - graph->addScale(-30.0, 390.0, 15, 5); graph->setUnitOfMeasure("Degree", "°"); + graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); + graph->setNumSamples(dataGraphSamples); + graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); break; case ADMTController::Channel::COUNT: dataGraphValue = &count; - graph->setAxisTitle(QwtAxis::YLeft, tr("Count")); - graph->addScale(-1.0, 20.0, 5, 1); graph->setUnitOfMeasure("Count", ""); + graph->setAxisScale(QwtAxis::YLeft, -1.0, 20.0); + graph->setNumSamples(dataGraphSamples); + graph->setAxisTitle(QwtAxis::YLeft, tr("Count")); break; } changeGraphColorByChannelName(graph, value); From 04094581bc926210a11227ce67f8160d5a1b0c92 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 16 Jul 2024 10:08:37 +0800 Subject: [PATCH 011/112] admt: Added calibration tab - Created method for calibration widget - Removed initial plot and data for acquisition tab Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 35 ++- plugins/admt/src/harmoniccalibration.cpp | 297 +++++++++++++++++- 2 files changed, 321 insertions(+), 11 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 7d029d564d..c2fc3543e8 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -15,6 +15,9 @@ #include #include #include +#include +#include +#include #include #include @@ -61,8 +64,10 @@ public Q_SLOTS: QPushButton *openLastMenuButton; QButtonGroup *rightMenuButtonGroup; - QLineEdit *sampleRateLineEdit, *bufferSizeLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit; - QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel; + QLineEdit *sampleRateLineEdit, *bufferSizeLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, + *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, + *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit; + QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, *calibrationAngleLabel; Sismograph *dataGraph, *tempGraph; @@ -72,6 +77,12 @@ public Q_SLOTS: MenuCollapseSection *rotationCollapse, *angleCollapse, *countCollapse, *tempCollapse; MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo; + QTabWidget *tabWidget; + + QListWidget *rawDataListWidget; + + QPlainTextEdit *logsPlainTextEdit; + void updateChannelValues(); void updateLineEditValues(); void updateGeneralSettingEnabled(bool value); @@ -80,11 +91,29 @@ public Q_SLOTS: void connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph); void changeGraphColorByChannelName(Sismograph* graph, const char* channelName); void connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph); + ToolTemplate* createCalibrationWidget(); + void updateLabelValue(QLabel* label, int channelIndex); + void updateChannelValue(int channelIndex); + void calibrationTask(); + void addAngleToRawDataList(); + void removeLastItemFromRawDataList(); + void calibrateData(); + void registerCalibrationData(); - QTimer *timer; + QTimer *timer, *calibrationTimer; int uuid = 0; const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; }; + +enum TABS +{ + ACQUISITION = 0, + UTILITIES = 1, + CALIBRATION = 2, +}; + + + } // namespace scopy::admt #endif // HARMONICCALIBRATION_H diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index f7427e73b6..bc670aa287 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -27,8 +27,10 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg tool = new ToolTemplate(this); setLayout(lay); lay->setMargin(0); - lay->addWidget(tool); - + tabWidget = new QTabWidget(this); + tabWidget->addTab(tool, "Acquisition"); + lay->insertWidget(0, tabWidget); + openLastMenuButton = new OpenLastMenuBtn(dynamic_cast(tool->rightContainer()), true, this); rightMenuButtonGroup = dynamic_cast(openLastMenuButton)->getButtonGroup(); @@ -36,6 +38,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg infoButton = new InfoBtn(this); runButton = new RunBtn(this); + rightMenuButtonGroup->addButton(settingsButton); // Raw Data Widget @@ -45,7 +48,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg rawDataScroll->setWidget(rawDataWidget); QVBoxLayout *rawDataLayout = new QVBoxLayout(rawDataWidget); rawDataLayout->setMargin(0); - // rawDataLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed)); rawDataWidget->setLayout(rawDataLayout); MenuSectionWidget *rotationWidget = new MenuSectionWidget(rawDataWidget); @@ -85,8 +87,10 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg tempValueLabel = new QLabel(tempSection); StyleHelper::MenuControlLabel(tempValueLabel, "tempValueLabel"); - updateChannelValues(); - updateLineEditValues(); + rotationValueLabel->setText("--.--°"); + angleValueLabel->setText("--.--°"); + countValueLabel->setText("--"); + tempValueLabel->setText("--.-- °C"); rotationSection->contentLayout()->addWidget(rotationValueLabel); angleSection->contentLayout()->addWidget(angleValueLabel); @@ -108,7 +112,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg dataGraph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); dataGraph->setNumSamples(dataGraphSamples); dataGraphValue = &rotation; - dataGraph->plot(*dataGraphValue); QLabel *tempGraphLabel = new QLabel(historicalGraphWidget); tempGraphLabel->setText("Temperature"); @@ -121,7 +124,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg tempGraph->setAutoscale(false); tempGraph->addScale(0.0, 100.0, 25, 5); tempGraph->setNumSamples(tempGraphSamples); - tempGraph->plot(temp); historicalGraphLayout->addWidget(dataGraphLabel); historicalGraphLayout->addWidget(dataGraph); @@ -261,7 +263,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); tool->addWidgetToTopContainerHelper(infoButton, TTA_LEFT); tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); - // tool->leftStack()->add("rawDataWidget", rawDataWidget); tool->leftStack()->add("rawDataScroll", rawDataScroll); tool->rightStack()->add("generalSettingScroll", generalSettingScroll); tool->addWidgetToCentralContainerHelper(historicalGraphWidget); @@ -272,6 +273,18 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &HarmonicCalibration::timerTask); + + calibrationTimer = new QTimer(this); + connect(calibrationTimer, &QTimer::timeout, this, &HarmonicCalibration::calibrationTask); + + tabWidget->addTab(createCalibrationWidget(), "Calibration"); + + connect(tabWidget, &QTabWidget::currentChanged, [=](int index){ + tabWidget->setCurrentIndex(index); + + if(index == 1) { calibrationTimer->start(sampleRate); } + else { calibrationTimer->stop(); } + }); } HarmonicCalibration::~HarmonicCalibration() {} @@ -435,4 +448,272 @@ void HarmonicCalibration::connectMenuComboToGraphChannel(MenuCombo* menuCombo, S changeGraphColorByChannelName(graph, value); graph->reset(); }); +} + +ToolTemplate* HarmonicCalibration::createCalibrationWidget() +{ + ToolTemplate *tool = new ToolTemplate(this); + + QScrollArea *calibrationControlScrollArea = new QScrollArea(this); + calibrationControlScrollArea->setWidgetResizable(true); + QWidget *controlWidget = new QWidget(calibrationControlScrollArea); + calibrationControlScrollArea->setWidget(controlWidget); + QVBoxLayout *controlLayout = new QVBoxLayout(controlWidget); + controlLayout->setMargin(0); + controlWidget->setLayout(controlLayout); + + // Angle Widget + MenuSectionWidget *angleWidget = new MenuSectionWidget(controlWidget); + angleWidget->contentLayout()->setSpacing(10); + MenuCollapseSection *angleSection = new MenuCollapseSection("Angle", MenuCollapseSection::MHCW_NONE, angleWidget); + angleSection->contentLayout()->setSpacing(10); + angleWidget->contentLayout()->addWidget(angleSection); + calibrationAngleLabel = new QLabel(angleSection); + StyleHelper::MenuControlLabel(calibrationAngleLabel, "calibrationAngleLabel"); + updateChannelValue(ADMTController::Channel::ANGLE); + updateLabelValue(calibrationAngleLabel, ADMTController::Channel::ANGLE); + angleSection->contentLayout()->addWidget(calibrationAngleLabel); + + // Calibration Widget + MenuSectionWidget *calibrationControlWidget = new MenuSectionWidget(controlWidget); + calibrationControlWidget->contentLayout()->setSpacing(10); + MenuCollapseSection *calibrationSection = new MenuCollapseSection("Calibration", MenuCollapseSection::MHCW_NONE, calibrationControlWidget); + calibrationSection->contentLayout()->setSpacing(10); + calibrationControlWidget->contentLayout()->addWidget(calibrationSection); + + QPushButton *addCalibrationDataButton = new QPushButton(calibrationControlWidget); + addCalibrationDataButton->setText("Add Data"); + StyleHelper::BlueButton(addCalibrationDataButton, "addCalibrationDataButton"); + + QPushButton *removeLastCalibrationDataButton = new QPushButton(calibrationControlWidget); + removeLastCalibrationDataButton->setText("Remove Last Data"); + StyleHelper::BlueButton(removeLastCalibrationDataButton, "removeLastCalibrationDataButton"); + + QPushButton *calibrateDataButton = new QPushButton(calibrationControlWidget); + calibrateDataButton->setText("Calibrate"); + StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); + + calibrationSection->contentLayout()->addWidget(addCalibrationDataButton); + calibrationSection->contentLayout()->addWidget(removeLastCalibrationDataButton); + calibrationSection->contentLayout()->addWidget(calibrateDataButton); + + controlLayout->addWidget(angleWidget); + controlLayout->addWidget(calibrationControlWidget); + controlLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + // Raw Data Widget + QWidget *calibrationDataWidget = new QWidget(this); + QHBoxLayout *calibrationDataLayout = new QHBoxLayout(calibrationDataWidget); + calibrationDataLayout->setMargin(0); + calibrationDataWidget->setLayout(calibrationDataLayout); + + MenuSectionWidget *rawDataWidget = new MenuSectionWidget(calibrationDataWidget); + rawDataWidget->contentLayout()->setSpacing(10); + rawDataWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + MenuCollapseSection *rawDataSection = new MenuCollapseSection("Raw Data", MenuCollapseSection::MHCW_NONE, calibrationDataWidget); + rawDataSection->contentLayout()->setSpacing(10); + rawDataWidget->contentLayout()->addWidget(rawDataSection); + + rawDataListWidget = new QListWidget(rawDataWidget); + calibrationDataLayout->addWidget(rawDataListWidget); + + rawDataSection->contentLayout()->addWidget(rawDataListWidget); + + calibrationDataLayout->addWidget(rawDataWidget); + + // Result Widget + QWidget *calibrationResultWidget = new QWidget(this); + QVBoxLayout *calibrationResultLayout = new QVBoxLayout(calibrationResultWidget); + calibrationResultLayout->setMargin(0); + calibrationResultWidget->setLayout(calibrationResultLayout); + + // Logs Widget + MenuSectionWidget *logsWidget = new MenuSectionWidget(calibrationResultWidget); + logsWidget->contentLayout()->setSpacing(10); + // logsWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + MenuCollapseSection *logsSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, logsWidget); + logsSection->contentLayout()->setSpacing(10); + logsWidget->contentLayout()->addWidget(logsSection); + + logsPlainTextEdit = new QPlainTextEdit(logsWidget); + logsPlainTextEdit->setReadOnly(true); + + logsSection->contentLayout()->addWidget(logsPlainTextEdit); + + calibrationResultLayout->addWidget(logsWidget); + + // Register Widget + QWidget *calibrationRegisterWidget = new QWidget(calibrationResultWidget); + QHBoxLayout *calibrationRegisterLayout = new QHBoxLayout(calibrationRegisterWidget); + calibrationRegisterLayout->setMargin(0); + calibrationRegisterLayout->setSpacing(10); + calibrationRegisterWidget->setLayout(calibrationRegisterLayout); + + QWidget *calibrationMagWidget = new QWidget(calibrationRegisterWidget); + QVBoxLayout *calibrationMagLayout = new QVBoxLayout(calibrationMagWidget); + calibrationMagLayout->setMargin(0); + calibrationMagLayout->setSpacing(10); + calibrationMagWidget->setLayout(calibrationMagLayout); + + QLabel *calibrationH1MagLabel = new QLabel(calibrationMagWidget); + calibrationH1MagLabel->setText("H1Mag"); + StyleHelper::MenuSmallLabel(calibrationH1MagLabel, "calibrationH1MagLabel"); + calibrationH1MagLineEdit = new QLineEdit(calibrationMagWidget); + + QLabel *calibrationH2MagLabel = new QLabel(calibrationMagWidget); + calibrationH2MagLabel->setText("H2Mag"); + StyleHelper::MenuSmallLabel(calibrationH2MagLabel, "calibrationH2MagLabel"); + calibrationH2MagLineEdit = new QLineEdit(calibrationMagWidget); + + QLabel *calibrationH3MagLabel = new QLabel(calibrationMagWidget); + calibrationH3MagLabel->setText("H3Mag"); + StyleHelper::MenuSmallLabel(calibrationH3MagLabel, "calibrationH3MagLabel"); + calibrationH3MagLineEdit = new QLineEdit(calibrationMagWidget); + + QLabel *calibrationH8MagLabel = new QLabel(calibrationMagWidget); + calibrationH8MagLabel->setText("H8Mag"); + StyleHelper::MenuSmallLabel(calibrationH8MagLabel, "calibrationH8MagLabel"); + calibrationH8MagLineEdit = new QLineEdit(calibrationMagWidget); + + calibrationMagLayout->addWidget(calibrationH1MagLabel); + calibrationMagLayout->addWidget(calibrationH1MagLineEdit); + calibrationMagLayout->addWidget(calibrationH2MagLabel); + calibrationMagLayout->addWidget(calibrationH2MagLineEdit); + calibrationMagLayout->addWidget(calibrationH3MagLabel); + calibrationMagLayout->addWidget(calibrationH3MagLineEdit); + calibrationMagLayout->addWidget(calibrationH8MagLabel); + calibrationMagLayout->addWidget(calibrationH8MagLineEdit); + + QWidget *calibrationPhaseWidget = new QWidget(calibrationRegisterWidget); + QVBoxLayout *calibrationPhaseLayout = new QVBoxLayout(calibrationPhaseWidget); + calibrationPhaseLayout->setMargin(0); + calibrationPhaseLayout->setSpacing(10); + calibrationPhaseWidget->setLayout(calibrationPhaseLayout); + + QLabel *calibrationH1PhaseLabel = new QLabel(calibrationPhaseWidget); + calibrationH1PhaseLabel->setText("H1Phase"); + StyleHelper::MenuSmallLabel(calibrationH1PhaseLabel, "calibrationH1PhaseLabel"); + calibrationH1PhaseLineEdit = new QLineEdit(calibrationPhaseWidget); + + QLabel *calibrationH2PhaseLabel = new QLabel(calibrationPhaseWidget); + calibrationH2PhaseLabel->setText("H2Phase"); + StyleHelper::MenuSmallLabel(calibrationH2PhaseLabel, "calibrationH2PhaseLabel"); + calibrationH2PhaseLineEdit = new QLineEdit(calibrationPhaseWidget); + + QLabel *calibrationH3PhaseLabel = new QLabel(calibrationPhaseWidget); + calibrationH3PhaseLabel->setText("H3Phase"); + StyleHelper::MenuSmallLabel(calibrationH3PhaseLabel, "calibrationH3PhaseLabel"); + calibrationH3PhaseLineEdit = new QLineEdit(calibrationPhaseWidget); + + QLabel *calibrationH8PhaseLabel = new QLabel(calibrationPhaseWidget); + calibrationH8PhaseLabel->setText("H8Phase"); + StyleHelper::MenuSmallLabel(calibrationH8PhaseLabel, "calibrationH8PhaseLabel"); + calibrationH8PhaseLineEdit = new QLineEdit(calibrationPhaseWidget); + + calibrationPhaseLayout->addWidget(calibrationH1PhaseLabel); + calibrationPhaseLayout->addWidget(calibrationH1PhaseLineEdit); + calibrationPhaseLayout->addWidget(calibrationH2PhaseLabel); + calibrationPhaseLayout->addWidget(calibrationH2PhaseLineEdit); + calibrationPhaseLayout->addWidget(calibrationH3PhaseLabel); + calibrationPhaseLayout->addWidget(calibrationH3PhaseLineEdit); + calibrationPhaseLayout->addWidget(calibrationH8PhaseLabel); + calibrationPhaseLayout->addWidget(calibrationH8PhaseLineEdit); + + QPushButton *registerCalibrationDataButton = new QPushButton(calibrationRegisterWidget); + registerCalibrationDataButton->setText("Register"); + StyleHelper::BlueButton(registerCalibrationDataButton, "registerCalibrationDataButton"); + + calibrationRegisterLayout->addWidget(calibrationMagWidget); + calibrationRegisterLayout->addWidget(calibrationPhaseWidget); + + calibrationResultLayout->addWidget(calibrationRegisterWidget); + calibrationResultLayout->addWidget(registerCalibrationDataButton); + + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(false); + tool->topContainerMenuControl()->setVisible(false); + tool->leftContainer()->setVisible(true); + tool->rightContainer()->setVisible(true); + tool->bottomContainer()->setVisible(true); + tool->setLeftContainerWidth(210); + tool->setRightContainerWidth(500); + tool->setTopContainerHeight(0); + tool->setBottomContainerHeight(90); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + + tool->leftStack()->add("calibrationControlScrollArea", calibrationControlScrollArea); + tool->addWidgetToCentralContainerHelper(calibrationDataWidget); + tool->rightStack()->add("calibrationResultWidget", calibrationResultWidget); + + connect(addCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::addAngleToRawDataList); + connect(removeLastCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::removeLastItemFromRawDataList); + connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::calibrateData); + connect(registerCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::registerCalibrationData); + + return tool; +} + +void HarmonicCalibration::updateLabelValue(QLabel* label, int channelIndex) +{ + switch(channelIndex) + { + case ADMTController::Channel::ROTATION: + label->setText(QString::number(rotation) + "°"); + break; + case ADMTController::Channel::ANGLE: + label->setText(QString::number(angle) + "°"); + break; + case ADMTController::Channel::COUNT: + label->setText(QString::number(count)); + break; + case ADMTController::Channel::TEMPERATURE: + label->setText(QString::number(temp) + "°C"); + break; + } +} + +void HarmonicCalibration::updateChannelValue(int channelIndex) +{ + switch(channelIndex) + { + case ADMTController::Channel::ROTATION: + rotation = m_admtController->getChannelValue(rotationChannelName, 1); + break; + case ADMTController::Channel::ANGLE: + angle = m_admtController->getChannelValue(angleChannelName, 1); + break; + case ADMTController::Channel::COUNT: + count = m_admtController->getChannelValue(countChannelName, 1); + break; + case ADMTController::Channel::TEMPERATURE: + temp = m_admtController->getChannelValue(temperatureChannelName, 1); + break; + } +} + +void HarmonicCalibration::calibrationTask() +{ + updateChannelValue(ADMTController::Channel::ANGLE); + updateLabelValue(calibrationAngleLabel, ADMTController::Channel::ANGLE); +} + +void HarmonicCalibration::addAngleToRawDataList() +{ + QString dataStr = QString::number(angle); + rawDataListWidget->addItem(dataStr); +} + +void HarmonicCalibration::removeLastItemFromRawDataList(){ + rawDataListWidget->takeItem(rawDataListWidget->count() - 1); +} + +void HarmonicCalibration::calibrateData() +{ + logsPlainTextEdit->appendPlainText("\n============ Calibration Start ============\n"); +} + +void HarmonicCalibration::registerCalibrationData() +{ + logsPlainTextEdit->appendPlainText("\n============ Register Calibration Start ============\n"); } \ No newline at end of file From 905081a9512b5c5bdfc5f948df9ce62359b57765 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 18 Jul 2024 16:03:02 +0800 Subject: [PATCH 012/112] admt: Implemented export and import raw calibration data Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 6 + plugins/admt/src/harmoniccalibration.cpp | 119 +++++++++++++++--- 2 files changed, 107 insertions(+), 18 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index c2fc3543e8..882d5579f9 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include namespace scopy::admt { @@ -99,6 +101,10 @@ public Q_SLOTS: void removeLastItemFromRawDataList(); void calibrateData(); void registerCalibrationData(); + void extractCalibrationData(); + void importCalibrationData(); + void calibrationLogWrite(QString message); + void calibrationLogWriteLn(QString message); QTimer *timer, *calibrationTimer; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index bc670aa287..ab98403dc0 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -470,8 +470,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() angleWidget->contentLayout()->addWidget(angleSection); calibrationAngleLabel = new QLabel(angleSection); StyleHelper::MenuControlLabel(calibrationAngleLabel, "calibrationAngleLabel"); - updateChannelValue(ADMTController::Channel::ANGLE); - updateLabelValue(calibrationAngleLabel, ADMTController::Channel::ANGLE); angleSection->contentLayout()->addWidget(calibrationAngleLabel); // Calibration Widget @@ -493,9 +491,19 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrateDataButton->setText("Calibrate"); StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); + QPushButton *extractDataButton = new QPushButton(calibrationControlWidget); + extractDataButton->setText("Extract"); + StyleHelper::BlueButton(extractDataButton, "extractDataButton"); + + QPushButton *importDataButton = new QPushButton(calibrationControlWidget); + importDataButton->setText("Import"); + StyleHelper::BlueButton(importDataButton, "importDataButton"); + calibrationSection->contentLayout()->addWidget(addCalibrationDataButton); calibrationSection->contentLayout()->addWidget(removeLastCalibrationDataButton); calibrationSection->contentLayout()->addWidget(calibrateDataButton); + calibrationSection->contentLayout()->addWidget(extractDataButton); + calibrationSection->contentLayout()->addWidget(importDataButton); controlLayout->addWidget(angleWidget); controlLayout->addWidget(calibrationControlWidget); @@ -503,7 +511,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() // Raw Data Widget QWidget *calibrationDataWidget = new QWidget(this); - QHBoxLayout *calibrationDataLayout = new QHBoxLayout(calibrationDataWidget); + QVBoxLayout *calibrationDataLayout = new QVBoxLayout(calibrationDataWidget); calibrationDataLayout->setMargin(0); calibrationDataWidget->setLayout(calibrationDataLayout); @@ -515,22 +523,11 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() rawDataWidget->contentLayout()->addWidget(rawDataSection); rawDataListWidget = new QListWidget(rawDataWidget); - calibrationDataLayout->addWidget(rawDataListWidget); - rawDataSection->contentLayout()->addWidget(rawDataListWidget); - calibrationDataLayout->addWidget(rawDataWidget); - - // Result Widget - QWidget *calibrationResultWidget = new QWidget(this); - QVBoxLayout *calibrationResultLayout = new QVBoxLayout(calibrationResultWidget); - calibrationResultLayout->setMargin(0); - calibrationResultWidget->setLayout(calibrationResultLayout); - // Logs Widget - MenuSectionWidget *logsWidget = new MenuSectionWidget(calibrationResultWidget); + MenuSectionWidget *logsWidget = new MenuSectionWidget(calibrationDataWidget); logsWidget->contentLayout()->setSpacing(10); - // logsWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); MenuCollapseSection *logsSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, logsWidget); logsSection->contentLayout()->setSpacing(10); logsWidget->contentLayout()->addWidget(logsSection); @@ -540,7 +537,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() logsSection->contentLayout()->addWidget(logsPlainTextEdit); - calibrationResultLayout->addWidget(logsWidget); + calibrationDataLayout->addWidget(rawDataWidget); + calibrationDataLayout->addWidget(logsWidget); + + // Result Widget + QWidget *calibrationResultWidget = new QWidget(this); + QVBoxLayout *calibrationResultLayout = new QVBoxLayout(calibrationResultWidget); + calibrationResultLayout->setMargin(0); + calibrationResultWidget->setLayout(calibrationResultLayout); // Register Widget QWidget *calibrationRegisterWidget = new QWidget(calibrationResultWidget); @@ -649,6 +653,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(addCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::addAngleToRawDataList); connect(removeLastCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::removeLastItemFromRawDataList); connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::calibrateData); + connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); + connect(importDataButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); connect(registerCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::registerCalibrationData); return tool; @@ -710,10 +716,87 @@ void HarmonicCalibration::removeLastItemFromRawDataList(){ void HarmonicCalibration::calibrateData() { - logsPlainTextEdit->appendPlainText("\n============ Calibration Start ============\n"); + logsPlainTextEdit->appendPlainText("\n======= Calibration Start =======\n"); } void HarmonicCalibration::registerCalibrationData() { - logsPlainTextEdit->appendPlainText("\n============ Register Calibration Start ============\n"); + logsPlainTextEdit->appendPlainText("\n=== Register Calibration Start ===\n"); +} + +void HarmonicCalibration::calibrationLogWrite(QString message) +{ + logsPlainTextEdit->appendPlainText(message); +} + +void HarmonicCalibration::calibrationLogWriteLn(QString message) +{ + logsPlainTextEdit->appendPlainText("\n" + message); +} + +void HarmonicCalibration::extractCalibrationData() +{ + QStringList filter; + filter += QString(tr("Comma-separated values files (*.csv)")); + filter += QString(tr("Tab-delimited values files (*.txt)")); + filter += QString(tr("All Files(*)")); + + QString selectedFilter = filter[0]; + + QString fileName = QFileDialog::getSaveFileName(this, tr("Export"), "", filter.join(";;"), &selectedFilter, QFileDialog::Options()); + + if(fileName.split(".").size() <= 1) { + // file name w/o extension. Let's append it + QString ext = selectedFilter.split(".")[1].split(")")[0]; + fileName += "." + ext; + } + + if(!fileName.isEmpty()) { + bool withScopyHeader = false; + FileManager fm("HarmonicCalibration"); + fm.open(fileName, FileManager::EXPORT); + + QVector rawData; + + for (int i = 0; i < rawDataListWidget->count(); ++i) { + QListWidgetItem* item = rawDataListWidget->item(i); + bool ok; + double value = item->text().toDouble(&ok); + if (ok) { + rawData.append(value); + } else { + // Handle the case where the conversion fails if necessary + } + } + + fm.save(rawData, "RawData"); + + fm.performWrite(withScopyHeader); + } +} + +void HarmonicCalibration::importCalibrationData() +{ + QString fileName = QFileDialog::getOpenFileName( + this, tr("Import"), "", + tr("Comma-separated values files (*.csv);;" + "Tab-delimited values files (*.txt)"), + nullptr, QFileDialog::Options()); + + FileManager fm("HarmonicCalibration"); + + try { + fm.open(fileName, FileManager::IMPORT); + + rawDataListWidget->clear(); + + QVector data = fm.read(0); + for(int i = 0; i < data.size(); ++i) { + QString dataStr = QString::number(data[i]); + rawDataListWidget->addItem(dataStr); + } + + } catch(FileManagerException &ex) { + calibrationLogWriteLn(QString(ex.what())); + } } \ No newline at end of file From ae013085cb8684f8f755ed9d8418c94df097a523 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 23 Jul 2024 10:30:34 +0800 Subject: [PATCH 013/112] admt: Implemented calibration routine in controller - Renamed acquisition labels Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 18 + .../admt/include/admt/harmoniccalibration.h | 2 +- plugins/admt/src/admtcontroller.cpp | 356 ++++++++++++++++++ plugins/admt/src/harmoniccalibration.cpp | 61 +-- 4 files changed, 411 insertions(+), 26 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index dfa6e1976e..7c5947b36d 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -9,6 +9,17 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + namespace scopy::admt { class ADMTController : public QObject { @@ -35,11 +46,18 @@ class ADMTController : public QObject QString getChannelValue(); int getChannelIndex(const char *channelName); double getChannelValue(const char *channelName, int bufferSize); + QString calibrate(vector PANG); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; Connection *m_conn; QString uri; + + unsigned int bitReverse(unsigned int x, int log2n); + template + void fft(Iter_T a, Iter_T b, int log2n); + int linear_fit(vector x, vector y, double* slope, double* intercept); + int calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err); }; } // namespace scopy::admt diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 882d5579f9..f9598dcbf0 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -66,7 +66,7 @@ public Q_SLOTS: QPushButton *openLastMenuButton; QButtonGroup *rightMenuButtonGroup; - QLineEdit *sampleRateLineEdit, *bufferSizeLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, + QLineEdit *graphUpdateIntervalLineEdit, *dataSampleSizeLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit; QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, *calibrationAngleLabel; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index d84a148277..5d9a9510cd 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -8,6 +8,14 @@ #include #include +#include +#include +#include +#include +#include +#include +#include + static const size_t maxAttrSize = 512; using namespace scopy::admt; @@ -175,4 +183,352 @@ double ADMTController::getChannelValue(const char *channelName, int bufferSize = message = message + result.toStdString(); iio_buffer_destroy(iioBuffer); return value; //QString::fromStdString(message); +} + +/* bit reversal from online example */ +unsigned int ADMTController::bitReverse(unsigned int x, int log2n) { + int n = 0; + int mask = 0x1; + for (int i = 0; i < log2n; i++) { + n <<= 1; + n |= (x & 1); + x >>= 1; + } + return n; +} + +template +/* fft from example codes online */ +void ADMTController::fft(Iter_T a, Iter_T b, int log2n) +{ + typedef typename iterator_traits::value_type complex; + const complex J(0, 1); + int n = 1 << log2n; + for (unsigned int i = 0; i < n; ++i) { + b[bitReverse(i, log2n)] = a[i]; + } + for (int s = 1; s <= log2n; ++s) { + int m = 1 << s; + int m2 = m >> 1; + complex w(1, 0); + complex wm = exp(-J * (M_PI / m2)); + for (int j = 0; j < m2; ++j) { + for (int k = j; k < n; k += m) { + complex t = w * b[k + m2]; + complex u = b[k]; + b[k] = u + t; + b[k + m2] = u - t; + } + w *= wm; + } + } +} + +/* For linear fitting (hard-coded based on examples and formula for polynomial fitting) */ +int ADMTController::linear_fit(vector x, vector y, double* slope, double* intercept) +{ + /* x, y, x^2, y^2, xy, xy^2 */ + double sum_x = 0, sum_y = 0, sum_x2 = 0, sum_y2 = 0, sum_xy = 0; + int i; + + if (x.size() != y.size()) + return -22; + + for (i = 0; i < x.size(); i++) { + sum_x += x[i]; + sum_y += y[i]; + sum_x2 += (x[i] * x[i]); + sum_y2 += (y[i] * y[i]); + sum_xy += (x[i] * y[i]); + } + + *slope = (x.size() * sum_xy - sum_x * sum_y) / (x.size() * sum_x2 - sum_x * sum_x); + + *intercept = (sum_y * sum_x2 - sum_x * sum_xy) / (x.size() * sum_x2 - sum_x * sum_x); + + return 0; +} + +/* Calculate angle error based on MATLAB and C# implementation */ +int ADMTController::calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err) +{ + vector angle_meas_rad(angle_meas.size()); // radian converted input + vector angle_meas_rad_unwrap(angle_meas.size()); // unwrapped radian input + vector angle_fit(angle_meas.size()); // array for polynomial fitted data + vector x_data(angle_meas.size()); + double coeff_a, coeff_b; // coefficients generated by polynomial fitting + + // convert to radian + for (int i = 0; i < angle_meas_rad.size(); i++) + angle_meas_rad[i] = angle_meas[i] * M_PI / 180.0; + + // unwrap angle (extracted from decompiled Angle GSF Unit + double num = 0.0; + angle_meas_rad_unwrap[0] = angle_meas_rad[0]; + for (int i = 1; i < angle_meas_rad.size(); i++) + { + double num2 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1]); + double num3 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] + M_PI * 2.0); + double num4 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] - M_PI * 2.0); + if (num3 < num2 && num3 < num4) + num += M_PI * 2.0; + + else if (num4 < num2 && num4 < num3) + num -= M_PI * 2.0; + + angle_meas_rad_unwrap[i] = angle_meas_rad[i] + num; + } + + // set initial point to zero + double offset = angle_meas_rad_unwrap[0]; + for (int i = 0; i < angle_meas_rad_unwrap.size(); ++i) + angle_meas_rad_unwrap[i] -= offset; + + /* Generate xdata for polynomial fitting */ + iota(x_data.begin(), x_data.end(), 1); + + // linear angle fitting (generated coefficients not same with matlab and python) + // expecting 0.26 -0.26 + // getting ~0.27 ~-0.27 as of 4/2/2024 + /* input args: x, y, *slope, *intercept */ + linear_fit(x_data, angle_meas_rad_unwrap, &coeff_a, &coeff_b); + + //cout << coeff_a << " " << coeff_b << "\n"; + + // generate data using coefficients from polynomial fitting + for (int i = 0; i < angle_fit.size(); i++) { + angle_fit[i] = coeff_a * x_data[i]; + //cout << "angle_fit " << angle_fit[i] << "\n"; + } + + // get angle error using pass by ref angle_error_ret + for (int i = 0; i < angle_error_ret.size(); i++) { + angle_error_ret[i] = angle_meas_rad_unwrap[i] - angle_fit[i]; + //cout << "angle_err_ret " << angle_error_ret[i] << "\n"; + } + + // Find the offset for error and subtract (using angle_error_ret) + auto minmax = minmax_element(angle_error_ret.begin(), angle_error_ret.end()); + double angle_err_offset = (*minmax.first + *minmax.second) / 2; + + for (int i = 0; i < angle_error_ret.size(); i++) + angle_error_ret[i] -= angle_err_offset; + + // Convert back to degrees (angle_error_ret) + for (int i = 0; i < angle_meas.size(); i++) + angle_error_ret[i] *= (180 / M_PI); + + // Find maximum absolute angle error + *max_angle_err = *minmax.second; + + return 0; +} + +QString ADMTController::calibrate(vector PANG){ + int cycles = 11, CCW = 0, circshiftData = 0; + QString result = ""; + + // original script data (measured data: from data capture using GUI or other medium i.e., csv) + //PANG = { 0.175781,11.5137,20.0391,39.0234,52.998,65.0391,76.4648,84.8145,98.7012,112.061,130.693,145.195,166.816,182.021,193.799,210.938,0.175781,11.5137,20.0391,39.0234,52.998,65.0391,76.4648,84.8145,98.7012,112.061,130.693,145.195,166.816,182.021,193.799,210.938 }; + + /* Check CCW flag to know if array is to be reversed */ + if (CCW) + reverse(PANG.begin(), PANG.end()); + + + /* Randomize starting point of array */ + if (circshiftData) { + int shift = rand() % PANG.size(); + + rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); + } + + // Calculate the angular errors for ideal and measured + double max_err = 0; + vector angle_errors(PANG.size()); + + /* Calculate angle errors */ + calculate_angle_error(PANG, angle_errors, &max_err); + + //for (int i = 0; i < angle_errors.size(); i++) + // cout << "angle_err " << angle_errors[i] << "\n"; + + /* Caluclate FFT of angle errors */ + /* FFT based on implementation from https://www.oreilly.com/library/view/c-cookbook/0596007612/ch11s18.html */ + vector angle_errors_fft_temp(PANG.size()); + vector angle_errors_fft_phase_temp(PANG.size()); + vector angle_errors_fft(PANG.size() / 2); + vector angle_errors_fft_phase(PANG.size() / 2); + typedef complex cx; + + /* array declaration must be constant so hardcoded as of now */ + cx fft_in[256]; + cx fft_out[256]; + + /* Format angle errros to match data type used in fft function */ + for (int i = 0; i < PANG.size(); i++) + fft_in[i] = cx(angle_errors[i], 0); + + /* Invoke FFT function */ + fft(fft_in, fft_out, 8); + + /* Extract magnitude and phase from complex fft_out array */ + for (int i = 0; i < PANG.size(); i++) { + //cout << "fft_out[" << i << "] = " << fft_out[i].real() / 256 << " " << fft_out[i].imag() / 256 << "\n"; + + angle_errors_fft_temp[i] = pow((pow(fft_out[i].real() / PANG.size(), 2) + pow(-fft_out[i].imag() / PANG.size(), 2)), 0.5); + angle_errors_fft_temp[i] *= 2; + + angle_errors_fft_phase_temp[i] = atan2(fft_out[i].imag(), fft_out[i].real()); + } + + /* get upper half only */ + for (int i = 0; i < PANG.size() / 2; i++) { + angle_errors_fft[i] = angle_errors_fft_temp[i]; + angle_errors_fft_phase[i] = angle_errors_fft_phase_temp[i]; + } + + /* end code for FFT of angle errors */ + // Extract HMag parameters + double H1Mag = angle_errors_fft[cycles]; + double H2Mag = angle_errors_fft[2 * cycles]; + double H3Mag = angle_errors_fft[3 * cycles]; + double H8Mag = angle_errors_fft[8 * cycles]; + + /* Display HMAG values */ + result.append("H1Mag = " + QString::number(H1Mag) + "\n"); + result.append("H2Mag = " + QString::number(H2Mag) + "\n"); + result.append("H3Mag = " + QString::number(H3Mag) + "\n"); + result.append("H8Mag = " + QString::number(H8Mag) + "\n"); + // cout << "H1Mag = " << H1Mag << "\n"; + // cout << "H2Mag = " << H2Mag << "\n"; + // cout << "H3Mag = " << H3Mag << "\n"; + // cout << "H8Mag = " << H8Mag << "\n"; + + // Extract HPhase parameters + double H1Phase = (180 / M_PI) * (angle_errors_fft_phase[cycles]); + double H2Phase = (180 / M_PI) * (angle_errors_fft_phase[2 * cycles]); + double H3Phase = (180 / M_PI) * (angle_errors_fft_phase[3 * cycles]); + double H8Phase = (180 / M_PI) * (angle_errors_fft_phase[8 * cycles]); + + /* Display HPHASE values */ + result.append("H1Phase = " + QString::number(H1Phase) + "\n"); + result.append("H2Phase = " + QString::number(H2Phase) + "\n"); + result.append("H3Phase = " + QString::number(H3Phase) + "\n"); + result.append("H8Phase = " + QString::number(H8Phase) + "\n"); + // cout << "H1Phase = " << H1Phase << "\n"; + // cout << "H2Phase = " << H2Phase << "\n"; + // cout << "H3Phase = " << H3Phase << "\n"; + // cout << "H8Phase = " << H8Phase << "\n"; + + // cout << "\n\n"; + + double H1 = H1Mag * cos(M_PI / 180 * (H1Phase)); + double H2 = H2Mag * cos(M_PI / 180 * (H2Phase)); + double H3 = H3Mag * cos(M_PI / 180 * (H3Phase)); + double H8 = H8Mag * cos(M_PI / 180 * (H8Phase)); + + double init_err = H1 + H2 + H3 + H8; + double init_angle = PANG[0] - init_err; + double H1PHcor, H2PHcor, H3PHcor, H8PHcor; + + /* Counterclock wise, slope of error FIT is negative */ + if (CCW) { + H1Phase *= -1; + H2Phase *= -1; + H3Phase *= -1; + H8Phase *= -1; + } + + /* Clockwise */ + H1PHcor = H1Phase - (1 * init_angle - 90); + H2PHcor = H2Phase - (2 * init_angle - 90); + H3PHcor = H3Phase - (3 * init_angle - 90); + H8PHcor = H8Phase - (8 * init_angle - 90); + + /* Get modulo from 360 */ + H1PHcor = (int)H1PHcor % 360; + H2PHcor = (int)H2PHcor % 360; + H3PHcor = (int)H3PHcor % 360; + H8PHcor = (int)H8PHcor % 360; + + /* Variables declaration for data correction */ + vector H1c(PANG.size()); + vector H2c(PANG.size()); + vector H3c(PANG.size()); + vector H8c(PANG.size()); + vector HXcorrection(PANG.size()); + + ///* Apply correction and check if working on original data */ + for (int i = 0; i < PANG.size(); i++) + { + H1c[i] = H1Mag * sin(M_PI / 180 * (PANG[i]) + M_PI / 180 * (H1PHcor)); + H2c[i] = H2Mag * sin(2 * M_PI / 180 * (PANG[i]) + M_PI / 180 * (H2PHcor)); + H3c[i] = H3Mag * sin(3 * M_PI / 180 * (PANG[i]) + M_PI / 180 * (H3PHcor)); + H8c[i] = H8Mag * sin(8 * M_PI / 180 * (PANG[i]) + M_PI / 180 * (H8PHcor)); + + HXcorrection[i] = H1c[i] + H2c[i] + H3c[i] + H8c[i]; + } + + // These are the results to be programmed into the device + // Magnitude scaling factor of 0.6072 is needed due to internal ADMT4000 + // CORDIC calculation scaling + + // Hardcoded value for comparison / reference + //H1Mag = 0.3259; + //H2Mag = 0.1275; + //H3Mag = 3.4849e-03; + //H8Mag = 0.088172; + //H1PHcor = 202.58; + //H2PHcor = 342.78; + //H3PHcor = 303.40; + //H8PHcor = 179.97; + + // HMag Scaling + H1Mag = H1Mag * 0.6072; + H2Mag = H2Mag * 0.6072; + H3Mag = H3Mag * 0.6072; + H8Mag = H8Mag * 0.6072; + + // Derive register compatible HMAG values + double mag_scale_factor_11bit = 11.2455 / (1 << 11); + double mag_scale_factor_8bit = 1.40076 / (1 << 8); + int HAR_MAG_1 = (int)(H1Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit + int HAR_MAG_2 = (int)(H2Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit + int HAR_MAG_3 = (int)(H3Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit + int HAR_MAG_8 = (int)(H8Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit + + // Derive register compatible HPHASE values + double pha_scale_factor_12bit = 360.0 / (1 << 12); // in Deg + int HAR_PHASE_1 = (int)(H1PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + int HAR_PHASE_2 = (int)(H2PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + int HAR_PHASE_3 = (int)(H3PHcor / pha_scale_factor_12bit) & (0xFFF);// 12bit number + int HAR_PHASE_8 = (int)(H8PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + + result.append("HMAG1: " + QString::number(HAR_MAG_1) + "\n"); + result.append("HMAG2: " + QString::number(HAR_MAG_2) + "\n"); + result.append("HMAG3: " + QString::number(HAR_MAG_3) + "\n"); + result.append("HMAG8: " + QString::number(HAR_MAG_8) + "\n"); + + result.append("HPHASE1: " + QString::number(HAR_PHASE_1) + "\n"); + result.append("HPHASE2: " + QString::number(HAR_PHASE_2) + "\n"); + result.append("HPHASE3: " + QString::number(HAR_PHASE_3) + "\n"); + result.append("HPHASE8: " + QString::number(HAR_PHASE_8) + "\n"); + + // cout << "HMAG1: " << HAR_MAG_1 << "\n"; + // cout << "HMAG2: " << HAR_MAG_2 << "\n"; + // cout << "HMAG3: " << HAR_MAG_3 << "\n"; + // cout << "HMAG8: " << HAR_MAG_8 << "\n"; + + // cout << "HPHASE1: " << HAR_PHASE_1 << "\n"; + // cout << "HPHASE2: " << HAR_PHASE_2 << "\n"; + // cout << "HPHASE3: " << HAR_PHASE_3 << "\n"; + // cout << "HPHASE8: " << HAR_PHASE_8 << "\n"; + + // cout << "\n\n"; + + // /* Sanity check */ + // cout << "Hello World" << "\n"; + + return result; } \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index ab98403dc0..e308437cbb 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -150,29 +150,29 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg generalSection->contentLayout()->setSpacing(10); generalWidget->contentLayout()->addWidget(generalSection); - // Sample Rate - QLabel *sampleRateLabel = new QLabel(generalSection); - sampleRateLabel->setText("Sample Rate (Update Freq.)"); - StyleHelper::MenuSmallLabel(sampleRateLabel, "sampleRateLabel"); - sampleRateLineEdit = new QLineEdit(generalSection); - sampleRateLineEdit->setText(QString::number(sampleRate)); + // Graph Update Interval + QLabel *graphUpdateIntervalLabel = new QLabel(generalSection); + graphUpdateIntervalLabel->setText("Graph Update Interval (ms)"); + StyleHelper::MenuSmallLabel(graphUpdateIntervalLabel, "graphUpdateIntervalLabel"); + graphUpdateIntervalLineEdit = new QLineEdit(generalSection); + graphUpdateIntervalLineEdit->setText(QString::number(sampleRate)); - connectLineEditToNumber(sampleRateLineEdit, sampleRate); + connectLineEditToNumber(graphUpdateIntervalLineEdit, sampleRate); - generalSection->contentLayout()->addWidget(sampleRateLabel); - generalSection->contentLayout()->addWidget(sampleRateLineEdit); + generalSection->contentLayout()->addWidget(graphUpdateIntervalLabel); + generalSection->contentLayout()->addWidget(graphUpdateIntervalLineEdit); - // Buffer Size - QLabel *bufferSizeLabel = new QLabel(generalSection); - bufferSizeLabel->setText("Buffer Sample Size"); - StyleHelper::MenuSmallLabel(bufferSizeLabel, "bufferSizeLabel"); - bufferSizeLineEdit = new QLineEdit(generalSection); - bufferSizeLineEdit->setText(QString::number(bufferSize)); + // Data Sample Size + QLabel *dataSampleSizeLabel = new QLabel(generalSection); + dataSampleSizeLabel->setText("Data Sample Size"); + StyleHelper::MenuSmallLabel(dataSampleSizeLabel, "dataSampleSizeLabel"); + dataSampleSizeLineEdit = new QLineEdit(generalSection); + dataSampleSizeLineEdit->setText(QString::number(bufferSize)); - connectLineEditToNumber(bufferSizeLineEdit, bufferSize); + connectLineEditToNumber(dataSampleSizeLineEdit, bufferSize); - generalSection->contentLayout()->addWidget(bufferSizeLabel); - generalSection->contentLayout()->addWidget(bufferSizeLineEdit); + generalSection->contentLayout()->addWidget(dataSampleSizeLabel); + generalSection->contentLayout()->addWidget(dataSampleSizeLineEdit); // Data Graph Setting Widget MenuSectionWidget *dataGraphWidget = new MenuSectionWidget(generalSettingWidget); @@ -352,8 +352,8 @@ void HarmonicCalibration::updateLineEditValues(){ void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { - sampleRateLineEdit->setEnabled(value); - bufferSizeLineEdit->setEnabled(value); + graphUpdateIntervalLineEdit->setEnabled(value); + dataSampleSizeLineEdit->setEnabled(value); dataGraphSamplesLineEdit->setEnabled(value); tempGraphSamplesLineEdit->setEnabled(value); m_dataGraphDirectionMenuCombo->setEnabled(value); @@ -623,15 +623,15 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationPhaseLayout->addWidget(calibrationH8PhaseLabel); calibrationPhaseLayout->addWidget(calibrationH8PhaseLineEdit); - QPushButton *registerCalibrationDataButton = new QPushButton(calibrationRegisterWidget); - registerCalibrationDataButton->setText("Register"); - StyleHelper::BlueButton(registerCalibrationDataButton, "registerCalibrationDataButton"); + QPushButton *applyCalibrationDataButton = new QPushButton(calibrationRegisterWidget); + applyCalibrationDataButton->setText("Apply"); + StyleHelper::BlueButton(applyCalibrationDataButton, "applyCalibrationDataButton"); calibrationRegisterLayout->addWidget(calibrationMagWidget); calibrationRegisterLayout->addWidget(calibrationPhaseWidget); calibrationResultLayout->addWidget(calibrationRegisterWidget); - calibrationResultLayout->addWidget(registerCalibrationDataButton); + calibrationResultLayout->addWidget(applyCalibrationDataButton); tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); tool->topContainer()->setVisible(false); @@ -655,7 +655,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::calibrateData); connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); connect(importDataButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); - connect(registerCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::registerCalibrationData); + connect(applyCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::registerCalibrationData); return tool; } @@ -717,6 +717,17 @@ void HarmonicCalibration::removeLastItemFromRawDataList(){ void HarmonicCalibration::calibrateData() { logsPlainTextEdit->appendPlainText("\n======= Calibration Start =======\n"); + QVector rawData; + + for (int i = 0; i < rawDataListWidget->count(); ++i) { + QListWidgetItem* item = rawDataListWidget->item(i); + std::string text = item->text().toStdString(); + double value = std::stod(text); + rawData.append(value); + } + std::vector stdData(rawData.begin(), rawData.end()); + + logsPlainTextEdit->appendPlainText(m_admtController->calibrate(stdData)); } void HarmonicCalibration::registerCalibrationData() From c882759a60160a8c2e348ac85faf811989543b51 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 31 Jul 2024 11:10:45 +0800 Subject: [PATCH 014/112] admt: Layout for motor controls - Added custom spinbox widget - Styled line edits and combo boxes Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/CMakeLists.txt | 16 +- plugins/admt/include/admt/admtcontroller.h | 4 +- .../admt/include/admt/harmoniccalibration.h | 14 +- .../include/admt/widgets/horizontalspinbox.h | 36 + plugins/admt/res/chevron-down-s.svg | 3 + plugins/admt/res/minus.svg | 3 + plugins/admt/res/plus.svg | 3 + plugins/admt/res/resources.qrc | 7 + plugins/admt/src/harmoniccalibration.cpp | 652 ++++++++++++------ .../admt/src/widgets/horizontalspinbox.cpp | 157 +++++ 10 files changed, 697 insertions(+), 198 deletions(-) create mode 100644 plugins/admt/include/admt/widgets/horizontalspinbox.h create mode 100644 plugins/admt/res/chevron-down-s.svg create mode 100644 plugins/admt/res/minus.svg create mode 100644 plugins/admt/res/plus.svg create mode 100644 plugins/admt/res/resources.qrc create mode 100644 plugins/admt/src/widgets/horizontalspinbox.cpp diff --git a/plugins/admt/CMakeLists.txt b/plugins/admt/CMakeLists.txt index 88570b24b0..c9691bd935 100644 --- a/plugins/admt/CMakeLists.txt +++ b/plugins/admt/CMakeLists.txt @@ -26,8 +26,20 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) -file(GLOB SRC_LIST src/*.cpp src/*.cc) -file(GLOB HEADER_LIST include/${SCOPY_MODULE}/*.h include/${SCOPY_MODULE}/*.hpp) +file( + GLOB + SRC_LIST + src/*.cpp + src/*.cc + src/widgets/*.cpp +) +file( + GLOB + HEADER_LIST + include/${SCOPY_MODULE}/*.h + include/${SCOPY_MODULE}/*.hpp + include/${SCOPY_MODULE}/widgets/*.h +) file(GLOB UI_LIST ui/*.ui) set(ENABLE_TESTING ON) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 7c5947b36d..961b02b192 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -1,6 +1,8 @@ #ifndef ADMTCONTROLLER_H #define ADMTCONTROLLER_H +#include "scopy-admt_export.h" + #include #include @@ -21,7 +23,7 @@ using namespace std; namespace scopy::admt { -class ADMTController : public QObject +class SCOPY_ADMT_EXPORT ADMTController : public QObject { Q_OBJECT public: diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index f9598dcbf0..6368e77d72 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -33,10 +35,12 @@ #include #include #include +#include +#include namespace scopy::admt { -class HarmonicCalibration : public QWidget +class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget { Q_OBJECT public: @@ -69,7 +73,7 @@ public Q_SLOTS: QLineEdit *graphUpdateIntervalLineEdit, *dataSampleSizeLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit; - QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, *calibrationAngleLabel; + QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, *calibrationMotorCurrentPositionLabel; Sismograph *dataGraph, *tempGraph; @@ -105,6 +109,12 @@ public Q_SLOTS: void importCalibrationData(); void calibrationLogWrite(QString message); void calibrationLogWriteLn(QString message); + void applyTextBoxStyle(QWidget *widget); + void applyLabelPadding(QLabel *widget); + void applyLineEditPadding(QLineEdit *widget); + void applyLineEditAlignment(QLineEdit *widget); + void applyComboBoxStyle(QComboBox *widget, const QString& styleHelperColor = "CH0"); + void applyLabelStyle(QWidget *widget, const QString& styleHelperColor = "CH0", bool isBold = false); QTimer *timer, *calibrationTimer; diff --git a/plugins/admt/include/admt/widgets/horizontalspinbox.h b/plugins/admt/include/admt/widgets/horizontalspinbox.h new file mode 100644 index 0000000000..6971f0e27e --- /dev/null +++ b/plugins/admt/include/admt/widgets/horizontalspinbox.h @@ -0,0 +1,36 @@ +#ifndef HORIZONTALSPINBOX_H +#define HORIZONTALSPINBOX_H + +#include "scopy-admt_export.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace scopy::admt { + class SCOPY_ADMT_EXPORT HorizontalSpinBox : public QWidget + { + Q_OBJECT + public: + HorizontalSpinBox(QString header = "", double initialValue = 0.0, QString unit = "", QWidget *parent = nullptr); + public Q_SLOTS: + void setValue(double); + protected Q_SLOTS: + void onMinusButtonPressed(); + void onPlusButtonPressed(); + void onLineEditTextEdited(); + private: + double m_value = 0; + QString m_unit = ""; + QLineEdit *lineEdit; + void applyLineEditStyle(QLineEdit *widget); + void applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius = 0, int topRightBorderRadius = 0, int bottomLeftBorderRadius = 0, int bottomRightBorderRadius = 0); + void applyUnitLabelStyle(QLabel *widget); + }; +} // namespace scopy::admt + +#endif // HORIZONTALSPINBOX_H \ No newline at end of file diff --git a/plugins/admt/res/chevron-down-s.svg b/plugins/admt/res/chevron-down-s.svg new file mode 100644 index 0000000000..31fc00f903 --- /dev/null +++ b/plugins/admt/res/chevron-down-s.svg @@ -0,0 +1,3 @@ + + + diff --git a/plugins/admt/res/minus.svg b/plugins/admt/res/minus.svg new file mode 100644 index 0000000000..d750fa52a0 --- /dev/null +++ b/plugins/admt/res/minus.svg @@ -0,0 +1,3 @@ + + + diff --git a/plugins/admt/res/plus.svg b/plugins/admt/res/plus.svg new file mode 100644 index 0000000000..90d50b4f38 --- /dev/null +++ b/plugins/admt/res/plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/plugins/admt/res/resources.qrc b/plugins/admt/res/resources.qrc new file mode 100644 index 0000000000..fa99638ef0 --- /dev/null +++ b/plugins/admt/res/resources.qrc @@ -0,0 +1,7 @@ + + + minus.svg + plus.svg + chevron-down-s.svg + + \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index e308437cbb..bd8bc3e8ae 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -1,8 +1,9 @@ #include "harmoniccalibration.h" +#include #include -static int sampleRate = 50; +static int sampleRate = 1000; static int bufferSize = 1; static int dataGraphSamples = 100; static int tempGraphSamples = 100; @@ -28,14 +29,27 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg setLayout(lay); lay->setMargin(0); tabWidget = new QTabWidget(this); + tabWidget->setObjectName("HarmonicTabWidget"); + QString tabStyle = QString("right: 0;"); + tabWidget->tabBar()->setStyleSheet(tabStyle); + QString tabWidgetStyle = QString(R"css( + QTabWidget::tab-bar { + alignment: center; + } + )css"); + tabWidget->tabBar()->setStyleSheet(tabWidgetStyle); tabWidget->addTab(tool, "Acquisition"); - lay->insertWidget(0, tabWidget); openLastMenuButton = new OpenLastMenuBtn(dynamic_cast(tool->rightContainer()), true, this); rightMenuButtonGroup = dynamic_cast(openLastMenuButton)->getButtonGroup(); settingsButton = new GearBtn(this); - infoButton = new InfoBtn(this); + // infoButton = new InfoBtn(this); + + // lay->insertWidget(0, infoButton); + + lay->insertWidget(1, tabWidget); + runButton = new RunBtn(this); @@ -155,6 +169,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg graphUpdateIntervalLabel->setText("Graph Update Interval (ms)"); StyleHelper::MenuSmallLabel(graphUpdateIntervalLabel, "graphUpdateIntervalLabel"); graphUpdateIntervalLineEdit = new QLineEdit(generalSection); + applyTextBoxStyle(graphUpdateIntervalLineEdit); + applyLineEditPadding(graphUpdateIntervalLineEdit); + applyLineEditAlignment(graphUpdateIntervalLineEdit); graphUpdateIntervalLineEdit->setText(QString::number(sampleRate)); connectLineEditToNumber(graphUpdateIntervalLineEdit, sampleRate); @@ -167,6 +184,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg dataSampleSizeLabel->setText("Data Sample Size"); StyleHelper::MenuSmallLabel(dataSampleSizeLabel, "dataSampleSizeLabel"); dataSampleSizeLineEdit = new QLineEdit(generalSection); + applyTextBoxStyle(dataSampleSizeLineEdit); + applyLineEditPadding(dataSampleSizeLineEdit); + applyLineEditAlignment(dataSampleSizeLineEdit); dataSampleSizeLineEdit->setText(QString::number(bufferSize)); connectLineEditToNumber(dataSampleSizeLineEdit, bufferSize); @@ -186,6 +206,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg dataGraphChannelCombo->addItem("Rotation", QVariant::fromValue(reinterpret_cast(const_cast(rotationChannelName)))); dataGraphChannelCombo->addItem("Angle", QVariant::fromValue(reinterpret_cast(const_cast(angleChannelName)))); dataGraphChannelCombo->addItem("Count", QVariant::fromValue(reinterpret_cast(const_cast(countChannelName)))); + applyComboBoxStyle(dataGraphChannelCombo); connectMenuComboToGraphChannel(m_dataGraphChannelMenuCombo, dataGraph); @@ -196,6 +217,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg dataGraphSamplesLabel->setText("Samples"); StyleHelper::MenuSmallLabel(dataGraphSamplesLabel, "dataGraphSamplesLabel"); dataGraphSamplesLineEdit = new QLineEdit(generalSection); + applyTextBoxStyle(dataGraphSamplesLineEdit); + applyLineEditPadding(dataGraphSamplesLineEdit); + applyLineEditAlignment(dataGraphSamplesLineEdit); dataGraphSamplesLineEdit->setText(QString::number(dataGraphSamples)); connectLineEditToGraphSamples(dataGraphSamplesLineEdit, dataGraphSamples, dataGraph); @@ -203,17 +227,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg dataGraphSection->contentLayout()->addWidget(dataGraphSamplesLabel); dataGraphSection->contentLayout()->addWidget(dataGraphSamplesLineEdit); - // Graph Direction - m_dataGraphDirectionMenuCombo = new MenuCombo("Direction", dataGraphSection); - auto dataGraphDirectionCombo = m_dataGraphDirectionMenuCombo->combo(); - dataGraphDirectionCombo->addItem("Left to right", Sismograph::LEFT_TO_RIGHT); - dataGraphDirectionCombo->addItem("Right to left", Sismograph::RIGHT_TO_LEFT); - dataGraphSection->contentLayout()->addWidget(m_dataGraphDirectionMenuCombo); - dataGraphWidget->contentLayout()->addWidget(dataGraphSection); - connectMenuComboToGraphDirection(m_dataGraphDirectionMenuCombo, dataGraph); - // Temperature Graph MenuSectionWidget *tempGraphWidget = new MenuSectionWidget(generalSettingWidget); tempGraphWidget->contentLayout()->setSpacing(10); @@ -225,22 +240,17 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg tempGraphSamplesLabel->setText("Samples"); StyleHelper::MenuSmallLabel(tempGraphSamplesLabel, "tempGraphSamplesLabel"); tempGraphSamplesLineEdit = new QLineEdit(generalSection); + applyTextBoxStyle(tempGraphSamplesLineEdit); + applyLineEditPadding(tempGraphSamplesLineEdit); + applyLineEditAlignment(tempGraphSamplesLineEdit); tempGraphSamplesLineEdit->setText(QString::number(tempGraphSamples)); tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLabel); tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLineEdit); connectLineEditToGraphSamples(tempGraphSamplesLineEdit, tempGraphSamples, tempGraph); - // Graph Direction - m_tempGraphDirectionMenuCombo = new MenuCombo("Direction", tempGraphSection); - auto tempGraphDirectionCombo = m_tempGraphDirectionMenuCombo->combo(); - tempGraphDirectionCombo->addItem("Left to right", Sismograph::LEFT_TO_RIGHT); - tempGraphDirectionCombo->addItem("Right to left", Sismograph::RIGHT_TO_LEFT); - tempGraphSection->contentLayout()->addWidget(m_tempGraphDirectionMenuCombo); tempGraphWidget->contentLayout()->addWidget(tempGraphSection); - connectMenuComboToGraphDirection(m_tempGraphDirectionMenuCombo, tempGraph); - generalSettingLayout->addWidget(header); generalSettingLayout->addSpacerItem(new QSpacerItem(0, 3, QSizePolicy::Fixed, QSizePolicy::Fixed)); generalSettingLayout->addWidget(generalWidget); @@ -261,7 +271,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg tool->openTopContainerHelper(false); tool->addWidgetToTopContainerMenuControlHelper(openLastMenuButton, TTA_RIGHT); tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); - tool->addWidgetToTopContainerHelper(infoButton, TTA_LEFT); + // tool->addWidgetToTopContainerHelper(infoButton, TTA_LEFT); tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); tool->leftStack()->add("rawDataScroll", rawDataScroll); tool->rightStack()->add("generalSettingScroll", generalSettingScroll); @@ -356,8 +366,6 @@ void HarmonicCalibration::updateGeneralSettingEnabled(bool value) dataSampleSizeLineEdit->setEnabled(value); dataGraphSamplesLineEdit->setEnabled(value); tempGraphSamplesLineEdit->setEnabled(value); - m_dataGraphDirectionMenuCombo->setEnabled(value); - m_tempGraphDirectionMenuCombo->setEnabled(value); } void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable) @@ -453,202 +461,356 @@ void HarmonicCalibration::connectMenuComboToGraphChannel(MenuCombo* menuCombo, S ToolTemplate* HarmonicCalibration::createCalibrationWidget() { ToolTemplate *tool = new ToolTemplate(this); - - QScrollArea *calibrationControlScrollArea = new QScrollArea(this); - calibrationControlScrollArea->setWidgetResizable(true); - QWidget *controlWidget = new QWidget(calibrationControlScrollArea); - calibrationControlScrollArea->setWidget(controlWidget); - QVBoxLayout *controlLayout = new QVBoxLayout(controlWidget); - controlLayout->setMargin(0); - controlWidget->setLayout(controlLayout); - - // Angle Widget - MenuSectionWidget *angleWidget = new MenuSectionWidget(controlWidget); - angleWidget->contentLayout()->setSpacing(10); - MenuCollapseSection *angleSection = new MenuCollapseSection("Angle", MenuCollapseSection::MHCW_NONE, angleWidget); - angleSection->contentLayout()->setSpacing(10); - angleWidget->contentLayout()->addWidget(angleSection); - calibrationAngleLabel = new QLabel(angleSection); - StyleHelper::MenuControlLabel(calibrationAngleLabel, "calibrationAngleLabel"); - angleSection->contentLayout()->addWidget(calibrationAngleLabel); - - // Calibration Widget - MenuSectionWidget *calibrationControlWidget = new MenuSectionWidget(controlWidget); - calibrationControlWidget->contentLayout()->setSpacing(10); - MenuCollapseSection *calibrationSection = new MenuCollapseSection("Calibration", MenuCollapseSection::MHCW_NONE, calibrationControlWidget); - calibrationSection->contentLayout()->setSpacing(10); - calibrationControlWidget->contentLayout()->addWidget(calibrationSection); - - QPushButton *addCalibrationDataButton = new QPushButton(calibrationControlWidget); - addCalibrationDataButton->setText("Add Data"); - StyleHelper::BlueButton(addCalibrationDataButton, "addCalibrationDataButton"); - - QPushButton *removeLastCalibrationDataButton = new QPushButton(calibrationControlWidget); - removeLastCalibrationDataButton->setText("Remove Last Data"); - StyleHelper::BlueButton(removeLastCalibrationDataButton, "removeLastCalibrationDataButton"); - QPushButton *calibrateDataButton = new QPushButton(calibrationControlWidget); - calibrateDataButton->setText("Calibrate"); - StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); + #pragma region Calibration Data Graph Widget + QWidget *calibrationDataGraphWidget = new QWidget(); + QVBoxLayout *calibrationDataGraphLayout = new QVBoxLayout(calibrationDataGraphWidget); + calibrationDataGraphWidget->setLayout(calibrationDataGraphLayout); + calibrationDataGraphLayout->setMargin(0); + calibrationDataGraphLayout->setSpacing(10); + + QWidget *calibrationRawDataGraphWidget = new QWidget(calibrationDataGraphWidget); + QVBoxLayout *calibrationRawDataGraphLayout = new QVBoxLayout(calibrationRawDataGraphWidget); + calibrationRawDataGraphWidget->setLayout(calibrationRawDataGraphLayout); + calibrationRawDataGraphLayout->setMargin(0); + calibrationRawDataGraphLayout->setSpacing(4); + QLabel *calibrationRawDataGraphLabel = new QLabel("Raw Data", calibrationRawDataGraphWidget); + StyleHelper::MenuCollapseHeaderLabel(calibrationRawDataGraphLabel, "calibrationRawDataGraphLabel"); + PlotWidget *calibrationRawDataPlotWidget = new PlotWidget(); + calibrationRawDataPlotWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + calibrationRawDataGraphLayout->addWidget(calibrationRawDataGraphLabel); + calibrationRawDataGraphLayout->addWidget(calibrationRawDataPlotWidget); + + QWidget *calibrationFFTDataGraphWidget = new QWidget(calibrationDataGraphWidget); + QVBoxLayout *calibrationFFTDataGraphLayout = new QVBoxLayout(calibrationFFTDataGraphWidget); + calibrationFFTDataGraphWidget->setLayout(calibrationFFTDataGraphLayout); + calibrationFFTDataGraphLayout->setMargin(0); + calibrationFFTDataGraphLayout->setSpacing(4); + QLabel *calibrationFFTDataGraphLabel = new QLabel("FFT Data", calibrationFFTDataGraphWidget); + StyleHelper::MenuCollapseHeaderLabel(calibrationFFTDataGraphLabel, "calibrationFFTDataGraphLabel"); + PlotWidget *calibrationFFTDataPlotWidget = new PlotWidget(); + calibrationFFTDataPlotWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataGraphLabel); + calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataPlotWidget); + + calibrationDataGraphLayout->addWidget(calibrationRawDataGraphWidget); + calibrationDataGraphLayout->addWidget(calibrationFFTDataGraphWidget); + #pragma endregion + + #pragma region Calibration Settings Widget + QScrollArea *calibrationSettingsScrollArea = new QScrollArea(); + QWidget *calibrationSettingsWidget = new QWidget(calibrationSettingsScrollArea); + QVBoxLayout *calibrationSettingsLayout = new QVBoxLayout(calibrationSettingsWidget); + calibrationSettingsScrollArea->setWidgetResizable(true); + // calibrationSettingsScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + calibrationSettingsScrollArea->setWidget(calibrationSettingsWidget); + calibrationSettingsWidget->setFixedWidth(260); + calibrationSettingsWidget->setLayout(calibrationSettingsLayout); + + #pragma region Calibration Coefficient Section Widget + MenuSectionWidget *calibrationCoeffSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + QLabel *calibrationDisplayFormatLabel = new QLabel(calibrationCoeffSectionWidget); + calibrationDisplayFormatLabel->setText("Display Format"); + StyleHelper::MenuCollapseHeaderLabel(calibrationDisplayFormatLabel, "calibrationDisplayFormatLabel"); + QLabel *calibrationCalculatedCoeffLabel = new QLabel(calibrationCoeffSectionWidget); + calibrationCalculatedCoeffLabel->setText("Calculated Coefficients"); + StyleHelper::MenuCollapseHeaderLabel(calibrationCalculatedCoeffLabel, "calibrationCalculatedCoeffLabel"); + + CustomSwitch *calibrationDisplayFormatSwitch = new CustomSwitch(); + calibrationDisplayFormatSwitch->setOffText("Hex"); + calibrationDisplayFormatSwitch->setOnText("Angle"); + calibrationDisplayFormatSwitch->setProperty("bigBtn", true); + QPushButton *applyCalibrationDataButton = new QPushButton(calibrationCoeffSectionWidget); + applyCalibrationDataButton->setText("Apply"); + StyleHelper::BlueButton(applyCalibrationDataButton, "applyCalibrationDataButton"); - QPushButton *extractDataButton = new QPushButton(calibrationControlWidget); - extractDataButton->setText("Extract"); + // Calculated Coefficients Widget + QWidget *calibrationCalculatedCoeffWidget = new QWidget(calibrationCoeffSectionWidget); + QGridLayout *calibrationCalculatedCoeffLayout = new QGridLayout(calibrationCalculatedCoeffWidget); + calibrationCalculatedCoeffWidget->setLayout(calibrationCalculatedCoeffLayout); + calibrationCalculatedCoeffLayout->setMargin(0); + calibrationCalculatedCoeffLayout->setVerticalSpacing(4); + QString calibrationCalculatedCoeffStyle = QString(R"css( + background-color: &&colorname&&; + )css"); + calibrationCalculatedCoeffStyle.replace(QString("&&colorname&&"), StyleHelper::getColor("UIElementBackground")); + calibrationCalculatedCoeffWidget->setStyleSheet(calibrationCalculatedCoeffStyle); + + QString rowContainerStyle = QString(R"css( + background-color: &&colorname&&; + border-radius: 4px; + )css"); + rowContainerStyle.replace(QString("&&colorname&&"), StyleHelper::getColor("ScopyBackground")); + + // H1 + QWidget *h1RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h1RowLayout = new QHBoxLayout(h1RowContainer); + h1RowContainer->setLayout(h1RowLayout); + h1RowContainer->setStyleSheet(rowContainerStyle); + h1RowContainer->setFixedHeight(30); + h1RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + h1RowLayout->setContentsMargins(12, 4, 12, 4); + QLabel *calibrationH1Label = new QLabel("H1", calibrationCalculatedCoeffWidget); + QLabel *calibrationH1MagLabel = new QLabel("999.99°", calibrationCalculatedCoeffWidget); + QLabel *calibrationH1PhaseLabel = new QLabel("Φ 999.99", calibrationCalculatedCoeffWidget); + calibrationH1Label->setFixedWidth(52); + applyLabelStyle(calibrationH1Label, "LabelText", true); + applyLabelStyle(calibrationH1MagLabel, "CH0"); + applyLabelStyle(calibrationH1PhaseLabel, "CH1"); + + h1RowLayout->addWidget(calibrationH1Label); + h1RowLayout->addWidget(calibrationH1MagLabel); + h1RowLayout->addWidget(calibrationH1PhaseLabel, 0, Qt::AlignRight); + + // H2 + QWidget *h2RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h2RowLayout = new QHBoxLayout(h2RowContainer); + h2RowContainer->setLayout(h2RowLayout); + h2RowContainer->setStyleSheet(rowContainerStyle); + h2RowContainer->setFixedHeight(30); + h2RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + h2RowLayout->setContentsMargins(12, 4, 12, 4); + QLabel *calibrationH2Label = new QLabel("H2", calibrationCalculatedCoeffWidget); + QLabel *calibrationH2MagLabel = new QLabel("999.99°", calibrationCalculatedCoeffWidget); + QLabel *calibrationH2PhaseLabel = new QLabel("Φ 999.99", calibrationCalculatedCoeffWidget); + calibrationH2Label->setFixedWidth(52); + applyLabelStyle(calibrationH2Label, "LabelText", true); + applyLabelStyle(calibrationH2MagLabel, "CH0"); + applyLabelStyle(calibrationH2PhaseLabel, "CH1"); + + h2RowLayout->addWidget(calibrationH2Label); + h2RowLayout->addWidget(calibrationH2MagLabel); + h2RowLayout->addWidget(calibrationH2PhaseLabel, 0, Qt::AlignRight); + + // H3 + QWidget *h3RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h3RowLayout = new QHBoxLayout(h3RowContainer); + h3RowContainer->setLayout(h3RowLayout); + h3RowContainer->setStyleSheet(rowContainerStyle); + h3RowContainer->setFixedHeight(30); + h3RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + h3RowLayout->setContentsMargins(12, 4, 12, 4); + QLabel *calibrationH3Label = new QLabel("H3", calibrationCalculatedCoeffWidget); + QLabel *calibrationH3MagLabel = new QLabel("999.99°", calibrationCalculatedCoeffWidget); + QLabel *calibrationH3PhaseLabel = new QLabel("Φ 999.99", calibrationCalculatedCoeffWidget); + calibrationH3Label->setFixedWidth(52); + applyLabelStyle(calibrationH3Label, "LabelText", true); + applyLabelStyle(calibrationH3MagLabel, "CH0"); + applyLabelStyle(calibrationH3PhaseLabel, "CH1"); + + h3RowLayout->addWidget(calibrationH3Label); + h3RowLayout->addWidget(calibrationH3MagLabel); + h3RowLayout->addWidget(calibrationH3PhaseLabel, 0, Qt::AlignRight); + + // H8 + QWidget *h8RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h8RowLayout = new QHBoxLayout(h8RowContainer); + h8RowContainer->setLayout(h8RowLayout); + h8RowContainer->setStyleSheet(rowContainerStyle); + h8RowContainer->setFixedHeight(30); + h8RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + h8RowLayout->setContentsMargins(12, 4, 12, 4); + QLabel *calibrationH8Label = new QLabel("H8", calibrationCalculatedCoeffWidget); + QLabel *calibrationH8MagLabel = new QLabel("999.99°", calibrationCalculatedCoeffWidget); + QLabel *calibrationH8PhaseLabel = new QLabel("Φ 999.99", calibrationCalculatedCoeffWidget); + calibrationH8Label->setFixedWidth(52); + applyLabelStyle(calibrationH8Label, "LabelText", true); + applyLabelStyle(calibrationH8MagLabel, "CH0"); + applyLabelStyle(calibrationH8PhaseLabel, "CH1"); + + h8RowLayout->addWidget(calibrationH8Label); + h8RowLayout->addWidget(calibrationH8MagLabel); + h8RowLayout->addWidget(calibrationH8PhaseLabel, 0, Qt::AlignRight); + + calibrationCalculatedCoeffLayout->addWidget(h1RowContainer, 0, 0); + calibrationCalculatedCoeffLayout->addWidget(h2RowContainer, 1, 0); + calibrationCalculatedCoeffLayout->addWidget(h3RowContainer, 2, 0); + calibrationCalculatedCoeffLayout->addWidget(h8RowContainer, 3, 0); + + calibrationCoeffSectionWidget->contentLayout()->setSpacing(10); + calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatLabel); + calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatSwitch); + calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffLabel); + calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffWidget); + calibrationCoeffSectionWidget->contentLayout()->addWidget(applyCalibrationDataButton); + #pragma endregion + + #pragma region Calibration Data Section Widget + MenuSectionWidget *calibrationDataSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection("Calibration Data", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, calibrationDataSectionWidget); + calibrationDataSectionWidget->contentLayout()->setSpacing(10); + calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); + + QPushButton *extractDataButton = new QPushButton(calibrationDataCollapseSection); + extractDataButton->setText("Extract to CSV"); StyleHelper::BlueButton(extractDataButton, "extractDataButton"); - - QPushButton *importDataButton = new QPushButton(calibrationControlWidget); - importDataButton->setText("Import"); + QPushButton *importDataButton = new QPushButton(calibrationDataCollapseSection); + importDataButton->setText("Import from CSV"); StyleHelper::BlueButton(importDataButton, "importDataButton"); - calibrationSection->contentLayout()->addWidget(addCalibrationDataButton); - calibrationSection->contentLayout()->addWidget(removeLastCalibrationDataButton); - calibrationSection->contentLayout()->addWidget(calibrateDataButton); - calibrationSection->contentLayout()->addWidget(extractDataButton); - calibrationSection->contentLayout()->addWidget(importDataButton); + calibrationDataCollapseSection->contentLayout()->setSpacing(10); + calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); + calibrationDataCollapseSection->contentLayout()->addWidget(importDataButton); + #pragma endregion + + #pragma region Motor Configuration Section Widget + MenuSectionWidget *motorConfigurationSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + MenuCollapseSection *motorConfigurationCollapseSection = new MenuCollapseSection("Motor Configuration", MenuCollapseSection::MHCW_NONE, motorConfigurationSectionWidget); + motorConfigurationSectionWidget->contentLayout()->addWidget(motorConfigurationCollapseSection); + + HorizontalSpinBox *motorMaxAccelerationSpinBox = new HorizontalSpinBox("Max Acceleration", 9999.99, "", motorConfigurationSectionWidget); + HorizontalSpinBox *motorMaxVelocitySpinBox = new HorizontalSpinBox("Max Velocity", 9999.99, "rpm", motorConfigurationSectionWidget); + HorizontalSpinBox *motorMaxDisplacementSpinBox = new HorizontalSpinBox("Max Displacement", 9999.99, "", motorConfigurationSectionWidget); + + MenuCombo *m_calibrationMotorRampModeMenuCombo = new MenuCombo("Ramp Mode", motorConfigurationSectionWidget); + auto calibrationMotorRampModeCombo = m_calibrationMotorRampModeMenuCombo->combo(); + calibrationMotorRampModeCombo->addItem("Position", QVariant::fromValue(reinterpret_cast(const_cast(rotationChannelName)))); + calibrationMotorRampModeCombo->addItem("Angle", QVariant::fromValue(reinterpret_cast(const_cast(angleChannelName)))); + calibrationMotorRampModeCombo->addItem("Count", QVariant::fromValue(reinterpret_cast(const_cast(countChannelName)))); + applyComboBoxStyle(calibrationMotorRampModeCombo); + + motorConfigurationCollapseSection->contentLayout()->setSpacing(10); + motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxAccelerationSpinBox); + motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxVelocitySpinBox); + motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxDisplacementSpinBox); + motorConfigurationCollapseSection->contentLayout()->addWidget(m_calibrationMotorRampModeMenuCombo); + #pragma endregion + + #pragma region Motor Control Section Widget + MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection("Motor Control", MenuCollapseSection::MHCW_NONE, motorControlSectionWidget); + motorControlSectionWidget->contentLayout()->setSpacing(10); + motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); + QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); + StyleHelper::MenuSmallLabel(currentPositionLabel, "currentPositionLabel"); + calibrationMotorCurrentPositionLabel = new QLabel("--.--°", motorControlSectionWidget); + // calibrationMotorCurrentPositionLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + calibrationMotorCurrentPositionLabel->setAlignment(Qt::AlignRight); + applyTextBoxStyle(calibrationMotorCurrentPositionLabel); + applyLabelPadding(calibrationMotorCurrentPositionLabel); + + HorizontalSpinBox *motorTargetPositionSpinBox = new HorizontalSpinBox("Target Position", 9999.99, "°", motorControlSectionWidget); + HorizontalSpinBox *motorVelocitySpinBox = new HorizontalSpinBox("Velocity", 9999.99, "rpm", motorControlSectionWidget); + + QPushButton *calibrationStartMotorButton = new QPushButton(motorControlSectionWidget); + calibrationStartMotorButton->setCheckable(true); + calibrationStartMotorButton->setChecked(false); + calibrationStartMotorButton->setText("Start Motor"); + calibrationStartMotorButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + calibrationStartMotorButton->setFixedHeight(36); + connect(calibrationStartMotorButton, &QPushButton::toggled, this, [=](bool b) { calibrationStartMotorButton->setText(b ? " Stop Motor" : " Start Motor"); }); + QString calibrationStartMotorButtonStyle = QString(R"css( + QPushButton { + border-radius: 2px; + padding-left: 20px; + padding-right: 20px; + color: white; + font-weight: 700; + font-size: 14px; + } - controlLayout->addWidget(angleWidget); - controlLayout->addWidget(calibrationControlWidget); - controlLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + QPushButton:!checked { + background-color: #27b34f; + } - // Raw Data Widget - QWidget *calibrationDataWidget = new QWidget(this); - QVBoxLayout *calibrationDataLayout = new QVBoxLayout(calibrationDataWidget); - calibrationDataLayout->setMargin(0); - calibrationDataWidget->setLayout(calibrationDataLayout); + QPushButton:checked { + background-color: #F45000; + } - MenuSectionWidget *rawDataWidget = new MenuSectionWidget(calibrationDataWidget); + QPushButton:disabled { + background-color: grey; + })css"); + calibrationStartMotorButton->setStyleSheet(calibrationStartMotorButtonStyle); + QIcon playIcon; + playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/play.svg", "white", 1), QIcon::Normal, QIcon::Off); + playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/scopy-default/icons/play_stop.svg", "white", 1), + QIcon::Normal, QIcon::On); + calibrationStartMotorButton->setIcon(playIcon); + calibrationStartMotorButton->setIconSize(QSize(64, 64)); + + QCheckBox *autoCalibrateCheckBox = new QCheckBox("Auto Calibrate", motorControlSectionWidget); + StyleHelper::BlueSquareCheckbox(autoCalibrateCheckBox, "autoCalibrateCheckBox"); + + motorControlCollapseSection->contentLayout()->setSpacing(10); + motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); + motorControlCollapseSection->contentLayout()->addWidget(calibrationMotorCurrentPositionLabel); + motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionSpinBox); + motorControlCollapseSection->contentLayout()->addWidget(motorVelocitySpinBox); + motorControlCollapseSection->contentLayout()->addWidget(calibrationStartMotorButton); + motorControlCollapseSection->contentLayout()->addWidget(autoCalibrateCheckBox); + #pragma endregion + + #pragma region Raw Data Section Widget + MenuSectionWidget *rawDataWidget = new MenuSectionWidget(calibrationDataGraphWidget); + MenuCollapseSection *rawDataSection = new MenuCollapseSection("Raw Data", MenuCollapseSection::MHCW_NONE, calibrationDataGraphWidget); rawDataWidget->contentLayout()->setSpacing(10); - rawDataWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - MenuCollapseSection *rawDataSection = new MenuCollapseSection("Raw Data", MenuCollapseSection::MHCW_NONE, calibrationDataWidget); - rawDataSection->contentLayout()->setSpacing(10); rawDataWidget->contentLayout()->addWidget(rawDataSection); + rawDataSection->contentLayout()->setSpacing(10); rawDataListWidget = new QListWidget(rawDataWidget); rawDataSection->contentLayout()->addWidget(rawDataListWidget); + #pragma endregion - // Logs Widget - MenuSectionWidget *logsWidget = new MenuSectionWidget(calibrationDataWidget); - logsWidget->contentLayout()->setSpacing(10); - MenuCollapseSection *logsSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, logsWidget); - logsSection->contentLayout()->setSpacing(10); - logsWidget->contentLayout()->addWidget(logsSection); + #pragma region Logs Section Widget + MenuSectionWidget *logsSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + MenuCollapseSection *logsCollapseSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, logsSectionWidget); + logsSectionWidget->contentLayout()->setSpacing(10); + logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); - logsPlainTextEdit = new QPlainTextEdit(logsWidget); + logsPlainTextEdit = new QPlainTextEdit(logsSectionWidget); logsPlainTextEdit->setReadOnly(true); - logsSection->contentLayout()->addWidget(logsPlainTextEdit); - - calibrationDataLayout->addWidget(rawDataWidget); - calibrationDataLayout->addWidget(logsWidget); - - // Result Widget - QWidget *calibrationResultWidget = new QWidget(this); - QVBoxLayout *calibrationResultLayout = new QVBoxLayout(calibrationResultWidget); - calibrationResultLayout->setMargin(0); - calibrationResultWidget->setLayout(calibrationResultLayout); - - // Register Widget - QWidget *calibrationRegisterWidget = new QWidget(calibrationResultWidget); - QHBoxLayout *calibrationRegisterLayout = new QHBoxLayout(calibrationRegisterWidget); - calibrationRegisterLayout->setMargin(0); - calibrationRegisterLayout->setSpacing(10); - calibrationRegisterWidget->setLayout(calibrationRegisterLayout); - - QWidget *calibrationMagWidget = new QWidget(calibrationRegisterWidget); - QVBoxLayout *calibrationMagLayout = new QVBoxLayout(calibrationMagWidget); - calibrationMagLayout->setMargin(0); - calibrationMagLayout->setSpacing(10); - calibrationMagWidget->setLayout(calibrationMagLayout); - - QLabel *calibrationH1MagLabel = new QLabel(calibrationMagWidget); - calibrationH1MagLabel->setText("H1Mag"); - StyleHelper::MenuSmallLabel(calibrationH1MagLabel, "calibrationH1MagLabel"); - calibrationH1MagLineEdit = new QLineEdit(calibrationMagWidget); - - QLabel *calibrationH2MagLabel = new QLabel(calibrationMagWidget); - calibrationH2MagLabel->setText("H2Mag"); - StyleHelper::MenuSmallLabel(calibrationH2MagLabel, "calibrationH2MagLabel"); - calibrationH2MagLineEdit = new QLineEdit(calibrationMagWidget); - - QLabel *calibrationH3MagLabel = new QLabel(calibrationMagWidget); - calibrationH3MagLabel->setText("H3Mag"); - StyleHelper::MenuSmallLabel(calibrationH3MagLabel, "calibrationH3MagLabel"); - calibrationH3MagLineEdit = new QLineEdit(calibrationMagWidget); - - QLabel *calibrationH8MagLabel = new QLabel(calibrationMagWidget); - calibrationH8MagLabel->setText("H8Mag"); - StyleHelper::MenuSmallLabel(calibrationH8MagLabel, "calibrationH8MagLabel"); - calibrationH8MagLineEdit = new QLineEdit(calibrationMagWidget); - - calibrationMagLayout->addWidget(calibrationH1MagLabel); - calibrationMagLayout->addWidget(calibrationH1MagLineEdit); - calibrationMagLayout->addWidget(calibrationH2MagLabel); - calibrationMagLayout->addWidget(calibrationH2MagLineEdit); - calibrationMagLayout->addWidget(calibrationH3MagLabel); - calibrationMagLayout->addWidget(calibrationH3MagLineEdit); - calibrationMagLayout->addWidget(calibrationH8MagLabel); - calibrationMagLayout->addWidget(calibrationH8MagLineEdit); - - QWidget *calibrationPhaseWidget = new QWidget(calibrationRegisterWidget); - QVBoxLayout *calibrationPhaseLayout = new QVBoxLayout(calibrationPhaseWidget); - calibrationPhaseLayout->setMargin(0); - calibrationPhaseLayout->setSpacing(10); - calibrationPhaseWidget->setLayout(calibrationPhaseLayout); - - QLabel *calibrationH1PhaseLabel = new QLabel(calibrationPhaseWidget); - calibrationH1PhaseLabel->setText("H1Phase"); - StyleHelper::MenuSmallLabel(calibrationH1PhaseLabel, "calibrationH1PhaseLabel"); - calibrationH1PhaseLineEdit = new QLineEdit(calibrationPhaseWidget); - - QLabel *calibrationH2PhaseLabel = new QLabel(calibrationPhaseWidget); - calibrationH2PhaseLabel->setText("H2Phase"); - StyleHelper::MenuSmallLabel(calibrationH2PhaseLabel, "calibrationH2PhaseLabel"); - calibrationH2PhaseLineEdit = new QLineEdit(calibrationPhaseWidget); - - QLabel *calibrationH3PhaseLabel = new QLabel(calibrationPhaseWidget); - calibrationH3PhaseLabel->setText("H3Phase"); - StyleHelper::MenuSmallLabel(calibrationH3PhaseLabel, "calibrationH3PhaseLabel"); - calibrationH3PhaseLineEdit = new QLineEdit(calibrationPhaseWidget); - - QLabel *calibrationH8PhaseLabel = new QLabel(calibrationPhaseWidget); - calibrationH8PhaseLabel->setText("H8Phase"); - StyleHelper::MenuSmallLabel(calibrationH8PhaseLabel, "calibrationH8PhaseLabel"); - calibrationH8PhaseLineEdit = new QLineEdit(calibrationPhaseWidget); - - calibrationPhaseLayout->addWidget(calibrationH1PhaseLabel); - calibrationPhaseLayout->addWidget(calibrationH1PhaseLineEdit); - calibrationPhaseLayout->addWidget(calibrationH2PhaseLabel); - calibrationPhaseLayout->addWidget(calibrationH2PhaseLineEdit); - calibrationPhaseLayout->addWidget(calibrationH3PhaseLabel); - calibrationPhaseLayout->addWidget(calibrationH3PhaseLineEdit); - calibrationPhaseLayout->addWidget(calibrationH8PhaseLabel); - calibrationPhaseLayout->addWidget(calibrationH8PhaseLineEdit); - - QPushButton *applyCalibrationDataButton = new QPushButton(calibrationRegisterWidget); - applyCalibrationDataButton->setText("Apply"); - StyleHelper::BlueButton(applyCalibrationDataButton, "applyCalibrationDataButton"); + logsCollapseSection->contentLayout()->setSpacing(10); + logsCollapseSection->contentLayout()->addWidget(logsPlainTextEdit); + #pragma endregion + + #pragma region Debug Section Widget + MenuSectionWidget *debugSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + MenuCollapseSection *debugCollapseSection = new MenuCollapseSection("Debug", MenuCollapseSection::MHCW_NONE, debugSectionWidget); + debugSectionWidget->contentLayout()->setSpacing(10); + debugSectionWidget->contentLayout()->addWidget(debugCollapseSection); - calibrationRegisterLayout->addWidget(calibrationMagWidget); - calibrationRegisterLayout->addWidget(calibrationPhaseWidget); + QPushButton *addCalibrationDataButton = new QPushButton(debugSectionWidget); + addCalibrationDataButton->setText("Add Data"); + StyleHelper::BlueButton(addCalibrationDataButton, "addCalibrationDataButton"); + + QPushButton *removeLastCalibrationDataButton = new QPushButton(debugSectionWidget); + removeLastCalibrationDataButton->setText("Remove Last Data"); + StyleHelper::BlueButton(removeLastCalibrationDataButton, "removeLastCalibrationDataButton"); + + QPushButton *calibrateDataButton = new QPushButton(debugSectionWidget); + calibrateDataButton->setText("Calibrate"); + StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); - calibrationResultLayout->addWidget(calibrationRegisterWidget); - calibrationResultLayout->addWidget(applyCalibrationDataButton); + debugCollapseSection->contentLayout()->setSpacing(10); + debugCollapseSection->contentLayout()->addWidget(addCalibrationDataButton); + debugCollapseSection->contentLayout()->addWidget(removeLastCalibrationDataButton); + debugCollapseSection->contentLayout()->addWidget(calibrateDataButton); + #pragma endregion + + calibrationSettingsLayout->setMargin(0); + calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); + calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); + calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); + calibrationSettingsLayout->addWidget(motorControlSectionWidget); + calibrationSettingsLayout->addWidget(rawDataWidget); + calibrationSettingsLayout->addWidget(logsSectionWidget); + calibrationSettingsLayout->addWidget(debugSectionWidget); + calibrationSettingsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + #pragma endregion tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); tool->topContainer()->setVisible(false); tool->topContainerMenuControl()->setVisible(false); - tool->leftContainer()->setVisible(true); + tool->leftContainer()->setVisible(false); tool->rightContainer()->setVisible(true); - tool->bottomContainer()->setVisible(true); - tool->setLeftContainerWidth(210); - tool->setRightContainerWidth(500); - tool->setTopContainerHeight(0); - tool->setBottomContainerHeight(90); + tool->bottomContainer()->setVisible(false); + tool->setRightContainerWidth(270); tool->openBottomContainerHelper(false); tool->openTopContainerHelper(false); - tool->leftStack()->add("calibrationControlScrollArea", calibrationControlScrollArea); - tool->addWidgetToCentralContainerHelper(calibrationDataWidget); - tool->rightStack()->add("calibrationResultWidget", calibrationResultWidget); + tool->addWidgetToCentralContainerHelper(calibrationDataGraphWidget); + tool->rightStack()->add("calibrationSettingsScrollArea", calibrationSettingsScrollArea); connect(addCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::addAngleToRawDataList); connect(removeLastCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::removeLastItemFromRawDataList); @@ -701,7 +863,7 @@ void HarmonicCalibration::updateChannelValue(int channelIndex) void HarmonicCalibration::calibrationTask() { updateChannelValue(ADMTController::Channel::ANGLE); - updateLabelValue(calibrationAngleLabel, ADMTController::Channel::ANGLE); + updateLabelValue(calibrationMotorCurrentPositionLabel, ADMTController::Channel::ANGLE); } void HarmonicCalibration::addAngleToRawDataList() @@ -810,4 +972,108 @@ void HarmonicCalibration::importCalibrationData() } catch(FileManagerException &ex) { calibrationLogWriteLn(QString(ex.what())); } +} + +void HarmonicCalibration::applyTextBoxStyle(QWidget *widget) +{ + applyLabelStyle(widget); + QString existingStyle = widget->styleSheet(); + QString style = QString(R"css( + background-color: black; + border-radius: 4px; + border: none; + )css"); + widget->setStyleSheet(existingStyle + style); + widget->setFixedHeight(30); +} + +void HarmonicCalibration::applyComboBoxStyle(QComboBox *widget, const QString& styleHelperColor) +{ + QString style = QString(R"css( + QWidget { + } + QComboBox { + text-align: right; + color: &&colorname&&; + border-radius: 4px; + height: 30px; + border-bottom: 0px solid none; + padding-left: 12px; + padding-right: 12px; + font-weight: normal; + font-size: 16px; + background-color: black; + } + QComboBox:disabled, QLineEdit:disabled { color: #555555; } + QComboBox QAbstractItemView { + border: none; + color: transparent; + outline: none; + background-color: black; + border-bottom: 0px solid transparent; + border-top: 0px solid transparent; + } + QComboBox QAbstractItemView::item { + text-align: right; + } + QComboBox::item:selected { + font-weight: bold; + font-size: 18px; + background-color: transparent; + } + QComboBox::drop-down { + border-image: none; + border: 0px; + width: 16px; + height: 16px; + margin-right: 12px; + } + QComboBox::down-arrow { + image: url(:/admt/chevron-down-s.svg); + } + QComboBox::indicator { + background-color: transparent; + selection-background-color: transparent; + color: transparent; + selection-color: transparent; + } + )css"); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor(styleHelperColor)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); +} + +void HarmonicCalibration::applyLabelPadding(QLabel *widget) +{ + widget->setContentsMargins(12, 4, 12, 4); +} + +void HarmonicCalibration::applyLineEditPadding(QLineEdit *widget) +{ + widget->setContentsMargins(0, 0, 0, 0); + widget->setTextMargins(12, 4, 12, 4); +} + +void HarmonicCalibration::applyLineEditAlignment(QLineEdit *widget) +{ + widget->setAlignment(Qt::AlignRight); +} + +void HarmonicCalibration::applyLabelStyle(QWidget *widget, const QString& styleHelperColor, bool isBold) +{ + QString existingStyle = widget->styleSheet(); + QString style = QString(R"css( + font-family: Open Sans; + font-size: 16px; + font-weight: &&fontweight&&; + text-align: right; + color: &&colorname&&; + )css"); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor(styleHelperColor)); + QString fontWeight = QString("normal"); + if(isBold){ + fontWeight = QString("bold"); + } + style = style.replace(QString("&&fontweight&&"), fontWeight); + widget->setStyleSheet(existingStyle + style); } \ No newline at end of file diff --git a/plugins/admt/src/widgets/horizontalspinbox.cpp b/plugins/admt/src/widgets/horizontalspinbox.cpp new file mode 100644 index 0000000000..a21baa21f4 --- /dev/null +++ b/plugins/admt/src/widgets/horizontalspinbox.cpp @@ -0,0 +1,157 @@ +#include +#include "widgets/horizontalspinbox.h" + +using namespace scopy::admt; + +HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, QString unit, QWidget *parent) + : QWidget(parent) + , m_value(initialValue) + , m_unit(unit) +{ + QVBoxLayout *container = new QVBoxLayout(this); + setLayout(container); + container->setMargin(0); + container->setSpacing(4); + + if(header != ""){ + QLabel *headerLabel = new QLabel(header, this); + StyleHelper::MenuSmallLabel(headerLabel, "headerLabel"); + container->addWidget(headerLabel); + } + + QWidget *controlWidget = new QWidget(this); + QHBoxLayout *controlLayout = new QHBoxLayout(controlWidget); + controlWidget->setLayout(controlLayout); + controlLayout->setMargin(0); + controlLayout->setSpacing(2); + + lineEdit = new QLineEdit(controlWidget); + applyLineEditStyle(lineEdit); + + if(QString::compare(m_unit, "") != 0) { + QWidget *lineEditContainer = new QWidget(controlWidget); + QHBoxLayout *lineEditLayout = new QHBoxLayout(lineEditContainer); + lineEditContainer->setLayout(lineEditLayout); + lineEditLayout->setMargin(0); + lineEditLayout->setSpacing(0); + + QLabel *unitLabel = new QLabel(m_unit, controlWidget); + applyUnitLabelStyle(unitLabel); + + lineEdit->setTextMargins(12, 4, 0, 4); + + lineEditLayout->addWidget(lineEdit); + lineEditLayout->addWidget(unitLabel); + controlLayout->addWidget(lineEditContainer); + } + else{ + controlLayout->addWidget(lineEdit); + } + + QPushButton *minusButton = new QPushButton(controlWidget); + minusButton->setIcon(QIcon(":/admt/minus.svg")); + applyPushButtonStyle(minusButton); + + QPushButton *plusButton = new QPushButton(controlWidget); + plusButton->setIcon(QIcon(":/admt/plus.svg")); + applyPushButtonStyle(plusButton, 0, 4, 0, 4); + + controlLayout->addWidget(minusButton); + controlLayout->addWidget(plusButton); + + container->addWidget(controlWidget); + + setValue(m_value); + connect(lineEdit, SIGNAL(editingFinished()), SLOT(onLineEditTextEdited())); + connect(minusButton, SIGNAL(clicked()), SLOT(onMinusButtonPressed())); + connect(plusButton, SIGNAL(clicked()), SLOT(onPlusButtonPressed())); +} + +void HorizontalSpinBox::onMinusButtonPressed() +{ + m_value--; + setValue(m_value); +} + +void HorizontalSpinBox::onPlusButtonPressed() +{ + m_value++; + setValue(m_value); +} + +void HorizontalSpinBox::onLineEditTextEdited() +{ + QLineEdit *lineEdit = static_cast(QObject::sender()); + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok) { + m_value = value; + } + setValue(m_value); +} + +void HorizontalSpinBox::setValue(double value) +{ + lineEdit->setText(QString::number(value)); +} + +void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) +{ + QString style = QString(R"css( + background-color: black; + font-family: Open Sans; + font-size: 16px; + color: &&colorname&&; + border: none; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + qproperty-frame: false; + )css"); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setAlignment(Qt::AlignRight); + widget->setContentsMargins(0, 0, 0, 0); + widget->setTextMargins(6, 4, 6, 4); +} + +void HorizontalSpinBox::applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius, int topRightBorderRadius, int bottomLeftBorderRadius, int bottomRightBorderRadius) +{ + QString style = QString(R"css( + background-color: black; + font-family: Open Sans; + font-size: 32px; + font-weight: bold; + text-align: center center; + color: &&colorname&&; + border-top-left-radius: &&topLeftBorderRadius&&px; + border-top-right-radius: &&topRightBorderRadius&&px; + border-bottom-left-radius: &&bottomLeftBorderRadius&&px; + border-bottom-right-radius: &&bottomRightBorderRadius&&px; + )css"); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("ScopyBlue")); + style = style.replace(QString("&&topLeftBorderRadius&&"), QString::number(topLeftBorderRadius)); + style = style.replace(QString("&&topRightBorderRadius&&"), QString::number(topRightBorderRadius)); + style = style.replace(QString("&&bottomLeftBorderRadius&&"), QString::number(bottomLeftBorderRadius)); + style = style.replace(QString("&&bottomRightBorderRadius&&"), QString::number(bottomRightBorderRadius)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setFixedWidth(38); +} + +void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget) +{ + QString style = QString(R"css( + background-color: black; + font-family: Open Sans; + font-size: 16px; + text-align: right; + color: &&colorname&&; + border: none; + )css"); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setAlignment(Qt::AlignRight); + widget->setContentsMargins(0, 4, 12, 4); +} \ No newline at end of file From 2400d1f9b1bbe73cbcb268b5b35f37da3e97445c Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 9 Aug 2024 11:02:16 +0800 Subject: [PATCH 015/112] admt: Added stepper motor control for calibration Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 37 +- .../admt/include/admt/harmoniccalibration.h | 47 +- plugins/admt/src/admtcontroller.cpp | 109 ++- plugins/admt/src/harmoniccalibration.cpp | 690 ++++++++++++++---- 4 files changed, 722 insertions(+), 161 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 961b02b192..1c1eb9f65c 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -30,6 +30,8 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject ADMTController(QString uri, QObject *parent = nullptr); ~ADMTController(); + int HAR_MAG_1, HAR_MAG_2, HAR_MAG_3, HAR_MAG_8 ,HAR_PHASE_1 ,HAR_PHASE_2 ,HAR_PHASE_3 ,HAR_PHASE_8; + enum Channel { ROTATION, @@ -39,16 +41,43 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject CHANNEL_COUNT }; + enum Device + { + ADMT4000, + TMC5240, + DEVICE_COUNT + }; + + enum MotorAttribute + { + AMAX, + ROTATE_VMAX, + DMAX, + DISABLE, + TARGET_POS, + CURRENT_POS, + RAMP_MODE, + MOTOR_ATTR_COUNT + }; + const char* ChannelIds[CHANNEL_COUNT] = {"rot", "angl", "count", "temp"}; + const char* DeviceIds[DEVICE_COUNT] = {"admt4000", "tmc5240"}; + const char* MotorAttributes[MOTOR_ATTR_COUNT] = {"amax", "rotate_vmax", "dmax", + "disable", "target_pos", "current_pos", + "ramp_mode"}; const char* getChannelId(Channel channel); + const char* getDeviceId(Device device); + const char* getMotorAttribute(MotorAttribute attribute); void connectADMT(); void disconnectADMT(); - QString getChannelValue(); - int getChannelIndex(const char *channelName); - double getChannelValue(const char *channelName, int bufferSize); - QString calibrate(vector PANG); + int getChannelIndex(const char *deviceName, const char *channelName); + double getChannelValue(const char *deviceName, const char *channelName, int bufferSize = 1); + int getDeviceAttributeValue(const char *deviceName, const char *attributeName, double *returnValue); + int setDeviceAttributeValue(const char *deviceName, const char *attributeName, double writeValue); + QString calibrate(vector PANG, int cycles = 11, int samplesPerCycle = 256); + int writeDeviceRegistry(const char *deviceName, uint32_t address, double value); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 6368e77d72..d5206fb6e4 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -37,6 +37,7 @@ #include #include #include +#include namespace scopy::admt { @@ -65,17 +66,32 @@ public Q_SLOTS: InfoBtn *infoButton; RunBtn *runButton; - double rotation, angle, count, temp; + double rotation, angle, count, temp, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode; - QPushButton *openLastMenuButton; + QPushButton *openLastMenuButton, *calibrationStartMotorButton; QButtonGroup *rightMenuButtonGroup; - QLineEdit *graphUpdateIntervalLineEdit, *dataSampleSizeLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, - *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, - *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit; - QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, *calibrationMotorCurrentPositionLabel; - - Sismograph *dataGraph, *tempGraph; + QLineEdit *graphUpdateIntervalLineEdit, *dataSampleSizeLineEdit, + *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, + *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, + *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, + *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, + *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit; + QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, + *calibrationMotorCurrentPositionLabel, + *motorAmaxValueLabel, *motorRotateVmaxValueLabel, *motorDmaxValueLabel, + *motorDisableValueLabel, *motorTargetPosValueLabel, *motorCurrentPosValueLabel, + *motorRampModeValueLabel, + *calibrationH1MagLabel, + *calibrationH1PhaseLabel, + *calibrationH2MagLabel, + *calibrationH2PhaseLabel, + *calibrationH3MagLabel, + *calibrationH3PhaseLabel, + *calibrationH8MagLabel, + *calibrationH8PhaseLabel; + + Sismograph *dataGraph, *tempGraph, *calibrationRawDataPlotWidget; MenuHeaderWidget *header; @@ -93,12 +109,14 @@ public Q_SLOTS: void updateLineEditValues(); void updateGeneralSettingEnabled(bool value); void connectLineEditToNumber(QLineEdit* lineEdit, int& variable); + void connectLineEditToNumber(QLineEdit* lineEdit, double& variable); void connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph); void connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph); void changeGraphColorByChannelName(Sismograph* graph, const char* channelName); void connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph); ToolTemplate* createCalibrationWidget(); void updateLabelValue(QLabel* label, int channelIndex); + void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); void updateChannelValue(int channelIndex); void calibrationTask(); void addAngleToRawDataList(); @@ -109,12 +127,15 @@ public Q_SLOTS: void importCalibrationData(); void calibrationLogWrite(QString message); void calibrationLogWriteLn(QString message); - void applyTextBoxStyle(QWidget *widget); - void applyLabelPadding(QLabel *widget); - void applyLineEditPadding(QLineEdit *widget); - void applyLineEditAlignment(QLineEdit *widget); + void readMotorAttributeValue(ADMTController::MotorAttribute attribute, double *value); + void writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); + void applyLineEditStyle(QLineEdit *widget); void applyComboBoxStyle(QComboBox *widget, const QString& styleHelperColor = "CH0"); - void applyLabelStyle(QWidget *widget, const QString& styleHelperColor = "CH0", bool isBold = false); + void applyTextStyle(QWidget *widget, const QString& styleHelperColor = "CH0", bool isBold = false); + void applyLabelStyle(QLabel *widget); + void initializeMotor(); + void startMotorAcquisition(); + void clearRawDataList(); QTimer *timer, *calibrationTimer; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 5d9a9510cd..99495753a2 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -17,6 +17,8 @@ #include static const size_t maxAttrSize = 512; +static vector angle_errors_fft; +static vector angle_errors_fft_phase; using namespace scopy::admt; using namespace std; @@ -56,9 +58,26 @@ const char* ADMTController::getChannelId(Channel channel) return "Unknown"; } -int ADMTController::getChannelIndex(const char *channelName) +const char* ADMTController::getDeviceId(Device device) { - iio_device *admtDevice = iio_context_find_device(m_iioCtx, "admt4000"); + if(device >= 0 && device < DEVICE_COUNT){ + return DeviceIds[device]; + } + return "Unknown"; +} + +const char* ADMTController::getMotorAttribute(MotorAttribute attribute) +{ + if(attribute >= 0 && attribute < MOTOR_ATTR_COUNT){ + return MotorAttributes[attribute]; + } + return "Unknown"; +} + + +int ADMTController::getChannelIndex(const char *deviceName, const char *channelName) +{ + iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); int channelCount = iio_device_get_channels_count(admtDevice); iio_channel *channel; std::string message = ""; @@ -80,7 +99,7 @@ int ADMTController::getChannelIndex(const char *channelName) return -1; } -double ADMTController::getChannelValue(const char *channelName, int bufferSize = 1) +double ADMTController::getChannelValue(const char *deviceName, const char *channelName, int bufferSize) { double value; char converted[bufferSize] = ""; @@ -88,7 +107,7 @@ double ADMTController::getChannelValue(const char *channelName, int bufferSize = int deviceCount = iio_context_get_devices_count(m_iioCtx); //if(deviceCount < 1) return QString("No devices found"); - iio_device *admtDevice = iio_context_find_device(m_iioCtx, "admt4000"); + iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); //if(admtDevice == NULL) return QString("No ADMT4000 device"); int channelCount = iio_device_get_channels_count(admtDevice); @@ -185,6 +204,60 @@ double ADMTController::getChannelValue(const char *channelName, int bufferSize = return value; //QString::fromStdString(message); } +/** @brief Get the attribute value of a device + * @param deviceName A pointer to the device name + * @param attributeName A NULL-terminated string corresponding to the name of the + * attribute + * @param returnValue A pointer to a double variable where the value should be stored + * @return On success, 0 is returned. + * @return On error, -1 is returned. */ +int ADMTController::getDeviceAttributeValue(const char *deviceName, const char *attributeName, double *returnValue) +{ + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount == 0) { return result; } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) { return result; } + const char* hasAttr = iio_device_find_attr(iioDevice, attributeName); + if(hasAttr == NULL) { return result; } + result = iio_device_attr_read_double(iioDevice, attributeName, returnValue); + + return result; +} + +/** @brief Set the attribute value of a device + * @param deviceName A pointer to the device name + * @param attributeName A NULL-terminated string corresponding to the name of the + * attribute + * @param writeValue A double variable of the value to be set + * @return On success, 0 is returned. + * @return On error, -1 is returned. */ +int ADMTController::setDeviceAttributeValue(const char *deviceName, const char *attributeName, double writeValue) +{ + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount == 0) { return result; } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) { return result; } + const char* hasAttr = iio_device_find_attr(iioDevice, attributeName); + if(hasAttr == NULL) { return result; } + result = iio_device_attr_write_double(iioDevice, attributeName, writeValue); + + return result; +} + +int ADMTController::writeDeviceRegistry(const char *deviceName, uint32_t address, double value) +{ + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount == 0) { return result; } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) { return result; } + result = iio_device_reg_write(iioDevice, address, static_cast(value)); + + return result; +} + /* bit reversal from online example */ unsigned int ADMTController::bitReverse(unsigned int x, int log2n) { int n = 0; @@ -324,8 +397,8 @@ int ADMTController::calculate_angle_error(vector angle_meas, vector PANG){ - int cycles = 11, CCW = 0, circshiftData = 0; +QString ADMTController::calibrate(vector PANG, int cycles, int samplesPerCycle){ + int CCW = 0, circshiftData = 0; QString result = ""; // original script data (measured data: from data capture using GUI or other medium i.e., csv) @@ -357,13 +430,13 @@ QString ADMTController::calibrate(vector PANG){ /* FFT based on implementation from https://www.oreilly.com/library/view/c-cookbook/0596007612/ch11s18.html */ vector angle_errors_fft_temp(PANG.size()); vector angle_errors_fft_phase_temp(PANG.size()); - vector angle_errors_fft(PANG.size() / 2); - vector angle_errors_fft_phase(PANG.size() / 2); + angle_errors_fft(PANG.size() / 2); + angle_errors_fft_phase(PANG.size() / 2); typedef complex cx; /* array declaration must be constant so hardcoded as of now */ - cx fft_in[256]; - cx fft_out[256]; + cx fft_in[samplesPerCycle*cycles]; + cx fft_out[samplesPerCycle*cycles]; /* Format angle errros to match data type used in fft function */ for (int i = 0; i < PANG.size(); i++) @@ -493,17 +566,17 @@ QString ADMTController::calibrate(vector PANG){ // Derive register compatible HMAG values double mag_scale_factor_11bit = 11.2455 / (1 << 11); double mag_scale_factor_8bit = 1.40076 / (1 << 8); - int HAR_MAG_1 = (int)(H1Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit - int HAR_MAG_2 = (int)(H2Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit - int HAR_MAG_3 = (int)(H3Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit - int HAR_MAG_8 = (int)(H8Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit + HAR_MAG_1 = (int)(H1Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit + HAR_MAG_2 = (int)(H2Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit + HAR_MAG_3 = (int)(H3Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit + HAR_MAG_8 = (int)(H8Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit // Derive register compatible HPHASE values double pha_scale_factor_12bit = 360.0 / (1 << 12); // in Deg - int HAR_PHASE_1 = (int)(H1PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - int HAR_PHASE_2 = (int)(H2PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - int HAR_PHASE_3 = (int)(H3PHcor / pha_scale_factor_12bit) & (0xFFF);// 12bit number - int HAR_PHASE_8 = (int)(H8PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + HAR_PHASE_1 = (int)(H1PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + HAR_PHASE_2 = (int)(H2PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + HAR_PHASE_3 = (int)(H3PHcor / pha_scale_factor_12bit) & (0xFFF);// 12bit number + HAR_PHASE_8 = (int)(H8PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number result.append("HMAG1: " + QString::number(HAR_MAG_1) + "\n"); result.append("HMAG2: " + QString::number(HAR_MAG_2) + "\n"); diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index bd8bc3e8ae..b93e6d32e9 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -3,13 +3,28 @@ #include -static int sampleRate = 1000; +static int sampleRate = 50; +static int calibrationRate = 20; static int bufferSize = 1; static int dataGraphSamples = 100; static int tempGraphSamples = 100; static bool running = false; static double *dataGraphValue; +static int cycleCount = 1; +static int samplesPerCycle = 256; +static int totalSamplesCount = cycleCount * samplesPerCycle; +static bool startMotor = false; + +static uint32_t h1MagDeviceRegister = 0x15; +static uint32_t h2MagDeviceRegister = 0x17; +static uint32_t h3MagDeviceRegister = 0x19; +static uint32_t h8MagDeviceRegister = 0x1B; +static uint32_t h1PhaseDeviceRegister = 0x16; +static uint32_t h2PhaseDeviceRegister = 0x18; +static uint32_t h3PhaseDeviceRegister = 0x1A; +static uint32_t h8PhaseDeviceRegister = 0x1C; + using namespace scopy; using namespace scopy::admt; using namespace scopy::grutil; @@ -124,7 +139,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg dataGraph->setUnitOfMeasure("Degree", "°"); dataGraph->setAutoscale(false); dataGraph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); - dataGraph->setNumSamples(dataGraphSamples); + //dataGraph->setNumSamples(dataGraphSamples); + dataGraph->setHistoryDuration(10.0); dataGraphValue = &rotation; QLabel *tempGraphLabel = new QLabel(historicalGraphWidget); @@ -169,9 +185,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg graphUpdateIntervalLabel->setText("Graph Update Interval (ms)"); StyleHelper::MenuSmallLabel(graphUpdateIntervalLabel, "graphUpdateIntervalLabel"); graphUpdateIntervalLineEdit = new QLineEdit(generalSection); - applyTextBoxStyle(graphUpdateIntervalLineEdit); - applyLineEditPadding(graphUpdateIntervalLineEdit); - applyLineEditAlignment(graphUpdateIntervalLineEdit); + applyLineEditStyle(graphUpdateIntervalLineEdit); graphUpdateIntervalLineEdit->setText(QString::number(sampleRate)); connectLineEditToNumber(graphUpdateIntervalLineEdit, sampleRate); @@ -184,9 +198,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg dataSampleSizeLabel->setText("Data Sample Size"); StyleHelper::MenuSmallLabel(dataSampleSizeLabel, "dataSampleSizeLabel"); dataSampleSizeLineEdit = new QLineEdit(generalSection); - applyTextBoxStyle(dataSampleSizeLineEdit); - applyLineEditPadding(dataSampleSizeLineEdit); - applyLineEditAlignment(dataSampleSizeLineEdit); + applyLineEditStyle(dataSampleSizeLineEdit); dataSampleSizeLineEdit->setText(QString::number(bufferSize)); connectLineEditToNumber(dataSampleSizeLineEdit, bufferSize); @@ -217,9 +229,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg dataGraphSamplesLabel->setText("Samples"); StyleHelper::MenuSmallLabel(dataGraphSamplesLabel, "dataGraphSamplesLabel"); dataGraphSamplesLineEdit = new QLineEdit(generalSection); - applyTextBoxStyle(dataGraphSamplesLineEdit); - applyLineEditPadding(dataGraphSamplesLineEdit); - applyLineEditAlignment(dataGraphSamplesLineEdit); + applyLineEditStyle(dataGraphSamplesLineEdit); dataGraphSamplesLineEdit->setText(QString::number(dataGraphSamples)); connectLineEditToGraphSamples(dataGraphSamplesLineEdit, dataGraphSamples, dataGraph); @@ -240,9 +250,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg tempGraphSamplesLabel->setText("Samples"); StyleHelper::MenuSmallLabel(tempGraphSamplesLabel, "tempGraphSamplesLabel"); tempGraphSamplesLineEdit = new QLineEdit(generalSection); - applyTextBoxStyle(tempGraphSamplesLineEdit); - applyLineEditPadding(tempGraphSamplesLineEdit); - applyLineEditAlignment(tempGraphSamplesLineEdit); + applyLineEditStyle(tempGraphSamplesLineEdit); tempGraphSamplesLineEdit->setText(QString::number(tempGraphSamples)); tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLabel); tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLineEdit); @@ -292,7 +300,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg connect(tabWidget, &QTabWidget::currentChanged, [=](int index){ tabWidget->setCurrentIndex(index); - if(index == 1) { calibrationTimer->start(sampleRate); } + if(index == 1) { calibrationTimer->start(calibrationRate); } else { calibrationTimer->stop(); } }); } @@ -347,10 +355,10 @@ void HarmonicCalibration::timerTask(){ } void HarmonicCalibration::updateChannelValues(){ - rotation = m_admtController->getChannelValue(rotationChannelName, bufferSize); - angle = m_admtController->getChannelValue(angleChannelName, bufferSize); - count = m_admtController->getChannelValue(countChannelName, bufferSize); - temp = m_admtController->getChannelValue(temperatureChannelName, bufferSize); + rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, bufferSize); + angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, bufferSize); + count = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, bufferSize); + temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, bufferSize); } void HarmonicCalibration::updateLineEditValues(){ @@ -381,6 +389,19 @@ void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& vari }); } +void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& variable) +{ + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok) { + variable = value; + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + void HarmonicCalibration::connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph) { connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, graph]() { @@ -416,7 +437,7 @@ void HarmonicCalibration::connectMenuComboToGraphDirection(MenuCombo* menuCombo, void HarmonicCalibration::changeGraphColorByChannelName(Sismograph* graph, const char* channelName) { - int index = m_admtController->getChannelIndex(channelName); + int index = m_admtController->getChannelIndex(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), channelName); if(index > -1){ graph->setColor(StyleHelper::getColor( QString::fromStdString("CH" + std::to_string(index) ))); } @@ -460,8 +481,255 @@ void HarmonicCalibration::connectMenuComboToGraphChannel(MenuCombo* menuCombo, S ToolTemplate* HarmonicCalibration::createCalibrationWidget() { + initializeMotor(); ToolTemplate *tool = new ToolTemplate(this); + #pragma region Motor Attributes Widget + QScrollArea *motorAttributesScroll = new QScrollArea(); + QWidget *motorAttributesWidget = new QWidget(); + QVBoxLayout *motorAttributesLayout = new QVBoxLayout(motorAttributesWidget); + motorAttributesScroll->setWidgetResizable(true); + motorAttributesScroll->setWidget(motorAttributesWidget); + motorAttributesWidget->setLayout(motorAttributesLayout); + + // amax + MenuSectionWidget *amaxSectionWidget = new MenuSectionWidget(motorAttributesWidget); + MenuCollapseSection *amaxCollapseSection = new MenuCollapseSection("amax", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, amaxSectionWidget); + amaxSectionWidget->contentLayout()->addWidget(amaxCollapseSection); + motorAmaxValueLabel = new QLabel("-", amaxSectionWidget); + StyleHelper::MenuSmallLabel(motorAmaxValueLabel); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, &amax); + updateLabelValue(motorAmaxValueLabel, ADMTController::MotorAttribute::AMAX); + QLineEdit *motorAmaxLineEdit = new QLineEdit(amaxSectionWidget); + applyLineEditStyle(motorAmaxLineEdit); + motorAmaxLineEdit->setText(QString::number(amax)); + connectLineEditToNumber(motorAmaxLineEdit, amax); + QWidget *motorAmaxButtonGroupWidget = new QWidget(amaxSectionWidget); + QHBoxLayout *motorAmaxButtonGroupLayout = new QHBoxLayout(motorAmaxButtonGroupWidget); + motorAmaxButtonGroupWidget->setLayout(motorAmaxButtonGroupLayout); + motorAmaxButtonGroupLayout->setMargin(0); + motorAmaxButtonGroupLayout->setSpacing(10); + QPushButton *readMotorAmaxButton = new QPushButton("Read", motorAmaxButtonGroupWidget); + StyleHelper::BlueButton(readMotorAmaxButton); + connect(readMotorAmaxButton, &QPushButton::pressed, this, [=]{ + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, &amax); + updateLabelValue(motorAmaxValueLabel, ADMTController::MotorAttribute::AMAX); + }); + QPushButton *writeMotorAmaxButton = new QPushButton("Write", motorAmaxButtonGroupWidget); + StyleHelper::BlueButton(writeMotorAmaxButton); + connect(writeMotorAmaxButton, &QPushButton::pressed, this, [=]{ + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, &amax); + updateLabelValue(motorAmaxValueLabel, ADMTController::MotorAttribute::AMAX); + }); + motorAmaxButtonGroupLayout->addWidget(readMotorAmaxButton); + motorAmaxButtonGroupLayout->addWidget(writeMotorAmaxButton); + amaxCollapseSection->contentLayout()->setSpacing(10); + amaxCollapseSection->contentLayout()->addWidget(motorAmaxValueLabel); + amaxCollapseSection->contentLayout()->addWidget(motorAmaxLineEdit); + amaxCollapseSection->contentLayout()->addWidget(motorAmaxButtonGroupWidget); + + //rotate_vmax + MenuSectionWidget *rotateVmaxSectionWidget = new MenuSectionWidget(motorAttributesWidget); + MenuCollapseSection *rotateVmaxCollapseSection = new MenuCollapseSection("rotate_vmax", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, rotateVmaxSectionWidget); + rotateVmaxSectionWidget->contentLayout()->addWidget(rotateVmaxCollapseSection); + motorRotateVmaxValueLabel = new QLabel("-", rotateVmaxSectionWidget); + StyleHelper::MenuSmallLabel(motorRotateVmaxValueLabel); + readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, &rotate_vmax); + updateLabelValue(motorRotateVmaxValueLabel, ADMTController::MotorAttribute::ROTATE_VMAX); + QLineEdit *motorRotateVmaxLineEdit = new QLineEdit(rotateVmaxSectionWidget); + applyLineEditStyle(motorRotateVmaxLineEdit); + motorRotateVmaxLineEdit->setText(QString::number(rotate_vmax)); + connectLineEditToNumber(motorRotateVmaxLineEdit, rotate_vmax); + QWidget *motorRotateVmaxButtonGroupWidget = new QWidget(rotateVmaxSectionWidget); + QHBoxLayout *motorRotateVmaxButtonGroupLayout = new QHBoxLayout(motorRotateVmaxButtonGroupWidget); + motorRotateVmaxButtonGroupWidget->setLayout(motorRotateVmaxButtonGroupLayout); + motorRotateVmaxButtonGroupLayout->setMargin(0); + motorRotateVmaxButtonGroupLayout->setSpacing(10); + QPushButton *readMotorRotateVmaxButton = new QPushButton("Read", motorRotateVmaxButtonGroupWidget); + StyleHelper::BlueButton(readMotorRotateVmaxButton); + connect(readMotorRotateVmaxButton, &QPushButton::pressed, this, [=]{ + readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, &rotate_vmax); + updateLabelValue(motorRotateVmaxValueLabel, ADMTController::MotorAttribute::ROTATE_VMAX); + }); + QPushButton *writeMotorRotateVmaxButton = new QPushButton("Write", motorRotateVmaxButtonGroupWidget); + StyleHelper::BlueButton(writeMotorRotateVmaxButton); + connect(writeMotorRotateVmaxButton, &QPushButton::pressed, this, [=]{ + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, &rotate_vmax); + updateLabelValue(motorRotateVmaxValueLabel, ADMTController::MotorAttribute::ROTATE_VMAX); + }); + motorRotateVmaxButtonGroupLayout->addWidget(readMotorRotateVmaxButton); + motorRotateVmaxButtonGroupLayout->addWidget(writeMotorRotateVmaxButton); + rotateVmaxCollapseSection->contentLayout()->setSpacing(10); + rotateVmaxCollapseSection->contentLayout()->addWidget(motorRotateVmaxValueLabel); + rotateVmaxCollapseSection->contentLayout()->addWidget(motorRotateVmaxLineEdit); + rotateVmaxCollapseSection->contentLayout()->addWidget(motorRotateVmaxButtonGroupWidget); + + //dmax + MenuSectionWidget *dmaxSectionWidget = new MenuSectionWidget(motorAttributesWidget); + MenuCollapseSection *dmaxCollapseSection = new MenuCollapseSection("dmax", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, dmaxSectionWidget); + dmaxSectionWidget->contentLayout()->addWidget(dmaxCollapseSection); + motorDmaxValueLabel = new QLabel("-", dmaxSectionWidget); + StyleHelper::MenuSmallLabel(motorDmaxValueLabel); + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, &dmax); + updateLabelValue(motorDmaxValueLabel, ADMTController::MotorAttribute::DMAX); + QLineEdit *motorDmaxLineEdit = new QLineEdit(dmaxSectionWidget); + applyLineEditStyle(motorDmaxLineEdit); + motorDmaxLineEdit->setText(QString::number(dmax)); + connectLineEditToNumber(motorDmaxLineEdit, dmax); + QWidget *motorDmaxButtonGroupWidget = new QWidget(dmaxSectionWidget); + QHBoxLayout *motorDmaxButtonGroupLayout = new QHBoxLayout(motorDmaxButtonGroupWidget); + motorDmaxButtonGroupWidget->setLayout(motorDmaxButtonGroupLayout); + motorDmaxButtonGroupLayout->setMargin(0); + motorDmaxButtonGroupLayout->setSpacing(10); + QPushButton *readMotorDmaxButton = new QPushButton("Read", motorDmaxButtonGroupWidget); + StyleHelper::BlueButton(readMotorDmaxButton); + connect(readMotorDmaxButton, &QPushButton::pressed, this, [=]{ + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, &dmax); + updateLabelValue(motorDmaxValueLabel, ADMTController::MotorAttribute::DMAX); + }); + QPushButton *writeMotorDmaxButton = new QPushButton("Write", motorDmaxButtonGroupWidget); + StyleHelper::BlueButton(writeMotorDmaxButton); + connect(writeMotorDmaxButton, &QPushButton::pressed, this, [=]{ + writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, &dmax); + updateLabelValue(motorDmaxValueLabel, ADMTController::MotorAttribute::DMAX); + }); + motorDmaxButtonGroupLayout->addWidget(readMotorDmaxButton); + motorDmaxButtonGroupLayout->addWidget(writeMotorDmaxButton); + dmaxCollapseSection->contentLayout()->setSpacing(10); + dmaxCollapseSection->contentLayout()->addWidget(motorDmaxValueLabel); + dmaxCollapseSection->contentLayout()->addWidget(motorDmaxLineEdit); + dmaxCollapseSection->contentLayout()->addWidget(motorDmaxButtonGroupWidget); + + //disable + MenuSectionWidget *disableSectionWidget = new MenuSectionWidget(motorAttributesWidget); + MenuCollapseSection *disableCollapseSection = new MenuCollapseSection("disable", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, disableSectionWidget); + disableSectionWidget->contentLayout()->addWidget(disableCollapseSection); + // motorDisableValueLabel = new QLabel("-", disableSectionWidget); + // readMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, &disable); + // updateLabelValue(motorDisableValueLabel, ADMTController::MotorAttribute::DISABLE); + QPushButton *writeMotorDisableButton = new QPushButton("Disable", disableSectionWidget); + StyleHelper::BlueButton(writeMotorDisableButton); + connect(writeMotorDisableButton, &QPushButton::pressed, this, [=]{ + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + }); + disableCollapseSection->contentLayout()->setSpacing(10); + // disableCollapseSection->contentLayout()->addWidget(motorDisableValueLabel); + // disableCollapseSection->contentLayout()->addWidget(motorDisableLineEdit); + disableCollapseSection->contentLayout()->addWidget(writeMotorDisableButton); + + //target_pos + MenuSectionWidget *targetPosSectionWidget = new MenuSectionWidget(motorAttributesWidget); + MenuCollapseSection *targetPosCollapseSection = new MenuCollapseSection("target_pos", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, targetPosSectionWidget); + targetPosSectionWidget->contentLayout()->addWidget(targetPosCollapseSection); + motorTargetPosValueLabel = new QLabel("-", targetPosSectionWidget); + StyleHelper::MenuSmallLabel(motorTargetPosValueLabel); + readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, &target_pos); + updateLabelValue(motorTargetPosValueLabel, ADMTController::MotorAttribute::TARGET_POS); + QLineEdit *motorTargetPosLineEdit = new QLineEdit(targetPosSectionWidget); + applyLineEditStyle(motorTargetPosLineEdit); + motorTargetPosLineEdit->setText(QString::number(target_pos)); + connectLineEditToNumber(motorTargetPosLineEdit, target_pos); + QWidget *motorTargetPosButtonGroupWidget = new QWidget(targetPosSectionWidget); + QHBoxLayout *motorTargetPosButtonGroupLayout = new QHBoxLayout(motorTargetPosButtonGroupWidget); + motorTargetPosButtonGroupWidget->setLayout(motorTargetPosButtonGroupLayout); + motorTargetPosButtonGroupLayout->setMargin(0); + motorTargetPosButtonGroupLayout->setSpacing(10); + QPushButton *readMotorTargetPosButton = new QPushButton("Read", motorTargetPosButtonGroupWidget); + StyleHelper::BlueButton(readMotorTargetPosButton); + connect(readMotorTargetPosButton, &QPushButton::pressed, this, [=]{ + readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, &target_pos); + updateLabelValue(motorTargetPosValueLabel, ADMTController::MotorAttribute::TARGET_POS); + }); + QPushButton *writeMotorTargetPosButton = new QPushButton("Write", motorTargetPosButtonGroupWidget); + StyleHelper::BlueButton(writeMotorTargetPosButton); + connect(writeMotorTargetPosButton, &QPushButton::pressed, this, [=]{ + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); + readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, &target_pos); + updateLabelValue(motorTargetPosValueLabel, ADMTController::MotorAttribute::TARGET_POS); + }); + motorTargetPosButtonGroupLayout->addWidget(readMotorTargetPosButton); + motorTargetPosButtonGroupLayout->addWidget(writeMotorTargetPosButton); + targetPosCollapseSection->contentLayout()->setSpacing(10); + targetPosCollapseSection->contentLayout()->addWidget(motorTargetPosValueLabel); + targetPosCollapseSection->contentLayout()->addWidget(motorTargetPosLineEdit); + targetPosCollapseSection->contentLayout()->addWidget(motorTargetPosButtonGroupWidget); + + //current_pos + MenuSectionWidget *currentPosSectionWidget = new MenuSectionWidget(motorAttributesWidget); + MenuCollapseSection *currentPosCollapseSection = new MenuCollapseSection("current_pos", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, currentPosSectionWidget); + currentPosSectionWidget->contentLayout()->addWidget(currentPosCollapseSection); + motorCurrentPosValueLabel = new QLabel("-", currentPosSectionWidget); + StyleHelper::MenuSmallLabel(motorCurrentPosValueLabel); + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, ¤t_pos); + updateLabelValue(motorCurrentPosValueLabel, ADMTController::MotorAttribute::CURRENT_POS); + QWidget *motorCurrentPosButtonGroupWidget = new QWidget(currentPosSectionWidget); + QHBoxLayout *motorCurrentPosButtonGroupLayout = new QHBoxLayout(motorCurrentPosButtonGroupWidget); + motorCurrentPosButtonGroupWidget->setLayout(motorCurrentPosButtonGroupLayout); + motorCurrentPosButtonGroupLayout->setMargin(0); + motorCurrentPosButtonGroupLayout->setSpacing(10); + QPushButton *readMotorCurrentPosButton = new QPushButton("Read", motorCurrentPosButtonGroupWidget); + StyleHelper::BlueButton(readMotorCurrentPosButton); + connect(readMotorCurrentPosButton, &QPushButton::pressed, this, [=]{ + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, ¤t_pos); + updateLabelValue(motorCurrentPosValueLabel, ADMTController::MotorAttribute::CURRENT_POS); + }); + motorCurrentPosButtonGroupLayout->addWidget(readMotorCurrentPosButton); + currentPosCollapseSection->contentLayout()->setSpacing(10); + currentPosCollapseSection->contentLayout()->addWidget(motorCurrentPosValueLabel); + currentPosCollapseSection->contentLayout()->addWidget(motorCurrentPosButtonGroupWidget); + + //ramp_mode + MenuSectionWidget *rampModeSectionWidget = new MenuSectionWidget(motorAttributesWidget); + MenuCollapseSection *rampModeCollapseSection = new MenuCollapseSection("ramp_mode", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, rampModeSectionWidget); + rampModeSectionWidget->contentLayout()->addWidget(rampModeCollapseSection); + motorRampModeValueLabel = new QLabel("-", rampModeSectionWidget); + StyleHelper::MenuSmallLabel(motorRampModeValueLabel); + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, &ramp_mode); + updateLabelValue(motorRampModeValueLabel, ADMTController::MotorAttribute::RAMP_MODE); + QLineEdit *motorRampModeLineEdit = new QLineEdit(rampModeSectionWidget); + applyLineEditStyle(motorRampModeLineEdit); + motorRampModeLineEdit->setText(QString::number(ramp_mode)); + connectLineEditToNumber(motorRampModeLineEdit, ramp_mode); + QWidget *motorRampModeButtonGroupWidget = new QWidget(rampModeSectionWidget); + QHBoxLayout *motorRampModeButtonGroupLayout = new QHBoxLayout(motorRampModeButtonGroupWidget); + motorRampModeButtonGroupWidget->setLayout(motorRampModeButtonGroupLayout); + motorRampModeButtonGroupLayout->setMargin(0); + motorRampModeButtonGroupLayout->setSpacing(10); + QPushButton *readMotorRampModeButton = new QPushButton("Read", motorRampModeButtonGroupWidget); + StyleHelper::BlueButton(readMotorRampModeButton); + connect(readMotorRampModeButton, &QPushButton::pressed, this, [=]{ + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, &ramp_mode); + updateLabelValue(motorRampModeValueLabel, ADMTController::MotorAttribute::RAMP_MODE); + }); + QPushButton *writeMotorRampModeButton = new QPushButton("Write", motorRampModeButtonGroupWidget); + StyleHelper::BlueButton(writeMotorRampModeButton); + connect(writeMotorRampModeButton, &QPushButton::pressed, this, [=]{ + writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, &ramp_mode); + updateLabelValue(motorRampModeValueLabel, ADMTController::MotorAttribute::RAMP_MODE); + }); + motorRampModeButtonGroupLayout->addWidget(readMotorRampModeButton); + motorRampModeButtonGroupLayout->addWidget(writeMotorRampModeButton); + rampModeCollapseSection->contentLayout()->setSpacing(10); + rampModeCollapseSection->contentLayout()->addWidget(motorRampModeValueLabel); + rampModeCollapseSection->contentLayout()->addWidget(motorRampModeLineEdit); + rampModeCollapseSection->contentLayout()->addWidget(motorRampModeButtonGroupWidget); + + motorAttributesLayout->setMargin(0); + motorAttributesLayout->setSpacing(10); + motorAttributesLayout->addWidget(amaxSectionWidget); + motorAttributesLayout->addWidget(rotateVmaxSectionWidget); + motorAttributesLayout->addWidget(dmaxSectionWidget); + motorAttributesLayout->addWidget(disableSectionWidget); + motorAttributesLayout->addWidget(targetPosSectionWidget); + motorAttributesLayout->addWidget(currentPosSectionWidget); + motorAttributesLayout->addWidget(rampModeSectionWidget); + motorAttributesLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + #pragma endregion + #pragma region Calibration Data Graph Widget QWidget *calibrationDataGraphWidget = new QWidget(); QVBoxLayout *calibrationDataGraphLayout = new QVBoxLayout(calibrationDataGraphWidget); @@ -476,25 +744,68 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataGraphLayout->setSpacing(4); QLabel *calibrationRawDataGraphLabel = new QLabel("Raw Data", calibrationRawDataGraphWidget); StyleHelper::MenuCollapseHeaderLabel(calibrationRawDataGraphLabel, "calibrationRawDataGraphLabel"); - PlotWidget *calibrationRawDataPlotWidget = new PlotWidget(); + calibrationRawDataPlotWidget = new Sismograph(); + // PlotWidget *calibrationRawDataPlotWidget = new PlotWidget(); + calibrationRawDataPlotWidget->setColor(StyleHelper::getColor("ScopyBlue")); + calibrationRawDataPlotWidget->setPlotAxisXTitle("Degree (°)"); + calibrationRawDataPlotWidget->setUnitOfMeasure("Degree", "°"); + calibrationRawDataPlotWidget->setAutoscale(false); + calibrationRawDataPlotWidget->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); + calibrationRawDataPlotWidget->setHistoryDuration(120.0); + calibrationRawDataPlotWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); calibrationRawDataGraphLayout->addWidget(calibrationRawDataGraphLabel); calibrationRawDataGraphLayout->addWidget(calibrationRawDataPlotWidget); - QWidget *calibrationFFTDataGraphWidget = new QWidget(calibrationDataGraphWidget); - QVBoxLayout *calibrationFFTDataGraphLayout = new QVBoxLayout(calibrationFFTDataGraphWidget); - calibrationFFTDataGraphWidget->setLayout(calibrationFFTDataGraphLayout); - calibrationFFTDataGraphLayout->setMargin(0); - calibrationFFTDataGraphLayout->setSpacing(4); - QLabel *calibrationFFTDataGraphLabel = new QLabel("FFT Data", calibrationFFTDataGraphWidget); - StyleHelper::MenuCollapseHeaderLabel(calibrationFFTDataGraphLabel, "calibrationFFTDataGraphLabel"); - PlotWidget *calibrationFFTDataPlotWidget = new PlotWidget(); - calibrationFFTDataPlotWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataGraphLabel); - calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataPlotWidget); + // QWidget *calibrationFFTDataGraphWidget = new QWidget(calibrationDataGraphWidget); + // QVBoxLayout *calibrationFFTDataGraphLayout = new QVBoxLayout(calibrationFFTDataGraphWidget); + // calibrationFFTDataGraphWidget->setLayout(calibrationFFTDataGraphLayout); + // calibrationFFTDataGraphLayout->setMargin(0); + // calibrationFFTDataGraphLayout->setSpacing(4); + // QLabel *calibrationFFTDataGraphLabel = new QLabel("FFT Data", calibrationFFTDataGraphWidget); + // StyleHelper::MenuCollapseHeaderLabel(calibrationFFTDataGraphLabel, "calibrationFFTDataGraphLabel"); + // PlotWidget *calibrationFFTDataPlotWidget = new PlotWidget(); + // calibrationFFTDataPlotWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + // calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataGraphLabel); + // calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataPlotWidget); + + #pragma region Raw Data Section Widget + QWidget *rawDataContainerWidget = new QWidget(calibrationDataGraphWidget); + QHBoxLayout *rawDataContainerLayout = new QHBoxLayout(rawDataContainerWidget); + rawDataContainerWidget->setLayout(rawDataContainerLayout); + + MenuSectionWidget *rawDataWidget = new MenuSectionWidget(rawDataContainerWidget); + MenuCollapseSection *rawDataSection = new MenuCollapseSection("Raw Data", MenuCollapseSection::MHCW_NONE, calibrationDataGraphWidget); + rawDataWidget->contentLayout()->setSpacing(10); + rawDataWidget->contentLayout()->addWidget(rawDataSection); + rawDataSection->contentLayout()->setSpacing(10); + + rawDataListWidget = new QListWidget(rawDataWidget); + rawDataSection->contentLayout()->addWidget(rawDataListWidget); + + #pragma region Logs Section Widget + MenuSectionWidget *logsSectionWidget = new MenuSectionWidget(rawDataContainerWidget); + MenuCollapseSection *logsCollapseSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, logsSectionWidget); + logsSectionWidget->contentLayout()->setSpacing(10); + logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); + + logsPlainTextEdit = new QPlainTextEdit(logsSectionWidget); + logsPlainTextEdit->setReadOnly(true); + + logsCollapseSection->contentLayout()->setSpacing(10); + logsCollapseSection->contentLayout()->addWidget(logsPlainTextEdit); + #pragma endregion + + rawDataContainerLayout->setMargin(0); + rawDataContainerLayout->setSpacing(10); + rawDataContainerLayout->addWidget(rawDataWidget); + rawDataContainerLayout->addWidget(logsSectionWidget); + + #pragma endregion calibrationDataGraphLayout->addWidget(calibrationRawDataGraphWidget); - calibrationDataGraphLayout->addWidget(calibrationFFTDataGraphWidget); + // calibrationDataGraphLayout->addWidget(calibrationFFTDataGraphWidget); + calibrationDataGraphLayout->addWidget(rawDataContainerWidget); #pragma endregion #pragma region Calibration Settings Widget @@ -551,16 +862,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() h1RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); h1RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH1Label = new QLabel("H1", calibrationCalculatedCoeffWidget); - QLabel *calibrationH1MagLabel = new QLabel("999.99°", calibrationCalculatedCoeffWidget); - QLabel *calibrationH1PhaseLabel = new QLabel("Φ 999.99", calibrationCalculatedCoeffWidget); - calibrationH1Label->setFixedWidth(52); - applyLabelStyle(calibrationH1Label, "LabelText", true); - applyLabelStyle(calibrationH1MagLabel, "CH0"); - applyLabelStyle(calibrationH1PhaseLabel, "CH1"); + calibrationH1MagLabel = new QLabel("--.--°", calibrationCalculatedCoeffWidget); + calibrationH1PhaseLabel = new QLabel("Φ --.--", calibrationCalculatedCoeffWidget); + applyTextStyle(calibrationH1Label, "LabelText", true); + applyTextStyle(calibrationH1MagLabel, "CH0"); + applyTextStyle(calibrationH1PhaseLabel, "CH1"); + calibrationH1Label->setFixedWidth(24); + calibrationH1MagLabel->setContentsMargins(0, 0, 48, 0); + calibrationH1PhaseLabel->setFixedWidth(56); h1RowLayout->addWidget(calibrationH1Label); - h1RowLayout->addWidget(calibrationH1MagLabel); - h1RowLayout->addWidget(calibrationH1PhaseLabel, 0, Qt::AlignRight); + h1RowLayout->addWidget(calibrationH1MagLabel, 0, Qt::AlignRight); + h1RowLayout->addWidget(calibrationH1PhaseLabel); // H2 QWidget *h2RowContainer = new QWidget(calibrationCalculatedCoeffWidget); @@ -571,16 +884,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() h2RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); h2RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH2Label = new QLabel("H2", calibrationCalculatedCoeffWidget); - QLabel *calibrationH2MagLabel = new QLabel("999.99°", calibrationCalculatedCoeffWidget); - QLabel *calibrationH2PhaseLabel = new QLabel("Φ 999.99", calibrationCalculatedCoeffWidget); - calibrationH2Label->setFixedWidth(52); - applyLabelStyle(calibrationH2Label, "LabelText", true); - applyLabelStyle(calibrationH2MagLabel, "CH0"); - applyLabelStyle(calibrationH2PhaseLabel, "CH1"); + calibrationH2MagLabel = new QLabel("--.--°", calibrationCalculatedCoeffWidget); + calibrationH2PhaseLabel = new QLabel("Φ --.--", calibrationCalculatedCoeffWidget); + applyTextStyle(calibrationH2Label, "LabelText", true); + applyTextStyle(calibrationH2MagLabel, "CH0"); + applyTextStyle(calibrationH2PhaseLabel, "CH1"); + calibrationH2Label->setFixedWidth(24); + calibrationH2MagLabel->setContentsMargins(0, 0, 48, 0); + calibrationH2PhaseLabel->setFixedWidth(56); h2RowLayout->addWidget(calibrationH2Label); - h2RowLayout->addWidget(calibrationH2MagLabel); - h2RowLayout->addWidget(calibrationH2PhaseLabel, 0, Qt::AlignRight); + h2RowLayout->addWidget(calibrationH2MagLabel, 0, Qt::AlignRight); + h2RowLayout->addWidget(calibrationH2PhaseLabel); // H3 QWidget *h3RowContainer = new QWidget(calibrationCalculatedCoeffWidget); @@ -591,16 +906,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() h3RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); h3RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH3Label = new QLabel("H3", calibrationCalculatedCoeffWidget); - QLabel *calibrationH3MagLabel = new QLabel("999.99°", calibrationCalculatedCoeffWidget); - QLabel *calibrationH3PhaseLabel = new QLabel("Φ 999.99", calibrationCalculatedCoeffWidget); - calibrationH3Label->setFixedWidth(52); - applyLabelStyle(calibrationH3Label, "LabelText", true); - applyLabelStyle(calibrationH3MagLabel, "CH0"); - applyLabelStyle(calibrationH3PhaseLabel, "CH1"); + calibrationH3MagLabel = new QLabel("--.--°", calibrationCalculatedCoeffWidget); + calibrationH3PhaseLabel = new QLabel("Φ --.--", calibrationCalculatedCoeffWidget); + applyTextStyle(calibrationH3Label, "LabelText", true); + applyTextStyle(calibrationH3MagLabel, "CH0"); + applyTextStyle(calibrationH3PhaseLabel, "CH1"); + calibrationH3Label->setFixedWidth(24); + calibrationH3MagLabel->setContentsMargins(0, 0, 48, 0); + calibrationH3PhaseLabel->setFixedWidth(56); h3RowLayout->addWidget(calibrationH3Label); - h3RowLayout->addWidget(calibrationH3MagLabel); - h3RowLayout->addWidget(calibrationH3PhaseLabel, 0, Qt::AlignRight); + h3RowLayout->addWidget(calibrationH3MagLabel, 0, Qt::AlignRight); + h3RowLayout->addWidget(calibrationH3PhaseLabel); // H8 QWidget *h8RowContainer = new QWidget(calibrationCalculatedCoeffWidget); @@ -611,16 +928,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() h8RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); h8RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH8Label = new QLabel("H8", calibrationCalculatedCoeffWidget); - QLabel *calibrationH8MagLabel = new QLabel("999.99°", calibrationCalculatedCoeffWidget); - QLabel *calibrationH8PhaseLabel = new QLabel("Φ 999.99", calibrationCalculatedCoeffWidget); - calibrationH8Label->setFixedWidth(52); - applyLabelStyle(calibrationH8Label, "LabelText", true); - applyLabelStyle(calibrationH8MagLabel, "CH0"); - applyLabelStyle(calibrationH8PhaseLabel, "CH1"); + calibrationH8MagLabel = new QLabel("--.--°", calibrationCalculatedCoeffWidget); + calibrationH8PhaseLabel = new QLabel("Φ --.--", calibrationCalculatedCoeffWidget); + applyTextStyle(calibrationH8Label, "LabelText", true); + applyTextStyle(calibrationH8MagLabel, "CH0"); + applyTextStyle(calibrationH8PhaseLabel, "CH1"); + calibrationH8Label->setFixedWidth(24); + calibrationH8MagLabel->setContentsMargins(0, 0, 48, 0); + calibrationH8PhaseLabel->setFixedWidth(56); h8RowLayout->addWidget(calibrationH8Label); - h8RowLayout->addWidget(calibrationH8MagLabel); - h8RowLayout->addWidget(calibrationH8PhaseLabel, 0, Qt::AlignRight); + h8RowLayout->addWidget(calibrationH8MagLabel, 0, Qt::AlignRight); + h8RowLayout->addWidget(calibrationH8PhaseLabel); calibrationCalculatedCoeffLayout->addWidget(h1RowContainer, 0, 0); calibrationCalculatedCoeffLayout->addWidget(h2RowContainer, 1, 0); @@ -684,21 +1003,22 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); StyleHelper::MenuSmallLabel(currentPositionLabel, "currentPositionLabel"); calibrationMotorCurrentPositionLabel = new QLabel("--.--°", motorControlSectionWidget); - // calibrationMotorCurrentPositionLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); calibrationMotorCurrentPositionLabel->setAlignment(Qt::AlignRight); - applyTextBoxStyle(calibrationMotorCurrentPositionLabel); - applyLabelPadding(calibrationMotorCurrentPositionLabel); + applyLabelStyle(calibrationMotorCurrentPositionLabel); HorizontalSpinBox *motorTargetPositionSpinBox = new HorizontalSpinBox("Target Position", 9999.99, "°", motorControlSectionWidget); HorizontalSpinBox *motorVelocitySpinBox = new HorizontalSpinBox("Velocity", 9999.99, "rpm", motorControlSectionWidget); - QPushButton *calibrationStartMotorButton = new QPushButton(motorControlSectionWidget); + calibrationStartMotorButton = new QPushButton(motorControlSectionWidget); calibrationStartMotorButton->setCheckable(true); calibrationStartMotorButton->setChecked(false); calibrationStartMotorButton->setText("Start Motor"); calibrationStartMotorButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); calibrationStartMotorButton->setFixedHeight(36); - connect(calibrationStartMotorButton, &QPushButton::toggled, this, [=](bool b) { calibrationStartMotorButton->setText(b ? " Stop Motor" : " Start Motor"); }); + connect(calibrationStartMotorButton, &QPushButton::toggled, this, [=](bool b) { + calibrationStartMotorButton->setText(b ? " Stop Motor" : " Start Motor"); + startMotor = b; + }); QString calibrationStartMotorButtonStyle = QString(R"css( QPushButton { border-radius: 2px; @@ -740,30 +1060,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() motorControlCollapseSection->contentLayout()->addWidget(autoCalibrateCheckBox); #pragma endregion - #pragma region Raw Data Section Widget - MenuSectionWidget *rawDataWidget = new MenuSectionWidget(calibrationDataGraphWidget); - MenuCollapseSection *rawDataSection = new MenuCollapseSection("Raw Data", MenuCollapseSection::MHCW_NONE, calibrationDataGraphWidget); - rawDataWidget->contentLayout()->setSpacing(10); - rawDataWidget->contentLayout()->addWidget(rawDataSection); - rawDataSection->contentLayout()->setSpacing(10); - - rawDataListWidget = new QListWidget(rawDataWidget); - rawDataSection->contentLayout()->addWidget(rawDataListWidget); - #pragma endregion - - #pragma region Logs Section Widget - MenuSectionWidget *logsSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - MenuCollapseSection *logsCollapseSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, logsSectionWidget); - logsSectionWidget->contentLayout()->setSpacing(10); - logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); - - logsPlainTextEdit = new QPlainTextEdit(logsSectionWidget); - logsPlainTextEdit->setReadOnly(true); - - logsCollapseSection->contentLayout()->setSpacing(10); - logsCollapseSection->contentLayout()->addWidget(logsPlainTextEdit); - #pragma endregion - #pragma region Debug Section Widget MenuSectionWidget *debugSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); MenuCollapseSection *debugCollapseSection = new MenuCollapseSection("Debug", MenuCollapseSection::MHCW_NONE, debugSectionWidget); @@ -782,10 +1078,15 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrateDataButton->setText("Calibrate"); StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); + QPushButton *clearCalibrateDataButton = new QPushButton(debugSectionWidget); + clearCalibrateDataButton->setText("Clear All Data"); + StyleHelper::BlueButton(clearCalibrateDataButton, "clearCalibrateDataButton"); + debugCollapseSection->contentLayout()->setSpacing(10); debugCollapseSection->contentLayout()->addWidget(addCalibrationDataButton); debugCollapseSection->contentLayout()->addWidget(removeLastCalibrationDataButton); debugCollapseSection->contentLayout()->addWidget(calibrateDataButton); + debugCollapseSection->contentLayout()->addWidget(clearCalibrateDataButton); #pragma endregion calibrationSettingsLayout->setMargin(0); @@ -793,8 +1094,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); calibrationSettingsLayout->addWidget(motorControlSectionWidget); - calibrationSettingsLayout->addWidget(rawDataWidget); - calibrationSettingsLayout->addWidget(logsSectionWidget); calibrationSettingsLayout->addWidget(debugSectionWidget); calibrationSettingsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); #pragma endregion @@ -802,13 +1101,15 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); tool->topContainer()->setVisible(false); tool->topContainerMenuControl()->setVisible(false); - tool->leftContainer()->setVisible(false); + tool->leftContainer()->setVisible(true); tool->rightContainer()->setVisible(true); tool->bottomContainer()->setVisible(false); + tool->setLeftContainerWidth(270); tool->setRightContainerWidth(270); tool->openBottomContainerHelper(false); tool->openTopContainerHelper(false); + tool->leftStack()->add("motorAttributesScroll", motorAttributesScroll); tool->addWidgetToCentralContainerHelper(calibrationDataGraphWidget); tool->rightStack()->add("calibrationSettingsScrollArea", calibrationSettingsScrollArea); @@ -818,6 +1119,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); connect(importDataButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); connect(applyCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::registerCalibrationData); + connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::clearRawDataList); return tool; } @@ -827,16 +1129,16 @@ void HarmonicCalibration::updateLabelValue(QLabel* label, int channelIndex) switch(channelIndex) { case ADMTController::Channel::ROTATION: - label->setText(QString::number(rotation) + "°"); + label->setText(QString("%1").arg(rotation, 0, 'f', 2) + "°"); break; case ADMTController::Channel::ANGLE: - label->setText(QString::number(angle) + "°"); + label->setText(QString("%1").arg(angle, 0, 'f', 2) + "°"); break; case ADMTController::Channel::COUNT: label->setText(QString::number(count)); break; case ADMTController::Channel::TEMPERATURE: - label->setText(QString::number(temp) + "°C"); + label->setText(QString("%1").arg(temp, 0, 'f', 2) + "°C"); break; } } @@ -846,24 +1148,68 @@ void HarmonicCalibration::updateChannelValue(int channelIndex) switch(channelIndex) { case ADMTController::Channel::ROTATION: - rotation = m_admtController->getChannelValue(rotationChannelName, 1); + rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, 1); break; case ADMTController::Channel::ANGLE: - angle = m_admtController->getChannelValue(angleChannelName, 1); + angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, 1); break; case ADMTController::Channel::COUNT: - count = m_admtController->getChannelValue(countChannelName, 1); + count = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, 1); break; case ADMTController::Channel::TEMPERATURE: - temp = m_admtController->getChannelValue(temperatureChannelName, 1); + temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, 1); break; } } +void HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute attribute, double *value) +{ + int result = m_admtController->getDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), m_admtController->getMotorAttribute(attribute), value); +} + +void HarmonicCalibration::writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value) +{ + int result = m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), + m_admtController->getMotorAttribute(attribute), + value); + if(result != 0) { calibrationLogWriteLn(QString(m_admtController->getMotorAttribute(attribute)) + ": Write Error " + QString::number(result)); } +} + +void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute) +{ + switch(attribute) + { + case ADMTController::MotorAttribute::AMAX: + label->setText(QString::number(amax)); + break; + case ADMTController::MotorAttribute::ROTATE_VMAX: + label->setText(QString::number(rotate_vmax)); + break; + case ADMTController::MotorAttribute::DMAX: + label->setText(QString::number(dmax)); + break; + case ADMTController::MotorAttribute::DISABLE: + label->setText(QString::number(disable)); + break; + case ADMTController::MotorAttribute::TARGET_POS: + label->setText(QString::number(target_pos)); + break; + case ADMTController::MotorAttribute::CURRENT_POS: + label->setText(QString::number(current_pos)); + break; + case ADMTController::MotorAttribute::RAMP_MODE: + label->setText(QString::number(ramp_mode)); + break; + + } +} + void HarmonicCalibration::calibrationTask() { updateChannelValue(ADMTController::Channel::ANGLE); updateLabelValue(calibrationMotorCurrentPositionLabel, ADMTController::Channel::ANGLE); + + startMotorAcquisition(); } void HarmonicCalibration::addAngleToRawDataList() @@ -878,7 +1224,7 @@ void HarmonicCalibration::removeLastItemFromRawDataList(){ void HarmonicCalibration::calibrateData() { - logsPlainTextEdit->appendPlainText("\n======= Calibration Start =======\n"); + calibrationLogWrite("==== Calibration Start ====\n"); QVector rawData; for (int i = 0; i < rawDataListWidget->count(); ++i) { @@ -889,12 +1235,48 @@ void HarmonicCalibration::calibrateData() } std::vector stdData(rawData.begin(), rawData.end()); - logsPlainTextEdit->appendPlainText(m_admtController->calibrate(stdData)); + calibrationLogWriteLn(m_admtController->calibrate(stdData, cycleCount, samplesPerCycle)); + + calibrationH1MagLabel->setText(QString::number(m_admtController->HAR_MAG_1) + "°"); + calibrationH2MagLabel->setText(QString::number(m_admtController->HAR_MAG_2) + "°"); + calibrationH3MagLabel->setText(QString::number(m_admtController->HAR_MAG_3) + "°"); + calibrationH8MagLabel->setText(QString::number(m_admtController->HAR_MAG_8) + "°"); + calibrationH1PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_1)); + calibrationH2PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_2)); + calibrationH3PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_3)); + calibrationH8PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_8)); } void HarmonicCalibration::registerCalibrationData() { - logsPlainTextEdit->appendPlainText("\n=== Register Calibration Start ===\n"); + calibrationLogWrite("=== Apply Calibration ===\n"); + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + h1MagDeviceRegister, m_admtController->HAR_MAG_1) != 0) + { calibrationLogWriteLn("Failed to write to H1 Mag Register"); } + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + h2MagDeviceRegister, m_admtController->HAR_MAG_2) != 0) + { calibrationLogWriteLn("Failed to write to H2 Mag Register"); } + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + h3MagDeviceRegister, m_admtController->HAR_MAG_3) != 0) + { calibrationLogWriteLn("Failed to write to H3 Mag Register"); } + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + h8MagDeviceRegister, m_admtController->HAR_MAG_8) != 0) + { calibrationLogWriteLn("Failed to write to H8 Mag Register"); } + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + h1PhaseDeviceRegister, m_admtController->HAR_PHASE_1) != 0) + { calibrationLogWriteLn("Failed to write to H1 Phase Register"); } + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + h2PhaseDeviceRegister, m_admtController->HAR_PHASE_2) != 0) + { calibrationLogWriteLn("Failed to write to H2 Phase Register"); } + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + h3PhaseDeviceRegister, m_admtController->HAR_PHASE_3) != 0) + { calibrationLogWriteLn("Failed to write to H3 Phase Register"); } + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + h8PhaseDeviceRegister, m_admtController->HAR_PHASE_8) != 0) + { calibrationLogWriteLn("Failed to write to H8 Phase Register"); } + + calibrationLogWrite("=== Calibration Complete ===\n"); } void HarmonicCalibration::calibrationLogWrite(QString message) @@ -974,9 +1356,64 @@ void HarmonicCalibration::importCalibrationData() } } -void HarmonicCalibration::applyTextBoxStyle(QWidget *widget) +void HarmonicCalibration::initializeMotor() +{ + amax = 1200; + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, &amax); + + rotate_vmax = 600000; + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, &rotate_vmax); + + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + + dmax = 3000; + writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, &dmax); + + ramp_mode = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, &ramp_mode); + + target_pos = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); +} + +void HarmonicCalibration::startMotorAcquisition() +{ + if(startMotor && rawDataListWidget->count() < totalSamplesCount){ + double magNum = 408; + + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, ¤t_pos); + target_pos = current_pos - 408; + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); + + while(target_pos != current_pos) { + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, ¤t_pos); + } + + double currentAngle = angle; + calibrationRawDataPlotWidget->plot(currentAngle); + QString dataStr = QString::number(currentAngle); + rawDataListWidget->addItem(dataStr); + rawDataListWidget->scrollToBottom(); + } + else if(rawDataListWidget->count() == totalSamplesCount) + { + calibrationStartMotorButton->setChecked(false); + } +} + +void HarmonicCalibration::clearRawDataList() { - applyLabelStyle(widget); + rawDataListWidget->clear(); + calibrationRawDataPlotWidget->reset(); +} + +void HarmonicCalibration::applyLineEditStyle(QLineEdit *widget) +{ + applyTextStyle(widget); QString existingStyle = widget->styleSheet(); QString style = QString(R"css( background-color: black; @@ -985,6 +1422,9 @@ void HarmonicCalibration::applyTextBoxStyle(QWidget *widget) )css"); widget->setStyleSheet(existingStyle + style); widget->setFixedHeight(30); + widget->setContentsMargins(0, 0, 0, 0); + widget->setTextMargins(12, 4, 12, 4); + widget->setAlignment(Qt::AlignRight); } void HarmonicCalibration::applyComboBoxStyle(QComboBox *widget, const QString& styleHelperColor) @@ -1043,23 +1483,7 @@ void HarmonicCalibration::applyComboBoxStyle(QComboBox *widget, const QString& s widget->setFixedHeight(30); } -void HarmonicCalibration::applyLabelPadding(QLabel *widget) -{ - widget->setContentsMargins(12, 4, 12, 4); -} - -void HarmonicCalibration::applyLineEditPadding(QLineEdit *widget) -{ - widget->setContentsMargins(0, 0, 0, 0); - widget->setTextMargins(12, 4, 12, 4); -} - -void HarmonicCalibration::applyLineEditAlignment(QLineEdit *widget) -{ - widget->setAlignment(Qt::AlignRight); -} - -void HarmonicCalibration::applyLabelStyle(QWidget *widget, const QString& styleHelperColor, bool isBold) +void HarmonicCalibration::applyTextStyle(QWidget *widget, const QString& styleHelperColor, bool isBold) { QString existingStyle = widget->styleSheet(); QString style = QString(R"css( @@ -1076,4 +1500,18 @@ void HarmonicCalibration::applyLabelStyle(QWidget *widget, const QString& styleH } style = style.replace(QString("&&fontweight&&"), fontWeight); widget->setStyleSheet(existingStyle + style); +} + +void HarmonicCalibration::applyLabelStyle(QLabel *widget) +{ + applyTextStyle(widget); + QString existingStyle = widget->styleSheet(); + QString style = QString(R"css( + background-color: black; + border-radius: 4px; + border: none; + )css"); + widget->setStyleSheet(existingStyle + style); + widget->setFixedHeight(30); + widget->setContentsMargins(12, 4, 12, 4); } \ No newline at end of file From 05d14a44a14170a807d6544940fcd755be50d52e Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 15 Aug 2024 13:57:36 +0800 Subject: [PATCH 016/112] admt: Adjusted Calibration GUI - Connected horizontal spinbox to stepper motor control - Added conversions for real world values to stepper motor attributes - Added FFT plot for magnitude and phase calibration values Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 8 + .../admt/include/admt/harmoniccalibration.h | 25 +- .../include/admt/widgets/horizontalspinbox.h | 3 +- plugins/admt/src/admtcontroller.cpp | 7 +- plugins/admt/src/harmoniccalibration.cpp | 744 +++++++++++------- .../admt/src/widgets/horizontalspinbox.cpp | 20 +- 6 files changed, 506 insertions(+), 301 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 1c1eb9f65c..836efb078a 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -32,6 +32,8 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject int HAR_MAG_1, HAR_MAG_2, HAR_MAG_3, HAR_MAG_8 ,HAR_PHASE_1 ,HAR_PHASE_2 ,HAR_PHASE_3 ,HAR_PHASE_8; + vector angle_errors_fft, angle_errors_fft_phase; + enum Channel { ROTATION, @@ -60,6 +62,12 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject MOTOR_ATTR_COUNT }; + enum MotorRampMode + { + POSITION, + RAMP_MODE_1 + }; + const char* ChannelIds[CHANNEL_COUNT] = {"rot", "angl", "count", "temp"}; const char* DeviceIds[DEVICE_COUNT] = {"admt4000", "tmc5240"}; const char* MotorAttributes[MOTOR_ATTR_COUNT] = {"amax", "rotate_vmax", "dmax", diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index d5206fb6e4..683a86e30d 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -68,7 +69,7 @@ public Q_SLOTS: double rotation, angle, count, temp, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode; - QPushButton *openLastMenuButton, *calibrationStartMotorButton; + QPushButton *openLastMenuButton, *calibrationStartMotorButton, *applyCalibrationDataButton; QButtonGroup *rightMenuButtonGroup; QLineEdit *graphUpdateIntervalLineEdit, *dataSampleSizeLineEdit, @@ -105,6 +106,10 @@ public Q_SLOTS: QPlainTextEdit *logsPlainTextEdit; + PlotWidget *calibrationFFTDataPlotWidget; + PlotAxis *calibrationFFTXPlotAxis, *calibrationFFTYPlotAxis; + PlotChannel *calibrationFFTPlotChannel, *calibrationFFTPhasePlotChannel; + void updateChannelValues(); void updateLineEditValues(); void updateGeneralSettingEnabled(bool value); @@ -127,17 +132,27 @@ public Q_SLOTS: void importCalibrationData(); void calibrationLogWrite(QString message); void calibrationLogWriteLn(QString message); - void readMotorAttributeValue(ADMTController::MotorAttribute attribute, double *value); + void readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value); void writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); void applyLineEditStyle(QLineEdit *widget); void applyComboBoxStyle(QComboBox *widget, const QString& styleHelperColor = "CH0"); void applyTextStyle(QWidget *widget, const QString& styleHelperColor = "CH0", bool isBold = false); void applyLabelStyle(QLabel *widget); void initializeMotor(); - void startMotorAcquisition(); + void stepMotorAcquisition(double step = -408); void clearRawDataList(); - - QTimer *timer, *calibrationTimer; + void motorCalibrationAcquisitionTask(); + void connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax); + double convertRPStoVMAX(double rps); + double convertVMAXtoRPS(double vmax); + void connectLineEditToAMAXConversion(QLineEdit* lineEdit, double& amax); + double convertAccelTimetoAMAX(double accelTime); + double convertAMAXtoAccelTime(double amax); + void updateCalculatedCoeff(); + void resetCalculatedCoeff(); + void connectMenuComboToNumber(MenuCombo* menuCombo, double& variable); + + QTimer *timer, *calibrationTimer, *motorCalibrationAcquisitionTimer; int uuid = 0; const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; diff --git a/plugins/admt/include/admt/widgets/horizontalspinbox.h b/plugins/admt/include/admt/widgets/horizontalspinbox.h index 6971f0e27e..957b96a221 100644 --- a/plugins/admt/include/admt/widgets/horizontalspinbox.h +++ b/plugins/admt/include/admt/widgets/horizontalspinbox.h @@ -17,6 +17,7 @@ namespace scopy::admt { Q_OBJECT public: HorizontalSpinBox(QString header = "", double initialValue = 0.0, QString unit = "", QWidget *parent = nullptr); + QLineEdit *lineEdit(); public Q_SLOTS: void setValue(double); protected Q_SLOTS: @@ -26,7 +27,7 @@ namespace scopy::admt { private: double m_value = 0; QString m_unit = ""; - QLineEdit *lineEdit; + QLineEdit *m_lineEdit; void applyLineEditStyle(QLineEdit *widget); void applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius = 0, int topRightBorderRadius = 0, int bottomLeftBorderRadius = 0, int bottomRightBorderRadius = 0); void applyUnitLabelStyle(QLabel *widget); diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 99495753a2..78323396b5 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -17,8 +17,6 @@ #include static const size_t maxAttrSize = 512; -static vector angle_errors_fft; -static vector angle_errors_fft_phase; using namespace scopy::admt; using namespace std; @@ -78,6 +76,7 @@ const char* ADMTController::getMotorAttribute(MotorAttribute attribute) int ADMTController::getChannelIndex(const char *deviceName, const char *channelName) { iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); + if(admtDevice == NULL) { return -1; } int channelCount = iio_device_get_channels_count(admtDevice); iio_channel *channel; std::string message = ""; @@ -430,8 +429,8 @@ QString ADMTController::calibrate(vector PANG, int cycles, int samplesPe /* FFT based on implementation from https://www.oreilly.com/library/view/c-cookbook/0596007612/ch11s18.html */ vector angle_errors_fft_temp(PANG.size()); vector angle_errors_fft_phase_temp(PANG.size()); - angle_errors_fft(PANG.size() / 2); - angle_errors_fft_phase(PANG.size() / 2); + angle_errors_fft = vector(PANG.size() / 2); + angle_errors_fft_phase = vector(PANG.size() / 2); typedef complex cx; /* array declaration must be constant so hardcoded as of now */ diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index b93e6d32e9..b7687c5fc3 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -4,18 +4,25 @@ #include static int sampleRate = 50; -static int calibrationRate = 20; +static int calibrationTimerRate = 100; +static int motorCalibrationAcquisitionTimerRate = 5; static int bufferSize = 1; static int dataGraphSamples = 100; static int tempGraphSamples = 100; static bool running = false; static double *dataGraphValue; -static int cycleCount = 1; +static int cycleCount = 11; static int samplesPerCycle = 256; static int totalSamplesCount = cycleCount * samplesPerCycle; static bool startMotor = false; +static bool isDebug = true; + +static double motorTimeUnit = 1.048576; // t = 2^24/16Mhz +static int motorMicrostepPerRevolution = 51200; +static int motorfCLK = 16000000; // 16Mhz + static uint32_t h1MagDeviceRegister = 0x15; static uint32_t h2MagDeviceRegister = 0x17; static uint32_t h3MagDeviceRegister = 0x19; @@ -295,190 +302,21 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg calibrationTimer = new QTimer(this); connect(calibrationTimer, &QTimer::timeout, this, &HarmonicCalibration::calibrationTask); + motorCalibrationAcquisitionTimer = new QTimer(this); + connect(motorCalibrationAcquisitionTimer, &QTimer::timeout, this, &HarmonicCalibration::motorCalibrationAcquisitionTask); + tabWidget->addTab(createCalibrationWidget(), "Calibration"); connect(tabWidget, &QTabWidget::currentChanged, [=](int index){ tabWidget->setCurrentIndex(index); - if(index == 1) { calibrationTimer->start(calibrationRate); } + if(index == 1) { calibrationTimer->start(calibrationTimerRate); } else { calibrationTimer->stop(); } }); } HarmonicCalibration::~HarmonicCalibration() {} -void HarmonicCalibration::restart() -{ - if(m_running) { - run(false); - run(true); - } -} - -bool HarmonicCalibration::running() const { return m_running; } - -void HarmonicCalibration::setRunning(bool newRunning) -{ - if(m_running == newRunning) - return; - m_running = newRunning; - Q_EMIT runningChanged(newRunning); -} - -void HarmonicCalibration::start() { run(true); } - -void HarmonicCalibration::stop() { run(false); } - -void HarmonicCalibration::run(bool b) -{ - qInfo() << b; - QElapsedTimer tim; - tim.start(); - - if(!b) { - runButton->setChecked(false); - timer->stop(); - } - else{ - timer->start(sampleRate); - } - - updateGeneralSettingEnabled(!b); -} - -void HarmonicCalibration::timerTask(){ - updateChannelValues(); - updateLineEditValues(); - - dataGraph->plot(*dataGraphValue); - tempGraph->plot(temp); -} - -void HarmonicCalibration::updateChannelValues(){ - rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, bufferSize); - angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, bufferSize); - count = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, bufferSize); - temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, bufferSize); -} - -void HarmonicCalibration::updateLineEditValues(){ - rotationValueLabel->setText(QString::number(rotation) + "°"); - angleValueLabel->setText(QString::number(angle) + "°"); - countValueLabel->setText(QString::number(count)); - tempValueLabel->setText(QString::number(temp) + " °C"); -} - -void HarmonicCalibration::updateGeneralSettingEnabled(bool value) -{ - graphUpdateIntervalLineEdit->setEnabled(value); - dataSampleSizeLineEdit->setEnabled(value); - dataGraphSamplesLineEdit->setEnabled(value); - tempGraphSamplesLineEdit->setEnabled(value); -} - -void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable) -{ - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { - bool ok; - int value = lineEdit->text().toInt(&ok); - if (ok) { - variable = value; - } else { - lineEdit->setText(QString::number(variable)); - } - }); -} - -void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& variable) -{ - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { - bool ok; - double value = lineEdit->text().toDouble(&ok); - if (ok) { - variable = value; - } else { - lineEdit->setText(QString::number(variable)); - } - }); -} - -void HarmonicCalibration::connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph) -{ - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, graph]() { - bool ok; - int value = lineEdit->text().toInt(&ok); - if (ok) { - variable = value; - graph->setNumSamples(variable); - } else { - lineEdit->setText(QString::number(variable)); - } - }); -} - -void HarmonicCalibration::connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph) -{ - QComboBox *combo = menuCombo->combo(); - connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [combo, graph]() { - int value = qvariant_cast(combo->currentData()); - switch(value) - { - case Sismograph::LEFT_TO_RIGHT: - graph->setPlotDirection(Sismograph::LEFT_TO_RIGHT); - graph->reset(); - break; - case Sismograph::RIGHT_TO_LEFT: - graph->setPlotDirection(Sismograph::RIGHT_TO_LEFT); - graph->reset(); - break; - } - }); -} - -void HarmonicCalibration::changeGraphColorByChannelName(Sismograph* graph, const char* channelName) -{ - int index = m_admtController->getChannelIndex(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), channelName); - if(index > -1){ - graph->setColor(StyleHelper::getColor( QString::fromStdString("CH" + std::to_string(index) ))); - } -} - -void HarmonicCalibration::connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph) -{ - QComboBox *combo = menuCombo->combo(); - connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [this, combo, graph]() { - int currentIndex = combo->currentIndex(); - QVariant currentData = combo->currentData(); - char *value = reinterpret_cast(currentData.value()); - switch(currentIndex) - { - case ADMTController::Channel::ROTATION: - dataGraphValue = &rotation; - graph->setUnitOfMeasure("Degree", "°"); - graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); - graph->setNumSamples(dataGraphSamples); - graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); - break; - case ADMTController::Channel::ANGLE: - dataGraphValue = ∠ - graph->setUnitOfMeasure("Degree", "°"); - graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); - graph->setNumSamples(dataGraphSamples); - graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); - break; - case ADMTController::Channel::COUNT: - dataGraphValue = &count; - graph->setUnitOfMeasure("Count", ""); - graph->setAxisScale(QwtAxis::YLeft, -1.0, 20.0); - graph->setNumSamples(dataGraphSamples); - graph->setAxisTitle(QwtAxis::YLeft, tr("Count")); - break; - } - changeGraphColorByChannelName(graph, value); - graph->reset(); - }); -} - ToolTemplate* HarmonicCalibration::createCalibrationWidget() { initializeMotor(); @@ -498,7 +336,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() amaxSectionWidget->contentLayout()->addWidget(amaxCollapseSection); motorAmaxValueLabel = new QLabel("-", amaxSectionWidget); StyleHelper::MenuSmallLabel(motorAmaxValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, &amax); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); updateLabelValue(motorAmaxValueLabel, ADMTController::MotorAttribute::AMAX); QLineEdit *motorAmaxLineEdit = new QLineEdit(amaxSectionWidget); applyLineEditStyle(motorAmaxLineEdit); @@ -512,14 +350,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QPushButton *readMotorAmaxButton = new QPushButton("Read", motorAmaxButtonGroupWidget); StyleHelper::BlueButton(readMotorAmaxButton); connect(readMotorAmaxButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, &amax); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); updateLabelValue(motorAmaxValueLabel, ADMTController::MotorAttribute::AMAX); }); QPushButton *writeMotorAmaxButton = new QPushButton("Write", motorAmaxButtonGroupWidget); StyleHelper::BlueButton(writeMotorAmaxButton); connect(writeMotorAmaxButton, &QPushButton::pressed, this, [=]{ writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, &amax); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); updateLabelValue(motorAmaxValueLabel, ADMTController::MotorAttribute::AMAX); }); motorAmaxButtonGroupLayout->addWidget(readMotorAmaxButton); @@ -535,7 +373,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() rotateVmaxSectionWidget->contentLayout()->addWidget(rotateVmaxCollapseSection); motorRotateVmaxValueLabel = new QLabel("-", rotateVmaxSectionWidget); StyleHelper::MenuSmallLabel(motorRotateVmaxValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, &rotate_vmax); + readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); updateLabelValue(motorRotateVmaxValueLabel, ADMTController::MotorAttribute::ROTATE_VMAX); QLineEdit *motorRotateVmaxLineEdit = new QLineEdit(rotateVmaxSectionWidget); applyLineEditStyle(motorRotateVmaxLineEdit); @@ -549,14 +387,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QPushButton *readMotorRotateVmaxButton = new QPushButton("Read", motorRotateVmaxButtonGroupWidget); StyleHelper::BlueButton(readMotorRotateVmaxButton); connect(readMotorRotateVmaxButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, &rotate_vmax); + readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); updateLabelValue(motorRotateVmaxValueLabel, ADMTController::MotorAttribute::ROTATE_VMAX); }); QPushButton *writeMotorRotateVmaxButton = new QPushButton("Write", motorRotateVmaxButtonGroupWidget); StyleHelper::BlueButton(writeMotorRotateVmaxButton); connect(writeMotorRotateVmaxButton, &QPushButton::pressed, this, [=]{ writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, &rotate_vmax); + readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); updateLabelValue(motorRotateVmaxValueLabel, ADMTController::MotorAttribute::ROTATE_VMAX); }); motorRotateVmaxButtonGroupLayout->addWidget(readMotorRotateVmaxButton); @@ -572,7 +410,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() dmaxSectionWidget->contentLayout()->addWidget(dmaxCollapseSection); motorDmaxValueLabel = new QLabel("-", dmaxSectionWidget); StyleHelper::MenuSmallLabel(motorDmaxValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, &dmax); + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); updateLabelValue(motorDmaxValueLabel, ADMTController::MotorAttribute::DMAX); QLineEdit *motorDmaxLineEdit = new QLineEdit(dmaxSectionWidget); applyLineEditStyle(motorDmaxLineEdit); @@ -586,14 +424,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QPushButton *readMotorDmaxButton = new QPushButton("Read", motorDmaxButtonGroupWidget); StyleHelper::BlueButton(readMotorDmaxButton); connect(readMotorDmaxButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, &dmax); + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); updateLabelValue(motorDmaxValueLabel, ADMTController::MotorAttribute::DMAX); }); QPushButton *writeMotorDmaxButton = new QPushButton("Write", motorDmaxButtonGroupWidget); StyleHelper::BlueButton(writeMotorDmaxButton); connect(writeMotorDmaxButton, &QPushButton::pressed, this, [=]{ writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, &dmax); + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); updateLabelValue(motorDmaxValueLabel, ADMTController::MotorAttribute::DMAX); }); motorDmaxButtonGroupLayout->addWidget(readMotorDmaxButton); @@ -607,17 +445,12 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() MenuSectionWidget *disableSectionWidget = new MenuSectionWidget(motorAttributesWidget); MenuCollapseSection *disableCollapseSection = new MenuCollapseSection("disable", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, disableSectionWidget); disableSectionWidget->contentLayout()->addWidget(disableCollapseSection); - // motorDisableValueLabel = new QLabel("-", disableSectionWidget); - // readMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, &disable); - // updateLabelValue(motorDisableValueLabel, ADMTController::MotorAttribute::DISABLE); QPushButton *writeMotorDisableButton = new QPushButton("Disable", disableSectionWidget); StyleHelper::BlueButton(writeMotorDisableButton); connect(writeMotorDisableButton, &QPushButton::pressed, this, [=]{ writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); }); disableCollapseSection->contentLayout()->setSpacing(10); - // disableCollapseSection->contentLayout()->addWidget(motorDisableValueLabel); - // disableCollapseSection->contentLayout()->addWidget(motorDisableLineEdit); disableCollapseSection->contentLayout()->addWidget(writeMotorDisableButton); //target_pos @@ -626,7 +459,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() targetPosSectionWidget->contentLayout()->addWidget(targetPosCollapseSection); motorTargetPosValueLabel = new QLabel("-", targetPosSectionWidget); StyleHelper::MenuSmallLabel(motorTargetPosValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, &target_pos); + readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); updateLabelValue(motorTargetPosValueLabel, ADMTController::MotorAttribute::TARGET_POS); QLineEdit *motorTargetPosLineEdit = new QLineEdit(targetPosSectionWidget); applyLineEditStyle(motorTargetPosLineEdit); @@ -640,14 +473,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QPushButton *readMotorTargetPosButton = new QPushButton("Read", motorTargetPosButtonGroupWidget); StyleHelper::BlueButton(readMotorTargetPosButton); connect(readMotorTargetPosButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, &target_pos); + readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); updateLabelValue(motorTargetPosValueLabel, ADMTController::MotorAttribute::TARGET_POS); }); QPushButton *writeMotorTargetPosButton = new QPushButton("Write", motorTargetPosButtonGroupWidget); StyleHelper::BlueButton(writeMotorTargetPosButton); connect(writeMotorTargetPosButton, &QPushButton::pressed, this, [=]{ writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, &target_pos); + readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); updateLabelValue(motorTargetPosValueLabel, ADMTController::MotorAttribute::TARGET_POS); }); motorTargetPosButtonGroupLayout->addWidget(readMotorTargetPosButton); @@ -663,7 +496,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() currentPosSectionWidget->contentLayout()->addWidget(currentPosCollapseSection); motorCurrentPosValueLabel = new QLabel("-", currentPosSectionWidget); StyleHelper::MenuSmallLabel(motorCurrentPosValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, ¤t_pos); + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); updateLabelValue(motorCurrentPosValueLabel, ADMTController::MotorAttribute::CURRENT_POS); QWidget *motorCurrentPosButtonGroupWidget = new QWidget(currentPosSectionWidget); QHBoxLayout *motorCurrentPosButtonGroupLayout = new QHBoxLayout(motorCurrentPosButtonGroupWidget); @@ -673,7 +506,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QPushButton *readMotorCurrentPosButton = new QPushButton("Read", motorCurrentPosButtonGroupWidget); StyleHelper::BlueButton(readMotorCurrentPosButton); connect(readMotorCurrentPosButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, ¤t_pos); + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); updateLabelValue(motorCurrentPosValueLabel, ADMTController::MotorAttribute::CURRENT_POS); }); motorCurrentPosButtonGroupLayout->addWidget(readMotorCurrentPosButton); @@ -687,7 +520,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() rampModeSectionWidget->contentLayout()->addWidget(rampModeCollapseSection); motorRampModeValueLabel = new QLabel("-", rampModeSectionWidget); StyleHelper::MenuSmallLabel(motorRampModeValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, &ramp_mode); + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); updateLabelValue(motorRampModeValueLabel, ADMTController::MotorAttribute::RAMP_MODE); QLineEdit *motorRampModeLineEdit = new QLineEdit(rampModeSectionWidget); applyLineEditStyle(motorRampModeLineEdit); @@ -701,14 +534,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QPushButton *readMotorRampModeButton = new QPushButton("Read", motorRampModeButtonGroupWidget); StyleHelper::BlueButton(readMotorRampModeButton); connect(readMotorRampModeButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, &ramp_mode); + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); updateLabelValue(motorRampModeValueLabel, ADMTController::MotorAttribute::RAMP_MODE); }); QPushButton *writeMotorRampModeButton = new QPushButton("Write", motorRampModeButtonGroupWidget); StyleHelper::BlueButton(writeMotorRampModeButton); connect(writeMotorRampModeButton, &QPushButton::pressed, this, [=]{ writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, &ramp_mode); + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); updateLabelValue(motorRampModeValueLabel, ADMTController::MotorAttribute::RAMP_MODE); }); motorRampModeButtonGroupLayout->addWidget(readMotorRampModeButton); @@ -718,8 +551,64 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() rampModeCollapseSection->contentLayout()->addWidget(motorRampModeLineEdit); rampModeCollapseSection->contentLayout()->addWidget(motorRampModeButtonGroupWidget); + #pragma region Debug Section Widget + MenuSectionWidget *debugSectionWidget = new MenuSectionWidget(motorAttributesWidget); + MenuCollapseSection *debugCollapseSection = new MenuCollapseSection("Debug", MenuCollapseSection::MHCW_NONE, debugSectionWidget); + debugSectionWidget->contentLayout()->setSpacing(10); + debugSectionWidget->contentLayout()->addWidget(debugCollapseSection); + + QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", debugSectionWidget); + StyleHelper::MenuSmallLabel(calibrationCycleCountLabel); + QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(debugSectionWidget); + applyLineEditStyle(calibrationCycleCountLineEdit); + calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); + connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount); + + QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", debugSectionWidget); + StyleHelper::MenuSmallLabel(calibrationSamplesPerCycleLabel); + QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(debugSectionWidget); + applyLineEditStyle(calibrationSamplesPerCycleLineEdit); + calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); + connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle); + + QPushButton *addCalibrationDataButton = new QPushButton(debugSectionWidget); + addCalibrationDataButton->setText("Add Data"); + StyleHelper::BlueButton(addCalibrationDataButton, "addCalibrationDataButton"); + + QPushButton *removeLastCalibrationDataButton = new QPushButton(debugSectionWidget); + removeLastCalibrationDataButton->setText("Remove Last Data"); + StyleHelper::BlueButton(removeLastCalibrationDataButton, "removeLastCalibrationDataButton"); + + QPushButton *calibrateDataButton = new QPushButton(debugSectionWidget); + calibrateDataButton->setText("Calibrate"); + StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); + + QPushButton *clearCalibrateDataButton = new QPushButton(debugSectionWidget); + clearCalibrateDataButton->setText("Clear All Data"); + StyleHelper::BlueButton(clearCalibrateDataButton, "clearCalibrateDataButton"); + + debugCollapseSection->contentLayout()->setSpacing(10); + debugCollapseSection->contentLayout()->addWidget(calibrationCycleCountLabel); + debugCollapseSection->contentLayout()->addWidget(calibrationCycleCountLineEdit); + debugCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleLabel); + debugCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleLineEdit); + debugCollapseSection->contentLayout()->addWidget(addCalibrationDataButton); + debugCollapseSection->contentLayout()->addWidget(removeLastCalibrationDataButton); + debugCollapseSection->contentLayout()->addWidget(calibrateDataButton); + debugCollapseSection->contentLayout()->addWidget(clearCalibrateDataButton); + #pragma endregion + + amaxCollapseSection->header()->setChecked(false); + rotateVmaxCollapseSection->header()->setChecked(false); + dmaxCollapseSection->header()->setChecked(false); + disableCollapseSection->header()->setChecked(false); + targetPosCollapseSection->header()->setChecked(false); + currentPosCollapseSection->header()->setChecked(false); + rampModeCollapseSection->header()->setChecked(false); + motorAttributesLayout->setMargin(0); motorAttributesLayout->setSpacing(10); + motorAttributesLayout->addWidget(debugSectionWidget); motorAttributesLayout->addWidget(amaxSectionWidget); motorAttributesLayout->addWidget(rotateVmaxSectionWidget); motorAttributesLayout->addWidget(dmaxSectionWidget); @@ -757,17 +646,45 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataGraphLayout->addWidget(calibrationRawDataGraphLabel); calibrationRawDataGraphLayout->addWidget(calibrationRawDataPlotWidget); - // QWidget *calibrationFFTDataGraphWidget = new QWidget(calibrationDataGraphWidget); - // QVBoxLayout *calibrationFFTDataGraphLayout = new QVBoxLayout(calibrationFFTDataGraphWidget); - // calibrationFFTDataGraphWidget->setLayout(calibrationFFTDataGraphLayout); - // calibrationFFTDataGraphLayout->setMargin(0); - // calibrationFFTDataGraphLayout->setSpacing(4); - // QLabel *calibrationFFTDataGraphLabel = new QLabel("FFT Data", calibrationFFTDataGraphWidget); - // StyleHelper::MenuCollapseHeaderLabel(calibrationFFTDataGraphLabel, "calibrationFFTDataGraphLabel"); - // PlotWidget *calibrationFFTDataPlotWidget = new PlotWidget(); + QWidget *calibrationFFTDataGraphWidget = new QWidget(calibrationDataGraphWidget); + QVBoxLayout *calibrationFFTDataGraphLayout = new QVBoxLayout(calibrationFFTDataGraphWidget); + calibrationFFTDataGraphWidget->setLayout(calibrationFFTDataGraphLayout); + calibrationFFTDataGraphLayout->setMargin(0); + calibrationFFTDataGraphLayout->setSpacing(4); + QLabel *calibrationFFTDataGraphLabel = new QLabel("FFT Data", calibrationFFTDataGraphWidget); + StyleHelper::MenuCollapseHeaderLabel(calibrationFFTDataGraphLabel, "calibrationFFTDataGraphLabel"); + + // FFT Plot + calibrationFFTDataPlotWidget = new PlotWidget(); + calibrationFFTDataPlotWidget->xAxis()->setVisible(false); + calibrationFFTDataPlotWidget->yAxis()->setVisible(false); + QPen calibrationFFTPen = QPen(StyleHelper::getColor("ScopyBlue")); + QPen calibrationFFTPhasePen = QPen(StyleHelper::getColor("CH0")); + + calibrationFFTXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationFFTDataPlotWidget, calibrationFFTPen); + calibrationFFTYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationFFTDataPlotWidget, calibrationFFTPen); + calibrationFFTYPlotAxis->setInterval(-10, 10); + + calibrationFFTPlotChannel = new PlotChannel("FFT", calibrationFFTPen, calibrationFFTXPlotAxis, calibrationFFTYPlotAxis); + calibrationFFTPhasePlotChannel = new PlotChannel("FFT Phase", calibrationFFTPhasePen, calibrationFFTXPlotAxis, calibrationFFTYPlotAxis); + calibrationFFTDataPlotWidget->addPlotChannel(calibrationFFTPlotChannel); + calibrationFFTDataPlotWidget->addPlotChannel(calibrationFFTPhasePlotChannel); + + calibrationFFTPlotChannel->setEnabled(true); + calibrationFFTPhasePlotChannel->setEnabled(true); + calibrationFFTDataPlotWidget->selectChannel(calibrationFFTPlotChannel); + calibrationFFTDataPlotWidget->replot(); + + // calibrationFFTPlotChannel->xAxis()->plot()->setAxisTitle(QwtAxis::XBottom, "Frequency (Hz)"); + // calibrationFFTPlotChannel->yAxis()->plot()->setAxisTitle(QwtAxis::YLeft, "Magnitude"); + + calibrationFFTDataPlotWidget->setShowXAxisLabels(true); + calibrationFFTDataPlotWidget->setShowYAxisLabels(true); + calibrationFFTDataPlotWidget->showAxisLabels(); + // calibrationFFTDataPlotWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - // calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataGraphLabel); - // calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataPlotWidget); + calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataGraphLabel); + calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataPlotWidget); #pragma region Raw Data Section Widget QWidget *rawDataContainerWidget = new QWidget(calibrationDataGraphWidget); @@ -804,7 +721,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma endregion calibrationDataGraphLayout->addWidget(calibrationRawDataGraphWidget); - // calibrationDataGraphLayout->addWidget(calibrationFFTDataGraphWidget); + calibrationDataGraphLayout->addWidget(calibrationFFTDataGraphWidget); calibrationDataGraphLayout->addWidget(rawDataContainerWidget); #pragma endregion @@ -831,9 +748,10 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDisplayFormatSwitch->setOffText("Hex"); calibrationDisplayFormatSwitch->setOnText("Angle"); calibrationDisplayFormatSwitch->setProperty("bigBtn", true); - QPushButton *applyCalibrationDataButton = new QPushButton(calibrationCoeffSectionWidget); + applyCalibrationDataButton = new QPushButton(calibrationCoeffSectionWidget); applyCalibrationDataButton->setText("Apply"); StyleHelper::BlueButton(applyCalibrationDataButton, "applyCalibrationDataButton"); + applyCalibrationDataButton->setEnabled(false); // Calculated Coefficients Widget QWidget *calibrationCalculatedCoeffWidget = new QWidget(calibrationCoeffSectionWidget); @@ -977,20 +895,19 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() MenuCollapseSection *motorConfigurationCollapseSection = new MenuCollapseSection("Motor Configuration", MenuCollapseSection::MHCW_NONE, motorConfigurationSectionWidget); motorConfigurationSectionWidget->contentLayout()->addWidget(motorConfigurationCollapseSection); - HorizontalSpinBox *motorMaxAccelerationSpinBox = new HorizontalSpinBox("Max Acceleration", 9999.99, "", motorConfigurationSectionWidget); - HorizontalSpinBox *motorMaxVelocitySpinBox = new HorizontalSpinBox("Max Velocity", 9999.99, "rpm", motorConfigurationSectionWidget); - HorizontalSpinBox *motorMaxDisplacementSpinBox = new HorizontalSpinBox("Max Displacement", 9999.99, "", motorConfigurationSectionWidget); + HorizontalSpinBox *motorMaxVelocitySpinBox = new HorizontalSpinBox("Max Velocity", convertVMAXtoRPS(rotate_vmax), "rps", motorConfigurationSectionWidget); + HorizontalSpinBox *motorAccelTimeSpinBox = new HorizontalSpinBox("Acceleration Time", convertAMAXtoAccelTime(amax), "sec", motorConfigurationSectionWidget); + HorizontalSpinBox *motorMaxDisplacementSpinBox = new HorizontalSpinBox("Max Displacement", dmax, "", motorConfigurationSectionWidget); MenuCombo *m_calibrationMotorRampModeMenuCombo = new MenuCombo("Ramp Mode", motorConfigurationSectionWidget); auto calibrationMotorRampModeCombo = m_calibrationMotorRampModeMenuCombo->combo(); - calibrationMotorRampModeCombo->addItem("Position", QVariant::fromValue(reinterpret_cast(const_cast(rotationChannelName)))); - calibrationMotorRampModeCombo->addItem("Angle", QVariant::fromValue(reinterpret_cast(const_cast(angleChannelName)))); - calibrationMotorRampModeCombo->addItem("Count", QVariant::fromValue(reinterpret_cast(const_cast(countChannelName)))); + calibrationMotorRampModeCombo->addItem("Position", QVariant(ADMTController::MotorRampMode::POSITION)); + calibrationMotorRampModeCombo->addItem("Ramp Mode 1", QVariant(ADMTController::MotorRampMode::RAMP_MODE_1)); applyComboBoxStyle(calibrationMotorRampModeCombo); motorConfigurationCollapseSection->contentLayout()->setSpacing(10); - motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxAccelerationSpinBox); motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxVelocitySpinBox); + motorConfigurationCollapseSection->contentLayout()->addWidget(motorAccelTimeSpinBox); motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxDisplacementSpinBox); motorConfigurationCollapseSection->contentLayout()->addWidget(m_calibrationMotorRampModeMenuCombo); #pragma endregion @@ -1002,12 +919,12 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); StyleHelper::MenuSmallLabel(currentPositionLabel, "currentPositionLabel"); - calibrationMotorCurrentPositionLabel = new QLabel("--.--°", motorControlSectionWidget); + calibrationMotorCurrentPositionLabel = new QLabel("--.--", motorControlSectionWidget); calibrationMotorCurrentPositionLabel->setAlignment(Qt::AlignRight); applyLabelStyle(calibrationMotorCurrentPositionLabel); - HorizontalSpinBox *motorTargetPositionSpinBox = new HorizontalSpinBox("Target Position", 9999.99, "°", motorControlSectionWidget); - HorizontalSpinBox *motorVelocitySpinBox = new HorizontalSpinBox("Velocity", 9999.99, "rpm", motorControlSectionWidget); + HorizontalSpinBox *motorTargetPositionSpinBox = new HorizontalSpinBox("Target Position", target_pos, "", motorControlSectionWidget); + // HorizontalSpinBox *motorVelocitySpinBox = new HorizontalSpinBox("Velocity", 9999.99, "rpm", motorControlSectionWidget); calibrationStartMotorButton = new QPushButton(motorControlSectionWidget); calibrationStartMotorButton->setCheckable(true); @@ -1017,7 +934,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationStartMotorButton->setFixedHeight(36); connect(calibrationStartMotorButton, &QPushButton::toggled, this, [=](bool b) { calibrationStartMotorButton->setText(b ? " Stop Motor" : " Start Motor"); + totalSamplesCount = cycleCount * samplesPerCycle; startMotor = b; + if(b){ + motorCalibrationAcquisitionTimer->start(motorCalibrationAcquisitionTimerRate); + } + else{ + motorCalibrationAcquisitionTimer->stop(); + } }); QString calibrationStartMotorButtonStyle = QString(R"css( QPushButton { @@ -1055,46 +979,16 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); motorControlCollapseSection->contentLayout()->addWidget(calibrationMotorCurrentPositionLabel); motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionSpinBox); - motorControlCollapseSection->contentLayout()->addWidget(motorVelocitySpinBox); + // motorControlCollapseSection->contentLayout()->addWidget(motorVelocitySpinBox); motorControlCollapseSection->contentLayout()->addWidget(calibrationStartMotorButton); motorControlCollapseSection->contentLayout()->addWidget(autoCalibrateCheckBox); #pragma endregion - #pragma region Debug Section Widget - MenuSectionWidget *debugSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - MenuCollapseSection *debugCollapseSection = new MenuCollapseSection("Debug", MenuCollapseSection::MHCW_NONE, debugSectionWidget); - debugSectionWidget->contentLayout()->setSpacing(10); - debugSectionWidget->contentLayout()->addWidget(debugCollapseSection); - - QPushButton *addCalibrationDataButton = new QPushButton(debugSectionWidget); - addCalibrationDataButton->setText("Add Data"); - StyleHelper::BlueButton(addCalibrationDataButton, "addCalibrationDataButton"); - - QPushButton *removeLastCalibrationDataButton = new QPushButton(debugSectionWidget); - removeLastCalibrationDataButton->setText("Remove Last Data"); - StyleHelper::BlueButton(removeLastCalibrationDataButton, "removeLastCalibrationDataButton"); - - QPushButton *calibrateDataButton = new QPushButton(debugSectionWidget); - calibrateDataButton->setText("Calibrate"); - StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); - - QPushButton *clearCalibrateDataButton = new QPushButton(debugSectionWidget); - clearCalibrateDataButton->setText("Clear All Data"); - StyleHelper::BlueButton(clearCalibrateDataButton, "clearCalibrateDataButton"); - - debugCollapseSection->contentLayout()->setSpacing(10); - debugCollapseSection->contentLayout()->addWidget(addCalibrationDataButton); - debugCollapseSection->contentLayout()->addWidget(removeLastCalibrationDataButton); - debugCollapseSection->contentLayout()->addWidget(calibrateDataButton); - debugCollapseSection->contentLayout()->addWidget(clearCalibrateDataButton); - #pragma endregion - calibrationSettingsLayout->setMargin(0); calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); calibrationSettingsLayout->addWidget(motorControlSectionWidget); - calibrationSettingsLayout->addWidget(debugSectionWidget); calibrationSettingsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); #pragma endregion @@ -1120,10 +1014,244 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(importDataButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); connect(applyCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::registerCalibrationData); connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::clearRawDataList); + connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); + connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); + connectLineEditToNumber(motorMaxDisplacementSpinBox->lineEdit(), dmax); + connectLineEditToNumber(motorTargetPositionSpinBox->lineEdit(), target_pos); + connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); return tool; } +void HarmonicCalibration::restart() +{ + if(m_running) { + run(false); + run(true); + } +} + +bool HarmonicCalibration::running() const { return m_running; } + +void HarmonicCalibration::setRunning(bool newRunning) +{ + if(m_running == newRunning) + return; + m_running = newRunning; + Q_EMIT runningChanged(newRunning); +} + +void HarmonicCalibration::start() { run(true); } + +void HarmonicCalibration::stop() { run(false); } + +void HarmonicCalibration::run(bool b) +{ + qInfo() << b; + QElapsedTimer tim; + tim.start(); + + if(!b) { + runButton->setChecked(false); + timer->stop(); + } + else{ + timer->start(sampleRate); + } + + updateGeneralSettingEnabled(!b); +} + +void HarmonicCalibration::timerTask(){ + updateChannelValues(); + updateLineEditValues(); + + dataGraph->plot(*dataGraphValue); + tempGraph->plot(temp); +} + +void HarmonicCalibration::updateChannelValues(){ + rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, bufferSize); + angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, bufferSize); + count = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, bufferSize); + temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, bufferSize); +} + +void HarmonicCalibration::updateLineEditValues(){ + rotationValueLabel->setText(QString::number(rotation) + "°"); + angleValueLabel->setText(QString::number(angle) + "°"); + countValueLabel->setText(QString::number(count)); + tempValueLabel->setText(QString::number(temp) + " °C"); +} + +void HarmonicCalibration::updateGeneralSettingEnabled(bool value) +{ + graphUpdateIntervalLineEdit->setEnabled(value); + dataSampleSizeLineEdit->setEnabled(value); + dataGraphSamplesLineEdit->setEnabled(value); + tempGraphSamplesLineEdit->setEnabled(value); +} + +void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable) +{ + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { + bool ok; + int value = lineEdit->text().toInt(&ok); + if (ok) { + variable = value; + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + +void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& variable) +{ + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok) { + variable = value; + + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + +void HarmonicCalibration::connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph) +{ + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, graph]() { + bool ok; + int value = lineEdit->text().toInt(&ok); + if (ok) { + variable = value; + graph->setNumSamples(variable); + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + +void HarmonicCalibration::connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph) +{ + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [combo, graph]() { + int value = qvariant_cast(combo->currentData()); + switch(value) + { + case Sismograph::LEFT_TO_RIGHT: + graph->setPlotDirection(Sismograph::LEFT_TO_RIGHT); + graph->reset(); + break; + case Sismograph::RIGHT_TO_LEFT: + graph->setPlotDirection(Sismograph::RIGHT_TO_LEFT); + graph->reset(); + break; + } + }); +} + +void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, double& variable) +{ + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), [=, &variable]() { + variable = qvariant_cast(combo->currentData()); + }); +} + +void HarmonicCalibration::changeGraphColorByChannelName(Sismograph* graph, const char* channelName) +{ + int index = m_admtController->getChannelIndex(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), channelName); + if(index > -1){ + graph->setColor(StyleHelper::getColor( QString::fromStdString("CH" + std::to_string(index) ))); + } +} + +void HarmonicCalibration::connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph) +{ + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [this, combo, graph]() { + int currentIndex = combo->currentIndex(); + QVariant currentData = combo->currentData(); + char *value = reinterpret_cast(currentData.value()); + switch(currentIndex) + { + case ADMTController::Channel::ROTATION: + dataGraphValue = &rotation; + graph->setUnitOfMeasure("Degree", "°"); + graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); + graph->setNumSamples(dataGraphSamples); + graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); + break; + case ADMTController::Channel::ANGLE: + dataGraphValue = ∠ + graph->setUnitOfMeasure("Degree", "°"); + graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); + graph->setNumSamples(dataGraphSamples); + graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); + break; + case ADMTController::Channel::COUNT: + dataGraphValue = &count; + graph->setUnitOfMeasure("Count", ""); + graph->setAxisScale(QwtAxis::YLeft, -1.0, 20.0); + graph->setNumSamples(dataGraphSamples); + graph->setAxisTitle(QwtAxis::YLeft, tr("Count")); + break; + } + changeGraphColorByChannelName(graph, value); + graph->reset(); + }); +} + +void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax) +{ + connect(lineEdit, &QLineEdit::editingFinished, [=, &vmax]() { + bool ok; + double rps = lineEdit->text().toDouble(&ok); + if (ok) { + vmax = convertRPStoVMAX(rps); + StatusBarManager::pushMessage("Converted VMAX: " + QString::number(vmax)); + } else { + lineEdit->setText(QString::number(convertVMAXtoRPS(vmax))); + } + }); +} + +void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit* lineEdit, double& amax) +{ + connect(lineEdit, &QLineEdit::editingFinished, [=, &amax]() { + bool ok; + double accelTime = lineEdit->text().toDouble(&ok); + if (ok) { + amax = convertAccelTimetoAMAX(accelTime); + StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); + } else { + lineEdit->setText(QString::number(convertAMAXtoAccelTime(amax))); + } + }); +} + +double HarmonicCalibration::convertRPStoVMAX(double rps) +{ + return (rps * motorMicrostepPerRevolution * motorTimeUnit); +} + +double HarmonicCalibration::convertVMAXtoRPS(double vmax) +{ + return (vmax / motorMicrostepPerRevolution / motorTimeUnit); +} + +double HarmonicCalibration::convertAccelTimetoAMAX(double accelTime) +{ + return (rotate_vmax * 131072 / accelTime / motorfCLK); +} + +double HarmonicCalibration::convertAMAXtoAccelTime(double amax) +{ + return ((rotate_vmax * 131072) / (amax * motorfCLK)); +} + void HarmonicCalibration::updateLabelValue(QLabel* label, int channelIndex) { switch(channelIndex) @@ -1162,17 +1290,24 @@ void HarmonicCalibration::updateChannelValue(int channelIndex) } } -void HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute attribute, double *value) +void HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value) { - int result = m_admtController->getDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), m_admtController->getMotorAttribute(attribute), value); + if(!isDebug){ + int result = m_admtController->getDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), + m_admtController->getMotorAttribute(attribute), + &value); + if(result != 0) { calibrationLogWriteLn(QString(m_admtController->getMotorAttribute(attribute)) + ": Read Error " + QString::number(result)); } + } } void HarmonicCalibration::writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value) { - int result = m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), - m_admtController->getMotorAttribute(attribute), - value); - if(result != 0) { calibrationLogWriteLn(QString(m_admtController->getMotorAttribute(attribute)) + ": Write Error " + QString::number(result)); } + if(!isDebug){ + int result = m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), + m_admtController->getMotorAttribute(attribute), + value); + if(result != 0) { calibrationLogWriteLn(QString(m_admtController->getMotorAttribute(attribute)) + ": Write Error " + QString::number(result)); } + } } void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute) @@ -1206,10 +1341,27 @@ void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorA void HarmonicCalibration::calibrationTask() { - updateChannelValue(ADMTController::Channel::ANGLE); - updateLabelValue(calibrationMotorCurrentPositionLabel, ADMTController::Channel::ANGLE); + if(!isDebug){ + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + updateLabelValue(calibrationMotorCurrentPositionLabel, ADMTController::MotorAttribute::CURRENT_POS); + } +} - startMotorAcquisition(); +void HarmonicCalibration::motorCalibrationAcquisitionTask() +{ + if(startMotor && rawDataListWidget->count() < totalSamplesCount){ + stepMotorAcquisition(); + double currentAngle = angle; + calibrationRawDataPlotWidget->plot(currentAngle); + QString dataStr = QString::number(currentAngle); + rawDataListWidget->addItem(dataStr); + rawDataListWidget->scrollToBottom(); + } + else if(rawDataListWidget->count() == totalSamplesCount) + { + startMotor = false; + calibrationStartMotorButton->setChecked(false); + } } void HarmonicCalibration::addAngleToRawDataList() @@ -1237,6 +1389,25 @@ void HarmonicCalibration::calibrateData() calibrationLogWriteLn(m_admtController->calibrate(stdData, cycleCount, samplesPerCycle)); + updateCalculatedCoeff(); + + vector calibrationAngleErrorsFFT = m_admtController->angle_errors_fft; + vector calibrationAngleErrorsFFTPhase = m_admtController->angle_errors_fft_phase; + + // Frequency axis (assuming sampling rate of 1 Hz for simplicity) + std::vector frequencyAxis(calibrationAngleErrorsFFT.size()); + for (size_t i = 0; i < frequencyAxis.size(); ++i) + { + frequencyAxis[i] = i; // Replace with actual frequency values if needed + } + + calibrationFFTPlotChannel->curve()->setSamples(frequencyAxis.data(), calibrationAngleErrorsFFT.data(), (calibrationAngleErrorsFFT.size() / 2)); // divide size by 2 for now, will be half the size + calibrationFFTPhasePlotChannel->curve()->setSamples(frequencyAxis.data(), calibrationAngleErrorsFFTPhase.data(), calibrationAngleErrorsFFTPhase.size()); + calibrationFFTXPlotAxis->setInterval(0, (calibrationAngleErrorsFFT.size() / 2)); // divide size by 2 for now, will be half the size +} + +void HarmonicCalibration::updateCalculatedCoeff() +{ calibrationH1MagLabel->setText(QString::number(m_admtController->HAR_MAG_1) + "°"); calibrationH2MagLabel->setText(QString::number(m_admtController->HAR_MAG_2) + "°"); calibrationH3MagLabel->setText(QString::number(m_admtController->HAR_MAG_3) + "°"); @@ -1245,6 +1416,20 @@ void HarmonicCalibration::calibrateData() calibrationH2PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_2)); calibrationH3PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_3)); calibrationH8PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_8)); + applyCalibrationDataButton->setEnabled(true); +} + +void HarmonicCalibration::resetCalculatedCoeff() +{ + calibrationH1MagLabel->setText("--.--°"); + calibrationH2MagLabel->setText("--.--°"); + calibrationH3MagLabel->setText("--.--°"); + calibrationH8MagLabel->setText("--.--°"); + calibrationH1PhaseLabel->setText("Φ --.--"); + calibrationH2PhaseLabel->setText("Φ --.--"); + calibrationH3PhaseLabel->setText("Φ --.--"); + calibrationH8PhaseLabel->setText("Φ --.--"); + applyCalibrationDataButton->setEnabled(false); } void HarmonicCalibration::registerCalibrationData() @@ -1360,48 +1545,37 @@ void HarmonicCalibration::initializeMotor() { amax = 1200; writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, &amax); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); rotate_vmax = 600000; writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, &rotate_vmax); + readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); dmax = 3000; writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, &dmax); + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); ramp_mode = 0; writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, &ramp_mode); + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); target_pos = 0; writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); + + current_pos = 0; + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); } -void HarmonicCalibration::startMotorAcquisition() +void HarmonicCalibration::stepMotorAcquisition(double step) { - if(startMotor && rawDataListWidget->count() < totalSamplesCount){ - double magNum = 408; - - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, ¤t_pos); - target_pos = current_pos - 408; - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - - while(target_pos != current_pos) { - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, ¤t_pos); - } + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + target_pos = current_pos + step; + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - double currentAngle = angle; - calibrationRawDataPlotWidget->plot(currentAngle); - QString dataStr = QString::number(currentAngle); - rawDataListWidget->addItem(dataStr); - rawDataListWidget->scrollToBottom(); - } - else if(rawDataListWidget->count() == totalSamplesCount) - { - calibrationStartMotorButton->setChecked(false); + while(target_pos != current_pos) { + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); } } @@ -1409,6 +1583,10 @@ void HarmonicCalibration::clearRawDataList() { rawDataListWidget->clear(); calibrationRawDataPlotWidget->reset(); + calibrationFFTPlotChannel->curve()->setData(nullptr); + calibrationFFTPhasePlotChannel->curve()->setData(nullptr); + calibrationFFTDataPlotWidget->replot(); + resetCalculatedCoeff(); } void HarmonicCalibration::applyLineEditStyle(QLineEdit *widget) diff --git a/plugins/admt/src/widgets/horizontalspinbox.cpp b/plugins/admt/src/widgets/horizontalspinbox.cpp index a21baa21f4..0b7e8d9209 100644 --- a/plugins/admt/src/widgets/horizontalspinbox.cpp +++ b/plugins/admt/src/widgets/horizontalspinbox.cpp @@ -25,8 +25,8 @@ HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, QStrin controlLayout->setMargin(0); controlLayout->setSpacing(2); - lineEdit = new QLineEdit(controlWidget); - applyLineEditStyle(lineEdit); + m_lineEdit = new QLineEdit(controlWidget); + applyLineEditStyle(m_lineEdit); if(QString::compare(m_unit, "") != 0) { QWidget *lineEditContainer = new QWidget(controlWidget); @@ -38,14 +38,14 @@ HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, QStrin QLabel *unitLabel = new QLabel(m_unit, controlWidget); applyUnitLabelStyle(unitLabel); - lineEdit->setTextMargins(12, 4, 0, 4); + m_lineEdit->setTextMargins(12, 4, 0, 4); - lineEditLayout->addWidget(lineEdit); + lineEditLayout->addWidget(m_lineEdit); lineEditLayout->addWidget(unitLabel); controlLayout->addWidget(lineEditContainer); } else{ - controlLayout->addWidget(lineEdit); + controlLayout->addWidget(m_lineEdit); } QPushButton *minusButton = new QPushButton(controlWidget); @@ -62,7 +62,7 @@ HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, QStrin container->addWidget(controlWidget); setValue(m_value); - connect(lineEdit, SIGNAL(editingFinished()), SLOT(onLineEditTextEdited())); + connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(onLineEditTextEdited())); connect(minusButton, SIGNAL(clicked()), SLOT(onMinusButtonPressed())); connect(plusButton, SIGNAL(clicked()), SLOT(onPlusButtonPressed())); } @@ -71,12 +71,14 @@ void HorizontalSpinBox::onMinusButtonPressed() { m_value--; setValue(m_value); + Q_EMIT m_lineEdit->editingFinished(); } void HorizontalSpinBox::onPlusButtonPressed() { m_value++; setValue(m_value); + Q_EMIT m_lineEdit->editingFinished(); } void HorizontalSpinBox::onLineEditTextEdited() @@ -92,7 +94,7 @@ void HorizontalSpinBox::onLineEditTextEdited() void HorizontalSpinBox::setValue(double value) { - lineEdit->setText(QString::number(value)); + m_lineEdit->setText(QString::number(value)); } void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) @@ -154,4 +156,6 @@ void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget) widget->setFixedHeight(30); widget->setAlignment(Qt::AlignRight); widget->setContentsMargins(0, 4, 12, 4); -} \ No newline at end of file +} + +QLineEdit *HorizontalSpinBox::lineEdit() { return m_lineEdit; } \ No newline at end of file From d4ea2c863c23cd9dcac398b5e02c915b720af4d2 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 15 Aug 2024 14:39:21 +0800 Subject: [PATCH 017/112] admt: Added read device registry Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 1 + plugins/admt/src/admtcontroller.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 836efb078a..4d0b56f2dc 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -86,6 +86,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject int setDeviceAttributeValue(const char *deviceName, const char *attributeName, double writeValue); QString calibrate(vector PANG, int cycles = 11, int samplesPerCycle = 256); int writeDeviceRegistry(const char *deviceName, uint32_t address, double value); + int readDeviceRegistry(const char *deviceName, uint32_t address, double& readValue); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 78323396b5..27c977b72b 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -257,6 +257,18 @@ int ADMTController::writeDeviceRegistry(const char *deviceName, uint32_t address return result; } +int ADMTController::readDeviceRegistry(const char *deviceName, uint32_t address, double& readValue) +{ + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount == 0) { return result; } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) { return result; } + result = iio_device_reg_read(iioDevice, address, reinterpret_cast(&readValue)); + + return result; +} + /* bit reversal from online example */ unsigned int ADMTController::bitReverse(unsigned int x, int log2n) { int n = 0; From 96a2d40a274e231fee5a608c450946d2768cf244 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 29 Aug 2024 14:47:33 +0800 Subject: [PATCH 018/112] admt: Removed raw motor controls - Added tabs for raw and calibrated graphs - Converted real-world values to motor values and vice versa - Moved raw data list to static vector Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 20 +- plugins/admt/src/harmoniccalibration.cpp | 650 ++++++------------ 2 files changed, 227 insertions(+), 443 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 683a86e30d..0b5c36d8f3 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -56,8 +57,10 @@ public Q_SLOTS: void start(); void restart(); void timerTask(); + void canCalibrate(bool); Q_SIGNALS: void runningChanged(bool); + void canCalibrateChanged(bool); private: ADMTController *m_admtController; iio_context *m_ctx; @@ -69,7 +72,7 @@ public Q_SLOTS: double rotation, angle, count, temp, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode; - QPushButton *openLastMenuButton, *calibrationStartMotorButton, *applyCalibrationDataButton; + QPushButton *openLastMenuButton, *calibrationStartMotorButton, *applyCalibrationDataButton, *calibrateDataButton, *extractDataButton; QButtonGroup *rightMenuButtonGroup; QLineEdit *graphUpdateIntervalLineEdit, *dataSampleSizeLineEdit, @@ -92,7 +95,7 @@ public Q_SLOTS: *calibrationH8MagLabel, *calibrationH8PhaseLabel; - Sismograph *dataGraph, *tempGraph, *calibrationRawDataPlotWidget; + Sismograph *dataGraph, *tempGraph, *calibrationRawDataSismograph; MenuHeaderWidget *header; @@ -106,9 +109,13 @@ public Q_SLOTS: QPlainTextEdit *logsPlainTextEdit; - PlotWidget *calibrationFFTDataPlotWidget; - PlotAxis *calibrationFFTXPlotAxis, *calibrationFFTYPlotAxis; - PlotChannel *calibrationFFTPlotChannel, *calibrationFFTPhasePlotChannel; + QCheckBox *autoCalibrateCheckBox; + + PlotWidget *calibrationFFTDataPlotWidget, *calibrationRawDataPlotWidget; + PlotAxis *calibrationFFTXPlotAxis, *calibrationFFTYPlotAxis, *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis; + PlotChannel *calibrationFFTPlotChannel, *calibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel; + + HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, *motorMaxDisplacementSpinBox, *motorTargetPositionSpinBox; void updateChannelValues(); void updateLineEditValues(); @@ -125,7 +132,6 @@ public Q_SLOTS: void updateChannelValue(int channelIndex); void calibrationTask(); void addAngleToRawDataList(); - void removeLastItemFromRawDataList(); void calibrateData(); void registerCalibrationData(); void extractCalibrationData(); @@ -151,6 +157,8 @@ public Q_SLOTS: void updateCalculatedCoeff(); void resetCalculatedCoeff(); void connectMenuComboToNumber(MenuCombo* menuCombo, double& variable); + void appendSamplesToPlotCurve(PlotWidget *plotWidget, QVector& newYData); + void applyTabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor = "ScopyBlue"); QTimer *timer, *calibrationTimer, *motorCalibrationAcquisitionTimer; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index b7687c5fc3..4a6804d6f3 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -18,11 +18,14 @@ static int totalSamplesCount = cycleCount * samplesPerCycle; static bool startMotor = false; static bool isDebug = true; +static bool isCalibrated = false; static double motorTimeUnit = 1.048576; // t = 2^24/16Mhz static int motorMicrostepPerRevolution = 51200; static int motorfCLK = 16000000; // 16Mhz +static bool autoCalibrate = false; + static uint32_t h1MagDeviceRegister = 0x15; static uint32_t h2MagDeviceRegister = 0x17; static uint32_t h3MagDeviceRegister = 0x19; @@ -32,6 +35,8 @@ static uint32_t h2PhaseDeviceRegister = 0x18; static uint32_t h3PhaseDeviceRegister = 0x1A; static uint32_t h8PhaseDeviceRegister = 0x1C; +static vector rawDataList; + using namespace scopy; using namespace scopy::admt; using namespace scopy::grutil; @@ -52,12 +57,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg lay->setMargin(0); tabWidget = new QTabWidget(this); tabWidget->setObjectName("HarmonicTabWidget"); - QString tabStyle = QString("right: 0;"); - tabWidget->tabBar()->setStyleSheet(tabStyle); QString tabWidgetStyle = QString(R"css( - QTabWidget::tab-bar { - alignment: center; - } + QTabWidget::tab-bar { left: 240px; } )css"); tabWidget->tabBar()->setStyleSheet(tabWidgetStyle); tabWidget->addTab(tool, "Acquisition"); @@ -66,10 +67,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg rightMenuButtonGroup = dynamic_cast(openLastMenuButton)->getButtonGroup(); settingsButton = new GearBtn(this); - // infoButton = new InfoBtn(this); - - // lay->insertWidget(0, infoButton); - lay->insertWidget(1, tabWidget); runButton = new RunBtn(this); @@ -286,7 +283,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg tool->openTopContainerHelper(false); tool->addWidgetToTopContainerMenuControlHelper(openLastMenuButton, TTA_RIGHT); tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); - // tool->addWidgetToTopContainerHelper(infoButton, TTA_LEFT); tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); tool->leftStack()->add("rawDataScroll", rawDataScroll); tool->rightStack()->add("generalSettingScroll", generalSettingScroll); @@ -322,303 +318,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() initializeMotor(); ToolTemplate *tool = new ToolTemplate(this); - #pragma region Motor Attributes Widget - QScrollArea *motorAttributesScroll = new QScrollArea(); - QWidget *motorAttributesWidget = new QWidget(); - QVBoxLayout *motorAttributesLayout = new QVBoxLayout(motorAttributesWidget); - motorAttributesScroll->setWidgetResizable(true); - motorAttributesScroll->setWidget(motorAttributesWidget); - motorAttributesWidget->setLayout(motorAttributesLayout); - - // amax - MenuSectionWidget *amaxSectionWidget = new MenuSectionWidget(motorAttributesWidget); - MenuCollapseSection *amaxCollapseSection = new MenuCollapseSection("amax", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, amaxSectionWidget); - amaxSectionWidget->contentLayout()->addWidget(amaxCollapseSection); - motorAmaxValueLabel = new QLabel("-", amaxSectionWidget); - StyleHelper::MenuSmallLabel(motorAmaxValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - updateLabelValue(motorAmaxValueLabel, ADMTController::MotorAttribute::AMAX); - QLineEdit *motorAmaxLineEdit = new QLineEdit(amaxSectionWidget); - applyLineEditStyle(motorAmaxLineEdit); - motorAmaxLineEdit->setText(QString::number(amax)); - connectLineEditToNumber(motorAmaxLineEdit, amax); - QWidget *motorAmaxButtonGroupWidget = new QWidget(amaxSectionWidget); - QHBoxLayout *motorAmaxButtonGroupLayout = new QHBoxLayout(motorAmaxButtonGroupWidget); - motorAmaxButtonGroupWidget->setLayout(motorAmaxButtonGroupLayout); - motorAmaxButtonGroupLayout->setMargin(0); - motorAmaxButtonGroupLayout->setSpacing(10); - QPushButton *readMotorAmaxButton = new QPushButton("Read", motorAmaxButtonGroupWidget); - StyleHelper::BlueButton(readMotorAmaxButton); - connect(readMotorAmaxButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - updateLabelValue(motorAmaxValueLabel, ADMTController::MotorAttribute::AMAX); - }); - QPushButton *writeMotorAmaxButton = new QPushButton("Write", motorAmaxButtonGroupWidget); - StyleHelper::BlueButton(writeMotorAmaxButton); - connect(writeMotorAmaxButton, &QPushButton::pressed, this, [=]{ - writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - updateLabelValue(motorAmaxValueLabel, ADMTController::MotorAttribute::AMAX); - }); - motorAmaxButtonGroupLayout->addWidget(readMotorAmaxButton); - motorAmaxButtonGroupLayout->addWidget(writeMotorAmaxButton); - amaxCollapseSection->contentLayout()->setSpacing(10); - amaxCollapseSection->contentLayout()->addWidget(motorAmaxValueLabel); - amaxCollapseSection->contentLayout()->addWidget(motorAmaxLineEdit); - amaxCollapseSection->contentLayout()->addWidget(motorAmaxButtonGroupWidget); - - //rotate_vmax - MenuSectionWidget *rotateVmaxSectionWidget = new MenuSectionWidget(motorAttributesWidget); - MenuCollapseSection *rotateVmaxCollapseSection = new MenuCollapseSection("rotate_vmax", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, rotateVmaxSectionWidget); - rotateVmaxSectionWidget->contentLayout()->addWidget(rotateVmaxCollapseSection); - motorRotateVmaxValueLabel = new QLabel("-", rotateVmaxSectionWidget); - StyleHelper::MenuSmallLabel(motorRotateVmaxValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - updateLabelValue(motorRotateVmaxValueLabel, ADMTController::MotorAttribute::ROTATE_VMAX); - QLineEdit *motorRotateVmaxLineEdit = new QLineEdit(rotateVmaxSectionWidget); - applyLineEditStyle(motorRotateVmaxLineEdit); - motorRotateVmaxLineEdit->setText(QString::number(rotate_vmax)); - connectLineEditToNumber(motorRotateVmaxLineEdit, rotate_vmax); - QWidget *motorRotateVmaxButtonGroupWidget = new QWidget(rotateVmaxSectionWidget); - QHBoxLayout *motorRotateVmaxButtonGroupLayout = new QHBoxLayout(motorRotateVmaxButtonGroupWidget); - motorRotateVmaxButtonGroupWidget->setLayout(motorRotateVmaxButtonGroupLayout); - motorRotateVmaxButtonGroupLayout->setMargin(0); - motorRotateVmaxButtonGroupLayout->setSpacing(10); - QPushButton *readMotorRotateVmaxButton = new QPushButton("Read", motorRotateVmaxButtonGroupWidget); - StyleHelper::BlueButton(readMotorRotateVmaxButton); - connect(readMotorRotateVmaxButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - updateLabelValue(motorRotateVmaxValueLabel, ADMTController::MotorAttribute::ROTATE_VMAX); - }); - QPushButton *writeMotorRotateVmaxButton = new QPushButton("Write", motorRotateVmaxButtonGroupWidget); - StyleHelper::BlueButton(writeMotorRotateVmaxButton); - connect(writeMotorRotateVmaxButton, &QPushButton::pressed, this, [=]{ - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - updateLabelValue(motorRotateVmaxValueLabel, ADMTController::MotorAttribute::ROTATE_VMAX); - }); - motorRotateVmaxButtonGroupLayout->addWidget(readMotorRotateVmaxButton); - motorRotateVmaxButtonGroupLayout->addWidget(writeMotorRotateVmaxButton); - rotateVmaxCollapseSection->contentLayout()->setSpacing(10); - rotateVmaxCollapseSection->contentLayout()->addWidget(motorRotateVmaxValueLabel); - rotateVmaxCollapseSection->contentLayout()->addWidget(motorRotateVmaxLineEdit); - rotateVmaxCollapseSection->contentLayout()->addWidget(motorRotateVmaxButtonGroupWidget); - - //dmax - MenuSectionWidget *dmaxSectionWidget = new MenuSectionWidget(motorAttributesWidget); - MenuCollapseSection *dmaxCollapseSection = new MenuCollapseSection("dmax", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, dmaxSectionWidget); - dmaxSectionWidget->contentLayout()->addWidget(dmaxCollapseSection); - motorDmaxValueLabel = new QLabel("-", dmaxSectionWidget); - StyleHelper::MenuSmallLabel(motorDmaxValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - updateLabelValue(motorDmaxValueLabel, ADMTController::MotorAttribute::DMAX); - QLineEdit *motorDmaxLineEdit = new QLineEdit(dmaxSectionWidget); - applyLineEditStyle(motorDmaxLineEdit); - motorDmaxLineEdit->setText(QString::number(dmax)); - connectLineEditToNumber(motorDmaxLineEdit, dmax); - QWidget *motorDmaxButtonGroupWidget = new QWidget(dmaxSectionWidget); - QHBoxLayout *motorDmaxButtonGroupLayout = new QHBoxLayout(motorDmaxButtonGroupWidget); - motorDmaxButtonGroupWidget->setLayout(motorDmaxButtonGroupLayout); - motorDmaxButtonGroupLayout->setMargin(0); - motorDmaxButtonGroupLayout->setSpacing(10); - QPushButton *readMotorDmaxButton = new QPushButton("Read", motorDmaxButtonGroupWidget); - StyleHelper::BlueButton(readMotorDmaxButton); - connect(readMotorDmaxButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - updateLabelValue(motorDmaxValueLabel, ADMTController::MotorAttribute::DMAX); - }); - QPushButton *writeMotorDmaxButton = new QPushButton("Write", motorDmaxButtonGroupWidget); - StyleHelper::BlueButton(writeMotorDmaxButton); - connect(writeMotorDmaxButton, &QPushButton::pressed, this, [=]{ - writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - updateLabelValue(motorDmaxValueLabel, ADMTController::MotorAttribute::DMAX); - }); - motorDmaxButtonGroupLayout->addWidget(readMotorDmaxButton); - motorDmaxButtonGroupLayout->addWidget(writeMotorDmaxButton); - dmaxCollapseSection->contentLayout()->setSpacing(10); - dmaxCollapseSection->contentLayout()->addWidget(motorDmaxValueLabel); - dmaxCollapseSection->contentLayout()->addWidget(motorDmaxLineEdit); - dmaxCollapseSection->contentLayout()->addWidget(motorDmaxButtonGroupWidget); - - //disable - MenuSectionWidget *disableSectionWidget = new MenuSectionWidget(motorAttributesWidget); - MenuCollapseSection *disableCollapseSection = new MenuCollapseSection("disable", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, disableSectionWidget); - disableSectionWidget->contentLayout()->addWidget(disableCollapseSection); - QPushButton *writeMotorDisableButton = new QPushButton("Disable", disableSectionWidget); - StyleHelper::BlueButton(writeMotorDisableButton); - connect(writeMotorDisableButton, &QPushButton::pressed, this, [=]{ - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - }); - disableCollapseSection->contentLayout()->setSpacing(10); - disableCollapseSection->contentLayout()->addWidget(writeMotorDisableButton); - - //target_pos - MenuSectionWidget *targetPosSectionWidget = new MenuSectionWidget(motorAttributesWidget); - MenuCollapseSection *targetPosCollapseSection = new MenuCollapseSection("target_pos", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, targetPosSectionWidget); - targetPosSectionWidget->contentLayout()->addWidget(targetPosCollapseSection); - motorTargetPosValueLabel = new QLabel("-", targetPosSectionWidget); - StyleHelper::MenuSmallLabel(motorTargetPosValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - updateLabelValue(motorTargetPosValueLabel, ADMTController::MotorAttribute::TARGET_POS); - QLineEdit *motorTargetPosLineEdit = new QLineEdit(targetPosSectionWidget); - applyLineEditStyle(motorTargetPosLineEdit); - motorTargetPosLineEdit->setText(QString::number(target_pos)); - connectLineEditToNumber(motorTargetPosLineEdit, target_pos); - QWidget *motorTargetPosButtonGroupWidget = new QWidget(targetPosSectionWidget); - QHBoxLayout *motorTargetPosButtonGroupLayout = new QHBoxLayout(motorTargetPosButtonGroupWidget); - motorTargetPosButtonGroupWidget->setLayout(motorTargetPosButtonGroupLayout); - motorTargetPosButtonGroupLayout->setMargin(0); - motorTargetPosButtonGroupLayout->setSpacing(10); - QPushButton *readMotorTargetPosButton = new QPushButton("Read", motorTargetPosButtonGroupWidget); - StyleHelper::BlueButton(readMotorTargetPosButton); - connect(readMotorTargetPosButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - updateLabelValue(motorTargetPosValueLabel, ADMTController::MotorAttribute::TARGET_POS); - }); - QPushButton *writeMotorTargetPosButton = new QPushButton("Write", motorTargetPosButtonGroupWidget); - StyleHelper::BlueButton(writeMotorTargetPosButton); - connect(writeMotorTargetPosButton, &QPushButton::pressed, this, [=]{ - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - readMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - updateLabelValue(motorTargetPosValueLabel, ADMTController::MotorAttribute::TARGET_POS); - }); - motorTargetPosButtonGroupLayout->addWidget(readMotorTargetPosButton); - motorTargetPosButtonGroupLayout->addWidget(writeMotorTargetPosButton); - targetPosCollapseSection->contentLayout()->setSpacing(10); - targetPosCollapseSection->contentLayout()->addWidget(motorTargetPosValueLabel); - targetPosCollapseSection->contentLayout()->addWidget(motorTargetPosLineEdit); - targetPosCollapseSection->contentLayout()->addWidget(motorTargetPosButtonGroupWidget); - - //current_pos - MenuSectionWidget *currentPosSectionWidget = new MenuSectionWidget(motorAttributesWidget); - MenuCollapseSection *currentPosCollapseSection = new MenuCollapseSection("current_pos", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, currentPosSectionWidget); - currentPosSectionWidget->contentLayout()->addWidget(currentPosCollapseSection); - motorCurrentPosValueLabel = new QLabel("-", currentPosSectionWidget); - StyleHelper::MenuSmallLabel(motorCurrentPosValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - updateLabelValue(motorCurrentPosValueLabel, ADMTController::MotorAttribute::CURRENT_POS); - QWidget *motorCurrentPosButtonGroupWidget = new QWidget(currentPosSectionWidget); - QHBoxLayout *motorCurrentPosButtonGroupLayout = new QHBoxLayout(motorCurrentPosButtonGroupWidget); - motorCurrentPosButtonGroupWidget->setLayout(motorCurrentPosButtonGroupLayout); - motorCurrentPosButtonGroupLayout->setMargin(0); - motorCurrentPosButtonGroupLayout->setSpacing(10); - QPushButton *readMotorCurrentPosButton = new QPushButton("Read", motorCurrentPosButtonGroupWidget); - StyleHelper::BlueButton(readMotorCurrentPosButton); - connect(readMotorCurrentPosButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - updateLabelValue(motorCurrentPosValueLabel, ADMTController::MotorAttribute::CURRENT_POS); - }); - motorCurrentPosButtonGroupLayout->addWidget(readMotorCurrentPosButton); - currentPosCollapseSection->contentLayout()->setSpacing(10); - currentPosCollapseSection->contentLayout()->addWidget(motorCurrentPosValueLabel); - currentPosCollapseSection->contentLayout()->addWidget(motorCurrentPosButtonGroupWidget); - - //ramp_mode - MenuSectionWidget *rampModeSectionWidget = new MenuSectionWidget(motorAttributesWidget); - MenuCollapseSection *rampModeCollapseSection = new MenuCollapseSection("ramp_mode", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, rampModeSectionWidget); - rampModeSectionWidget->contentLayout()->addWidget(rampModeCollapseSection); - motorRampModeValueLabel = new QLabel("-", rampModeSectionWidget); - StyleHelper::MenuSmallLabel(motorRampModeValueLabel); - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - updateLabelValue(motorRampModeValueLabel, ADMTController::MotorAttribute::RAMP_MODE); - QLineEdit *motorRampModeLineEdit = new QLineEdit(rampModeSectionWidget); - applyLineEditStyle(motorRampModeLineEdit); - motorRampModeLineEdit->setText(QString::number(ramp_mode)); - connectLineEditToNumber(motorRampModeLineEdit, ramp_mode); - QWidget *motorRampModeButtonGroupWidget = new QWidget(rampModeSectionWidget); - QHBoxLayout *motorRampModeButtonGroupLayout = new QHBoxLayout(motorRampModeButtonGroupWidget); - motorRampModeButtonGroupWidget->setLayout(motorRampModeButtonGroupLayout); - motorRampModeButtonGroupLayout->setMargin(0); - motorRampModeButtonGroupLayout->setSpacing(10); - QPushButton *readMotorRampModeButton = new QPushButton("Read", motorRampModeButtonGroupWidget); - StyleHelper::BlueButton(readMotorRampModeButton); - connect(readMotorRampModeButton, &QPushButton::pressed, this, [=]{ - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - updateLabelValue(motorRampModeValueLabel, ADMTController::MotorAttribute::RAMP_MODE); - }); - QPushButton *writeMotorRampModeButton = new QPushButton("Write", motorRampModeButtonGroupWidget); - StyleHelper::BlueButton(writeMotorRampModeButton); - connect(writeMotorRampModeButton, &QPushButton::pressed, this, [=]{ - writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - updateLabelValue(motorRampModeValueLabel, ADMTController::MotorAttribute::RAMP_MODE); - }); - motorRampModeButtonGroupLayout->addWidget(readMotorRampModeButton); - motorRampModeButtonGroupLayout->addWidget(writeMotorRampModeButton); - rampModeCollapseSection->contentLayout()->setSpacing(10); - rampModeCollapseSection->contentLayout()->addWidget(motorRampModeValueLabel); - rampModeCollapseSection->contentLayout()->addWidget(motorRampModeLineEdit); - rampModeCollapseSection->contentLayout()->addWidget(motorRampModeButtonGroupWidget); - - #pragma region Debug Section Widget - MenuSectionWidget *debugSectionWidget = new MenuSectionWidget(motorAttributesWidget); - MenuCollapseSection *debugCollapseSection = new MenuCollapseSection("Debug", MenuCollapseSection::MHCW_NONE, debugSectionWidget); - debugSectionWidget->contentLayout()->setSpacing(10); - debugSectionWidget->contentLayout()->addWidget(debugCollapseSection); - - QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", debugSectionWidget); - StyleHelper::MenuSmallLabel(calibrationCycleCountLabel); - QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(debugSectionWidget); - applyLineEditStyle(calibrationCycleCountLineEdit); - calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); - connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount); - - QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", debugSectionWidget); - StyleHelper::MenuSmallLabel(calibrationSamplesPerCycleLabel); - QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(debugSectionWidget); - applyLineEditStyle(calibrationSamplesPerCycleLineEdit); - calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); - connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle); - - QPushButton *addCalibrationDataButton = new QPushButton(debugSectionWidget); - addCalibrationDataButton->setText("Add Data"); - StyleHelper::BlueButton(addCalibrationDataButton, "addCalibrationDataButton"); - - QPushButton *removeLastCalibrationDataButton = new QPushButton(debugSectionWidget); - removeLastCalibrationDataButton->setText("Remove Last Data"); - StyleHelper::BlueButton(removeLastCalibrationDataButton, "removeLastCalibrationDataButton"); - - QPushButton *calibrateDataButton = new QPushButton(debugSectionWidget); - calibrateDataButton->setText("Calibrate"); - StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); - - QPushButton *clearCalibrateDataButton = new QPushButton(debugSectionWidget); - clearCalibrateDataButton->setText("Clear All Data"); - StyleHelper::BlueButton(clearCalibrateDataButton, "clearCalibrateDataButton"); - - debugCollapseSection->contentLayout()->setSpacing(10); - debugCollapseSection->contentLayout()->addWidget(calibrationCycleCountLabel); - debugCollapseSection->contentLayout()->addWidget(calibrationCycleCountLineEdit); - debugCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleLabel); - debugCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleLineEdit); - debugCollapseSection->contentLayout()->addWidget(addCalibrationDataButton); - debugCollapseSection->contentLayout()->addWidget(removeLastCalibrationDataButton); - debugCollapseSection->contentLayout()->addWidget(calibrateDataButton); - debugCollapseSection->contentLayout()->addWidget(clearCalibrateDataButton); - #pragma endregion - - amaxCollapseSection->header()->setChecked(false); - rotateVmaxCollapseSection->header()->setChecked(false); - dmaxCollapseSection->header()->setChecked(false); - disableCollapseSection->header()->setChecked(false); - targetPosCollapseSection->header()->setChecked(false); - currentPosCollapseSection->header()->setChecked(false); - rampModeCollapseSection->header()->setChecked(false); - - motorAttributesLayout->setMargin(0); - motorAttributesLayout->setSpacing(10); - motorAttributesLayout->addWidget(debugSectionWidget); - motorAttributesLayout->addWidget(amaxSectionWidget); - motorAttributesLayout->addWidget(rotateVmaxSectionWidget); - motorAttributesLayout->addWidget(dmaxSectionWidget); - motorAttributesLayout->addWidget(disableSectionWidget); - motorAttributesLayout->addWidget(targetPosSectionWidget); - motorAttributesLayout->addWidget(currentPosSectionWidget); - motorAttributesLayout->addWidget(rampModeSectionWidget); - motorAttributesLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); - #pragma endregion - #pragma region Calibration Data Graph Widget QWidget *calibrationDataGraphWidget = new QWidget(); QVBoxLayout *calibrationDataGraphLayout = new QVBoxLayout(calibrationDataGraphWidget); @@ -626,35 +325,46 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDataGraphLayout->setMargin(0); calibrationDataGraphLayout->setSpacing(10); - QWidget *calibrationRawDataGraphWidget = new QWidget(calibrationDataGraphWidget); - QVBoxLayout *calibrationRawDataGraphLayout = new QVBoxLayout(calibrationRawDataGraphWidget); - calibrationRawDataGraphWidget->setLayout(calibrationRawDataGraphLayout); - calibrationRawDataGraphLayout->setMargin(0); - calibrationRawDataGraphLayout->setSpacing(4); - QLabel *calibrationRawDataGraphLabel = new QLabel("Raw Data", calibrationRawDataGraphWidget); - StyleHelper::MenuCollapseHeaderLabel(calibrationRawDataGraphLabel, "calibrationRawDataGraphLabel"); - calibrationRawDataPlotWidget = new Sismograph(); - // PlotWidget *calibrationRawDataPlotWidget = new PlotWidget(); - calibrationRawDataPlotWidget->setColor(StyleHelper::getColor("ScopyBlue")); - calibrationRawDataPlotWidget->setPlotAxisXTitle("Degree (°)"); - calibrationRawDataPlotWidget->setUnitOfMeasure("Degree", "°"); - calibrationRawDataPlotWidget->setAutoscale(false); - calibrationRawDataPlotWidget->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); - calibrationRawDataPlotWidget->setHistoryDuration(120.0); - - calibrationRawDataPlotWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - calibrationRawDataGraphLayout->addWidget(calibrationRawDataGraphLabel); - calibrationRawDataGraphLayout->addWidget(calibrationRawDataPlotWidget); - - QWidget *calibrationFFTDataGraphWidget = new QWidget(calibrationDataGraphWidget); - QVBoxLayout *calibrationFFTDataGraphLayout = new QVBoxLayout(calibrationFFTDataGraphWidget); - calibrationFFTDataGraphWidget->setLayout(calibrationFFTDataGraphLayout); - calibrationFFTDataGraphLayout->setMargin(0); - calibrationFFTDataGraphLayout->setSpacing(4); - QLabel *calibrationFFTDataGraphLabel = new QLabel("FFT Data", calibrationFFTDataGraphWidget); - StyleHelper::MenuCollapseHeaderLabel(calibrationFFTDataGraphLabel, "calibrationFFTDataGraphLabel"); - - // FFT Plot + MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); + QTabWidget *calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); + applyTabWidgetStyle(calibrationDataGraphTabWidget); + calibrationDataGraphSectionWidget->contentLayout()->setSpacing(10); + calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); + + // Raw Data Plot Widget + calibrationRawDataPlotWidget = new PlotWidget(); + QPen calibrationRawDataPen = QPen(StyleHelper::getColor("ScopyBlue")); + calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, calibrationRawDataPen); + calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, calibrationRawDataPen); + calibrationRawDataYPlotAxis->setInterval(0, 360); + calibrationRawDataYPlotAxis->setUnits("°"); + calibrationRawDataYPlotAxis->setDivs(4); + + PrefixFormatter *calibrationRawDataFormatter = new PrefixFormatter({}); + calibrationRawDataFormatter->setTrimZeroes(true); + calibrationRawDataFormatter->setTwoDecimalMode(false); + calibrationRawDataXPlotAxis->setFormatter(calibrationRawDataFormatter); + + calibrationRawDataPlotChannel = new PlotChannel("Raw Data", calibrationRawDataPen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + calibrationRawDataPlotChannel->setStyle(PlotChannel::PCS_DOTS); + calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); + calibrationRawDataPlotChannel->setEnabled(true); + calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); + calibrationRawDataPlotWidget->replot(); + + // Calibrated Plot Widget + PlotWidget *calibrationCalibratedDataPlotWidget = new PlotWidget(); + + calibrationDataGraphTabWidget->addTab(calibrationRawDataPlotWidget, "Raw"); + calibrationDataGraphTabWidget->addTab(calibrationCalibratedDataPlotWidget, "Calibrated"); + + MenuSectionWidget *FFTDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); + QTabWidget *FFTDataGraphTabWidget = new QTabWidget(FFTDataGraphSectionWidget); + applyTabWidgetStyle(FFTDataGraphTabWidget); + FFTDataGraphSectionWidget->contentLayout()->setSpacing(10); + FFTDataGraphSectionWidget->contentLayout()->addWidget(FFTDataGraphTabWidget); + + // FFT Plot Widget calibrationFFTDataPlotWidget = new PlotWidget(); calibrationFFTDataPlotWidget->xAxis()->setVisible(false); calibrationFFTDataPlotWidget->yAxis()->setVisible(false); @@ -663,7 +373,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationFFTXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationFFTDataPlotWidget, calibrationFFTPen); calibrationFFTYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationFFTDataPlotWidget, calibrationFFTPen); - calibrationFFTYPlotAxis->setInterval(-10, 10); + calibrationFFTYPlotAxis->setInterval(-4, 4); calibrationFFTPlotChannel = new PlotChannel("FFT", calibrationFFTPen, calibrationFFTXPlotAxis, calibrationFFTYPlotAxis); calibrationFFTPhasePlotChannel = new PlotChannel("FFT Phase", calibrationFFTPhasePen, calibrationFFTXPlotAxis, calibrationFFTYPlotAxis); @@ -675,54 +385,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationFFTDataPlotWidget->selectChannel(calibrationFFTPlotChannel); calibrationFFTDataPlotWidget->replot(); - // calibrationFFTPlotChannel->xAxis()->plot()->setAxisTitle(QwtAxis::XBottom, "Frequency (Hz)"); - // calibrationFFTPlotChannel->yAxis()->plot()->setAxisTitle(QwtAxis::YLeft, "Magnitude"); - calibrationFFTDataPlotWidget->setShowXAxisLabels(true); calibrationFFTDataPlotWidget->setShowYAxisLabels(true); calibrationFFTDataPlotWidget->showAxisLabels(); - // calibrationFFTDataPlotWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataGraphLabel); - calibrationFFTDataGraphLayout->addWidget(calibrationFFTDataPlotWidget); - - #pragma region Raw Data Section Widget - QWidget *rawDataContainerWidget = new QWidget(calibrationDataGraphWidget); - QHBoxLayout *rawDataContainerLayout = new QHBoxLayout(rawDataContainerWidget); - rawDataContainerWidget->setLayout(rawDataContainerLayout); - - MenuSectionWidget *rawDataWidget = new MenuSectionWidget(rawDataContainerWidget); - MenuCollapseSection *rawDataSection = new MenuCollapseSection("Raw Data", MenuCollapseSection::MHCW_NONE, calibrationDataGraphWidget); - rawDataWidget->contentLayout()->setSpacing(10); - rawDataWidget->contentLayout()->addWidget(rawDataSection); - rawDataSection->contentLayout()->setSpacing(10); - - rawDataListWidget = new QListWidget(rawDataWidget); - rawDataSection->contentLayout()->addWidget(rawDataListWidget); - - #pragma region Logs Section Widget - MenuSectionWidget *logsSectionWidget = new MenuSectionWidget(rawDataContainerWidget); - MenuCollapseSection *logsCollapseSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, logsSectionWidget); - logsSectionWidget->contentLayout()->setSpacing(10); - logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); + FFTDataGraphTabWidget->addTab(calibrationFFTDataPlotWidget, "FFT"); - logsPlainTextEdit = new QPlainTextEdit(logsSectionWidget); - logsPlainTextEdit->setReadOnly(true); - - logsCollapseSection->contentLayout()->setSpacing(10); - logsCollapseSection->contentLayout()->addWidget(logsPlainTextEdit); - #pragma endregion - - rawDataContainerLayout->setMargin(0); - rawDataContainerLayout->setSpacing(10); - rawDataContainerLayout->addWidget(rawDataWidget); - rawDataContainerLayout->addWidget(logsSectionWidget); - - #pragma endregion - - calibrationDataGraphLayout->addWidget(calibrationRawDataGraphWidget); - calibrationDataGraphLayout->addWidget(calibrationFFTDataGraphWidget); - calibrationDataGraphLayout->addWidget(rawDataContainerWidget); + calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget); + calibrationDataGraphLayout->addWidget(FFTDataGraphSectionWidget); #pragma endregion #pragma region Calibration Settings Widget @@ -730,7 +400,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QWidget *calibrationSettingsWidget = new QWidget(calibrationSettingsScrollArea); QVBoxLayout *calibrationSettingsLayout = new QVBoxLayout(calibrationSettingsWidget); calibrationSettingsScrollArea->setWidgetResizable(true); - // calibrationSettingsScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); calibrationSettingsScrollArea->setWidget(calibrationSettingsWidget); calibrationSettingsWidget->setFixedWidth(260); calibrationSettingsWidget->setLayout(calibrationSettingsLayout); @@ -872,22 +541,54 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationCoeffSectionWidget->contentLayout()->addWidget(applyCalibrationDataButton); #pragma endregion + #pragma region Calibration Dataset Configuration + MenuSectionWidget *calibrationDatasetConfigSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + MenuCollapseSection *calibrationDatasetConfigCollapseSection = new MenuCollapseSection("Dataset Configuration", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, calibrationDatasetConfigSectionWidget); + calibrationDatasetConfigSectionWidget->contentLayout()->setSpacing(10); + calibrationDatasetConfigSectionWidget->contentLayout()->addWidget(calibrationDatasetConfigCollapseSection); + + QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", calibrationDatasetConfigCollapseSection); + StyleHelper::MenuSmallLabel(calibrationCycleCountLabel); + QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(calibrationDatasetConfigCollapseSection); + applyLineEditStyle(calibrationCycleCountLineEdit); + calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); + connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount); + + QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", calibrationDatasetConfigCollapseSection); + StyleHelper::MenuSmallLabel(calibrationSamplesPerCycleLabel); + QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationDatasetConfigCollapseSection); + applyLineEditStyle(calibrationSamplesPerCycleLineEdit); + calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); + connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle); + + calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(10); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountLabel); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountLineEdit); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleLabel); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleLineEdit); + + #pragma endregion + #pragma region Calibration Data Section Widget MenuSectionWidget *calibrationDataSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection("Calibration Data", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, calibrationDataSectionWidget); calibrationDataSectionWidget->contentLayout()->setSpacing(10); calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); - QPushButton *extractDataButton = new QPushButton(calibrationDataCollapseSection); - extractDataButton->setText("Extract to CSV"); - StyleHelper::BlueButton(extractDataButton, "extractDataButton"); QPushButton *importDataButton = new QPushButton(calibrationDataCollapseSection); importDataButton->setText("Import from CSV"); StyleHelper::BlueButton(importDataButton, "importDataButton"); + QPushButton *extractDataButton = new QPushButton(calibrationDataCollapseSection); + extractDataButton->setText("Extract to CSV"); + StyleHelper::BlueButton(extractDataButton, "extractDataButton"); + QPushButton *clearCalibrateDataButton = new QPushButton(calibrationDataCollapseSection); + clearCalibrateDataButton->setText("Clear All Data"); + StyleHelper::BlueButton(clearCalibrateDataButton, "clearCalibrateDataButton"); calibrationDataCollapseSection->contentLayout()->setSpacing(10); - calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); calibrationDataCollapseSection->contentLayout()->addWidget(importDataButton); + calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); + calibrationDataCollapseSection->contentLayout()->addWidget(clearCalibrateDataButton); #pragma endregion #pragma region Motor Configuration Section Widget @@ -895,9 +596,9 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() MenuCollapseSection *motorConfigurationCollapseSection = new MenuCollapseSection("Motor Configuration", MenuCollapseSection::MHCW_NONE, motorConfigurationSectionWidget); motorConfigurationSectionWidget->contentLayout()->addWidget(motorConfigurationCollapseSection); - HorizontalSpinBox *motorMaxVelocitySpinBox = new HorizontalSpinBox("Max Velocity", convertVMAXtoRPS(rotate_vmax), "rps", motorConfigurationSectionWidget); - HorizontalSpinBox *motorAccelTimeSpinBox = new HorizontalSpinBox("Acceleration Time", convertAMAXtoAccelTime(amax), "sec", motorConfigurationSectionWidget); - HorizontalSpinBox *motorMaxDisplacementSpinBox = new HorizontalSpinBox("Max Displacement", dmax, "", motorConfigurationSectionWidget); + motorMaxVelocitySpinBox = new HorizontalSpinBox("Max Velocity", convertVMAXtoRPS(rotate_vmax), "rps", motorConfigurationSectionWidget); + motorAccelTimeSpinBox = new HorizontalSpinBox("Acceleration Time", convertAMAXtoAccelTime(amax), "sec", motorConfigurationSectionWidget); + motorMaxDisplacementSpinBox = new HorizontalSpinBox("Max Displacement", dmax, "", motorConfigurationSectionWidget); MenuCombo *m_calibrationMotorRampModeMenuCombo = new MenuCombo("Ramp Mode", motorConfigurationSectionWidget); auto calibrationMotorRampModeCombo = m_calibrationMotorRampModeMenuCombo->combo(); @@ -923,8 +624,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationMotorCurrentPositionLabel->setAlignment(Qt::AlignRight); applyLabelStyle(calibrationMotorCurrentPositionLabel); - HorizontalSpinBox *motorTargetPositionSpinBox = new HorizontalSpinBox("Target Position", target_pos, "", motorControlSectionWidget); - // HorizontalSpinBox *motorVelocitySpinBox = new HorizontalSpinBox("Velocity", 9999.99, "rpm", motorControlSectionWidget); + motorTargetPositionSpinBox = new HorizontalSpinBox("Target Position", target_pos, "", motorControlSectionWidget); calibrationStartMotorButton = new QPushButton(motorControlSectionWidget); calibrationStartMotorButton->setCheckable(true); @@ -972,30 +672,50 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationStartMotorButton->setIcon(playIcon); calibrationStartMotorButton->setIconSize(QSize(64, 64)); - QCheckBox *autoCalibrateCheckBox = new QCheckBox("Auto Calibrate", motorControlSectionWidget); + calibrateDataButton = new QPushButton(motorControlSectionWidget); + calibrateDataButton->setText("Calibrate"); + StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); + + autoCalibrateCheckBox = new QCheckBox("Auto Calibrate", motorControlSectionWidget); StyleHelper::BlueSquareCheckbox(autoCalibrateCheckBox, "autoCalibrateCheckBox"); motorControlCollapseSection->contentLayout()->setSpacing(10); motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); motorControlCollapseSection->contentLayout()->addWidget(calibrationMotorCurrentPositionLabel); motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionSpinBox); - // motorControlCollapseSection->contentLayout()->addWidget(motorVelocitySpinBox); motorControlCollapseSection->contentLayout()->addWidget(calibrationStartMotorButton); + motorControlCollapseSection->contentLayout()->addWidget(calibrateDataButton); motorControlCollapseSection->contentLayout()->addWidget(autoCalibrateCheckBox); #pragma endregion + #pragma region Logs Section Widget + MenuSectionWidget *logsSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + MenuCollapseSection *logsCollapseSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, logsSectionWidget); + logsSectionWidget->contentLayout()->setSpacing(10); + logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); + + logsPlainTextEdit = new QPlainTextEdit(logsSectionWidget); + logsPlainTextEdit->setReadOnly(true); + logsPlainTextEdit->setFixedHeight(320); + + logsCollapseSection->contentLayout()->setSpacing(10); + logsCollapseSection->contentLayout()->addWidget(logsPlainTextEdit); + #pragma endregion + calibrationSettingsLayout->setMargin(0); calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); + calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); calibrationSettingsLayout->addWidget(motorControlSectionWidget); + calibrationSettingsLayout->addWidget(logsSectionWidget); calibrationSettingsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); #pragma endregion tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); tool->topContainer()->setVisible(false); tool->topContainerMenuControl()->setVisible(false); - tool->leftContainer()->setVisible(true); + tool->leftContainer()->setVisible(false); tool->rightContainer()->setVisible(true); tool->bottomContainer()->setVisible(false); tool->setLeftContainerWidth(270); @@ -1003,12 +723,10 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() tool->openBottomContainerHelper(false); tool->openTopContainerHelper(false); - tool->leftStack()->add("motorAttributesScroll", motorAttributesScroll); + // tool->leftStack()->add("motorAttributesScroll", motorAttributesScroll); tool->addWidgetToCentralContainerHelper(calibrationDataGraphWidget); tool->rightStack()->add("calibrationSettingsScrollArea", calibrationSettingsScrollArea); - connect(addCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::addAngleToRawDataList); - connect(removeLastCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::removeLastItemFromRawDataList); connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::calibrateData); connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); connect(importDataButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); @@ -1019,6 +737,10 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connectLineEditToNumber(motorMaxDisplacementSpinBox->lineEdit(), dmax); connectLineEditToNumber(motorTargetPositionSpinBox->lineEdit(), target_pos); connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); + connect(autoCalibrateCheckBox, &QCheckBox::toggled, [=](bool toggled){ + autoCalibrate = toggled; + StatusBarManager::pushMessage(QString("Auto Calibrate: ") + QString((toggled ? "True" : "False"))); + }); return tool; } @@ -1062,6 +784,12 @@ void HarmonicCalibration::run(bool b) updateGeneralSettingEnabled(!b); } +void HarmonicCalibration::canCalibrate(bool value) +{ + calibrateDataButton->setEnabled(value); + +} + void HarmonicCalibration::timerTask(){ updateChannelValues(); updateLineEditValues(); @@ -1212,6 +940,11 @@ void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit* lineEdit, do if (ok) { vmax = convertRPStoVMAX(rps); StatusBarManager::pushMessage("Converted VMAX: " + QString::number(vmax)); + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + amax = convertAccelTimetoAMAX(motorAccelTimeSpinBox->lineEdit()->text().toDouble()); + StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); } else { lineEdit->setText(QString::number(convertVMAXtoRPS(vmax))); } @@ -1349,45 +1082,50 @@ void HarmonicCalibration::calibrationTask() void HarmonicCalibration::motorCalibrationAcquisitionTask() { - if(startMotor && rawDataListWidget->count() < totalSamplesCount){ + if(startMotor && rawDataList.size() < totalSamplesCount){ stepMotorAcquisition(); double currentAngle = angle; - calibrationRawDataPlotWidget->plot(currentAngle); - QString dataStr = QString::number(currentAngle); - rawDataListWidget->addItem(dataStr); - rawDataListWidget->scrollToBottom(); + QVector angles = { currentAngle }; + appendSamplesToPlotCurve(calibrationRawDataPlotWidget, angles); + rawDataList.push_back(currentAngle); } - else if(rawDataListWidget->count() == totalSamplesCount) + else if(rawDataList.size() == totalSamplesCount) { startMotor = false; calibrationStartMotorButton->setChecked(false); } } -void HarmonicCalibration::addAngleToRawDataList() +void HarmonicCalibration::appendSamplesToPlotCurve(PlotWidget *plotWidget, QVector& newYData) { - QString dataStr = QString::number(angle); - rawDataListWidget->addItem(dataStr); + const QwtSeriesData *seriesData = plotWidget->selectedChannel()->curve()->data(); + QVector yData; + + if(seriesData != nullptr){ + for (int i = 0; i < seriesData->size(); ++i) { + calibrationLogWriteLn("append: " + QString::number(seriesData->sample(i).y())); + yData.append(seriesData->sample(i).y()); + } + } + + yData.append(newYData); + calibrationLogWriteLn("yData Size: " + QString::number(yData.size())); + plotWidget->selectedChannel()->curve()->setSamples(yData); + plotWidget->selectedChannel()->xAxis()->setMax(yData.size()); } -void HarmonicCalibration::removeLastItemFromRawDataList(){ - rawDataListWidget->takeItem(rawDataListWidget->count() - 1); +void HarmonicCalibration::addAngleToRawDataList() +{ + QVector angles = { angle }; + appendSamplesToPlotCurve(calibrationRawDataPlotWidget, angles); + rawDataList.push_back(angle); } void HarmonicCalibration::calibrateData() { calibrationLogWrite("==== Calibration Start ====\n"); - QVector rawData; - for (int i = 0; i < rawDataListWidget->count(); ++i) { - QListWidgetItem* item = rawDataListWidget->item(i); - std::string text = item->text().toStdString(); - double value = std::stod(text); - rawData.append(value); - } - std::vector stdData(rawData.begin(), rawData.end()); - - calibrationLogWriteLn(m_admtController->calibrate(stdData, cycleCount, samplesPerCycle)); + calibrationLogWriteLn(m_admtController->calibrate(rawDataList, cycleCount, samplesPerCycle)); updateCalculatedCoeff(); @@ -1496,20 +1234,31 @@ void HarmonicCalibration::extractCalibrationData() FileManager fm("HarmonicCalibration"); fm.open(fileName, FileManager::EXPORT); - QVector rawData; - - for (int i = 0; i < rawDataListWidget->count(); ++i) { - QListWidgetItem* item = rawDataListWidget->item(i); - bool ok; - double value = item->text().toDouble(&ok); - if (ok) { - rawData.append(value); - } else { - // Handle the case where the conversion fails if necessary - } - } - - fm.save(rawData, "RawData"); + QVector rawData(rawDataList.begin(), rawDataList.end()); + + QVector angleErrorsFFT(m_admtController->angle_errors_fft.begin(), m_admtController->angle_errors_fft.end()); + QVector angleErrorsFFTPhase(m_admtController->angle_errors_fft_phase.begin(), m_admtController->angle_errors_fft_phase.end()); + + QVector h1Mag = { static_cast(m_admtController->HAR_MAG_1) }; + QVector h2Mag = { static_cast(m_admtController->HAR_MAG_2) }; + QVector h3Mag = { static_cast(m_admtController->HAR_MAG_3) }; + QVector h8Mag = { static_cast(m_admtController->HAR_MAG_8) }; + QVector h1Phase = { static_cast(m_admtController->HAR_PHASE_1) }; + QVector h2Phase = { static_cast(m_admtController->HAR_PHASE_2) }; + QVector h3Phase = { static_cast(m_admtController->HAR_PHASE_3) }; + QVector h8Phase = { static_cast(m_admtController->HAR_PHASE_8) }; + + fm.save(rawData, "Raw Data"); + fm.save(angleErrorsFFT, "Angle Errors FFT"); + fm.save(angleErrorsFFTPhase, "Angle Errors FFT Phase"); + fm.save(h1Mag, "H1 Mag"); + fm.save(h2Mag, "H2 Mag"); + fm.save(h3Mag, "H3 Mag"); + fm.save(h8Mag, "H8 Mag"); + fm.save(h1Phase, "H1 Phase"); + fm.save(h2Phase, "H2 Phase"); + fm.save(h3Phase, "H3 Phase"); + fm.save(h8Phase, "H8 Phase"); fm.performWrite(withScopyHeader); } @@ -1528,12 +1277,11 @@ void HarmonicCalibration::importCalibrationData() try { fm.open(fileName, FileManager::IMPORT); - rawDataListWidget->clear(); - QVector data = fm.read(0); + calibrationRawDataPlotChannel->curve()->setSamples(data.data(), data.size()); + calibrationRawDataXPlotAxis->setInterval(0, data.size()); for(int i = 0; i < data.size(); ++i) { - QString dataStr = QString::number(data[i]); - rawDataListWidget->addItem(dataStr); + rawDataList.push_back(data[i]); } } catch(FileManagerException &ex) { @@ -1581,11 +1329,15 @@ void HarmonicCalibration::stepMotorAcquisition(double step) void HarmonicCalibration::clearRawDataList() { - rawDataListWidget->clear(); - calibrationRawDataPlotWidget->reset(); + rawDataList.clear(); + + calibrationRawDataPlotChannel->curve()->setData(nullptr); + calibrationRawDataPlotWidget->replot(); + calibrationFFTPlotChannel->curve()->setData(nullptr); calibrationFFTPhasePlotChannel->curve()->setData(nullptr); calibrationFFTDataPlotWidget->replot(); + resetCalculatedCoeff(); } @@ -1692,4 +1444,28 @@ void HarmonicCalibration::applyLabelStyle(QLabel *widget) widget->setStyleSheet(existingStyle + style); widget->setFixedHeight(30); widget->setContentsMargins(12, 4, 12, 4); +} + +void HarmonicCalibration::applyTabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor) +{ + QString style = QString(R"css( + QTabWidget::tab-bar { + left: 5px; /* move to the right by 5px */ + } + QTabBar::tab { + min-width: 100px; + min-height: 32px; + padding-bottom: 5px; + background-color: &&UIElementBackground&&; + font: normal; + } + QTabBar::tab:selected { + color: white; + border-bottom: 2px solid &&ScopyBlue&&; + margin-top: 0px; + } + )css"); + style.replace("&&ScopyBlue&&", StyleHelper::getColor(styleHelperColor)); + style.replace("&&UIElementBackground&&", StyleHelper::getColor("UIElementBackground")); + widget->tabBar()->setStyleSheet(style); } \ No newline at end of file From bebf35ca878306597087224dac1921c8bcd527e5 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 2 Sep 2024 15:26:18 +0800 Subject: [PATCH 019/112] admt: Added registers tab - Fixed calibration graph sizing behavior Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 2 + .../admt/widgets/registerblockwidget.h | 35 +++++ plugins/admt/src/harmoniccalibration.cpp | 133 +++++++++++++++-- .../admt/src/widgets/registerblockwidget.cpp | 134 ++++++++++++++++++ 4 files changed, 292 insertions(+), 12 deletions(-) create mode 100644 plugins/admt/include/admt/widgets/registerblockwidget.h create mode 100644 plugins/admt/src/widgets/registerblockwidget.cpp diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 0b5c36d8f3..0f24d00ccb 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -39,6 +39,7 @@ #include #include #include +#include #include namespace scopy::admt { @@ -127,6 +128,7 @@ public Q_SLOTS: void changeGraphColorByChannelName(Sismograph* graph, const char* channelName); void connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph); ToolTemplate* createCalibrationWidget(); + ToolTemplate* createRegistersWidget(); void updateLabelValue(QLabel* label, int channelIndex); void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); void updateChannelValue(int channelIndex); diff --git a/plugins/admt/include/admt/widgets/registerblockwidget.h b/plugins/admt/include/admt/widgets/registerblockwidget.h new file mode 100644 index 0000000000..06b613f3d9 --- /dev/null +++ b/plugins/admt/include/admt/widgets/registerblockwidget.h @@ -0,0 +1,35 @@ +#ifndef REGISTERBLOCKWIDGET_H +#define REGISTERBLOCKWIDGET_H + +#include "scopy-admt_export.h" + +#include +#include +#include +#include +#include + +#include +#include + +namespace scopy::admt { + class SCOPY_ADMT_EXPORT RegisterBlockWidget : public QWidget + { + Q_OBJECT + public: + enum ACCESS_PERMISSION{ + READ, + WRITE, + READWRITE + }; + + RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t defaultValue, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent = nullptr); + private: + void addReadButton(QWidget *parent); + void addWriteButton(QWidget *parent); + void applyLineEditStyle(QLineEdit *widget); + void applySpinBoxStyle(QSpinBox *widget); + }; +} // namespace scopy::admt + +#endif // REGISTERBLOCKWIDGET_H \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 4a6804d6f3..b75592d26c 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -302,6 +302,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg connect(motorCalibrationAcquisitionTimer, &QTimer::timeout, this, &HarmonicCalibration::motorCalibrationAcquisitionTask); tabWidget->addTab(createCalibrationWidget(), "Calibration"); + tabWidget->addTab(createRegistersWidget(), "Registers"); connect(tabWidget, &QTabWidget::currentChanged, [=](int index){ tabWidget->setCurrentIndex(index); @@ -320,10 +321,10 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Calibration Data Graph Widget QWidget *calibrationDataGraphWidget = new QWidget(); - QVBoxLayout *calibrationDataGraphLayout = new QVBoxLayout(calibrationDataGraphWidget); + QGridLayout *calibrationDataGraphLayout = new QGridLayout(calibrationDataGraphWidget); calibrationDataGraphWidget->setLayout(calibrationDataGraphLayout); calibrationDataGraphLayout->setMargin(0); - calibrationDataGraphLayout->setSpacing(10); + calibrationDataGraphLayout->setSpacing(5); MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); QTabWidget *calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); @@ -333,17 +334,11 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() // Raw Data Plot Widget calibrationRawDataPlotWidget = new PlotWidget(); + calibrationRawDataPlotWidget->setContentsMargins(10, 20, 10, 10); QPen calibrationRawDataPen = QPen(StyleHelper::getColor("ScopyBlue")); calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, calibrationRawDataPen); calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, calibrationRawDataPen); calibrationRawDataYPlotAxis->setInterval(0, 360); - calibrationRawDataYPlotAxis->setUnits("°"); - calibrationRawDataYPlotAxis->setDivs(4); - - PrefixFormatter *calibrationRawDataFormatter = new PrefixFormatter({}); - calibrationRawDataFormatter->setTrimZeroes(true); - calibrationRawDataFormatter->setTwoDecimalMode(false); - calibrationRawDataXPlotAxis->setFormatter(calibrationRawDataFormatter); calibrationRawDataPlotChannel = new PlotChannel("Raw Data", calibrationRawDataPen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); calibrationRawDataPlotChannel->setStyle(PlotChannel::PCS_DOTS); @@ -354,6 +349,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() // Calibrated Plot Widget PlotWidget *calibrationCalibratedDataPlotWidget = new PlotWidget(); + calibrationCalibratedDataPlotWidget->setContentsMargins(10, 20, 10, 10); calibrationDataGraphTabWidget->addTab(calibrationRawDataPlotWidget, "Raw"); calibrationDataGraphTabWidget->addTab(calibrationCalibratedDataPlotWidget, "Calibrated"); @@ -366,6 +362,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() // FFT Plot Widget calibrationFFTDataPlotWidget = new PlotWidget(); + calibrationFFTDataPlotWidget->setContentsMargins(10, 20, 10, 10); calibrationFFTDataPlotWidget->xAxis()->setVisible(false); calibrationFFTDataPlotWidget->yAxis()->setVisible(false); QPen calibrationFFTPen = QPen(StyleHelper::getColor("ScopyBlue")); @@ -391,8 +388,12 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTDataGraphTabWidget->addTab(calibrationFFTDataPlotWidget, "FFT"); - calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget); - calibrationDataGraphLayout->addWidget(FFTDataGraphSectionWidget); + calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget, 0, 0); + calibrationDataGraphLayout->addWidget(FFTDataGraphSectionWidget, 1, 0); + + calibrationDataGraphLayout->setColumnStretch(0, 1); + calibrationDataGraphLayout->setRowStretch(0, 1); + calibrationDataGraphLayout->setRowStretch(1, 1); #pragma endregion #pragma region Calibration Settings Widget @@ -723,7 +724,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() tool->openBottomContainerHelper(false); tool->openTopContainerHelper(false); - // tool->leftStack()->add("motorAttributesScroll", motorAttributesScroll); tool->addWidgetToCentralContainerHelper(calibrationDataGraphWidget); tool->rightStack()->add("calibrationSettingsScrollArea", calibrationSettingsScrollArea); @@ -745,6 +745,115 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() return tool; } +ToolTemplate* HarmonicCalibration::createRegistersWidget() +{ + ToolTemplate *tool = new ToolTemplate(this); + + QScrollArea *registerScrollArea = new QScrollArea(); + QWidget *registerWidget = new QWidget(registerScrollArea); + QVBoxLayout *registerLayout = new QVBoxLayout(registerWidget); + QWidget *registerGridWidget = new QWidget(registerWidget); + QGridLayout *registerGridLayout = new QGridLayout(registerGridWidget); + registerScrollArea->setWidgetResizable(true); + registerScrollArea->setWidget(registerWidget); + registerWidget->setLayout(registerLayout); + registerLayout->setMargin(0); + registerLayout->setSpacing(10); + + registerLayout->addWidget(registerGridWidget); + registerLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + registerGridWidget->setLayout(registerGridLayout); + registerGridLayout->setMargin(0); + registerGridLayout->setSpacing(10); + + RegisterBlockWidget *cnvPageRegisterBlock = new RegisterBlockWidget("CNVPAGE", "Convert Start and Page Select", 0x01, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *absAngleRegisterBlock = new RegisterBlockWidget("ABSANGLE", "Absolute Angle", 0x03, 0xDB00, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *digIORegisterBlock = new RegisterBlockWidget("DIGIO", "Digital Input Output", 0x04, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *angleRegisterBlock = new RegisterBlockWidget("ANGLE", "Angle Register", 0x05, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *faultRegisterBlock = new RegisterBlockWidget("FAULT", "Fault Register", 0x06, 0xFFFF, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *angleSecRegisterBlock = new RegisterBlockWidget("ANGLESEC", "Secondary Angle", 0x08, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *sineRegisterBlock = new RegisterBlockWidget("SINE", "Sine Measurement", 0x10, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *cosineRegisterBlock = new RegisterBlockWidget("COSINE", "Cosine Measurement", 0x11, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *secAnglIRegisterBlock = new RegisterBlockWidget("SECANGLI", "In-phase secondary angle measurement", 0x12, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *secAnglQRegisterBlock = new RegisterBlockWidget("SECANGLQ", "Quadrature phase secondary angle measurement", 0x13, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *radiusRegisterBlock = new RegisterBlockWidget("RADIUS", "Angle measurement radius", 0x18, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *diag1RegisterBlock = new RegisterBlockWidget("DIAG1", "State of the MT reference resistors and AFE fixed input voltage", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *diag2RegisterBlock = new RegisterBlockWidget("DIAG2", "Measurements of two diagnostics resistors of fixed value", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *tmp0RegisterBlock = new RegisterBlockWidget("TMP0", "Primary Temperature Sensor", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *tmp1RegisterBlock = new RegisterBlockWidget("TMP1", "Secondary Temperature Sensor", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *generalRegisterBlock = new RegisterBlockWidget("GENERAL", "General Device Configuration", 0x10, 0x1230, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *digIOEnRegisterBlock = new RegisterBlockWidget("DIGIOEN", "Enable Digital Input/Outputs", 0x12, 0x241B, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *angleCkRegisterBlock = new RegisterBlockWidget("ANGLECK", "Primary vs Secondary Angle Check", 0x13, 0x000F, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *cnvCntRegisterBlock = new RegisterBlockWidget("CNVCNT", "Conversion Count", 0x14, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *h1MagRegisterBlock = new RegisterBlockWidget("H1MAG", "1st Harmonic error magnitude", 0x15, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *h1PhRegisterBlock = new RegisterBlockWidget("H1PH", "1st Harmonic error phase", 0x16, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *h2MagRegisterBlock = new RegisterBlockWidget("H2MAG", "2nd Harmonic error magnitude", 0x17, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *h2PhRegisterBlock = new RegisterBlockWidget("H2PH", "2nd Harmonic error phase", 0x18, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *h3MagRegisterBlock = new RegisterBlockWidget("H3MAG", "3rd Harmonic error magnitude", 0x19, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *h3PhRegisterBlock = new RegisterBlockWidget("H3PH", "3rd Harmonic error phase", 0x1A, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *h8MagRegisterBlock = new RegisterBlockWidget("H8MAG", "8th Harmonic error magnitude", 0x1B, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *h8PhRegisterBlock = new RegisterBlockWidget("H8PH", "8th Harmonic error phase", 0x1C, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *eccDcdeRegisterBlock = new RegisterBlockWidget("ECCDCDE", "Error Correction Codes", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *uniqID0RegisterBlock = new RegisterBlockWidget("UNIQID0", "Unique ID Register 0", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *uniqID1RegisterBlock = new RegisterBlockWidget("UNIQID1", "Unique ID Register 1", 0x1F, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *uniqID2RegisterBlock = new RegisterBlockWidget("UNIQID2", "Unique ID Register 2", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *uniqID3RegisterBlock = new RegisterBlockWidget("UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", 0x21, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *eccDisRegisterBlock = new RegisterBlockWidget("ECCDIS", "Error Correction Code disable", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + + registerGridLayout->addWidget(cnvPageRegisterBlock, 0, 0); + registerGridLayout->addWidget(absAngleRegisterBlock, 0, 1); + registerGridLayout->addWidget(digIORegisterBlock, 0, 2); + registerGridLayout->addWidget(angleRegisterBlock, 0, 3); + registerGridLayout->addWidget(faultRegisterBlock, 0, 4); + registerGridLayout->addWidget(angleSecRegisterBlock, 1, 0); + registerGridLayout->addWidget(sineRegisterBlock, 1, 1); + registerGridLayout->addWidget(cosineRegisterBlock, 1, 2); + registerGridLayout->addWidget(secAnglIRegisterBlock, 1, 3); + registerGridLayout->addWidget(secAnglQRegisterBlock, 1, 4); + registerGridLayout->addWidget(radiusRegisterBlock, 2, 0); + registerGridLayout->addWidget(diag1RegisterBlock, 2, 1); + registerGridLayout->addWidget(diag2RegisterBlock, 2, 2); + registerGridLayout->addWidget(tmp0RegisterBlock, 2, 3); + registerGridLayout->addWidget(tmp1RegisterBlock, 2, 4); + registerGridLayout->addWidget(generalRegisterBlock, 3, 0); + registerGridLayout->addWidget(digIOEnRegisterBlock, 3, 1); + registerGridLayout->addWidget(angleCkRegisterBlock, 3, 2); + registerGridLayout->addWidget(cnvCntRegisterBlock, 3, 3); + registerGridLayout->addWidget(h1MagRegisterBlock, 3, 4); + registerGridLayout->addWidget(h1PhRegisterBlock, 4, 0); + registerGridLayout->addWidget(h2MagRegisterBlock, 4, 1); + registerGridLayout->addWidget(h2PhRegisterBlock, 4, 2); + registerGridLayout->addWidget(h3MagRegisterBlock, 4, 3); + registerGridLayout->addWidget(h3PhRegisterBlock, 4, 4); + registerGridLayout->addWidget(h8MagRegisterBlock, 5, 0); + registerGridLayout->addWidget(h8PhRegisterBlock, 5, 1); + registerGridLayout->addWidget(eccDcdeRegisterBlock, 5, 2); + registerGridLayout->addWidget(uniqID0RegisterBlock, 5, 3); + registerGridLayout->addWidget(uniqID1RegisterBlock, 5, 4); + registerGridLayout->addWidget(uniqID2RegisterBlock, 6, 0); + registerGridLayout->addWidget(uniqID3RegisterBlock, 6, 1); + registerGridLayout->addWidget(eccDisRegisterBlock, 6, 2); + + for(int c=0; c < registerGridLayout->columnCount(); ++c) registerGridLayout->setColumnStretch(c,1); + for(int r=0; r < registerGridLayout->rowCount(); ++r) registerGridLayout->setRowStretch(r,1); + + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(false); + tool->topContainerMenuControl()->setVisible(false); + tool->leftContainer()->setVisible(false); + tool->rightContainer()->setVisible(false); + tool->bottomContainer()->setVisible(false); + tool->setLeftContainerWidth(270); + tool->setRightContainerWidth(270); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + + tool->addWidgetToCentralContainerHelper(registerScrollArea); + + return tool; +} + void HarmonicCalibration::restart() { if(m_running) { diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp new file mode 100644 index 0000000000..4caca0094a --- /dev/null +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -0,0 +1,134 @@ +#include +#include "widgets/registerblockwidget.h" + +using namespace scopy; +using namespace scopy::admt; + +RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t defaultValue, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent) + : QWidget(parent) +{ + QVBoxLayout *container = new QVBoxLayout(this); + setLayout(container); + container->setMargin(0); + container->setSpacing(0); + MenuSectionWidget *menuSectionWidget = new MenuSectionWidget(this); + MenuCollapseSection *menuCollapseSection = new MenuCollapseSection(header, MenuCollapseSection::MHCW_NONE, menuSectionWidget); + menuCollapseSection->contentLayout()->setSpacing(10); + menuSectionWidget->setFixedHeight(180); + menuSectionWidget->contentLayout()->setSpacing(10); + menuSectionWidget->contentLayout()->addWidget(menuCollapseSection); + + QLabel *descriptionLabel = new QLabel(description, menuSectionWidget); + QString labelStyle = QString(R"css( + QLabel { + color: white; + background-color: rgba(255,255,255,0); + font-weight: 500; + font-family: Open Sans; + font-size: 12px; + font-style: normal; + } + QLabel:disabled { + color: grey; + } + )css"); + descriptionLabel->setStyleSheet(labelStyle); + descriptionLabel->setWordWrap(true); + descriptionLabel->setMinimumHeight(24); + descriptionLabel->setAlignment(Qt::AlignTop); + descriptionLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); + + // QLineEdit *lineEdit = new QLineEdit(menuSectionWidget); + // applyLineEditStyle(lineEdit); + + QSpinBox *spinBox = new QSpinBox(menuSectionWidget); + applySpinBoxStyle(spinBox); + spinBox->setDisplayIntegerBase(16); + spinBox->setMinimum(0); + spinBox->setMaximum(INT_MAX); + spinBox->setPrefix("0x"); + spinBox->setValue(defaultValue); + + QWidget *buttonsWidget = new QWidget(menuSectionWidget); + QHBoxLayout *buttonsContainer = new QHBoxLayout(buttonsWidget); + buttonsWidget->setLayout(buttonsContainer); + + buttonsContainer->setMargin(0); + buttonsContainer->setSpacing(10); + switch(accessPermission) + { + case ACCESS_PERMISSION::READWRITE: + addReadButton(buttonsWidget); + addWriteButton(buttonsWidget); + break; + case ACCESS_PERMISSION::WRITE: + addWriteButton(buttonsWidget); + break; + case ACCESS_PERMISSION::READ: + addReadButton(buttonsWidget); + // lineEdit->setReadOnly(true); + spinBox->setReadOnly(true); + break; + } + + menuCollapseSection->contentLayout()->setSpacing(10); + menuCollapseSection->contentLayout()->addWidget(descriptionLabel); + // menuCollapseSection->contentLayout()->addWidget(lineEdit); + menuCollapseSection->contentLayout()->addWidget(spinBox); + menuCollapseSection->contentLayout()->addWidget(buttonsWidget); + + container->addWidget(menuSectionWidget); + container->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Preferred)); +} + +void RegisterBlockWidget::addReadButton(QWidget *parent) +{ + QPushButton *readButton = new QPushButton("Read", parent); + StyleHelper::BlueButton(readButton, "readButton"); + parent->layout()->addWidget(readButton); +} + +void RegisterBlockWidget::addWriteButton(QWidget *parent) +{ + QPushButton *writeButton = new QPushButton("Write", parent); + StyleHelper::BlueButton(writeButton, "writeButton"); + parent->layout()->addWidget(writeButton); +} + +void RegisterBlockWidget::applyLineEditStyle(QLineEdit *widget) +{ + QString style = QString(R"css( + background-color: black; + font-family: Open Sans; + font-size: 16px; + color: &&colorname&&; + border: none; + border-radius: 4px; + qproperty-frame: false; + )css"); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setAlignment(Qt::AlignRight); + widget->setContentsMargins(0, 0, 0, 0); + widget->setTextMargins(6, 4, 6, 4); +} + +void RegisterBlockWidget::applySpinBoxStyle(QSpinBox *widget) +{ + QString style = QString(R"css( + background-color: black; + font-family: Open Sans; + font-size: 16px; + color: &&colorname&&; + border: none; + border-radius: 4px; + font-weight: normal; + )css"); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setAlignment(Qt::AlignRight); + widget->setContentsMargins(12, 4, 12, 4); + widget->setButtonSymbols(widget->ButtonSymbols::NoButtons); +} \ No newline at end of file From 901004c086018479153230d64dd762cebdddd14f Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 5 Sep 2024 12:48:53 +0800 Subject: [PATCH 020/112] admt: Added Sine and Cosine channels to raw calibration graph - Added sequence configuration for acquisition tab - Fixed calibration graph sizing bug - Grouped registers in registry tab - Added utility tab Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 3 +- .../admt/include/admt/harmoniccalibration.h | 4 +- plugins/admt/src/admtcontroller.cpp | 25 +- plugins/admt/src/harmoniccalibration.cpp | 314 ++++++++++++++---- 4 files changed, 282 insertions(+), 64 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 4d0b56f2dc..f1e95648f8 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -32,7 +32,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject int HAR_MAG_1, HAR_MAG_2, HAR_MAG_3, HAR_MAG_8 ,HAR_PHASE_1 ,HAR_PHASE_2 ,HAR_PHASE_3 ,HAR_PHASE_8; - vector angle_errors_fft, angle_errors_fft_phase; + vector angle_errors_fft, angle_errors_fft_phase, calibration_samples_sine, calibration_samples_cosine, calibration_samples_sine_scaled, calibration_samples_cosine_scaled; enum Channel { @@ -87,6 +87,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject QString calibrate(vector PANG, int cycles = 11, int samplesPerCycle = 256); int writeDeviceRegistry(const char *deviceName, uint32_t address, double value); int readDeviceRegistry(const char *deviceName, uint32_t address, double& readValue); + void computeSineCosineOfAngles(const vector& angles); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 0f24d00ccb..bb343a0e7c 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -114,7 +114,7 @@ public Q_SLOTS: PlotWidget *calibrationFFTDataPlotWidget, *calibrationRawDataPlotWidget; PlotAxis *calibrationFFTXPlotAxis, *calibrationFFTYPlotAxis, *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis; - PlotChannel *calibrationFFTPlotChannel, *calibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel; + PlotChannel *calibrationFFTPlotChannel, *calibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel; HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, *motorMaxDisplacementSpinBox, *motorTargetPositionSpinBox; @@ -129,6 +129,7 @@ public Q_SLOTS: void connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph); ToolTemplate* createCalibrationWidget(); ToolTemplate* createRegistersWidget(); + ToolTemplate* createUtilityWidget(); void updateLabelValue(QLabel* label, int channelIndex); void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); void updateChannelValue(int channelIndex); @@ -151,6 +152,7 @@ public Q_SLOTS: void clearRawDataList(); void motorCalibrationAcquisitionTask(); void connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax); + void connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute); double convertRPStoVMAX(double rps); double convertVMAXtoRPS(double vmax); void connectLineEditToAMAXConversion(QLineEdit* lineEdit, double& amax); diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 27c977b72b..e73d6c6dad 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -615,4 +615,27 @@ QString ADMTController::calibrate(vector PANG, int cycles, int samplesPe // cout << "Hello World" << "\n"; return result; -} \ No newline at end of file +} + +void ADMTController::computeSineCosineOfAngles(const vector& angles) { + // Vectors to store sine and cosine values + calibration_samples_sine = vector(angles.size()); + calibration_samples_cosine = vector(angles.size()); + calibration_samples_sine_scaled = vector(angles.size()); + calibration_samples_cosine_scaled = vector(angles.size()); + + const double scaleMin = 0.0; + const double scaleMax = 360.0; + + // Convert angles to radians and compute sine, cosine, and their scaled versions + for (size_t i = 0; i < angles.size(); ++i) { + double radians = angles[i] * M_PI / 180.0; // Convert degrees to radians + calibration_samples_sine[i] = sin(radians); + calibration_samples_cosine[i] = cos(radians); + + // Scale sine and cosine to the range 0 to 360 + calibration_samples_sine_scaled[i] = ((calibration_samples_sine[i] + 1) / 2) * (scaleMax - scaleMin) + scaleMin; + calibration_samples_cosine_scaled[i] = ((calibration_samples_cosine[i] + 1) / 2) * (scaleMax - scaleMin) + scaleMin; + } +} + diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index b75592d26c..91b4b4286b 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -5,7 +5,7 @@ static int sampleRate = 50; static int calibrationTimerRate = 100; -static int motorCalibrationAcquisitionTimerRate = 5; +static int motorCalibrationAcquisitionTimerRate = 20; static int bufferSize = 1; static int dataGraphSamples = 100; static int tempGraphSamples = 100; @@ -210,6 +210,57 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg generalSection->contentLayout()->addWidget(dataSampleSizeLabel); generalSection->contentLayout()->addWidget(dataSampleSizeLineEdit); + MenuSectionWidget *sequenceWidget = new MenuSectionWidget(generalSettingWidget); + MenuCollapseSection *sequenceSection = new MenuCollapseSection("Sequence", MenuCollapseSection::MHCW_NONE, sequenceWidget); + sequenceWidget->contentLayout()->addWidget(sequenceSection); + sequenceSection->contentLayout()->setSpacing(10); + + MenuCombo *sequenceTypeMenuCombo = new MenuCombo("Sequence Type", sequenceSection); + QComboBox *sequenceTypeComboBox = sequenceTypeMenuCombo->combo(); + sequenceTypeComboBox->addItem("Mode 1", QVariant(0)); + sequenceTypeComboBox->addItem("Mode 2", QVariant(1)); + sequenceTypeComboBox->setCurrentIndex(1); + applyComboBoxStyle(sequenceTypeComboBox); + + MenuCombo *conversionTypeMenuCombo = new MenuCombo("Conversion Type", sequenceSection); + QComboBox *conversionTypeComboBox = conversionTypeMenuCombo->combo(); + conversionTypeComboBox->addItem("Continuous", QVariant(0)); + conversionTypeComboBox->addItem("One Shot", QVariant(1)); + applyComboBoxStyle(conversionTypeComboBox); + + MenuCombo *cnvSourceMenuCombo = new MenuCombo("CNV Source", sequenceSection); + QComboBox *cnvSourceComboBox = cnvSourceMenuCombo->combo(); + cnvSourceComboBox->addItem("External", QVariant(0)); + cnvSourceComboBox->addItem("Software", QVariant(1)); + applyComboBoxStyle(cnvSourceComboBox); + + MenuCombo *convertSynchronizationMenuCombo = new MenuCombo("Convert Synchronization", sequenceSection); + QComboBox *convertSynchronizationComboBox = convertSynchronizationMenuCombo->combo(); + convertSynchronizationComboBox->addItem("Enabled", QVariant(0)); + convertSynchronizationComboBox->addItem("Disabled", QVariant(1)); + convertSynchronizationComboBox->setCurrentIndex(1); + applyComboBoxStyle(convertSynchronizationComboBox); + + MenuCombo *angleFilterMenuCombo = new MenuCombo("Angle Filter", sequenceSection); + QComboBox *angleFilterComboBox = angleFilterMenuCombo->combo(); + angleFilterComboBox->addItem("Enabled", QVariant(0)); + angleFilterComboBox->addItem("Disabled", QVariant(1)); + angleFilterComboBox->setCurrentIndex(1); + applyComboBoxStyle(angleFilterComboBox); + + MenuCombo *eighthHarmonicMenuCombo = new MenuCombo("8th Harmonic", sequenceSection); + QComboBox *eighthHarmonicComboBox = eighthHarmonicMenuCombo->combo(); + eighthHarmonicComboBox->addItem("Factory Set", QVariant(0)); + eighthHarmonicComboBox->addItem("User", QVariant(1)); + applyComboBoxStyle(eighthHarmonicComboBox); + + sequenceSection->contentLayout()->addWidget(sequenceTypeMenuCombo); + sequenceSection->contentLayout()->addWidget(conversionTypeMenuCombo); + sequenceSection->contentLayout()->addWidget(cnvSourceMenuCombo); + sequenceSection->contentLayout()->addWidget(convertSynchronizationMenuCombo); + sequenceSection->contentLayout()->addWidget(angleFilterMenuCombo); + sequenceSection->contentLayout()->addWidget(eighthHarmonicMenuCombo); + // Data Graph Setting Widget MenuSectionWidget *dataGraphWidget = new MenuSectionWidget(generalSettingWidget); dataGraphWidget->contentLayout()->setSpacing(10); @@ -266,6 +317,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg generalSettingLayout->addWidget(header); generalSettingLayout->addSpacerItem(new QSpacerItem(0, 3, QSizePolicy::Fixed, QSizePolicy::Fixed)); generalSettingLayout->addWidget(generalWidget); + generalSettingLayout->addWidget(sequenceWidget); generalSettingLayout->addWidget(dataGraphWidget); generalSettingLayout->addWidget(tempGraphWidget); generalSettingLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); @@ -302,6 +354,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg connect(motorCalibrationAcquisitionTimer, &QTimer::timeout, this, &HarmonicCalibration::motorCalibrationAcquisitionTask); tabWidget->addTab(createCalibrationWidget(), "Calibration"); + tabWidget->addTab(createUtilityWidget(), "Utility"); tabWidget->addTab(createRegistersWidget(), "Registers"); connect(tabWidget, &QTabWidget::currentChanged, [=](int index){ @@ -330,29 +383,47 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QTabWidget *calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); applyTabWidgetStyle(calibrationDataGraphTabWidget); calibrationDataGraphSectionWidget->contentLayout()->setSpacing(10); - calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); // Raw Data Plot Widget calibrationRawDataPlotWidget = new PlotWidget(); calibrationRawDataPlotWidget->setContentsMargins(10, 20, 10, 10); + calibrationRawDataPlotWidget->xAxis()->setVisible(false); + calibrationRawDataPlotWidget->yAxis()->setVisible(false); QPen calibrationRawDataPen = QPen(StyleHelper::getColor("ScopyBlue")); + QPen calibrationSineDataPen = QPen(StyleHelper::getColor("CH0")); + calibrationSineDataPen.color().setAlphaF(0.1); + QPen calibrationCosineDataPen = QPen(StyleHelper::getColor("CH1")); + calibrationCosineDataPen.color().setAlphaF(0.1); + calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, calibrationRawDataPen); calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, calibrationRawDataPen); - calibrationRawDataYPlotAxis->setInterval(0, 360); + calibrationRawDataYPlotAxis->setInterval(0, 400); + + calibrationRawDataPlotChannel = new PlotChannel("Samples", calibrationRawDataPen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + calibrationSineDataPlotChannel = new PlotChannel("Sine", calibrationSineDataPen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + calibrationCosineDataPlotChannel = new PlotChannel("Cosine", calibrationCosineDataPen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - calibrationRawDataPlotChannel = new PlotChannel("Raw Data", calibrationRawDataPen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - calibrationRawDataPlotChannel->setStyle(PlotChannel::PCS_DOTS); calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); + calibrationRawDataPlotWidget->addPlotChannel(calibrationSineDataPlotChannel); + calibrationRawDataPlotWidget->addPlotChannel(calibrationCosineDataPlotChannel); + calibrationRawDataPlotChannel->setStyle(PlotChannel::PCS_DOTS); calibrationRawDataPlotChannel->setEnabled(true); + calibrationSineDataPlotChannel->setEnabled(true); + calibrationCosineDataPlotChannel->setEnabled(true); calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); calibrationRawDataPlotWidget->replot(); + calibrationRawDataPlotWidget->setShowXAxisLabels(true); + calibrationRawDataPlotWidget->setShowYAxisLabels(true); + calibrationRawDataPlotWidget->showAxisLabels(); + // Calibrated Plot Widget - PlotWidget *calibrationCalibratedDataPlotWidget = new PlotWidget(); - calibrationCalibratedDataPlotWidget->setContentsMargins(10, 20, 10, 10); + // PlotWidget *calibrationCalibratedDataPlotWidget = new PlotWidget(); + // calibrationCalibratedDataPlotWidget->setContentsMargins(10, 20, 10, 10); - calibrationDataGraphTabWidget->addTab(calibrationRawDataPlotWidget, "Raw"); - calibrationDataGraphTabWidget->addTab(calibrationCalibratedDataPlotWidget, "Calibrated"); + calibrationDataGraphTabWidget->addTab(calibrationRawDataPlotWidget, "Calibration Samples"); + // calibrationDataGraphTabWidget->addTab(calibrationCalibratedDataPlotWidget, "Calibrated"); + calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); MenuSectionWidget *FFTDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); QTabWidget *FFTDataGraphTabWidget = new QTabWidget(FFTDataGraphSectionWidget); @@ -386,7 +457,10 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationFFTDataPlotWidget->setShowYAxisLabels(true); calibrationFFTDataPlotWidget->showAxisLabels(); - FFTDataGraphTabWidget->addTab(calibrationFFTDataPlotWidget, "FFT"); + PlotWidget *postCalibrationAngularErrorPlotWidget = new PlotWidget(); + + FFTDataGraphTabWidget->addTab(calibrationFFTDataPlotWidget, "Pre-Calibration Angular Error"); + FFTDataGraphTabWidget->addTab(postCalibrationAngularErrorPlotWidget, "Post-Calibration Angular Error"); calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget, 0, 0); calibrationDataGraphLayout->addWidget(FFTDataGraphSectionWidget, 1, 0); @@ -734,8 +808,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::clearRawDataList); connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); - connectLineEditToNumber(motorMaxDisplacementSpinBox->lineEdit(), dmax); - connectLineEditToNumber(motorTargetPositionSpinBox->lineEdit(), target_pos); + connectLineEditToNumberWrite(motorMaxDisplacementSpinBox->lineEdit(), dmax, ADMTController::MotorAttribute::DMAX); + connectLineEditToNumberWrite(motorTargetPositionSpinBox->lineEdit(), target_pos, ADMTController::MotorAttribute::TARGET_POS); connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); connect(autoCalibrateCheckBox, &QCheckBox::toggled, [=](bool toggled){ autoCalibrate = toggled; @@ -752,20 +826,49 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() QScrollArea *registerScrollArea = new QScrollArea(); QWidget *registerWidget = new QWidget(registerScrollArea); QVBoxLayout *registerLayout = new QVBoxLayout(registerWidget); - QWidget *registerGridWidget = new QWidget(registerWidget); - QGridLayout *registerGridLayout = new QGridLayout(registerGridWidget); registerScrollArea->setWidgetResizable(true); registerScrollArea->setWidget(registerWidget); registerWidget->setLayout(registerLayout); registerLayout->setMargin(0); registerLayout->setSpacing(10); - registerLayout->addWidget(registerGridWidget); - registerLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); - - registerGridWidget->setLayout(registerGridLayout); - registerGridLayout->setMargin(0); - registerGridLayout->setSpacing(10); + // QWidget *registerGridWidget = new QWidget(registerWidget); + // QGridLayout *registerGridLayout = new QGridLayout(registerGridWidget); + // registerGridWidget->setLayout(registerGridLayout); + // registerGridLayout->setMargin(0); + // registerGridLayout->setSpacing(10); + + QLabel *registerConfigurationLabel = new QLabel("Configuration", registerWidget); + StyleHelper::MenuControlLabel(registerConfigurationLabel, "registerConfigurationLabel"); + QWidget *registerConfigurationGridWidget = new QWidget(registerWidget); + QGridLayout *registerConfigurationGridLayout = new QGridLayout(registerConfigurationGridWidget); + registerConfigurationGridWidget->setLayout(registerConfigurationGridLayout); + registerConfigurationGridLayout->setMargin(0); + registerConfigurationGridLayout->setSpacing(10); + + QLabel *registerDeviceIDLabel = new QLabel("Device ID", registerWidget); + StyleHelper::MenuControlLabel(registerDeviceIDLabel, "registerDeviceIDLabel"); + QWidget *registerDeviceIDGridWidget = new QWidget(registerWidget); + QGridLayout *registerDeviceIDGridLayout = new QGridLayout(registerDeviceIDGridWidget); + registerDeviceIDGridWidget->setLayout(registerDeviceIDGridLayout); + registerDeviceIDGridLayout->setMargin(0); + registerDeviceIDGridLayout->setSpacing(10); + + QLabel *registerHarmonicsLabel = new QLabel("Harmonics", registerWidget); + StyleHelper::MenuControlLabel(registerHarmonicsLabel, "registerHarmonicsLabel"); + QWidget *registerHarmonicsGridWidget = new QWidget(registerWidget); + QGridLayout *registerHarmonicsGridLayout = new QGridLayout(registerHarmonicsGridWidget); + registerHarmonicsGridWidget->setLayout(registerHarmonicsGridLayout); + registerHarmonicsGridLayout->setMargin(0); + registerHarmonicsGridLayout->setSpacing(10); + + QLabel *registerSensorDataLabel = new QLabel("Sensor Data", registerWidget); + StyleHelper::MenuControlLabel(registerSensorDataLabel, "registerSensorDataLabel"); + QWidget *registerSensorDataGridWidget = new QWidget(registerWidget); + QGridLayout *registerSensorDataGridLayout = new QGridLayout(registerSensorDataGridWidget); + registerSensorDataGridWidget->setLayout(registerSensorDataGridLayout); + registerSensorDataGridLayout->setMargin(0); + registerSensorDataGridLayout->setSpacing(10); RegisterBlockWidget *cnvPageRegisterBlock = new RegisterBlockWidget("CNVPAGE", "Convert Start and Page Select", 0x01, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *absAngleRegisterBlock = new RegisterBlockWidget("ABSANGLE", "Absolute Angle", 0x03, 0xDB00, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); @@ -801,42 +904,62 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() RegisterBlockWidget *uniqID3RegisterBlock = new RegisterBlockWidget("UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", 0x21, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *eccDisRegisterBlock = new RegisterBlockWidget("ECCDIS", "Error Correction Code disable", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - registerGridLayout->addWidget(cnvPageRegisterBlock, 0, 0); - registerGridLayout->addWidget(absAngleRegisterBlock, 0, 1); - registerGridLayout->addWidget(digIORegisterBlock, 0, 2); - registerGridLayout->addWidget(angleRegisterBlock, 0, 3); - registerGridLayout->addWidget(faultRegisterBlock, 0, 4); - registerGridLayout->addWidget(angleSecRegisterBlock, 1, 0); - registerGridLayout->addWidget(sineRegisterBlock, 1, 1); - registerGridLayout->addWidget(cosineRegisterBlock, 1, 2); - registerGridLayout->addWidget(secAnglIRegisterBlock, 1, 3); - registerGridLayout->addWidget(secAnglQRegisterBlock, 1, 4); - registerGridLayout->addWidget(radiusRegisterBlock, 2, 0); - registerGridLayout->addWidget(diag1RegisterBlock, 2, 1); - registerGridLayout->addWidget(diag2RegisterBlock, 2, 2); - registerGridLayout->addWidget(tmp0RegisterBlock, 2, 3); - registerGridLayout->addWidget(tmp1RegisterBlock, 2, 4); - registerGridLayout->addWidget(generalRegisterBlock, 3, 0); - registerGridLayout->addWidget(digIOEnRegisterBlock, 3, 1); - registerGridLayout->addWidget(angleCkRegisterBlock, 3, 2); - registerGridLayout->addWidget(cnvCntRegisterBlock, 3, 3); - registerGridLayout->addWidget(h1MagRegisterBlock, 3, 4); - registerGridLayout->addWidget(h1PhRegisterBlock, 4, 0); - registerGridLayout->addWidget(h2MagRegisterBlock, 4, 1); - registerGridLayout->addWidget(h2PhRegisterBlock, 4, 2); - registerGridLayout->addWidget(h3MagRegisterBlock, 4, 3); - registerGridLayout->addWidget(h3PhRegisterBlock, 4, 4); - registerGridLayout->addWidget(h8MagRegisterBlock, 5, 0); - registerGridLayout->addWidget(h8PhRegisterBlock, 5, 1); - registerGridLayout->addWidget(eccDcdeRegisterBlock, 5, 2); - registerGridLayout->addWidget(uniqID0RegisterBlock, 5, 3); - registerGridLayout->addWidget(uniqID1RegisterBlock, 5, 4); - registerGridLayout->addWidget(uniqID2RegisterBlock, 6, 0); - registerGridLayout->addWidget(uniqID3RegisterBlock, 6, 1); - registerGridLayout->addWidget(eccDisRegisterBlock, 6, 2); - - for(int c=0; c < registerGridLayout->columnCount(); ++c) registerGridLayout->setColumnStretch(c,1); - for(int r=0; r < registerGridLayout->rowCount(); ++r) registerGridLayout->setRowStretch(r,1); + registerConfigurationGridLayout->addWidget(cnvPageRegisterBlock, 0, 0); + registerConfigurationGridLayout->addWidget(digIORegisterBlock, 0, 1); + registerConfigurationGridLayout->addWidget(faultRegisterBlock, 0, 2); + registerConfigurationGridLayout->addWidget(generalRegisterBlock, 0, 3); + registerConfigurationGridLayout->addWidget(digIOEnRegisterBlock, 0, 4); + registerConfigurationGridLayout->addWidget(angleCkRegisterBlock, 1, 0); + registerConfigurationGridLayout->addWidget(eccDcdeRegisterBlock, 1, 1); + registerConfigurationGridLayout->addWidget(eccDisRegisterBlock, 1, 2); + + registerDeviceIDGridLayout->addWidget(uniqID0RegisterBlock, 0, 0); + registerDeviceIDGridLayout->addWidget(uniqID1RegisterBlock, 0, 1); + registerDeviceIDGridLayout->addWidget(uniqID2RegisterBlock, 0, 2); + registerDeviceIDGridLayout->addWidget(uniqID3RegisterBlock, 0, 3); + QSpacerItem *registerDeviceSpacer = new QSpacerItem(0, 0, QSizePolicy::Preferred, QSizePolicy::Preferred); + registerDeviceIDGridLayout->addItem(registerDeviceSpacer, 0, 4); + + registerHarmonicsGridLayout->addWidget(h1MagRegisterBlock, 0, 0); + registerHarmonicsGridLayout->addWidget(h1PhRegisterBlock, 0, 1); + registerHarmonicsGridLayout->addWidget(h2MagRegisterBlock, 0, 2); + registerHarmonicsGridLayout->addWidget(h2PhRegisterBlock, 0, 3); + registerHarmonicsGridLayout->addWidget(h3MagRegisterBlock, 0, 4); + registerHarmonicsGridLayout->addWidget(h3PhRegisterBlock, 1, 0); + registerHarmonicsGridLayout->addWidget(h8MagRegisterBlock, 1, 1); + registerHarmonicsGridLayout->addWidget(h8PhRegisterBlock, 1, 2); + + registerSensorDataGridLayout->addWidget(absAngleRegisterBlock, 0, 0); + registerSensorDataGridLayout->addWidget(angleRegisterBlock, 0, 1); + registerSensorDataGridLayout->addWidget(angleSecRegisterBlock, 0, 2); + registerSensorDataGridLayout->addWidget(sineRegisterBlock, 0, 3); + registerSensorDataGridLayout->addWidget(cosineRegisterBlock, 0, 4); + registerSensorDataGridLayout->addWidget(secAnglIRegisterBlock, 1, 0); + registerSensorDataGridLayout->addWidget(secAnglQRegisterBlock, 1, 1); + registerSensorDataGridLayout->addWidget(radiusRegisterBlock, 1, 2); + registerSensorDataGridLayout->addWidget(diag1RegisterBlock, 1, 3); + registerSensorDataGridLayout->addWidget(diag2RegisterBlock, 1, 4); + registerSensorDataGridLayout->addWidget(tmp0RegisterBlock, 2, 0); + registerSensorDataGridLayout->addWidget(tmp1RegisterBlock, 2, 1); + registerSensorDataGridLayout->addWidget(cnvCntRegisterBlock, 2, 2); + + // for(int c=0; c < registerGridLayout->columnCount(); ++c) registerGridLayout->setColumnStretch(c,1); + // for(int r=0; r < registerGridLayout->rowCount(); ++r) registerGridLayout->setRowStretch(r,1); + for(int c=0; c < registerConfigurationGridLayout->columnCount(); ++c) registerConfigurationGridLayout->setColumnStretch(c,1); + for(int c=0; c < registerDeviceIDGridLayout->columnCount(); ++c) registerDeviceIDGridLayout->setColumnStretch(c,1); + for(int c=0; c < registerHarmonicsGridLayout->columnCount(); ++c) registerHarmonicsGridLayout->setColumnStretch(c,1); + for(int c=0; c < registerSensorDataGridLayout->columnCount(); ++c) registerSensorDataGridLayout->setColumnStretch(c,1); + + // registerLayout->addWidget(registerGridWidget); + registerLayout->addWidget(registerConfigurationLabel); + registerLayout->addWidget(registerConfigurationGridWidget); + registerLayout->addWidget(registerDeviceIDLabel); + registerLayout->addWidget(registerDeviceIDGridWidget); + registerLayout->addWidget(registerHarmonicsLabel); + registerLayout->addWidget(registerHarmonicsGridWidget); + registerLayout->addWidget(registerSensorDataLabel); + registerLayout->addWidget(registerSensorDataGridWidget); + registerLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); tool->topContainer()->setVisible(false); @@ -854,6 +977,52 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() return tool; } +ToolTemplate* HarmonicCalibration::createUtilityWidget() +{ + ToolTemplate *tool = new ToolTemplate(this); + + QScrollArea *rightUtilityScrollArea = new QScrollArea(this); + QWidget *rightUtilityWidget = new QWidget(rightUtilityScrollArea); + rightUtilityScrollArea->setWidget(rightUtilityWidget); + rightUtilityScrollArea->setWidgetResizable(true); + QVBoxLayout *rightUtilityLayout = new QVBoxLayout(rightUtilityWidget); + rightUtilityWidget->setLayout(rightUtilityLayout); + rightUtilityLayout->setMargin(0); + rightUtilityLayout->setSpacing(10); + + MenuSectionWidget *faultRegisterSectionWidget = new MenuSectionWidget(rightUtilityWidget); + rightUtilityLayout->addWidget(faultRegisterSectionWidget); + MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection("Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, faultRegisterSectionWidget); + faultRegisterSectionWidget->contentLayout()->addWidget(faultRegisterCollapseSection); + + MenuControlButton *testFaultButton = new MenuControlButton(faultRegisterSectionWidget); + testFaultButton->setName("VDD Under Voltage"); + testFaultButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); + testFaultButton->setOpenMenuChecksThis(true); + testFaultButton->setDoubleClickToOpenMenu(true); + testFaultButton->setColor(QColor("#c81a28")); + testFaultButton->button()->setVisible(false); + testFaultButton->setCheckable(true); + testFaultButton->checkBox()->setChecked(true); + + faultRegisterCollapseSection->contentLayout()->addWidget(testFaultButton); + + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(false); + tool->topContainerMenuControl()->setVisible(false); + tool->leftContainer()->setVisible(false); + tool->rightContainer()->setVisible(true); + tool->bottomContainer()->setVisible(false); + tool->setLeftContainerWidth(270); + tool->setRightContainerWidth(270); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + + tool->rightStack()->addWidget(rightUtilityScrollArea); + + return tool; +} + void HarmonicCalibration::restart() { if(m_running) { @@ -956,6 +1125,21 @@ void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& v }); } +void HarmonicCalibration::connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute) +{ + connect(lineEdit, &QLineEdit::editingFinished, [=, &variable]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok) { + variable = value; + writeMotorAttributeValue(attribute, variable); + + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + void HarmonicCalibration::connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph) { connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, graph]() { @@ -1193,6 +1377,7 @@ void HarmonicCalibration::motorCalibrationAcquisitionTask() { if(startMotor && rawDataList.size() < totalSamplesCount){ stepMotorAcquisition(); + updateChannelValue(ADMTController::Channel::ANGLE); double currentAngle = angle; QVector angles = { currentAngle }; appendSamplesToPlotCurve(calibrationRawDataPlotWidget, angles); @@ -1387,12 +1572,17 @@ void HarmonicCalibration::importCalibrationData() fm.open(fileName, FileManager::IMPORT); QVector data = fm.read(0); - calibrationRawDataPlotChannel->curve()->setSamples(data.data(), data.size()); - calibrationRawDataXPlotAxis->setInterval(0, data.size()); - for(int i = 0; i < data.size(); ++i) { - rawDataList.push_back(data[i]); + if(data.size() > 0) + { + calibrationRawDataPlotChannel->curve()->setSamples(data.data(), data.size()); + calibrationRawDataXPlotAxis->setInterval(0, data.size()); + m_admtController->computeSineCosineOfAngles(vector(data.begin(), data.end())); + calibrationSineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_sine_scaled.data(), m_admtController->calibration_samples_sine_scaled.size()); + calibrationCosineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_cosine_scaled.data(), m_admtController->calibration_samples_cosine_scaled.size()); + for(int i = 0; i < data.size(); ++i) { + rawDataList.push_back(data[i]); + } } - } catch(FileManagerException &ex) { calibrationLogWriteLn(QString(ex.what())); } @@ -1565,6 +1755,8 @@ void HarmonicCalibration::applyTabWidgetStyle(QTabWidget *widget, const QString& min-width: 100px; min-height: 32px; padding-bottom: 5px; + padding-left: 16px; + padding-right: 16px; background-color: &&UIElementBackground&&; font: normal; } From 5a512f1b736d333bc3afc04de220ea994f778313 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 6 Sep 2024 14:42:33 +0800 Subject: [PATCH 021/112] admt: Added calibration graph toggles Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 2 + plugins/admt/src/harmoniccalibration.cpp | 310 +++++++++++++++--- 2 files changed, 264 insertions(+), 48 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index bb343a0e7c..bfd10bcf5a 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -163,6 +163,8 @@ public Q_SLOTS: void connectMenuComboToNumber(MenuCombo* menuCombo, double& variable); void appendSamplesToPlotCurve(PlotWidget *plotWidget, QVector& newYData); void applyTabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor = "ScopyBlue"); + MenuControlButton *createStatusLEDWidget(const QString title, QColor color, QWidget *parent = nullptr); + MenuControlButton *createChannelToggleWidget(const QString title, QColor color, QWidget *parent = nullptr); QTimer *timer, *calibrationTimer, *motorCalibrationAcquisitionTimer; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 91b4b4286b..2c88e03963 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -37,6 +37,11 @@ static uint32_t h8PhaseDeviceRegister = 0x1C; static vector rawDataList; +static const QColor sineColor = QColor("#85e94c"); +static const QColor cosineColor = QColor("#91e6cf"); +static const QColor faultLEDColor = QColor("#c81a28"); +static const QColor statusLEDColor = QColor("#2e9e6f"); + using namespace scopy; using namespace scopy::admt; using namespace scopy::grutil; @@ -390,10 +395,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataPlotWidget->xAxis()->setVisible(false); calibrationRawDataPlotWidget->yAxis()->setVisible(false); QPen calibrationRawDataPen = QPen(StyleHelper::getColor("ScopyBlue")); - QPen calibrationSineDataPen = QPen(StyleHelper::getColor("CH0")); - calibrationSineDataPen.color().setAlphaF(0.1); - QPen calibrationCosineDataPen = QPen(StyleHelper::getColor("CH1")); - calibrationCosineDataPen.color().setAlphaF(0.1); + QPen calibrationSineDataPen = QPen(sineColor); + QPen calibrationCosineDataPen = QPen(cosineColor); calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, calibrationRawDataPen); calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, calibrationRawDataPen); @@ -417,13 +420,30 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataPlotWidget->setShowYAxisLabels(true); calibrationRawDataPlotWidget->showAxisLabels(); - // Calibrated Plot Widget - // PlotWidget *calibrationCalibratedDataPlotWidget = new PlotWidget(); - // calibrationCalibratedDataPlotWidget->setContentsMargins(10, 20, 10, 10); - calibrationDataGraphTabWidget->addTab(calibrationRawDataPlotWidget, "Calibration Samples"); - // calibrationDataGraphTabWidget->addTab(calibrationCalibratedDataPlotWidget, "Calibrated"); + + QWidget *calibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphSectionWidget); + QHBoxLayout *calibrationDataGraphChannelsLayout = new QHBoxLayout(calibrationDataGraphChannelsWidget); + calibrationDataGraphChannelsWidget->setLayout(calibrationDataGraphChannelsLayout); + QString calibrationDataGraphChannelsStyle = QString(R"css( + background-color: &&colorname&&; + )css"); + calibrationDataGraphChannelsStyle.replace(QString("&&colorname&&"), StyleHelper::getColor("UIElementBackground")); + calibrationDataGraphChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); + calibrationDataGraphChannelsLayout->setMargin(0); + calibrationDataGraphChannelsLayout->setSpacing(10); + + MenuControlButton *toggleAngleButton = createChannelToggleWidget("Angle", QColor(StyleHelper::getColor("ScopyBlue")), calibrationDataGraphChannelsWidget); + MenuControlButton *toggleSineButton = createChannelToggleWidget("Sine", sineColor, calibrationDataGraphChannelsWidget); + MenuControlButton *toggleCosineButton = createChannelToggleWidget("Cosine", cosineColor, calibrationDataGraphChannelsWidget); + + calibrationDataGraphChannelsLayout->addWidget(toggleAngleButton); + calibrationDataGraphChannelsLayout->addWidget(toggleSineButton); + calibrationDataGraphChannelsLayout->addWidget(toggleCosineButton); + calibrationDataGraphChannelsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred)); + calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); + calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphChannelsWidget); MenuSectionWidget *FFTDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); QTabWidget *FFTDataGraphTabWidget = new QTabWidget(FFTDataGraphSectionWidget); @@ -815,6 +835,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() autoCalibrate = toggled; StatusBarManager::pushMessage(QString("Auto Calibrate: ") + QString((toggled ? "True" : "False"))); }); + connect(toggleAngleButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); + calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleSineButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + calibrationRawDataPlotWidget->selectChannel(calibrationSineDataPlotChannel); + calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleCosineButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + calibrationRawDataPlotWidget->selectChannel(calibrationCosineDataPlotChannel); + calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); return tool; } @@ -871,10 +903,14 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerSensorDataGridLayout->setSpacing(10); RegisterBlockWidget *cnvPageRegisterBlock = new RegisterBlockWidget("CNVPAGE", "Convert Start and Page Select", 0x01, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *absAngleRegisterBlock = new RegisterBlockWidget("ABSANGLE", "Absolute Angle", 0x03, 0xDB00, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *digIORegisterBlock = new RegisterBlockWidget("DIGIO", "Digital Input Output", 0x04, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *angleRegisterBlock = new RegisterBlockWidget("ANGLE", "Angle Register", 0x05, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *faultRegisterBlock = new RegisterBlockWidget("FAULT", "Fault Register", 0x06, 0xFFFF, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *generalRegisterBlock = new RegisterBlockWidget("GENERAL", "General Device Configuration", 0x10, 0x1230, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *digIOEnRegisterBlock = new RegisterBlockWidget("DIGIOEN", "Enable Digital Input/Outputs", 0x12, 0x241B, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *angleCkRegisterBlock = new RegisterBlockWidget("ANGLECK", "Primary vs Secondary Angle Check", 0x13, 0x000F, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + + RegisterBlockWidget *absAngleRegisterBlock = new RegisterBlockWidget("ABSANGLE", "Absolute Angle", 0x03, 0xDB00, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *angleRegisterBlock = new RegisterBlockWidget("ANGLE", "Angle Register", 0x05, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *angleSecRegisterBlock = new RegisterBlockWidget("ANGLESEC", "Secondary Angle", 0x08, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *sineRegisterBlock = new RegisterBlockWidget("SINE", "Sine Measurement", 0x10, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *cosineRegisterBlock = new RegisterBlockWidget("COSINE", "Cosine Measurement", 0x11, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); @@ -885,10 +921,14 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() RegisterBlockWidget *diag2RegisterBlock = new RegisterBlockWidget("DIAG2", "Measurements of two diagnostics resistors of fixed value", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *tmp0RegisterBlock = new RegisterBlockWidget("TMP0", "Primary Temperature Sensor", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *tmp1RegisterBlock = new RegisterBlockWidget("TMP1", "Secondary Temperature Sensor", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *generalRegisterBlock = new RegisterBlockWidget("GENERAL", "General Device Configuration", 0x10, 0x1230, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *digIOEnRegisterBlock = new RegisterBlockWidget("DIGIOEN", "Enable Digital Input/Outputs", 0x12, 0x241B, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *angleCkRegisterBlock = new RegisterBlockWidget("ANGLECK", "Primary vs Secondary Angle Check", 0x13, 0x000F, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *cnvCntRegisterBlock = new RegisterBlockWidget("CNVCNT", "Conversion Count", 0x14, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *eccDcdeRegisterBlock = new RegisterBlockWidget("ECCDCDE", "Error Correction Codes", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *uniqID0RegisterBlock = new RegisterBlockWidget("UNIQID0", "Unique ID Register 0", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *uniqID1RegisterBlock = new RegisterBlockWidget("UNIQID1", "Unique ID Register 1", 0x1F, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *uniqID2RegisterBlock = new RegisterBlockWidget("UNIQID2", "Unique ID Register 2", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *uniqID3RegisterBlock = new RegisterBlockWidget("UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", 0x21, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + RegisterBlockWidget *eccDisRegisterBlock = new RegisterBlockWidget("ECCDIS", "Error Correction Code disable", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *h1MagRegisterBlock = new RegisterBlockWidget("H1MAG", "1st Harmonic error magnitude", 0x15, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *h1PhRegisterBlock = new RegisterBlockWidget("H1PH", "1st Harmonic error phase", 0x16, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *h2MagRegisterBlock = new RegisterBlockWidget("H2MAG", "2nd Harmonic error magnitude", 0x17, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); @@ -897,12 +937,6 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() RegisterBlockWidget *h3PhRegisterBlock = new RegisterBlockWidget("H3PH", "3rd Harmonic error phase", 0x1A, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *h8MagRegisterBlock = new RegisterBlockWidget("H8MAG", "8th Harmonic error magnitude", 0x1B, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *h8PhRegisterBlock = new RegisterBlockWidget("H8PH", "8th Harmonic error phase", 0x1C, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *eccDcdeRegisterBlock = new RegisterBlockWidget("ECCDCDE", "Error Correction Codes", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *uniqID0RegisterBlock = new RegisterBlockWidget("UNIQID0", "Unique ID Register 0", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *uniqID1RegisterBlock = new RegisterBlockWidget("UNIQID1", "Unique ID Register 1", 0x1F, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *uniqID2RegisterBlock = new RegisterBlockWidget("UNIQID2", "Unique ID Register 2", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *uniqID3RegisterBlock = new RegisterBlockWidget("UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", 0x21, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *eccDisRegisterBlock = new RegisterBlockWidget("ECCDIS", "Error Correction Code disable", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); registerConfigurationGridLayout->addWidget(cnvPageRegisterBlock, 0, 0); registerConfigurationGridLayout->addWidget(digIORegisterBlock, 0, 1); @@ -913,6 +947,20 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerConfigurationGridLayout->addWidget(eccDcdeRegisterBlock, 1, 1); registerConfigurationGridLayout->addWidget(eccDisRegisterBlock, 1, 2); + registerSensorDataGridLayout->addWidget(absAngleRegisterBlock, 0, 0); + registerSensorDataGridLayout->addWidget(angleRegisterBlock, 0, 1); + registerSensorDataGridLayout->addWidget(angleSecRegisterBlock, 0, 2); + registerSensorDataGridLayout->addWidget(sineRegisterBlock, 0, 3); + registerSensorDataGridLayout->addWidget(cosineRegisterBlock, 0, 4); + registerSensorDataGridLayout->addWidget(secAnglIRegisterBlock, 1, 0); + registerSensorDataGridLayout->addWidget(secAnglQRegisterBlock, 1, 1); + registerSensorDataGridLayout->addWidget(radiusRegisterBlock, 1, 2); + registerSensorDataGridLayout->addWidget(diag1RegisterBlock, 1, 3); + registerSensorDataGridLayout->addWidget(diag2RegisterBlock, 1, 4); + registerSensorDataGridLayout->addWidget(tmp0RegisterBlock, 2, 0); + registerSensorDataGridLayout->addWidget(tmp1RegisterBlock, 2, 1); + registerSensorDataGridLayout->addWidget(cnvCntRegisterBlock, 2, 2); + registerDeviceIDGridLayout->addWidget(uniqID0RegisterBlock, 0, 0); registerDeviceIDGridLayout->addWidget(uniqID1RegisterBlock, 0, 1); registerDeviceIDGridLayout->addWidget(uniqID2RegisterBlock, 0, 2); @@ -929,19 +977,6 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerHarmonicsGridLayout->addWidget(h8MagRegisterBlock, 1, 1); registerHarmonicsGridLayout->addWidget(h8PhRegisterBlock, 1, 2); - registerSensorDataGridLayout->addWidget(absAngleRegisterBlock, 0, 0); - registerSensorDataGridLayout->addWidget(angleRegisterBlock, 0, 1); - registerSensorDataGridLayout->addWidget(angleSecRegisterBlock, 0, 2); - registerSensorDataGridLayout->addWidget(sineRegisterBlock, 0, 3); - registerSensorDataGridLayout->addWidget(cosineRegisterBlock, 0, 4); - registerSensorDataGridLayout->addWidget(secAnglIRegisterBlock, 1, 0); - registerSensorDataGridLayout->addWidget(secAnglQRegisterBlock, 1, 1); - registerSensorDataGridLayout->addWidget(radiusRegisterBlock, 1, 2); - registerSensorDataGridLayout->addWidget(diag1RegisterBlock, 1, 3); - registerSensorDataGridLayout->addWidget(diag2RegisterBlock, 1, 4); - registerSensorDataGridLayout->addWidget(tmp0RegisterBlock, 2, 0); - registerSensorDataGridLayout->addWidget(tmp1RegisterBlock, 2, 1); - registerSensorDataGridLayout->addWidget(cnvCntRegisterBlock, 2, 2); // for(int c=0; c < registerGridLayout->columnCount(); ++c) registerGridLayout->setColumnStretch(c,1); // for(int r=0; r < registerGridLayout->rowCount(); ++r) registerGridLayout->setRowStretch(r,1); @@ -953,12 +988,12 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() // registerLayout->addWidget(registerGridWidget); registerLayout->addWidget(registerConfigurationLabel); registerLayout->addWidget(registerConfigurationGridWidget); + registerLayout->addWidget(registerSensorDataLabel); + registerLayout->addWidget(registerSensorDataGridWidget); registerLayout->addWidget(registerDeviceIDLabel); registerLayout->addWidget(registerDeviceIDGridWidget); registerLayout->addWidget(registerHarmonicsLabel); registerLayout->addWidget(registerHarmonicsGridWidget); - registerLayout->addWidget(registerSensorDataLabel); - registerLayout->addWidget(registerSensorDataGridWidget); registerLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -981,6 +1016,128 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() { ToolTemplate *tool = new ToolTemplate(this); + #pragma region Left Utility Widget + QWidget *leftUtilityWidget = new QWidget(this); + QVBoxLayout *leftUtilityLayout = new QVBoxLayout(leftUtilityWidget); + leftUtilityWidget->setLayout(leftUtilityLayout); + leftUtilityLayout->setMargin(0); + leftUtilityLayout->setSpacing(10); + #pragma region Command Log Widget + MenuSectionWidget *commandLogSectionWidget = new MenuSectionWidget(leftUtilityWidget); + MenuCollapseSection *commandLogCollapseSection = new MenuCollapseSection("Command Log", MenuCollapseSection::MHCW_NONE, commandLogSectionWidget); + commandLogSectionWidget->contentLayout()->addWidget(commandLogCollapseSection); + + QPlainTextEdit *commandLogPlainTextEdit = new QPlainTextEdit(commandLogSectionWidget); + commandLogPlainTextEdit->setReadOnly(true); + commandLogPlainTextEdit->setFixedHeight(320); + + commandLogCollapseSection->contentLayout()->addWidget(commandLogPlainTextEdit); + + leftUtilityLayout->addWidget(commandLogSectionWidget); + leftUtilityLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + #pragma endregion + #pragma endregion + + #pragma region Center Utility Widget + QWidget *centerUtilityWidget = new QWidget(this); + QHBoxLayout *centerUtilityLayout = new QHBoxLayout(centerUtilityWidget); + centerUtilityWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + centerUtilityWidget->setLayout(centerUtilityLayout); + centerUtilityLayout->setMargin(0); + centerUtilityLayout->setSpacing(10); + // centerUtilityLayout->setAlignment(Qt::AlignTop); + + #pragma region DIGIO Monitor + MenuSectionWidget *DIGIOMonitorSectionWidget = new MenuSectionWidget(centerUtilityWidget); + MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection("DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, DIGIOMonitorSectionWidget); + DIGIOMonitorSectionWidget->contentLayout()->addWidget(DIGIOMonitorCollapseSection); + + MenuControlButton *DIGIOBusyStatusLED = createStatusLEDWidget("BUSY", statusLEDColor, DIGIOMonitorCollapseSection); + MenuControlButton *DIGIOCNVStatusLED = createStatusLEDWidget("CNV", statusLEDColor, DIGIOMonitorCollapseSection); + MenuControlButton *DIGIOSENTStatusLED = createStatusLEDWidget("SENT", statusLEDColor, DIGIOMonitorCollapseSection); + MenuControlButton *DIGIOACALCStatusLED = createStatusLEDWidget("ACALC", statusLEDColor, DIGIOMonitorCollapseSection); + MenuControlButton *DIGIOFaultStatusLED = createStatusLEDWidget("FAULT", statusLEDColor, DIGIOMonitorCollapseSection); + MenuControlButton *DIGIOBootloaderStatusLED = createStatusLEDWidget("BOOTLOADER", statusLEDColor, DIGIOMonitorCollapseSection); + + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBusyStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOCNVStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOSENTStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOACALCStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOFaultStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBootloaderStatusLED); + #pragma endregion + + #pragma region MTDIAG1 Widget + MenuSectionWidget *MTDIAG1SectionWidget = new MenuSectionWidget(centerUtilityWidget); + MenuCollapseSection *MTDIAG1CollapseSection = new MenuCollapseSection("MT Diagnostic Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MTDIAG1SectionWidget); + MTDIAG1SectionWidget->contentLayout()->addWidget(MTDIAG1CollapseSection); + + MenuControlButton *R0StatusLED = createStatusLEDWidget("R0", statusLEDColor, MTDIAG1SectionWidget); + MenuControlButton *R1StatusLED = createStatusLEDWidget("R1", statusLEDColor, MTDIAG1SectionWidget); + MenuControlButton *R2StatusLED = createStatusLEDWidget("R2", statusLEDColor, MTDIAG1SectionWidget); + MenuControlButton *R3StatusLED = createStatusLEDWidget("R3", statusLEDColor, MTDIAG1SectionWidget); + MenuControlButton *R4StatusLED = createStatusLEDWidget("R4", statusLEDColor, MTDIAG1SectionWidget); + MenuControlButton *R5StatusLED = createStatusLEDWidget("R5", statusLEDColor, MTDIAG1SectionWidget); + MenuControlButton *R6StatusLED = createStatusLEDWidget("R6", statusLEDColor, MTDIAG1SectionWidget); + MenuControlButton *R7StatusLED = createStatusLEDWidget("R7", statusLEDColor, MTDIAG1SectionWidget); + + MTDIAG1CollapseSection->contentLayout()->addWidget(R0StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R1StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R2StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R3StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R4StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R5StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R6StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R7StatusLED); + #pragma endregion + + #pragma region MT Diagnostics + QScrollArea *MTDiagnosticsScrollArea = new QScrollArea(centerUtilityWidget); + QWidget *MTDiagnosticsWidget = new QWidget(MTDiagnosticsScrollArea); + MTDiagnosticsScrollArea->setWidget(MTDiagnosticsWidget); + MTDiagnosticsScrollArea->setWidgetResizable(true); + QVBoxLayout *MTDiagnosticsLayout = new QVBoxLayout(MTDiagnosticsWidget); + MTDiagnosticsLayout->setMargin(0); + MTDiagnosticsLayout->setSpacing(10); + + MenuSectionWidget *MTDiagnosticsSectionWidget = new MenuSectionWidget(centerUtilityWidget); + MenuCollapseSection *MTDiagnosticsCollapseSection = new MenuCollapseSection("MT Diagnostics", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MTDiagnosticsSectionWidget); + MTDiagnosticsSectionWidget->contentLayout()->addWidget(MTDiagnosticsCollapseSection); + MTDiagnosticsCollapseSection->contentLayout()->setSpacing(10); + + QLabel *AFEDIAG0Label = new QLabel("AFEDIAG0 (%)"); + StyleHelper::MenuSmallLabel(AFEDIAG0Label, "AFEDIAG0Label"); + QLabel *AFEDIAG1Label = new QLabel("AFEDIAG1 (%)"); + StyleHelper::MenuSmallLabel(AFEDIAG1Label, "AFEDIAG1Label"); + QLabel *AFEDIAG2Label = new QLabel("AFEDIAG2 (V)"); + StyleHelper::MenuSmallLabel(AFEDIAG2Label, "AFEDIAG2Label"); + + QLineEdit *AFEDIAG0LineEdit = new QLineEdit("-57.0312", MTDiagnosticsSectionWidget); + QLineEdit *AFEDIAG1LineEdit = new QLineEdit("56.25", MTDiagnosticsSectionWidget); + QLineEdit *AFEDIAG2LineEdit = new QLineEdit("-312.499m", MTDiagnosticsSectionWidget); + applyLineEditStyle(AFEDIAG0LineEdit); + applyLineEditStyle(AFEDIAG1LineEdit); + applyLineEditStyle(AFEDIAG2LineEdit); + + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0Label); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0LineEdit); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1Label); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1LineEdit); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2Label); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2LineEdit); + + MTDiagnosticsLayout->addWidget(MTDiagnosticsSectionWidget); + MTDiagnosticsLayout->addWidget(MTDIAG1SectionWidget); + #pragma endregion + + centerUtilityLayout->addWidget(DIGIOMonitorSectionWidget, 0, Qt::AlignTop); + centerUtilityLayout->addWidget(MTDiagnosticsScrollArea, 0, Qt::AlignTop); + // centerUtilityLayout->addWidget(MTDIAG1SectionWidget, 0, Qt::AlignTop); + // centerUtilityLayout->addWidget(MTDiagnosticsSectionWidget, 0, Qt::AlignTop); + + #pragma endregion + + #pragma region Right Utility Widget QScrollArea *rightUtilityScrollArea = new QScrollArea(this); QWidget *rightUtilityWidget = new QWidget(rightUtilityScrollArea); rightUtilityScrollArea->setWidget(rightUtilityWidget); @@ -991,26 +1148,49 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() rightUtilityLayout->setSpacing(10); MenuSectionWidget *faultRegisterSectionWidget = new MenuSectionWidget(rightUtilityWidget); - rightUtilityLayout->addWidget(faultRegisterSectionWidget); MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection("Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, faultRegisterSectionWidget); faultRegisterSectionWidget->contentLayout()->addWidget(faultRegisterCollapseSection); - MenuControlButton *testFaultButton = new MenuControlButton(faultRegisterSectionWidget); - testFaultButton->setName("VDD Under Voltage"); - testFaultButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); - testFaultButton->setOpenMenuChecksThis(true); - testFaultButton->setDoubleClickToOpenMenu(true); - testFaultButton->setColor(QColor("#c81a28")); - testFaultButton->button()->setVisible(false); - testFaultButton->setCheckable(true); - testFaultButton->checkBox()->setChecked(true); - - faultRegisterCollapseSection->contentLayout()->addWidget(testFaultButton); + MenuControlButton *vddUnderVoltageStatusLED = createStatusLEDWidget("VDD Under Voltage", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *vddOverVoltageStatusLED = createStatusLEDWidget("VDD Over Voltage", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *vDriveUnderVoltageStatusLED = createStatusLEDWidget("VDRIVE Under Voltage", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *vDriveOverVoltageStatusLED = createStatusLEDWidget("VDRIVE Over Voltage", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *AFEDIAGStatusLED = createStatusLEDWidget("AFEDIAG", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *NVMCRCFaultStatusLED = createStatusLEDWidget("NVM CRC Fault", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *ECCDoubleBitErrorStatusLED = createStatusLEDWidget("ECC Double Bit Error", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *OscillatorDriftStatusLED = createStatusLEDWidget("Oscillator Drift", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *CountSensorFalseStateStatusLED = createStatusLEDWidget("Count Sensor False State", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *AngleCrossCheckStatusLED = createStatusLEDWidget("Angle Cross Check", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *TurnCountSensorLevelsStatusLED = createStatusLEDWidget("Turn Count Sensor Levels", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *MTDIAGStatusLED = createStatusLEDWidget("MTDIAG", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *TurnCounterCrossCheckStatusLED = createStatusLEDWidget("Turn Counter Cross Check", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *RadiusCheckStatusLED = createStatusLEDWidget("Radius Check", faultLEDColor, faultRegisterCollapseSection); + MenuControlButton *SequencerWatchdogStatusLED = createStatusLEDWidget("Sequencer Watchdog", faultLEDColor, faultRegisterCollapseSection); + + faultRegisterCollapseSection->contentLayout()->addWidget(vddUnderVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(vddOverVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(vDriveUnderVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(vDriveOverVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(AFEDIAGStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(NVMCRCFaultStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(ECCDoubleBitErrorStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(OscillatorDriftStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(CountSensorFalseStateStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(AngleCrossCheckStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(TurnCountSensorLevelsStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(MTDIAGStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(TurnCounterCrossCheckStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(RadiusCheckStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(SequencerWatchdogStatusLED); + rightUtilityLayout->addWidget(faultRegisterSectionWidget); + rightUtilityLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + #pragma endregion + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); tool->topContainer()->setVisible(false); tool->topContainerMenuControl()->setVisible(false); - tool->leftContainer()->setVisible(false); + tool->leftContainer()->setVisible(true); tool->rightContainer()->setVisible(true); tool->bottomContainer()->setVisible(false); tool->setLeftContainerWidth(270); @@ -1018,6 +1198,8 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() tool->openBottomContainerHelper(false); tool->openTopContainerHelper(false); + tool->leftStack()->addWidget(leftUtilityWidget); + tool->addWidgetToCentralContainerHelper(centerUtilityWidget); tool->rightStack()->addWidget(rightUtilityScrollArea); return tool; @@ -1098,6 +1280,35 @@ void HarmonicCalibration::updateGeneralSettingEnabled(bool value) tempGraphSamplesLineEdit->setEnabled(value); } +MenuControlButton *HarmonicCalibration::createStatusLEDWidget(const QString title, QColor color, QWidget *parent) +{ + MenuControlButton *menuControlButton = new MenuControlButton(parent); + menuControlButton->setName(title); + menuControlButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); + menuControlButton->setOpenMenuChecksThis(true); + menuControlButton->setDoubleClickToOpenMenu(true); + menuControlButton->setColor(color); + menuControlButton->button()->setVisible(false); + menuControlButton->setCheckable(true); + menuControlButton->checkBox()->setChecked(true); + menuControlButton->setEnabled(false); + return menuControlButton; +} + +MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString title, QColor color, QWidget *parent) +{ + MenuControlButton *menuControlButton = new MenuControlButton(parent); + menuControlButton->setName(title); + menuControlButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); + menuControlButton->setOpenMenuChecksThis(true); + menuControlButton->setDoubleClickToOpenMenu(true); + menuControlButton->setColor(color); + menuControlButton->button()->setVisible(false); + menuControlButton->setCheckable(false); + menuControlButton->checkBox()->setChecked(true); + return menuControlButton; +} + void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable) { connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { @@ -1582,6 +1793,7 @@ void HarmonicCalibration::importCalibrationData() for(int i = 0; i < data.size(); ++i) { rawDataList.push_back(data[i]); } + calibrationRawDataPlotWidget->replot(); } } catch(FileManagerException &ex) { calibrationLogWriteLn(QString(ex.what())); @@ -1631,6 +1843,8 @@ void HarmonicCalibration::clearRawDataList() rawDataList.clear(); calibrationRawDataPlotChannel->curve()->setData(nullptr); + calibrationSineDataPlotChannel->curve()->setData(nullptr); + calibrationCosineDataPlotChannel->curve()->setData(nullptr); calibrationRawDataPlotWidget->replot(); calibrationFFTPlotChannel->curve()->setData(nullptr); From 23e813ec55272d48026e6943f78a514a70c6ab10 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 9 Sep 2024 14:27:09 +0800 Subject: [PATCH 022/112] admt: Refactored read and write to registry - Added calculation for scaled harmonic coefficient - Reverted raw data plot from dot to line - Connected read and write buttons from register block widget Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 22 ++- .../admt/include/admt/harmoniccalibration.h | 3 +- .../admt/widgets/registerblockwidget.h | 15 ++ plugins/admt/src/admtcontroller.cpp | 115 ++++++++++- plugins/admt/src/harmoniccalibration.cpp | 187 +++++++++++++++++- .../admt/src/widgets/registerblockwidget.cpp | 57 ++++-- 6 files changed, 365 insertions(+), 34 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index f1e95648f8..d0fe97beec 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -68,15 +68,30 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject RAMP_MODE_1 }; + enum HarmonicRegister + { + H1MAG, + H1PH, + H2MAG, + H2PH, + H3MAG, + H3PH, + H8MAG, + H8PH, + HARMONIC_REGISTER_COUNT + }; + const char* ChannelIds[CHANNEL_COUNT] = {"rot", "angl", "count", "temp"}; const char* DeviceIds[DEVICE_COUNT] = {"admt4000", "tmc5240"}; const char* MotorAttributes[MOTOR_ATTR_COUNT] = {"amax", "rotate_vmax", "dmax", "disable", "target_pos", "current_pos", "ramp_mode"}; + const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = {0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C}; const char* getChannelId(Channel channel); const char* getDeviceId(Device device); const char* getMotorAttribute(MotorAttribute attribute); + const uint32_t getHarmonicRegister(HarmonicRegister registerID); void connectADMT(); void disconnectADMT(); @@ -85,9 +100,12 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject int getDeviceAttributeValue(const char *deviceName, const char *attributeName, double *returnValue); int setDeviceAttributeValue(const char *deviceName, const char *attributeName, double writeValue); QString calibrate(vector PANG, int cycles = 11, int samplesPerCycle = 256); - int writeDeviceRegistry(const char *deviceName, uint32_t address, double value); - int readDeviceRegistry(const char *deviceName, uint32_t address, double& readValue); + int writeDeviceRegistry(const char *deviceName, uint32_t address, uint32_t value); + int readDeviceRegistry(const char *deviceName, uint32_t address, uint32_t *returnValue); void computeSineCosineOfAngles(const vector& angles); + uint16_t calculateHarmonicCoefficientMagnitude(double harmonicCoefficient, uint16_t originalValue, string key); + uint16_t calculateHarmonicCoefficientPhase(double harmonicCoefficient, uint16_t originalValue); + uint16_t readRegister(uint16_t registerValue, const string key); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index bfd10bcf5a..bce915af3e 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -140,7 +140,7 @@ public Q_SLOTS: void extractCalibrationData(); void importCalibrationData(); void calibrationLogWrite(QString message); - void calibrationLogWriteLn(QString message); + void calibrationLogWriteLn(QString message = ""); void readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value); void writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); void applyLineEditStyle(QLineEdit *widget); @@ -156,6 +156,7 @@ public Q_SLOTS: double convertRPStoVMAX(double rps); double convertVMAXtoRPS(double vmax); void connectLineEditToAMAXConversion(QLineEdit* lineEdit, double& amax); + void connectRegisterBlockToRegistry(RegisterBlockWidget* widget); double convertAccelTimetoAMAX(double accelTime); double convertAMAXtoAccelTime(double amax); void updateCalculatedCoeff(); diff --git a/plugins/admt/include/admt/widgets/registerblockwidget.h b/plugins/admt/include/admt/widgets/registerblockwidget.h index 06b613f3d9..e0f5775cb3 100644 --- a/plugins/admt/include/admt/widgets/registerblockwidget.h +++ b/plugins/admt/include/admt/widgets/registerblockwidget.h @@ -23,8 +23,23 @@ namespace scopy::admt { READWRITE }; + QPushButton *m_readButton, *m_writeButton; + RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t defaultValue, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent = nullptr); + QPushButton *readButton(); + QPushButton *writeButton(); + uint32_t getAddress(); + uint32_t getValue(); + void setValue(uint32_t value); + RegisterBlockWidget::ACCESS_PERMISSION getAccessPermission(); + public Q_SLOTS: + void onValueChanged(int); private: + uint32_t m_address, m_value; + RegisterBlockWidget::ACCESS_PERMISSION m_accessPermission; + + QSpinBox *m_spinBox; + void addReadButton(QWidget *parent); void addWriteButton(QWidget *parent); void applyLineEditStyle(QLineEdit *widget); diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index e73d6c6dad..0ae1df3c5e 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -72,6 +72,13 @@ const char* ADMTController::getMotorAttribute(MotorAttribute attribute) return "Unknown"; } +const uint32_t ADMTController::getHarmonicRegister(HarmonicRegister registerID) +{ + if(registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT){ + return HarmonicRegisters[registerID]; + } + return 0x0; +} int ADMTController::getChannelIndex(const char *deviceName, const char *channelName) { @@ -245,26 +252,26 @@ int ADMTController::setDeviceAttributeValue(const char *deviceName, const char * return result; } -int ADMTController::writeDeviceRegistry(const char *deviceName, uint32_t address, double value) +int ADMTController::writeDeviceRegistry(const char *deviceName, uint32_t address, uint32_t value) { int result = -1; int deviceCount = iio_context_get_devices_count(m_iioCtx); if(deviceCount == 0) { return result; } iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); if(iioDevice == NULL) { return result; } - result = iio_device_reg_write(iioDevice, address, static_cast(value)); + result = iio_device_reg_write(iioDevice, address, value); return result; } -int ADMTController::readDeviceRegistry(const char *deviceName, uint32_t address, double& readValue) +int ADMTController::readDeviceRegistry(const char *deviceName, uint32_t address, uint32_t *returnValue) { int result = -1; int deviceCount = iio_context_get_devices_count(m_iioCtx); if(deviceCount == 0) { return result; } iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); if(iioDevice == NULL) { return result; } - result = iio_device_reg_read(iioDevice, address, reinterpret_cast(&readValue)); + result = iio_device_reg_read(iioDevice, address, returnValue); return result; } @@ -639,3 +646,103 @@ void ADMTController::computeSineCosineOfAngles(const vector& angles) { } } +// Function to calculate the scaled harmonic coefficient magnitude and return a 16-bit unsigned integer +uint16_t ADMTController::calculateHarmonicCoefficientMagnitude(double harmonicCoefficient, uint16_t originalValue, string key) { + // CORDIC scaler + const double cordicScaler = 0.6072; + + // LSB value (0.005493 degrees) + const double LSB = 0.005493; + + // Multiply the harmonic coefficient by the CORDIC scaler + double scaledValue = harmonicCoefficient * cordicScaler; + + uint16_t result = 0; + + // Switch case for different bitmapping based on the key + if (key == "h1" || key == "h2") { + // For h1 and h2: [15:11 reserved], [10:0 write] + result = static_cast(scaledValue / LSB) & 0x07FF; + originalValue = (originalValue & 0xF800) | result; + } + else if (key == "h3" || key == "h8") { + // For h3 and h8: [15:8 reserved], [7:0 write] + result = static_cast(scaledValue / LSB) & 0x00FF; + originalValue = (originalValue & 0xFF00) | result; + } + else { + // Handle invalid key, here we return the original value unchanged + return originalValue; + } + return result; +} + +// Function to calculate the scaled harmonic coefficient phase and return a 16-bit unsigned integer +uint16_t ADMTController::calculateHarmonicCoefficientPhase(double harmonicCoefficient, uint16_t originalValue) { + // LSB value (0.087891 degrees) + const double LSB = 0.087891; + + uint16_t result = 0; + + // Convert the result to an unsigned integer by dividing by LSB, fitting into 12 bits + // Mask to keep only bits 11:0 + result = static_cast(harmonicCoefficient / LSB) & 0x0FFF; + + // Clear bits 11:0 of the original value, keeping bits 15:12 intact + uint16_t preservedValue = (originalValue & 0xF000) | result; + + return preservedValue; +} + +uint16_t ADMTController::readRegister(uint16_t registerValue, const string key) { + double result = 0.0; + const double cordicScaler = 0.6072; + + // Switch case for different bitmapping based on the key + if (key == "h1mag" || key == "h2mag") { + // For h1h2mag: value is in bits [10:0], bits [15:12] are reserved + const double LSB = 0.005493; + + // Extract the value from bits [10:0] + uint16_t extractedValue = registerValue & 0x07FF; + + // Convert the extracted value by applying CORDIC scaler and LSB + double convertedValue = extractedValue * LSB / cordicScaler; + + // Convert the scaled value back to uint16_t + result = static_cast(convertedValue); + } + else if (key == "h3mag" || key == "h8mag") { + // For h3h8mag: value is in bits [7:0], bits [15:8] are reserved + const double LSB = 0.005493; + + // Extract the value from bits [7:0] + uint16_t extractedValue = registerValue & 0x00FF; + + // Convert the extracted value by applying CORDIC scaler and LSB + double convertedValue = extractedValue * LSB / cordicScaler; + + // Convert the scaled value back to uint16_t + result = static_cast(convertedValue); + } + else if (key == "h1phase" || key == "h2phase" || key == "h3phase" || key == "h8phase") { + // For Phase: value is in bits [11:0], bits [15:12] are reserved + const double LSB = 0.087891; + + // Extract the value from bits [11:0] + uint16_t extractedValue = registerValue & 0x0FFF; + + // Convert the extracted value by applying the LSB + double convertedValue = extractedValue * LSB; + + // Convert the scaled value back to uint16_t + result = static_cast(convertedValue); + } + else { + // Indicating an error or invalid key + result = -1.0; + } + + return result; +} + diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 2c88e03963..575a80c8f7 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -409,7 +409,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); calibrationRawDataPlotWidget->addPlotChannel(calibrationSineDataPlotChannel); calibrationRawDataPlotWidget->addPlotChannel(calibrationCosineDataPlotChannel); - calibrationRawDataPlotChannel->setStyle(PlotChannel::PCS_DOTS); + // calibrationRawDataPlotChannel->setStyle(PlotChannel::PCS_DOTS); calibrationRawDataPlotChannel->setEnabled(true); calibrationSineDataPlotChannel->setEnabled(true); calibrationCosineDataPlotChannel->setEnabled(true); @@ -864,12 +864,6 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerLayout->setMargin(0); registerLayout->setSpacing(10); - // QWidget *registerGridWidget = new QWidget(registerWidget); - // QGridLayout *registerGridLayout = new QGridLayout(registerGridWidget); - // registerGridWidget->setLayout(registerGridLayout); - // registerGridLayout->setMargin(0); - // registerGridLayout->setSpacing(10); - QLabel *registerConfigurationLabel = new QLabel("Configuration", registerWidget); StyleHelper::MenuControlLabel(registerConfigurationLabel, "registerConfigurationLabel"); QWidget *registerConfigurationGridWidget = new QWidget(registerWidget); @@ -908,6 +902,8 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() RegisterBlockWidget *generalRegisterBlock = new RegisterBlockWidget("GENERAL", "General Device Configuration", 0x10, 0x1230, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *digIOEnRegisterBlock = new RegisterBlockWidget("DIGIOEN", "Enable Digital Input/Outputs", 0x12, 0x241B, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *angleCkRegisterBlock = new RegisterBlockWidget("ANGLECK", "Primary vs Secondary Angle Check", 0x13, 0x000F, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *eccDcdeRegisterBlock = new RegisterBlockWidget("ECCDCDE", "Error Correction Codes", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *eccDisRegisterBlock = new RegisterBlockWidget("ECCDIS", "Error Correction Code disable", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *absAngleRegisterBlock = new RegisterBlockWidget("ABSANGLE", "Absolute Angle", 0x03, 0xDB00, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *angleRegisterBlock = new RegisterBlockWidget("ANGLE", "Angle Register", 0x05, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); @@ -922,12 +918,11 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() RegisterBlockWidget *tmp0RegisterBlock = new RegisterBlockWidget("TMP0", "Primary Temperature Sensor", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *tmp1RegisterBlock = new RegisterBlockWidget("TMP1", "Secondary Temperature Sensor", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *cnvCntRegisterBlock = new RegisterBlockWidget("CNVCNT", "Conversion Count", 0x14, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *eccDcdeRegisterBlock = new RegisterBlockWidget("ECCDCDE", "Error Correction Codes", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + RegisterBlockWidget *uniqID0RegisterBlock = new RegisterBlockWidget("UNIQID0", "Unique ID Register 0", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *uniqID1RegisterBlock = new RegisterBlockWidget("UNIQID1", "Unique ID Register 1", 0x1F, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *uniqID2RegisterBlock = new RegisterBlockWidget("UNIQID2", "Unique ID Register 2", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); RegisterBlockWidget *uniqID3RegisterBlock = new RegisterBlockWidget("UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", 0x21, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *eccDisRegisterBlock = new RegisterBlockWidget("ECCDIS", "Error Correction Code disable", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *h1MagRegisterBlock = new RegisterBlockWidget("H1MAG", "1st Harmonic error magnitude", 0x15, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *h1PhRegisterBlock = new RegisterBlockWidget("H1PH", "1st Harmonic error phase", 0x16, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); @@ -1009,6 +1004,43 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() tool->addWidgetToCentralContainerHelper(registerScrollArea); + connectRegisterBlockToRegistry(cnvPageRegisterBlock); + connectRegisterBlockToRegistry(digIORegisterBlock); + connectRegisterBlockToRegistry(faultRegisterBlock); + connectRegisterBlockToRegistry(generalRegisterBlock); + connectRegisterBlockToRegistry(digIOEnRegisterBlock); + connectRegisterBlockToRegistry(angleCkRegisterBlock); + connectRegisterBlockToRegistry(eccDcdeRegisterBlock); + connectRegisterBlockToRegistry(eccDisRegisterBlock); + + connectRegisterBlockToRegistry(absAngleRegisterBlock); + connectRegisterBlockToRegistry(angleRegisterBlock); + connectRegisterBlockToRegistry(angleSecRegisterBlock); + connectRegisterBlockToRegistry(sineRegisterBlock); + connectRegisterBlockToRegistry(cosineRegisterBlock); + connectRegisterBlockToRegistry(secAnglIRegisterBlock); + connectRegisterBlockToRegistry(secAnglQRegisterBlock); + connectRegisterBlockToRegistry(radiusRegisterBlock); + connectRegisterBlockToRegistry(diag1RegisterBlock); + connectRegisterBlockToRegistry(diag2RegisterBlock); + connectRegisterBlockToRegistry(tmp0RegisterBlock); + connectRegisterBlockToRegistry(tmp1RegisterBlock); + connectRegisterBlockToRegistry(cnvCntRegisterBlock); + + connectRegisterBlockToRegistry(uniqID0RegisterBlock); + connectRegisterBlockToRegistry(uniqID1RegisterBlock); + connectRegisterBlockToRegistry(uniqID2RegisterBlock); + connectRegisterBlockToRegistry(uniqID3RegisterBlock); + + connectRegisterBlockToRegistry(h1MagRegisterBlock); + connectRegisterBlockToRegistry(h1PhRegisterBlock); + connectRegisterBlockToRegistry(h2MagRegisterBlock); + connectRegisterBlockToRegistry(h2PhRegisterBlock); + connectRegisterBlockToRegistry(h3MagRegisterBlock); + connectRegisterBlockToRegistry(h3PhRegisterBlock); + connectRegisterBlockToRegistry(h8MagRegisterBlock); + connectRegisterBlockToRegistry(h8PhRegisterBlock); + return tool; } @@ -1469,6 +1501,25 @@ void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit* lineEdit, d }); } +void HarmonicCalibration::connectRegisterBlockToRegistry(RegisterBlockWidget* widget) +{ + uint32_t *readValue = new uint32_t; + connect(widget->readButton(), &QPushButton::clicked, this, [=]{ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) + { widget->setValue(*readValue); } + }); + if(widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::READWRITE || + widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::WRITE){ + connect(widget->writeButton(), &QPushButton::clicked, this, [=]{ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), widget->getValue()) == 0) + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) + { widget->setValue(*readValue); } + } + }); + } +} + double HarmonicCalibration::convertRPStoVMAX(double rps) { return (rps * motorMicrostepPerRevolution * motorTimeUnit); @@ -1632,6 +1683,124 @@ void HarmonicCalibration::calibrateData() calibrationLogWriteLn(m_admtController->calibrate(rawDataList, cycleCount, samplesPerCycle)); + uint32_t *h1MagCurrent = new uint32_t, + *h1PhaseCurrent = new uint32_t, + *h2MagCurrent = new uint32_t, + *h2PhaseCurrent = new uint32_t, + *h3MagCurrent = new uint32_t, + *h3PhaseCurrent = new uint32_t, + *h8MagCurrent = new uint32_t, + *h8PhaseCurrent = new uint32_t, + h1MagScaled, + h1PhaseScaled, + h2MagScaled, + h2PhaseScaled, + h3MagScaled, + h3PhaseScaled, + h8MagScaled, + h8PhaseScaled, + h1MagConverted, + h1PhaseConverted, + h2MagConverted, + h2PhaseConverted, + h3MagConverted, + h3PhaseConverted, + h8MagConverted, + h8PhaseConverted; + + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); + + calibrationLogWriteLn(); + calibrationLogWrite("H1 Mag Current: " + QString::number(*h1MagCurrent) + "\n"); + calibrationLogWrite("H1 Phase Current: " + QString::number(*h1PhaseCurrent) + "\n"); + calibrationLogWrite("H2 Mag Current: " + QString::number(*h2MagCurrent) + "\n"); + calibrationLogWrite("H2 Phase Current: " + QString::number(*h2PhaseCurrent) + "\n"); + calibrationLogWrite("H3 Mag Current: " + QString::number(*h3MagCurrent) + "\n"); + calibrationLogWrite("H3 Phase Current: " + QString::number(*h3PhaseCurrent) + "\n"); + calibrationLogWrite("H8 Mag Current: " + QString::number(*h8MagCurrent) + "\n"); + calibrationLogWrite("H8 Phase Current: " + QString::number(*h8PhaseCurrent) + "\n"); + + h1MagScaled = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(m_admtController->HAR_MAG_1, static_cast(*h1MagCurrent), "h1")); + h1PhaseScaled = static_cast(m_admtController->calculateHarmonicCoefficientPhase(m_admtController->HAR_PHASE_1, static_cast(*h1PhaseCurrent))); + h2MagScaled = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(m_admtController->HAR_MAG_2, static_cast(*h2MagCurrent), "h2")); + h2PhaseScaled = static_cast(m_admtController->calculateHarmonicCoefficientPhase(m_admtController->HAR_PHASE_2, static_cast(*h2PhaseCurrent))); + h3MagScaled = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(m_admtController->HAR_MAG_3, static_cast(*h3MagCurrent), "h3")); + h3PhaseScaled = static_cast(m_admtController->calculateHarmonicCoefficientPhase(m_admtController->HAR_PHASE_3, static_cast(*h3PhaseCurrent))); + h8MagScaled = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(m_admtController->HAR_MAG_8, static_cast(*h8MagCurrent), "h8")); + h8PhaseScaled = static_cast(m_admtController->calculateHarmonicCoefficientPhase(m_admtController->HAR_PHASE_8, static_cast(*h8PhaseCurrent))); + + calibrationLogWriteLn(); + calibrationLogWrite("H1 Mag Scaled: " + QString::number(h1MagScaled) + "\n"); + calibrationLogWrite("H1 Phase Scaled: " + QString::number(h1PhaseScaled) + "\n"); + calibrationLogWrite("H2 Mag Scaled: " + QString::number(h2MagScaled) + "\n"); + calibrationLogWrite("H2 Phase Scaled: " + QString::number(h2PhaseScaled) + "\n"); + calibrationLogWrite("H3 Mag Scaled: " + QString::number(h3MagScaled) + "\n"); + calibrationLogWrite("H3 Phase Scaled: " + QString::number(h3PhaseScaled) + "\n"); + calibrationLogWrite("H8 Mag Scaled: " + QString::number(h8MagScaled) + "\n"); + calibrationLogWrite("H8 Phase Scaled: " + QString::number(h8PhaseScaled) + "\n"); + + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), 0x01, 0x02); + + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), + h1MagScaled); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), + h1PhaseScaled); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), + h2MagScaled); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), + h2PhaseScaled); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), + h3MagScaled); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), + h3PhaseScaled); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), + h8MagScaled); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), + h8PhaseScaled); + + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); + + h1MagConverted = m_admtController->readRegister(static_cast(*h1MagCurrent), "h1mag"); + h1PhaseConverted = m_admtController->readRegister(static_cast(*h1PhaseCurrent), "h1phase"); + h2MagConverted = m_admtController->readRegister(static_cast(*h2MagCurrent), "h2mag"); + h2PhaseConverted = m_admtController->readRegister(static_cast(*h2PhaseCurrent), "h2phase"); + h3MagConverted = m_admtController->readRegister(static_cast(*h3MagCurrent), "h3mag"); + h3PhaseConverted = m_admtController->readRegister(static_cast(*h3PhaseCurrent), "h3phase"); + h8MagConverted = m_admtController->readRegister(static_cast(*h8MagCurrent), "h8mag"); + h8PhaseConverted = m_admtController->readRegister(static_cast(*h8PhaseCurrent), "h8phase"); + + calibrationLogWriteLn(); + calibrationLogWrite("H1 Mag Converted: " + QString::number(h1MagConverted) + "\n"); + calibrationLogWrite("H1 Phase Converted: " + QString::number(h1PhaseConverted) + "\n"); + calibrationLogWrite("H2 Mag Converted: " + QString::number(h2MagConverted) + "\n"); + calibrationLogWrite("H2 Phase Converted: " + QString::number(h2PhaseConverted) + "\n"); + calibrationLogWrite("H3 Mag Converted: " + QString::number(h3MagConverted) + "\n"); + calibrationLogWrite("H3 Phase Converted: " + QString::number(h3PhaseConverted) + "\n"); + calibrationLogWrite("H8 Mag Converted: " + QString::number(h8MagConverted) + "\n"); + calibrationLogWrite("H8 Phase Converted: " + QString::number(h8PhaseConverted)); + updateCalculatedCoeff(); vector calibrationAngleErrorsFFT = m_admtController->angle_errors_fft; diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp index 4caca0094a..ccaa4a8db8 100644 --- a/plugins/admt/src/widgets/registerblockwidget.cpp +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -6,6 +6,8 @@ using namespace scopy::admt; RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t defaultValue, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent) : QWidget(parent) + , m_address(address) + , m_accessPermission(accessPermission) { QVBoxLayout *container = new QVBoxLayout(this); setLayout(container); @@ -41,13 +43,14 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui // QLineEdit *lineEdit = new QLineEdit(menuSectionWidget); // applyLineEditStyle(lineEdit); - QSpinBox *spinBox = new QSpinBox(menuSectionWidget); - applySpinBoxStyle(spinBox); - spinBox->setDisplayIntegerBase(16); - spinBox->setMinimum(0); - spinBox->setMaximum(INT_MAX); - spinBox->setPrefix("0x"); - spinBox->setValue(defaultValue); + m_spinBox = new QSpinBox(menuSectionWidget); + applySpinBoxStyle(m_spinBox); + m_spinBox->setDisplayIntegerBase(16); + m_spinBox->setMinimum(0); + m_spinBox->setMaximum(INT_MAX); + m_spinBox->setPrefix("0x"); + m_value = defaultValue; + m_spinBox->setValue(m_value); QWidget *buttonsWidget = new QWidget(menuSectionWidget); QHBoxLayout *buttonsContainer = new QHBoxLayout(buttonsWidget); @@ -55,7 +58,7 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui buttonsContainer->setMargin(0); buttonsContainer->setSpacing(10); - switch(accessPermission) + switch(m_accessPermission) { case ACCESS_PERMISSION::READWRITE: addReadButton(buttonsWidget); @@ -66,35 +69,53 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui break; case ACCESS_PERMISSION::READ: addReadButton(buttonsWidget); - // lineEdit->setReadOnly(true); - spinBox->setReadOnly(true); + m_spinBox->setReadOnly(true); break; } menuCollapseSection->contentLayout()->setSpacing(10); menuCollapseSection->contentLayout()->addWidget(descriptionLabel); - // menuCollapseSection->contentLayout()->addWidget(lineEdit); - menuCollapseSection->contentLayout()->addWidget(spinBox); + menuCollapseSection->contentLayout()->addWidget(m_spinBox); menuCollapseSection->contentLayout()->addWidget(buttonsWidget); container->addWidget(menuSectionWidget); container->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Preferred)); + + connect(m_spinBox, QOverload::of(&QSpinBox::valueChanged), this, &RegisterBlockWidget::onValueChanged); +} + +void RegisterBlockWidget::onValueChanged(int newValue){ m_value = static_cast(newValue); } + +uint32_t RegisterBlockWidget::getValue() { return m_value; } + +void RegisterBlockWidget::setValue(uint32_t value) +{ + m_value = value; + m_spinBox->setValue(m_value); } +uint32_t RegisterBlockWidget::getAddress() { return m_address; } + +RegisterBlockWidget::ACCESS_PERMISSION RegisterBlockWidget::getAccessPermission() { return m_accessPermission; } + void RegisterBlockWidget::addReadButton(QWidget *parent) { - QPushButton *readButton = new QPushButton("Read", parent); - StyleHelper::BlueButton(readButton, "readButton"); - parent->layout()->addWidget(readButton); + m_readButton = new QPushButton("Read", parent); + StyleHelper::BlueButton(m_readButton, "readButton"); + parent->layout()->addWidget(m_readButton); } +QPushButton *RegisterBlockWidget::readButton() { return m_readButton; } + void RegisterBlockWidget::addWriteButton(QWidget *parent) { - QPushButton *writeButton = new QPushButton("Write", parent); - StyleHelper::BlueButton(writeButton, "writeButton"); - parent->layout()->addWidget(writeButton); + m_writeButton = new QPushButton("Write", parent); + StyleHelper::BlueButton(m_writeButton, "writeButton"); + parent->layout()->addWidget(m_writeButton); } +QPushButton *RegisterBlockWidget::writeButton() { return m_writeButton; } + void RegisterBlockWidget::applyLineEditStyle(QLineEdit *widget) { QString style = QString(R"css( From 88e99d884b4c0535e77b58a86d7ee0875ee47206 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 10 Sep 2024 14:05:41 +0800 Subject: [PATCH 023/112] admt: Implement compatible selected plugin Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtplugin.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index 0fe8fdc29a..4a2a3d4eb8 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -15,10 +15,10 @@ bool ADMTPlugin::compatible(QString m_param, QString category) { m_name = "ADMT4000"; bool ret = false; - Connection *conn = ConnectionProvider::open(m_param); + Connection *conn = ConnectionProvider::GetInstance()->open(m_param); if(!conn) { - qWarning(CAT_ADMTPLUGIN) << "No context available for admt"; + qWarning(CAT_ADMTPLUGIN) << "No context available for ADMT"; return false; } @@ -28,7 +28,7 @@ bool ADMTPlugin::compatible(QString m_param, QString category) } ConnectionProvider::close(m_param); - ret = true; + return ret; } @@ -194,11 +194,11 @@ void ADMTPlugin::initMetadata() loadMetadata( R"plugin( { - "priority":100, + "priority":102, "category":[ "iio" ], - "exclude":[""] + "exclude":["*", "!debugger"] } )plugin"); } From 014bc107d0649503a3405f45576238e1c4badf0d Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 10 Sep 2024 14:11:25 +0800 Subject: [PATCH 024/112] admt: Adjusted UI - Set spacing from 10 to 8 - Reduced margin from MenuControlButton Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/harmoniccalibration.cpp | 95 +++++++++++++----------- 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 575a80c8f7..baea1b8702 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -92,18 +92,18 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg MenuSectionWidget *angleWidget = new MenuSectionWidget(rawDataWidget); MenuSectionWidget *countWidget = new MenuSectionWidget(rawDataWidget); MenuSectionWidget *tempWidget = new MenuSectionWidget(rawDataWidget); - rotationWidget->contentLayout()->setSpacing(10); - angleWidget->contentLayout()->setSpacing(10); - countWidget->contentLayout()->setSpacing(10); - tempWidget->contentLayout()->setSpacing(10); + rotationWidget->contentLayout()->setSpacing(8); + angleWidget->contentLayout()->setSpacing(8); + countWidget->contentLayout()->setSpacing(8); + tempWidget->contentLayout()->setSpacing(8); MenuCollapseSection *rotationSection = new MenuCollapseSection("Rotation", MenuCollapseSection::MHCW_NONE, rotationWidget); MenuCollapseSection *angleSection = new MenuCollapseSection("Angle", MenuCollapseSection::MHCW_NONE, angleWidget); MenuCollapseSection *countSection = new MenuCollapseSection("Count", MenuCollapseSection::MHCW_NONE, countWidget); MenuCollapseSection *tempSection = new MenuCollapseSection("Temperature", MenuCollapseSection::MHCW_NONE, tempWidget); - rotationSection->contentLayout()->setSpacing(10); - angleSection->contentLayout()->setSpacing(10); - countSection->contentLayout()->setSpacing(10); - tempSection->contentLayout()->setSpacing(10); + rotationSection->contentLayout()->setSpacing(8); + angleSection->contentLayout()->setSpacing(8); + countSection->contentLayout()->setSpacing(8); + tempSection->contentLayout()->setSpacing(8); rotationWidget->contentLayout()->addWidget(rotationSection); angleWidget->contentLayout()->addWidget(angleSection); @@ -184,9 +184,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg // General Setting Widget MenuSectionWidget *generalWidget = new MenuSectionWidget(generalSettingWidget); - generalWidget->contentLayout()->setSpacing(10); + generalWidget->contentLayout()->setSpacing(8); MenuCollapseSection *generalSection = new MenuCollapseSection("Data Acquisition", MenuCollapseSection::MHCW_NONE, generalWidget); - generalSection->contentLayout()->setSpacing(10); + generalSection->contentLayout()->setSpacing(8); generalWidget->contentLayout()->addWidget(generalSection); // Graph Update Interval @@ -218,7 +218,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg MenuSectionWidget *sequenceWidget = new MenuSectionWidget(generalSettingWidget); MenuCollapseSection *sequenceSection = new MenuCollapseSection("Sequence", MenuCollapseSection::MHCW_NONE, sequenceWidget); sequenceWidget->contentLayout()->addWidget(sequenceSection); - sequenceSection->contentLayout()->setSpacing(10); + sequenceSection->contentLayout()->setSpacing(8); MenuCombo *sequenceTypeMenuCombo = new MenuCombo("Sequence Type", sequenceSection); QComboBox *sequenceTypeComboBox = sequenceTypeMenuCombo->combo(); @@ -268,9 +268,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg // Data Graph Setting Widget MenuSectionWidget *dataGraphWidget = new MenuSectionWidget(generalSettingWidget); - dataGraphWidget->contentLayout()->setSpacing(10); + dataGraphWidget->contentLayout()->setSpacing(8); MenuCollapseSection *dataGraphSection = new MenuCollapseSection("Data Graph", MenuCollapseSection::MHCW_NONE, dataGraphWidget); - dataGraphSection->contentLayout()->setSpacing(10); + dataGraphSection->contentLayout()->setSpacing(8); // Graph Channel m_dataGraphChannelMenuCombo = new MenuCombo("Channel", dataGraphSection); @@ -301,9 +301,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg // Temperature Graph MenuSectionWidget *tempGraphWidget = new MenuSectionWidget(generalSettingWidget); - tempGraphWidget->contentLayout()->setSpacing(10); + tempGraphWidget->contentLayout()->setSpacing(8); MenuCollapseSection *tempGraphSection = new MenuCollapseSection("Temperature Graph", MenuCollapseSection::MHCW_NONE, tempGraphWidget); - tempGraphSection->contentLayout()->setSpacing(10); + tempGraphSection->contentLayout()->setSpacing(8); // Graph Samples QLabel *tempGraphSamplesLabel = new QLabel(generalSection); @@ -387,7 +387,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); QTabWidget *calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); applyTabWidgetStyle(calibrationDataGraphTabWidget); - calibrationDataGraphSectionWidget->contentLayout()->setSpacing(10); + calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); // Raw Data Plot Widget calibrationRawDataPlotWidget = new PlotWidget(); @@ -430,8 +430,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() )css"); calibrationDataGraphChannelsStyle.replace(QString("&&colorname&&"), StyleHelper::getColor("UIElementBackground")); calibrationDataGraphChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); - calibrationDataGraphChannelsLayout->setMargin(0); - calibrationDataGraphChannelsLayout->setSpacing(10); + calibrationDataGraphChannelsLayout->setContentsMargins(20, 5, 20, 5); + calibrationDataGraphChannelsLayout->setSpacing(20); MenuControlButton *toggleAngleButton = createChannelToggleWidget("Angle", QColor(StyleHelper::getColor("ScopyBlue")), calibrationDataGraphChannelsWidget); MenuControlButton *toggleSineButton = createChannelToggleWidget("Sine", sineColor, calibrationDataGraphChannelsWidget); @@ -448,7 +448,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() MenuSectionWidget *FFTDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); QTabWidget *FFTDataGraphTabWidget = new QTabWidget(FFTDataGraphSectionWidget); applyTabWidgetStyle(FFTDataGraphTabWidget); - FFTDataGraphSectionWidget->contentLayout()->setSpacing(10); + FFTDataGraphSectionWidget->contentLayout()->setSpacing(8); FFTDataGraphSectionWidget->contentLayout()->addWidget(FFTDataGraphTabWidget); // FFT Plot Widget @@ -628,7 +628,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationCalculatedCoeffLayout->addWidget(h3RowContainer, 2, 0); calibrationCalculatedCoeffLayout->addWidget(h8RowContainer, 3, 0); - calibrationCoeffSectionWidget->contentLayout()->setSpacing(10); + calibrationCoeffSectionWidget->contentLayout()->setSpacing(8); calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatLabel); calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatSwitch); calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffLabel); @@ -639,7 +639,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Calibration Dataset Configuration MenuSectionWidget *calibrationDatasetConfigSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); MenuCollapseSection *calibrationDatasetConfigCollapseSection = new MenuCollapseSection("Dataset Configuration", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, calibrationDatasetConfigSectionWidget); - calibrationDatasetConfigSectionWidget->contentLayout()->setSpacing(10); + calibrationDatasetConfigSectionWidget->contentLayout()->setSpacing(8); calibrationDatasetConfigSectionWidget->contentLayout()->addWidget(calibrationDatasetConfigCollapseSection); QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", calibrationDatasetConfigCollapseSection); @@ -656,7 +656,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle); - calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(10); + calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(8); calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountLabel); calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountLineEdit); calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleLabel); @@ -667,7 +667,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Calibration Data Section Widget MenuSectionWidget *calibrationDataSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection("Calibration Data", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, calibrationDataSectionWidget); - calibrationDataSectionWidget->contentLayout()->setSpacing(10); + calibrationDataSectionWidget->contentLayout()->setSpacing(8); calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); QPushButton *importDataButton = new QPushButton(calibrationDataCollapseSection); @@ -680,7 +680,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() clearCalibrateDataButton->setText("Clear All Data"); StyleHelper::BlueButton(clearCalibrateDataButton, "clearCalibrateDataButton"); - calibrationDataCollapseSection->contentLayout()->setSpacing(10); + calibrationDataCollapseSection->contentLayout()->setSpacing(8); calibrationDataCollapseSection->contentLayout()->addWidget(importDataButton); calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); calibrationDataCollapseSection->contentLayout()->addWidget(clearCalibrateDataButton); @@ -701,7 +701,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationMotorRampModeCombo->addItem("Ramp Mode 1", QVariant(ADMTController::MotorRampMode::RAMP_MODE_1)); applyComboBoxStyle(calibrationMotorRampModeCombo); - motorConfigurationCollapseSection->contentLayout()->setSpacing(10); + motorConfigurationCollapseSection->contentLayout()->setSpacing(8); motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxVelocitySpinBox); motorConfigurationCollapseSection->contentLayout()->addWidget(motorAccelTimeSpinBox); motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxDisplacementSpinBox); @@ -711,7 +711,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Motor Control Section Widget MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection("Motor Control", MenuCollapseSection::MHCW_NONE, motorControlSectionWidget); - motorControlSectionWidget->contentLayout()->setSpacing(10); + motorControlSectionWidget->contentLayout()->setSpacing(8); motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); StyleHelper::MenuSmallLabel(currentPositionLabel, "currentPositionLabel"); @@ -774,7 +774,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() autoCalibrateCheckBox = new QCheckBox("Auto Calibrate", motorControlSectionWidget); StyleHelper::BlueSquareCheckbox(autoCalibrateCheckBox, "autoCalibrateCheckBox"); - motorControlCollapseSection->contentLayout()->setSpacing(10); + motorControlCollapseSection->contentLayout()->setSpacing(8); motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); motorControlCollapseSection->contentLayout()->addWidget(calibrationMotorCurrentPositionLabel); motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionSpinBox); @@ -786,14 +786,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Logs Section Widget MenuSectionWidget *logsSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); MenuCollapseSection *logsCollapseSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, logsSectionWidget); - logsSectionWidget->contentLayout()->setSpacing(10); + logsSectionWidget->contentLayout()->setSpacing(8); logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); logsPlainTextEdit = new QPlainTextEdit(logsSectionWidget); logsPlainTextEdit->setReadOnly(true); logsPlainTextEdit->setFixedHeight(320); - logsCollapseSection->contentLayout()->setSpacing(10); + logsCollapseSection->contentLayout()->setSpacing(8); logsCollapseSection->contentLayout()->addWidget(logsPlainTextEdit); #pragma endregion @@ -862,7 +862,7 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerScrollArea->setWidget(registerWidget); registerWidget->setLayout(registerLayout); registerLayout->setMargin(0); - registerLayout->setSpacing(10); + registerLayout->setSpacing(8); QLabel *registerConfigurationLabel = new QLabel("Configuration", registerWidget); StyleHelper::MenuControlLabel(registerConfigurationLabel, "registerConfigurationLabel"); @@ -870,7 +870,7 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() QGridLayout *registerConfigurationGridLayout = new QGridLayout(registerConfigurationGridWidget); registerConfigurationGridWidget->setLayout(registerConfigurationGridLayout); registerConfigurationGridLayout->setMargin(0); - registerConfigurationGridLayout->setSpacing(10); + registerConfigurationGridLayout->setSpacing(8); QLabel *registerDeviceIDLabel = new QLabel("Device ID", registerWidget); StyleHelper::MenuControlLabel(registerDeviceIDLabel, "registerDeviceIDLabel"); @@ -878,7 +878,7 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() QGridLayout *registerDeviceIDGridLayout = new QGridLayout(registerDeviceIDGridWidget); registerDeviceIDGridWidget->setLayout(registerDeviceIDGridLayout); registerDeviceIDGridLayout->setMargin(0); - registerDeviceIDGridLayout->setSpacing(10); + registerDeviceIDGridLayout->setSpacing(8); QLabel *registerHarmonicsLabel = new QLabel("Harmonics", registerWidget); StyleHelper::MenuControlLabel(registerHarmonicsLabel, "registerHarmonicsLabel"); @@ -886,7 +886,7 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() QGridLayout *registerHarmonicsGridLayout = new QGridLayout(registerHarmonicsGridWidget); registerHarmonicsGridWidget->setLayout(registerHarmonicsGridLayout); registerHarmonicsGridLayout->setMargin(0); - registerHarmonicsGridLayout->setSpacing(10); + registerHarmonicsGridLayout->setSpacing(8); QLabel *registerSensorDataLabel = new QLabel("Sensor Data", registerWidget); StyleHelper::MenuControlLabel(registerSensorDataLabel, "registerSensorDataLabel"); @@ -894,7 +894,7 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() QGridLayout *registerSensorDataGridLayout = new QGridLayout(registerSensorDataGridWidget); registerSensorDataGridWidget->setLayout(registerSensorDataGridLayout); registerSensorDataGridLayout->setMargin(0); - registerSensorDataGridLayout->setSpacing(10); + registerSensorDataGridLayout->setSpacing(8); RegisterBlockWidget *cnvPageRegisterBlock = new RegisterBlockWidget("CNVPAGE", "Convert Start and Page Select", 0x01, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); RegisterBlockWidget *digIORegisterBlock = new RegisterBlockWidget("DIGIO", "Digital Input Output", 0x04, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); @@ -1053,30 +1053,32 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() QVBoxLayout *leftUtilityLayout = new QVBoxLayout(leftUtilityWidget); leftUtilityWidget->setLayout(leftUtilityLayout); leftUtilityLayout->setMargin(0); - leftUtilityLayout->setSpacing(10); + leftUtilityLayout->setSpacing(8); #pragma region Command Log Widget MenuSectionWidget *commandLogSectionWidget = new MenuSectionWidget(leftUtilityWidget); MenuCollapseSection *commandLogCollapseSection = new MenuCollapseSection("Command Log", MenuCollapseSection::MHCW_NONE, commandLogSectionWidget); + commandLogSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); commandLogSectionWidget->contentLayout()->addWidget(commandLogCollapseSection); QPlainTextEdit *commandLogPlainTextEdit = new QPlainTextEdit(commandLogSectionWidget); commandLogPlainTextEdit->setReadOnly(true); - commandLogPlainTextEdit->setFixedHeight(320); + commandLogPlainTextEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); commandLogCollapseSection->contentLayout()->addWidget(commandLogPlainTextEdit); - leftUtilityLayout->addWidget(commandLogSectionWidget); - leftUtilityLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + leftUtilityLayout->addWidget(commandLogSectionWidget, 1); + leftUtilityLayout->addStretch(); #pragma endregion #pragma endregion #pragma region Center Utility Widget QWidget *centerUtilityWidget = new QWidget(this); QHBoxLayout *centerUtilityLayout = new QHBoxLayout(centerUtilityWidget); - centerUtilityWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + centerUtilityWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + centerUtilityWidget->setContentsMargins(2, 0, 2, 0); centerUtilityWidget->setLayout(centerUtilityLayout); centerUtilityLayout->setMargin(0); - centerUtilityLayout->setSpacing(10); + centerUtilityLayout->setSpacing(8); // centerUtilityLayout->setAlignment(Qt::AlignTop); #pragma region DIGIO Monitor @@ -1130,12 +1132,12 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MTDiagnosticsScrollArea->setWidgetResizable(true); QVBoxLayout *MTDiagnosticsLayout = new QVBoxLayout(MTDiagnosticsWidget); MTDiagnosticsLayout->setMargin(0); - MTDiagnosticsLayout->setSpacing(10); + MTDiagnosticsLayout->setSpacing(5); MenuSectionWidget *MTDiagnosticsSectionWidget = new MenuSectionWidget(centerUtilityWidget); MenuCollapseSection *MTDiagnosticsCollapseSection = new MenuCollapseSection("MT Diagnostics", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MTDiagnosticsSectionWidget); MTDiagnosticsSectionWidget->contentLayout()->addWidget(MTDiagnosticsCollapseSection); - MTDiagnosticsCollapseSection->contentLayout()->setSpacing(10); + MTDiagnosticsCollapseSection->contentLayout()->setSpacing(8); QLabel *AFEDIAG0Label = new QLabel("AFEDIAG0 (%)"); StyleHelper::MenuSmallLabel(AFEDIAG0Label, "AFEDIAG0Label"); @@ -1160,10 +1162,11 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MTDiagnosticsLayout->addWidget(MTDiagnosticsSectionWidget); MTDiagnosticsLayout->addWidget(MTDIAG1SectionWidget); + MTDiagnosticsLayout->addStretch(); #pragma endregion - centerUtilityLayout->addWidget(DIGIOMonitorSectionWidget, 0, Qt::AlignTop); - centerUtilityLayout->addWidget(MTDiagnosticsScrollArea, 0, Qt::AlignTop); + centerUtilityLayout->addWidget(DIGIOMonitorSectionWidget, 1, Qt::AlignTop); + centerUtilityLayout->addWidget(MTDiagnosticsScrollArea); // centerUtilityLayout->addWidget(MTDIAG1SectionWidget, 0, Qt::AlignTop); // centerUtilityLayout->addWidget(MTDiagnosticsSectionWidget, 0, Qt::AlignTop); @@ -1177,7 +1180,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() QVBoxLayout *rightUtilityLayout = new QVBoxLayout(rightUtilityWidget); rightUtilityWidget->setLayout(rightUtilityLayout); rightUtilityLayout->setMargin(0); - rightUtilityLayout->setSpacing(10); + rightUtilityLayout->setSpacing(8); MenuSectionWidget *faultRegisterSectionWidget = new MenuSectionWidget(rightUtilityWidget); MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection("Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, faultRegisterSectionWidget); @@ -1324,6 +1327,7 @@ MenuControlButton *HarmonicCalibration::createStatusLEDWidget(const QString titl menuControlButton->setCheckable(true); menuControlButton->checkBox()->setChecked(true); menuControlButton->setEnabled(false); + menuControlButton->layout()->setMargin(8); return menuControlButton; } @@ -1338,6 +1342,7 @@ MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString menuControlButton->button()->setVisible(false); menuControlButton->setCheckable(false); menuControlButton->checkBox()->setChecked(true); + menuControlButton->layout()->setMargin(0); return menuControlButton; } From a94f677936b0a5a30eee38e9851bbe79ae17492b Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 11 Sep 2024 14:35:35 +0800 Subject: [PATCH 025/112] admt: Set debug to false Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/harmoniccalibration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index baea1b8702..ec32eb981c 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -17,7 +17,7 @@ static int samplesPerCycle = 256; static int totalSamplesCount = cycleCount * samplesPerCycle; static bool startMotor = false; -static bool isDebug = true; +static bool isDebug = false; static bool isCalibrated = false; static double motorTimeUnit = 1.048576; // t = 2^24/16Mhz From 95fdbb9c100cdf6a455879e7151a47523c6a97ef Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 25 Sep 2024 10:41:44 +0800 Subject: [PATCH 026/112] admt: Implemented status indicators for registers in utility tab - Added register enums in controller - Created task for utility tab - Added unit to connect LineEdits - Added isDebug variable to plugin Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 48 ++- .../admt/include/admt/harmoniccalibration.h | 40 ++- plugins/admt/src/admtcontroller.cpp | 242 +++++++++++++- plugins/admt/src/admtplugin.cpp | 6 +- plugins/admt/src/harmoniccalibration.cpp | 307 ++++++++++++++---- 5 files changed, 550 insertions(+), 93 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index d0fe97beec..9bba860f61 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -19,6 +19,7 @@ #include #include #include +#include using namespace std; @@ -81,17 +82,54 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject HARMONIC_REGISTER_COUNT }; + enum ConfigurationRegister + { + CNVPAGE, + DIGIO, + FAULT, + GENERAL, + DIGIOEN, + ANGLECK, + ECCDCDE, + ECCDIS, + CONFIGURATION_REGISTER_COUNT + }; + + enum SensorRegister + { + ABSANGLE, + ANGLEREG, + ANGLESEC, + SINE, + COSINE, + SECANGLI, + SECANGLQ, + RADIUS, + DIAG1, + DIAG2, + TMP0, + TMP1, + CNVCNT, + SENSOR_REGISTER_COUNT + }; + const char* ChannelIds[CHANNEL_COUNT] = {"rot", "angl", "count", "temp"}; const char* DeviceIds[DEVICE_COUNT] = {"admt4000", "tmc5240"}; const char* MotorAttributes[MOTOR_ATTR_COUNT] = {"amax", "rotate_vmax", "dmax", "disable", "target_pos", "current_pos", "ramp_mode"}; - const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = {0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C}; + const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = { 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C }; + const uint32_t ConfigurationRegisters[CONFIGURATION_REGISTER_COUNT] = { 0x01, 0x04, 0x06, 0x10, 0x12, 0x13, 0x1D, 0x23 }; + const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = { 0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14 }; + const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }; const char* getChannelId(Channel channel); const char* getDeviceId(Device device); const char* getMotorAttribute(MotorAttribute attribute); const uint32_t getHarmonicRegister(HarmonicRegister registerID); + const uint32_t getConfigurationRegister(ConfigurationRegister registerID); + const uint32_t getSensorRegister(SensorRegister registerID); + const uint32_t getSensorPage(SensorRegister registerID); void connectADMT(); void disconnectADMT(); @@ -105,7 +143,13 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject void computeSineCosineOfAngles(const vector& angles); uint16_t calculateHarmonicCoefficientMagnitude(double harmonicCoefficient, uint16_t originalValue, string key); uint16_t calculateHarmonicCoefficientPhase(double harmonicCoefficient, uint16_t originalValue); - uint16_t readRegister(uint16_t registerValue, const string key); + double getActualHarmonicRegisterValue(uint16_t registerValue, const string key); + map getFaultRegisterBitMapping(uint16_t registerValue); + map getGeneralRegisterBitMapping(uint16_t registerValue); + map getDigioenRegisterBitMapping(uint16_t registerValue); + map getDiag1RegisterBitMapping_Register(uint16_t registerValue); + map getDiag1RegisterBitMapping_Afe(uint16_t registerValue); + map getDiag2RegisterBitMapping(uint16_t registerValue); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index bce915af3e..d902e15cf3 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -4,6 +4,8 @@ #include "scopy-admt_export.h" #include "sismograph.hpp" +#include + #include #include #include @@ -48,7 +50,7 @@ class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget { Q_OBJECT public: - HarmonicCalibration(ADMTController *m_admtController, QWidget *parent = nullptr); + HarmonicCalibration(ADMTController *m_admtController, bool isDebug = false, QWidget *parent = nullptr); ~HarmonicCalibration(); bool running() const; void setRunning(bool newRunning); @@ -58,6 +60,10 @@ public Q_SLOTS: void start(); void restart(); void timerTask(); + void calibrationTask(); + void motorCalibrationAcquisitionTask(); + void utilityTask(); + void clearCommandLog(); void canCalibrate(bool); Q_SIGNALS: void runningChanged(bool); @@ -65,15 +71,17 @@ public Q_SLOTS: private: ADMTController *m_admtController; iio_context *m_ctx; - bool m_running; + bool m_running, isDebug; ToolTemplate *tool; GearBtn *settingsButton; InfoBtn *infoButton; RunBtn *runButton; - double rotation, angle, count, temp, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode; + double rotation, angle, count, temp, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode, + afeDiag0, afeDiag1, afeDiag2; - QPushButton *openLastMenuButton, *calibrationStartMotorButton, *applyCalibrationDataButton, *calibrateDataButton, *extractDataButton; + QPushButton *openLastMenuButton, *calibrationStartMotorButton, *applyCalibrationDataButton, *calibrateDataButton, *extractDataButton, + *clearCommandLogButton; QButtonGroup *rightMenuButtonGroup; QLineEdit *graphUpdateIntervalLineEdit, *dataSampleSizeLineEdit, @@ -81,7 +89,9 @@ public Q_SLOTS: *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, - *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit; + *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit, + *AFEDIAG0LineEdit, *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; + QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, *calibrationMotorCurrentPositionLabel, *motorAmaxValueLabel, *motorRotateVmaxValueLabel, *motorDmaxValueLabel, @@ -108,7 +118,7 @@ public Q_SLOTS: QListWidget *rawDataListWidget; - QPlainTextEdit *logsPlainTextEdit; + QPlainTextEdit *logsPlainTextEdit, *commandLogPlainTextEdit; QCheckBox *autoCalibrateCheckBox; @@ -118,11 +128,17 @@ public Q_SLOTS: HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, *motorMaxDisplacementSpinBox, *motorTargetPositionSpinBox; + MenuControlButton *DIGIOBusyStatusLED ,*DIGIOCNVStatusLED ,*DIGIOSENTStatusLED ,*DIGIOACALCStatusLED ,*DIGIOFaultStatusLED ,*DIGIOBootloaderStatusLED, + *R0StatusLED, *R1StatusLED, *R2StatusLED, *R3StatusLED, *R4StatusLED, *R5StatusLED, *R6StatusLED, *R7StatusLED, + *VDDUnderVoltageStatusLED, *VDDOverVoltageStatusLED, *VDRIVEUnderVoltageStatusLED, *VDRIVEOverVoltageStatusLED, + *AFEDIAGStatusLED, *NVMCRCFaultStatusLED, *ECCDoubleBitErrorStatusLED, *OscillatorDriftStatusLED, *CountSensorFalseStateStatusLED, + *AngleCrossCheckStatusLED, *TurnCountSensorLevelsStatusLED, *MTDIAGStatusLED, *TurnCounterCrossCheckStatusLED, *RadiusCheckStatusLED, *SequencerWatchdogStatusLED; + void updateChannelValues(); void updateLineEditValues(); void updateGeneralSettingEnabled(bool value); void connectLineEditToNumber(QLineEdit* lineEdit, int& variable); - void connectLineEditToNumber(QLineEdit* lineEdit, double& variable); + void connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit = ""); void connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph); void connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph); void changeGraphColorByChannelName(Sismograph* graph, const char* channelName); @@ -133,7 +149,6 @@ public Q_SLOTS: void updateLabelValue(QLabel* label, int channelIndex); void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); void updateChannelValue(int channelIndex); - void calibrationTask(); void addAngleToRawDataList(); void calibrateData(); void registerCalibrationData(); @@ -141,6 +156,7 @@ public Q_SLOTS: void importCalibrationData(); void calibrationLogWrite(QString message); void calibrationLogWriteLn(QString message = ""); + void commandLogWrite(QString message); void readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value); void writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); void applyLineEditStyle(QLineEdit *widget); @@ -150,7 +166,6 @@ public Q_SLOTS: void initializeMotor(); void stepMotorAcquisition(double step = -408); void clearRawDataList(); - void motorCalibrationAcquisitionTask(); void connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax); void connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute); double convertRPStoVMAX(double rps); @@ -166,8 +181,13 @@ public Q_SLOTS: void applyTabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor = "ScopyBlue"); MenuControlButton *createStatusLEDWidget(const QString title, QColor color, QWidget *parent = nullptr); MenuControlButton *createChannelToggleWidget(const QString title, QColor color, QWidget *parent = nullptr); + void updateDigioMonitor(); + void updateMTDiagRegister(); + void updateFaultRegister(); + void updateMTDiagnostics(); + void changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked = true); - QTimer *timer, *calibrationTimer, *motorCalibrationAcquisitionTimer; + QTimer *timer, *calibrationTimer, *motorCalibrationAcquisitionTimer, *utilityTimer; int uuid = 0; const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 0ae1df3c5e..73516ece93 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -15,6 +15,7 @@ #include #include #include +#include static const size_t maxAttrSize = 512; @@ -80,6 +81,30 @@ const uint32_t ADMTController::getHarmonicRegister(HarmonicRegister registerID) return 0x0; } +const uint32_t ADMTController::getConfigurationRegister(ConfigurationRegister registerID) +{ + if(registerID >= 0 && registerID < CONFIGURATION_REGISTER_COUNT){ + return ConfigurationRegisters[registerID]; + } + return UINT32_MAX; +} + +const uint32_t ADMTController::getSensorRegister(SensorRegister registerID) +{ + if(registerID >= 0 && registerID < SENSOR_REGISTER_COUNT){ + return SensorRegisters[registerID]; + } + return UINT32_MAX; +} + +const uint32_t ADMTController::getSensorPage(SensorRegister registerID) +{ + if(registerID >= 0 && registerID < SENSOR_REGISTER_COUNT){ + return SensorPages[registerID]; + } + return UINT32_MAX; +} + int ADMTController::getChannelIndex(const char *deviceName, const char *channelName) { iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); @@ -694,7 +719,7 @@ uint16_t ADMTController::calculateHarmonicCoefficientPhase(double harmonicCoeffi return preservedValue; } -uint16_t ADMTController::readRegister(uint16_t registerValue, const string key) { +double ADMTController::getActualHarmonicRegisterValue(uint16_t registerValue, const string key) { double result = 0.0; const double cordicScaler = 0.6072; @@ -707,10 +732,7 @@ uint16_t ADMTController::readRegister(uint16_t registerValue, const string key) uint16_t extractedValue = registerValue & 0x07FF; // Convert the extracted value by applying CORDIC scaler and LSB - double convertedValue = extractedValue * LSB / cordicScaler; - - // Convert the scaled value back to uint16_t - result = static_cast(convertedValue); + result = extractedValue * LSB / cordicScaler; } else if (key == "h3mag" || key == "h8mag") { // For h3h8mag: value is in bits [7:0], bits [15:8] are reserved @@ -720,10 +742,7 @@ uint16_t ADMTController::readRegister(uint16_t registerValue, const string key) uint16_t extractedValue = registerValue & 0x00FF; // Convert the extracted value by applying CORDIC scaler and LSB - double convertedValue = extractedValue * LSB / cordicScaler; - - // Convert the scaled value back to uint16_t - result = static_cast(convertedValue); + result = extractedValue * LSB / cordicScaler; } else if (key == "h1phase" || key == "h2phase" || key == "h3phase" || key == "h8phase") { // For Phase: value is in bits [11:0], bits [15:12] are reserved @@ -733,16 +752,211 @@ uint16_t ADMTController::readRegister(uint16_t registerValue, const string key) uint16_t extractedValue = registerValue & 0x0FFF; // Convert the extracted value by applying the LSB - double convertedValue = extractedValue * LSB; - - // Convert the scaled value back to uint16_t - result = static_cast(convertedValue); + result = extractedValue * LSB; } else { // Indicating an error or invalid key - result = -1.0; + result = -404.0; + } + + return result; +} + +map ADMTController::getFaultRegisterBitMapping(uint16_t registerValue) { + map result; + + // Extract each bit and store the result in the map + // Rain: Current returns it as value. + result["Sequencer Watchdog"] = (registerValue >> 15) & 0x01; + result["AMR Radius Check"] = (registerValue >> 14) & 0x01; + result["Turn Counter Cross Check"] = (registerValue >> 13) & 0x01; + result["MT Diagnostic"] = (registerValue >> 12) & 0x01; + result["Turn Count Sensor Levels"] = (registerValue >> 11) & 0x01; + result["Angle Cross Check"] = (registerValue >> 10) & 0x01; + result["Count Sensor False State"] = (registerValue >> 9) & 0x01; + result["Oscillator Drift"] = (registerValue >> 8) & 0x01; + result["ECC Double Bit Error"] = (registerValue >> 7) & 0x01; + result["Reserved"] = (registerValue >> 6) & 0x01; + result["NVM CRC Fault"] = (registerValue >> 5) & 0x01; + result["AFE Diagnostic"] = (registerValue >> 4) & 0x01; + result["VDRIVE Over Voltage"] = (registerValue >> 3) & 0x01; + result["VDRIVE Under Voltage"] = (registerValue >> 2) & 0x01; + result["VDD Over Voltage"] = (registerValue >> 1) & 0x01; + result["VDD Under Voltage"] = (registerValue >> 0) & 0x01; + + return result; +} +// // How to read each value sample +// for (const auto& pair : result) { +// std::cout << pair.first << ": " << (pair.second ? "Set" : "Not Set") << std::endl; +// } + +map ADMTController::getGeneralRegisterBitMapping(uint16_t registerValue) { + map result; + + // Bit 15: STORAGE[7] + result["STORAGE[7]"] = ((registerValue >> 15) & 0x01) ? "Set" : "Not Set"; + + // Bits 14:13: Convert Synchronization + uint16_t convertSync = (registerValue >> 13) & 0x03; + switch (convertSync) { + case 0x00: + result["Convert Synchronization"] = "Disabled"; + break; + case 0x03: + result["Convert Synchronization"] = "Enabled"; + break; + default: + result["Convert Synchronization"] = "Reserved"; + break; + } + + // Bit 12: Angle Filter + result["Angle Filter"] = ((registerValue >> 12) & 0x01) ? "Enabled" : "Disabled"; + + // Bit 11: STORAGE[6] + result["STORAGE[6]"] = ((registerValue >> 11) & 0x01) ? "Set" : "Not Set"; + + // Bit 10: 8th Harmonic + result["8th Harmonic"] = ((registerValue >> 10) & 0x01) ? "User-Supplied Values" : "ADI Factory Values"; + + // // Bit 9: Reserved (skipped) + // result["Reserved"] = "Reserved"; + + // Bits 8:6: STORAGE[5:3] + uint16_t storage_5_3 = (registerValue >> 6) & 0x07; + result["STORAGE[5:3]"] = std::to_string(storage_5_3); + + // Bits 5:4: Sequence Type + uint16_t sequenceType = (registerValue >> 4) & 0x03; + switch (sequenceType) { + case 0x00: + result["Sequence Type"] = "Mode 2"; + break; + case 0x03: + result["Sequence Type"] = "Mode 1"; + break; + default: + result["Sequence Type"] = "Reserved"; + break; } + // Bits 3:1: STORAGE[2:0] + uint16_t storage_2_0 = (registerValue >> 1) & 0x07; + result["STORAGE[2:0]"] = std::to_string(storage_2_0); + + // Bit 0: Conversion Type + result["Conversion Type"] = (registerValue & 0x01) ? "One-shot conversion" : "Continuous conversions"; + + return result; +} +// // How to read each value sample +// for (const auto& pair : result) { +// std::cout << pair.first << ": " << pair.second << std::endl; +// } + +map ADMTController::getDigioenRegisterBitMapping(uint16_t registerValue) { + map result; + + // // Bits 15:14: Reserved (skipped) + // result["Reserved (15:14)"] = "Reserved"; + + // Bit 13: DIGIO5EN + result["DIGIO5EN"] = ((registerValue >> 13) & 0x01) ? true : false; // ? "GPIO5 output enable" : "GPIO5 output disable"; + + // Bit 12: DIGIO4EN + result["DIGIO4EN"] = ((registerValue >> 12) & 0x01) ? true : false; // ? "GPIO4 output enable" : "GPIO4 output disable"; + + // Bit 11: DIGIO3EN + result["DIGIO3EN"] = ((registerValue >> 11) & 0x01) ? true : false; // ? "GPIO3 output enable" : "GPIO3 output disable"; + + // Bit 10: DIGIO2EN + result["DIGIO2EN"] = ((registerValue >> 10) & 0x01) ? true : false; // ? "GPIO2 output enable" : "GPIO2 output disable"; + + // Bit 9: DIGIO1EN + result["DIGIO1EN"] = ((registerValue >> 9) & 0x01) ? true : false; // ? "GPIO1 output enable" : "GPIO1 output disable"; + + // Bit 8: DIGIO0EN + result["DIGIO0EN"] = ((registerValue >> 8) & 0x01) ? true : false; // ? "GPIO0 output enable" : "GPIO0 output disable"; + + // // Bits 7:6: Reserved (skipped) + // result["Reserved (7:6)"] = "Reserved"; + + // Bit 5: Bootload + result["BOOTLOAD"] = ((registerValue >> 5) & 0x01) ? false : true; // ? "GPIO5" : "Bootload (Output only)"; + + // Bit 4: Fault + result["FAULT"] = ((registerValue >> 4) & 0x01) ? false : true; // ? "GPIO4" : "Fault (Output only)"; + + // Bit 3: Acalc + result["ACALC"] = ((registerValue >> 3) & 0x01) ? false : true; // ? "GPIO3" : "Acalc (Output only)"; + + // Bit 2: Sent + result["SENT"] = ((registerValue >> 2) & 0x01) ? false : true; // ? "GPIO2" : "Sent (Output only)"; + + // Bit 1: Cnv + result["CNV"] = ((registerValue >> 1) & 0x01) ? false : true; // ? "GPIO1" : "Cnv (Output only)"; + + // Bit 0: Busy + result["BUSY"] = (registerValue & 0x01) ? false : true; // ? "GPIO0" : "Busy (Output only)"; + + return result; +} + +map ADMTController::getDiag1RegisterBitMapping_Register(uint16_t registerValue) { + map result; + + // Bits 15 to 8: R7 to R0 (Enabled or Disabled) + result["R7"] = ((registerValue >> 15) & 0x01) ? true : false; + result["R6"] = ((registerValue >> 14) & 0x01) ? true : false; + result["R5"] = ((registerValue >> 13) & 0x01) ? true : false; + result["R4"] = ((registerValue >> 12) & 0x01) ? true : false; + result["R3"] = ((registerValue >> 11) & 0x01) ? true : false; + result["R2"] = ((registerValue >> 10) & 0x01) ? true : false; + result["R1"] = ((registerValue >> 9) & 0x01) ? true : false; + result["R0"] = ((registerValue >> 8) & 0x01) ? true : false; + + return result; +} + +map ADMTController::getDiag1RegisterBitMapping_Afe(uint16_t registerValue) { + map result; + + // Bits 7:0: AFE Diagnostic 2 - Measurement of Fixed voltage (stored in 2's complement) + int8_t afeDiagnostic = static_cast(registerValue & 0x00FF); // Interpret as signed 8-bit + + // Choose the correct resolution based on the voltage level (5V or 3.3V part) + double resolution = 0.003222; // 0.0048828 if 5V + + // Convert the AFE Diagnostic value to a voltage + double diagnosticVoltage = static_cast(afeDiagnostic) * resolution; + result["AFE Diagnostic 2"] = diagnosticVoltage; + return result; } +map ADMTController::getDiag2RegisterBitMapping(uint16_t registerValue) { + map result; + + // Bits 15:8: AFE Diagnostic 1 - Measurement of AFE +57% diagnostic resistor + uint16_t afeDiagnostic1 = (registerValue >> 8) & 0x00FF; + + // Convert AFE Diagnostic 1 value to double + // Rain: adjust scaling factor as needed with actual method. + double diagnostic1Voltage = static_cast(afeDiagnostic1) * 0.01; // what I found (to be confirmed) + + // Store the result with fixed precision + result["AFE Diagnostic 1 (+57%)"] = diagnostic1Voltage; + + // Bits 7:0: AFE Diagnostic 0 - Measurement of AFE -57% diagnostic resistor + uint16_t afeDiagnostic0 = registerValue & 0x00FF; + + // Convert AFE Diagnostic 0 value to double + // Rain: adjust scaling factor as needed with actual method. + double diagnostic0Voltage = static_cast(afeDiagnostic0) * 0.01; // what I found (to be confirmed) + + // Store the result with fixed precision + result["AFE Diagnostic 0 (-57%)"] = diagnostic0Voltage; + + return result; +} \ No newline at end of file diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index 4a2a3d4eb8..aee3146a94 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -11,6 +11,8 @@ Q_LOGGING_CATEGORY(CAT_ADMTPLUGIN, "ADMTPlugin") using namespace scopy::admt; using namespace scopy::grutil; +const bool isDebug = false; + bool ADMTPlugin::compatible(QString m_param, QString category) { m_name = "ADMT4000"; @@ -28,7 +30,7 @@ bool ADMTPlugin::compatible(QString m_param, QString category) } ConnectionProvider::close(m_param); - + if(isDebug) return true; return ret; } @@ -164,7 +166,7 @@ bool ADMTPlugin::onConnect() m_admtController = new ADMTController(m_param, this); m_admtController->connectADMT(); - harmonicCalibration = new HarmonicCalibration(m_admtController); + harmonicCalibration = new HarmonicCalibration(m_admtController, isDebug); m_toolList[0]->setTool(harmonicCalibration); return true; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index ec32eb981c..9deee33554 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -6,6 +6,8 @@ static int sampleRate = 50; static int calibrationTimerRate = 100; static int motorCalibrationAcquisitionTimerRate = 20; +static int utilityTimerRate = 1000; + static int bufferSize = 1; static int dataGraphSamples = 100; static int tempGraphSamples = 100; @@ -17,7 +19,6 @@ static int samplesPerCycle = 256; static int totalSamplesCount = cycleCount * samplesPerCycle; static bool startMotor = false; -static bool isDebug = false; static bool isCalibrated = false; static double motorTimeUnit = 1.048576; // t = 2^24/16Mhz @@ -46,8 +47,9 @@ using namespace scopy; using namespace scopy::admt; using namespace scopy::grutil; -HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidget *parent) +HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool isDebug, QWidget *parent) : QWidget(parent) + , isDebug(isDebug) , m_admtController(m_admtController) { rotationChannelName = m_admtController->getChannelId(ADMTController::Channel::ROTATION); @@ -96,10 +98,10 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg angleWidget->contentLayout()->setSpacing(8); countWidget->contentLayout()->setSpacing(8); tempWidget->contentLayout()->setSpacing(8); - MenuCollapseSection *rotationSection = new MenuCollapseSection("Rotation", MenuCollapseSection::MHCW_NONE, rotationWidget); - MenuCollapseSection *angleSection = new MenuCollapseSection("Angle", MenuCollapseSection::MHCW_NONE, angleWidget); + MenuCollapseSection *rotationSection = new MenuCollapseSection("AMR Angle", MenuCollapseSection::MHCW_NONE, rotationWidget); + MenuCollapseSection *angleSection = new MenuCollapseSection("GMR Angle", MenuCollapseSection::MHCW_NONE, angleWidget); MenuCollapseSection *countSection = new MenuCollapseSection("Count", MenuCollapseSection::MHCW_NONE, countWidget); - MenuCollapseSection *tempSection = new MenuCollapseSection("Temperature", MenuCollapseSection::MHCW_NONE, tempWidget); + MenuCollapseSection *tempSection = new MenuCollapseSection("Sensor Temperature", MenuCollapseSection::MHCW_NONE, tempWidget); rotationSection->contentLayout()->setSpacing(8); angleSection->contentLayout()->setSpacing(8); countSection->contentLayout()->setSpacing(8); @@ -358,6 +360,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg motorCalibrationAcquisitionTimer = new QTimer(this); connect(motorCalibrationAcquisitionTimer, &QTimer::timeout, this, &HarmonicCalibration::motorCalibrationAcquisitionTask); + utilityTimer = new QTimer(this); + connect(utilityTimer, &QTimer::timeout, this, &HarmonicCalibration::utilityTask); + tabWidget->addTab(createCalibrationWidget(), "Calibration"); tabWidget->addTab(createUtilityWidget(), "Utility"); tabWidget->addTab(createRegistersWidget(), "Registers"); @@ -367,6 +372,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, QWidg if(index == 1) { calibrationTimer->start(calibrationTimerRate); } else { calibrationTimer->stop(); } + + if(index == 2) { utilityTimer->start(utilityTimerRate); } + else { utilityTimer->stop(); } }); } @@ -1059,12 +1067,18 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MenuCollapseSection *commandLogCollapseSection = new MenuCollapseSection("Command Log", MenuCollapseSection::MHCW_NONE, commandLogSectionWidget); commandLogSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); commandLogSectionWidget->contentLayout()->addWidget(commandLogCollapseSection); + commandLogCollapseSection->contentLayout()->setSpacing(8); - QPlainTextEdit *commandLogPlainTextEdit = new QPlainTextEdit(commandLogSectionWidget); + commandLogPlainTextEdit = new QPlainTextEdit(commandLogSectionWidget); commandLogPlainTextEdit->setReadOnly(true); commandLogPlainTextEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + clearCommandLogButton = new QPushButton("Clear Command Logs", commandLogSectionWidget); + StyleHelper::BlueButton(clearCommandLogButton, "clearCommandLogButton"); + connect(clearCommandLogButton, &QPushButton::clicked, this, &HarmonicCalibration::clearCommandLog); + commandLogCollapseSection->contentLayout()->addWidget(commandLogPlainTextEdit); + commandLogCollapseSection->contentLayout()->addWidget(clearCommandLogButton); leftUtilityLayout->addWidget(commandLogSectionWidget, 1); leftUtilityLayout->addStretch(); @@ -1086,12 +1100,12 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection("DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, DIGIOMonitorSectionWidget); DIGIOMonitorSectionWidget->contentLayout()->addWidget(DIGIOMonitorCollapseSection); - MenuControlButton *DIGIOBusyStatusLED = createStatusLEDWidget("BUSY", statusLEDColor, DIGIOMonitorCollapseSection); - MenuControlButton *DIGIOCNVStatusLED = createStatusLEDWidget("CNV", statusLEDColor, DIGIOMonitorCollapseSection); - MenuControlButton *DIGIOSENTStatusLED = createStatusLEDWidget("SENT", statusLEDColor, DIGIOMonitorCollapseSection); - MenuControlButton *DIGIOACALCStatusLED = createStatusLEDWidget("ACALC", statusLEDColor, DIGIOMonitorCollapseSection); - MenuControlButton *DIGIOFaultStatusLED = createStatusLEDWidget("FAULT", statusLEDColor, DIGIOMonitorCollapseSection); - MenuControlButton *DIGIOBootloaderStatusLED = createStatusLEDWidget("BOOTLOADER", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOBusyStatusLED = createStatusLEDWidget("BUSY", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOCNVStatusLED = createStatusLEDWidget("CNV", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOSENTStatusLED = createStatusLEDWidget("SENT", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOACALCStatusLED = createStatusLEDWidget("ACALC", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOFaultStatusLED = createStatusLEDWidget("FAULT", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOBootloaderStatusLED = createStatusLEDWidget("BOOTLOADER", statusLEDColor, DIGIOMonitorCollapseSection); DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBusyStatusLED); DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOCNVStatusLED); @@ -1106,14 +1120,14 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MenuCollapseSection *MTDIAG1CollapseSection = new MenuCollapseSection("MT Diagnostic Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MTDIAG1SectionWidget); MTDIAG1SectionWidget->contentLayout()->addWidget(MTDIAG1CollapseSection); - MenuControlButton *R0StatusLED = createStatusLEDWidget("R0", statusLEDColor, MTDIAG1SectionWidget); - MenuControlButton *R1StatusLED = createStatusLEDWidget("R1", statusLEDColor, MTDIAG1SectionWidget); - MenuControlButton *R2StatusLED = createStatusLEDWidget("R2", statusLEDColor, MTDIAG1SectionWidget); - MenuControlButton *R3StatusLED = createStatusLEDWidget("R3", statusLEDColor, MTDIAG1SectionWidget); - MenuControlButton *R4StatusLED = createStatusLEDWidget("R4", statusLEDColor, MTDIAG1SectionWidget); - MenuControlButton *R5StatusLED = createStatusLEDWidget("R5", statusLEDColor, MTDIAG1SectionWidget); - MenuControlButton *R6StatusLED = createStatusLEDWidget("R6", statusLEDColor, MTDIAG1SectionWidget); - MenuControlButton *R7StatusLED = createStatusLEDWidget("R7", statusLEDColor, MTDIAG1SectionWidget); + R0StatusLED = createStatusLEDWidget("R0", statusLEDColor, MTDIAG1SectionWidget); + R1StatusLED = createStatusLEDWidget("R1", statusLEDColor, MTDIAG1SectionWidget); + R2StatusLED = createStatusLEDWidget("R2", statusLEDColor, MTDIAG1SectionWidget); + R3StatusLED = createStatusLEDWidget("R3", statusLEDColor, MTDIAG1SectionWidget); + R4StatusLED = createStatusLEDWidget("R4", statusLEDColor, MTDIAG1SectionWidget); + R5StatusLED = createStatusLEDWidget("R5", statusLEDColor, MTDIAG1SectionWidget); + R6StatusLED = createStatusLEDWidget("R6", statusLEDColor, MTDIAG1SectionWidget); + R7StatusLED = createStatusLEDWidget("R7", statusLEDColor, MTDIAG1SectionWidget); MTDIAG1CollapseSection->contentLayout()->addWidget(R0StatusLED); MTDIAG1CollapseSection->contentLayout()->addWidget(R1StatusLED); @@ -1146,12 +1160,18 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() QLabel *AFEDIAG2Label = new QLabel("AFEDIAG2 (V)"); StyleHelper::MenuSmallLabel(AFEDIAG2Label, "AFEDIAG2Label"); - QLineEdit *AFEDIAG0LineEdit = new QLineEdit("-57.0312", MTDiagnosticsSectionWidget); - QLineEdit *AFEDIAG1LineEdit = new QLineEdit("56.25", MTDiagnosticsSectionWidget); - QLineEdit *AFEDIAG2LineEdit = new QLineEdit("-312.499m", MTDiagnosticsSectionWidget); + AFEDIAG0LineEdit = new QLineEdit("-57.0312", MTDiagnosticsSectionWidget); + AFEDIAG1LineEdit = new QLineEdit("56.25", MTDiagnosticsSectionWidget); + AFEDIAG2LineEdit = new QLineEdit("-312.499m", MTDiagnosticsSectionWidget); applyLineEditStyle(AFEDIAG0LineEdit); applyLineEditStyle(AFEDIAG1LineEdit); applyLineEditStyle(AFEDIAG2LineEdit); + AFEDIAG0LineEdit->setReadOnly(true); + AFEDIAG1LineEdit->setReadOnly(true); + AFEDIAG2LineEdit->setReadOnly(true); + connectLineEditToNumber(AFEDIAG0LineEdit, afeDiag0, "V"); + connectLineEditToNumber(AFEDIAG1LineEdit, afeDiag1, "V"); + connectLineEditToNumber(AFEDIAG2LineEdit, afeDiag2, "V"); MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0Label); MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0LineEdit); @@ -1186,26 +1206,26 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection("Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, faultRegisterSectionWidget); faultRegisterSectionWidget->contentLayout()->addWidget(faultRegisterCollapseSection); - MenuControlButton *vddUnderVoltageStatusLED = createStatusLEDWidget("VDD Under Voltage", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *vddOverVoltageStatusLED = createStatusLEDWidget("VDD Over Voltage", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *vDriveUnderVoltageStatusLED = createStatusLEDWidget("VDRIVE Under Voltage", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *vDriveOverVoltageStatusLED = createStatusLEDWidget("VDRIVE Over Voltage", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *AFEDIAGStatusLED = createStatusLEDWidget("AFEDIAG", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *NVMCRCFaultStatusLED = createStatusLEDWidget("NVM CRC Fault", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *ECCDoubleBitErrorStatusLED = createStatusLEDWidget("ECC Double Bit Error", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *OscillatorDriftStatusLED = createStatusLEDWidget("Oscillator Drift", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *CountSensorFalseStateStatusLED = createStatusLEDWidget("Count Sensor False State", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *AngleCrossCheckStatusLED = createStatusLEDWidget("Angle Cross Check", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *TurnCountSensorLevelsStatusLED = createStatusLEDWidget("Turn Count Sensor Levels", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *MTDIAGStatusLED = createStatusLEDWidget("MTDIAG", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *TurnCounterCrossCheckStatusLED = createStatusLEDWidget("Turn Counter Cross Check", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *RadiusCheckStatusLED = createStatusLEDWidget("Radius Check", faultLEDColor, faultRegisterCollapseSection); - MenuControlButton *SequencerWatchdogStatusLED = createStatusLEDWidget("Sequencer Watchdog", faultLEDColor, faultRegisterCollapseSection); - - faultRegisterCollapseSection->contentLayout()->addWidget(vddUnderVoltageStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(vddOverVoltageStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(vDriveUnderVoltageStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(vDriveOverVoltageStatusLED); + VDDUnderVoltageStatusLED = createStatusLEDWidget("VDD Under Voltage", faultLEDColor, faultRegisterCollapseSection); + VDDOverVoltageStatusLED = createStatusLEDWidget("VDD Over Voltage", faultLEDColor, faultRegisterCollapseSection); + VDRIVEUnderVoltageStatusLED = createStatusLEDWidget("VDRIVE Under Voltage", faultLEDColor, faultRegisterCollapseSection); + VDRIVEOverVoltageStatusLED = createStatusLEDWidget("VDRIVE Over Voltage", faultLEDColor, faultRegisterCollapseSection); + AFEDIAGStatusLED = createStatusLEDWidget("AFEDIAG", faultLEDColor, faultRegisterCollapseSection); + NVMCRCFaultStatusLED = createStatusLEDWidget("NVM CRC Fault", faultLEDColor, faultRegisterCollapseSection); + ECCDoubleBitErrorStatusLED = createStatusLEDWidget("ECC Double Bit Error", faultLEDColor, faultRegisterCollapseSection); + OscillatorDriftStatusLED = createStatusLEDWidget("Oscillator Drift", faultLEDColor, faultRegisterCollapseSection); + CountSensorFalseStateStatusLED = createStatusLEDWidget("Count Sensor False State", faultLEDColor, faultRegisterCollapseSection); + AngleCrossCheckStatusLED = createStatusLEDWidget("Angle Cross Check", faultLEDColor, faultRegisterCollapseSection); + TurnCountSensorLevelsStatusLED = createStatusLEDWidget("Turn Count Sensor Levels", faultLEDColor, faultRegisterCollapseSection); + MTDIAGStatusLED = createStatusLEDWidget("MTDIAG", faultLEDColor, faultRegisterCollapseSection); + TurnCounterCrossCheckStatusLED = createStatusLEDWidget("Turn Counter Cross Check", faultLEDColor, faultRegisterCollapseSection); + RadiusCheckStatusLED = createStatusLEDWidget("Radius Check", faultLEDColor, faultRegisterCollapseSection); + SequencerWatchdogStatusLED = createStatusLEDWidget("Sequencer Watchdog", faultLEDColor, faultRegisterCollapseSection); + + faultRegisterCollapseSection->contentLayout()->addWidget(VDDUnderVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(VDDOverVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(VDRIVEUnderVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(VDRIVEOverVoltageStatusLED); faultRegisterCollapseSection->contentLayout()->addWidget(AFEDIAGStatusLED); faultRegisterCollapseSection->contentLayout()->addWidget(NVMCRCFaultStatusLED); faultRegisterCollapseSection->contentLayout()->addWidget(ECCDoubleBitErrorStatusLED); @@ -1293,6 +1313,152 @@ void HarmonicCalibration::timerTask(){ tempGraph->plot(temp); } +void HarmonicCalibration::utilityTask(){ + updateDigioMonitor(); + updateFaultRegister(); + updateMTDiagRegister(); + updateMTDiagnostics(); + commandLogWrite(""); +} + +void HarmonicCalibration::updateDigioMonitor(){ + uint32_t *digioRegValue = new uint32_t; + uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIO); + + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), digioRegisterAddress, digioRegValue) != -1){ + std::map digioBitMapping = m_admtController->getDigioenRegisterBitMapping(static_cast(*digioRegValue)); + if(digioBitMapping.at("DIGIO0EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("BUSY")); } + else { changeStatusLEDColor(DIGIOBusyStatusLED, faultLEDColor); } + if(digioBitMapping.at("DIGIO1EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("CNV")); } + else { changeStatusLEDColor(DIGIOCNVStatusLED, faultLEDColor); } + if(digioBitMapping.at("DIGIO2EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("SENT")); } + else { changeStatusLEDColor(DIGIOSENTStatusLED, faultLEDColor); } + if(digioBitMapping.at("DIGIO3EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("ACALC")); } + else { changeStatusLEDColor(DIGIOACALCStatusLED, faultLEDColor); } + if(digioBitMapping.at("DIGIO4EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("FAULT")); } + else { changeStatusLEDColor(DIGIOFaultStatusLED, faultLEDColor); } + if(digioBitMapping.at("DIGIO5EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("BOOTLOAD")); } + else { changeStatusLEDColor(DIGIOBootloaderStatusLED, faultLEDColor); } + commandLogWrite("DIGIO: 0x" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); + } + else{ commandLogWrite("Failed to read DIGIO Register"); } +} + +void HarmonicCalibration::updateMTDiagRegister(){ + uint32_t *mtDiag1RegValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1); + uint32_t mtDiag1PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag1PageValue) != -1){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ + if(*cnvPageRegValue == mtDiag1PageValue){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1){ + std::map mtDiag1BitMapping = m_admtController->getDiag1RegisterBitMapping_Register(static_cast(*mtDiag1RegValue)); + changeStatusLEDColor(R0StatusLED, statusLEDColor, mtDiag1BitMapping.at("R0")); + changeStatusLEDColor(R1StatusLED, statusLEDColor, mtDiag1BitMapping.at("R1")); + changeStatusLEDColor(R2StatusLED, statusLEDColor, mtDiag1BitMapping.at("R2")); + changeStatusLEDColor(R3StatusLED, statusLEDColor, mtDiag1BitMapping.at("R3")); + changeStatusLEDColor(R4StatusLED, statusLEDColor, mtDiag1BitMapping.at("R4")); + changeStatusLEDColor(R5StatusLED, statusLEDColor, mtDiag1BitMapping.at("R5")); + changeStatusLEDColor(R6StatusLED, statusLEDColor, mtDiag1BitMapping.at("R6")); + changeStatusLEDColor(R7StatusLED, statusLEDColor, mtDiag1BitMapping.at("R7")); + commandLogWrite("DIAG1: 0x" + QString::number(static_cast(*mtDiag1RegValue), 2).rightJustified(16, '0')); + } + else{ commandLogWrite("Failed to read MT Diagnostic 1 Register"); } + } + else{ commandLogWrite("CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); } + } + else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 1"); } + } + else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 1"); } +} + +void HarmonicCalibration::updateFaultRegister(){ + uint32_t *faultRegValue = new uint32_t; + uint32_t faultRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, faultRegValue); + + if(*faultRegValue != -1){ + std::map faultBitMapping = m_admtController->getFaultRegisterBitMapping(static_cast(*faultRegValue)); + changeStatusLEDColor(VDDUnderVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDD Under Voltage")); + changeStatusLEDColor(VDDOverVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDD Over Voltage")); + changeStatusLEDColor(VDRIVEUnderVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDRIVE Under Voltage")); + changeStatusLEDColor(VDRIVEOverVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDRIVE Over Voltage")); + changeStatusLEDColor(AFEDIAGStatusLED, faultLEDColor, faultBitMapping.at("AFE Diagnostic")); + changeStatusLEDColor(NVMCRCFaultStatusLED, faultLEDColor, faultBitMapping.at("NVM CRC Fault")); + changeStatusLEDColor(ECCDoubleBitErrorStatusLED, faultLEDColor, faultBitMapping.at("ECC Double Bit Error")); + changeStatusLEDColor(OscillatorDriftStatusLED, faultLEDColor, faultBitMapping.at("Oscillator Drift")); + changeStatusLEDColor(CountSensorFalseStateStatusLED, faultLEDColor, faultBitMapping.at("Count Sensor False State")); + changeStatusLEDColor(AngleCrossCheckStatusLED, faultLEDColor, faultBitMapping.at("Angle Cross Check")); + changeStatusLEDColor(TurnCountSensorLevelsStatusLED, faultLEDColor, faultBitMapping.at("Turn Count Sensor Levels")); + changeStatusLEDColor(MTDIAGStatusLED, faultLEDColor, faultBitMapping.at("MT Diagnostic")); + changeStatusLEDColor(TurnCounterCrossCheckStatusLED, faultLEDColor, faultBitMapping.at("Turn Counter Cross Check")); + changeStatusLEDColor(RadiusCheckStatusLED, faultLEDColor, faultBitMapping.at("AMR Radius Check")); + changeStatusLEDColor(SequencerWatchdogStatusLED, faultLEDColor, faultBitMapping.at("Sequencer Watchdog")); + + commandLogWrite("FAULT: 0x" + QString::number(static_cast(*faultRegValue), 2).rightJustified(16, '0')); + } + else{ commandLogWrite("Failed to read FAULT Register"); } +} + +void HarmonicCalibration::updateMTDiagnostics(){ + uint32_t *mtDiag1RegValue = new uint32_t; + uint32_t *mtDiag2RegValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + + uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1); + uint32_t mtDiag2RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG2); + + uint32_t mtDiag1PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); + uint32_t mtDiag2PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2); + + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag1PageValue) != -1){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ + if(*cnvPageRegValue == mtDiag1PageValue){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1){ + std::map mtDiag1BitMapping = m_admtController->getDiag1RegisterBitMapping_Afe(static_cast(*mtDiag1RegValue)); + + afeDiag2 = mtDiag1BitMapping.at("AFE Diagnostic 2"); + AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); + } + else{ commandLogWrite("Failed to read MT Diagnostic 1 Register"); } + } + else{ commandLogWrite("CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); } + } + else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 1"); } + } + else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 1"); } + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag2PageValue) != -1){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ + if(*cnvPageRegValue == mtDiag2PageValue){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag2RegisterAddress, mtDiag2RegValue) != -1){ + std::map mtDiag2BitMapping = m_admtController->getDiag2RegisterBitMapping(static_cast(*mtDiag2RegValue)); + + afeDiag0 = mtDiag2BitMapping.at("AFE Diagnostic 0 (-57%)"); + afeDiag1 = mtDiag2BitMapping.at("AFE Diagnostic 1 (+57%)"); + AFEDIAG0LineEdit->setText(QString::number(afeDiag0) + " V"); + AFEDIAG1LineEdit->setText(QString::number(afeDiag1) + " V"); + + commandLogWrite("DIAG2: 0x" + QString::number(static_cast(*mtDiag2RegValue), 2).rightJustified(16, '0')); + } + else{ commandLogWrite("Failed to read MT Diagnostic 2 Register"); } + } + else{ commandLogWrite("CNVPAGE for MT Diagnostic 2 is a different value, abort reading"); } + } + else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 2"); } + } + else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 2"); } +} + +void HarmonicCalibration::clearCommandLog(){ + commandLogPlainTextEdit->clear(); +} + void HarmonicCalibration::updateChannelValues(){ rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, bufferSize); angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, bufferSize); @@ -1325,12 +1491,18 @@ MenuControlButton *HarmonicCalibration::createStatusLEDWidget(const QString titl menuControlButton->setColor(color); menuControlButton->button()->setVisible(false); menuControlButton->setCheckable(true); - menuControlButton->checkBox()->setChecked(true); + menuControlButton->checkBox()->setChecked(false); menuControlButton->setEnabled(false); menuControlButton->layout()->setMargin(8); return menuControlButton; } +void HarmonicCalibration::changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked) +{ + menuControlButton->setColor(color); + menuControlButton->checkBox()->setChecked(checked); +} + MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString title, QColor color, QWidget *parent) { MenuControlButton *menuControlButton = new MenuControlButton(parent); @@ -1359,16 +1531,16 @@ void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& vari }); } -void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& variable) +void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit) { - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, unit]() { bool ok; - double value = lineEdit->text().toDouble(&ok); + double value = lineEdit->text().replace(unit, "").trimmed().toDouble(&ok); if (ok) { variable = value; } else { - lineEdit->setText(QString::number(variable)); + lineEdit->setText(QString::number(variable) + " " + unit); } }); } @@ -1703,15 +1875,15 @@ void HarmonicCalibration::calibrateData() h3MagScaled, h3PhaseScaled, h8MagScaled, - h8PhaseScaled, - h1MagConverted, - h1PhaseConverted, - h2MagConverted, - h2PhaseConverted, - h3MagConverted, - h3PhaseConverted, - h8MagConverted, - h8PhaseConverted; + h8PhaseScaled; + double h1MagConverted, + h1PhaseConverted, + h2MagConverted, + h2PhaseConverted, + h3MagConverted, + h3PhaseConverted, + h8MagConverted, + h8PhaseConverted; m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); @@ -1787,14 +1959,14 @@ void HarmonicCalibration::calibrateData() m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); - h1MagConverted = m_admtController->readRegister(static_cast(*h1MagCurrent), "h1mag"); - h1PhaseConverted = m_admtController->readRegister(static_cast(*h1PhaseCurrent), "h1phase"); - h2MagConverted = m_admtController->readRegister(static_cast(*h2MagCurrent), "h2mag"); - h2PhaseConverted = m_admtController->readRegister(static_cast(*h2PhaseCurrent), "h2phase"); - h3MagConverted = m_admtController->readRegister(static_cast(*h3MagCurrent), "h3mag"); - h3PhaseConverted = m_admtController->readRegister(static_cast(*h3PhaseCurrent), "h3phase"); - h8MagConverted = m_admtController->readRegister(static_cast(*h8MagCurrent), "h8mag"); - h8PhaseConverted = m_admtController->readRegister(static_cast(*h8PhaseCurrent), "h8phase"); + h1MagConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h1MagCurrent), "h1mag"); + h1PhaseConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h1PhaseCurrent), "h1phase"); + h2MagConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h2MagCurrent), "h2mag"); + h2PhaseConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h2PhaseCurrent), "h2phase"); + h3MagConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h3MagCurrent), "h3mag"); + h3PhaseConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h3PhaseCurrent), "h3phase"); + h8MagConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h8MagCurrent), "h8mag"); + h8PhaseConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h8PhaseCurrent), "h8phase"); calibrationLogWriteLn(); calibrationLogWrite("H1 Mag Converted: " + QString::number(h1MagConverted) + "\n"); @@ -1891,6 +2063,11 @@ void HarmonicCalibration::calibrationLogWriteLn(QString message) logsPlainTextEdit->appendPlainText("\n" + message); } +void HarmonicCalibration::commandLogWrite(QString message) +{ + commandLogPlainTextEdit->appendPlainText(message); +} + void HarmonicCalibration::extractCalibrationData() { QStringList filter; From cdced438a37807d6933895e5dee35a237a28c555 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Wed, 25 Sep 2024 15:18:00 +0800 Subject: [PATCH 027/112] Update admtcontroller.cpp - Fixed calculation of angular error. - Abstracted functions for FFT of both pre and post angle error ffts. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 324 ++++++++++++++-------------- 1 file changed, 161 insertions(+), 163 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 73516ece93..91df8bb117 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -368,176 +368,126 @@ int ADMTController::linear_fit(vector x, vector y, double* slope /* Calculate angle error based on MATLAB and C# implementation */ int ADMTController::calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err) { - vector angle_meas_rad(angle_meas.size()); // radian converted input - vector angle_meas_rad_unwrap(angle_meas.size()); // unwrapped radian input - vector angle_fit(angle_meas.size()); // array for polynomial fitted data - vector x_data(angle_meas.size()); - double coeff_a, coeff_b; // coefficients generated by polynomial fitting - - // convert to radian - for (int i = 0; i < angle_meas_rad.size(); i++) + // Ideal angles + vector expected_angles = { + 0.00000, 15.46875, 30.93750, 46.40625, 61.87500, 77.34375, 92.81250, 108.28125, 123.75000, 139.21875, 154.68750, 170.15625, 185.62500, 201.09375, 216.56250, 232.03125, 247.50000, 262.96875, 278.43750, 293.90625, 309.37500, 324.84375, 340.31250, 355.78125, + 11.25000, 26.71875, 42.18750, 57.65625, 73.12500, 88.59375, 104.06250, 119.53125, 135.00000, 150.46875, 165.93750, 181.40625, 196.87500, 212.34375, 227.81250, 243.28125, 258.75000, 274.21875, 289.68750, 305.15625, 320.62500, 336.09375, 351.56250, 7.03125, + 22.50000, 37.96875, 53.43750, 68.90625, 84.37500, 99.84375, 115.31250, 130.78125, 146.25000, 161.71875, 177.18750, 192.65625, 208.12500, 223.59375, 239.06250, 254.53125, 270.00000, 285.46875, 300.93750, 316.40625, 331.87500, 347.34375, 2.81250, 18.28125, + 33.75000, 49.21875, 64.68750, 80.15625, 95.62500, 111.09375, 126.56250, 142.03125, 157.50000, 172.96875, 188.43750, 203.90625, 219.37500, 234.84375, 250.31250, 265.78125, 281.25000, 296.71875, 312.18750, 327.65625, 343.12500, 358.59375, 14.06250, 29.53125, + 45.00000, 60.46875, 75.93750, 91.40625, 106.87500, 122.34375, 137.81250, 153.28125, 168.75000, 184.21875, 199.68750, 215.15625, 230.62500, 246.09375, 261.56250, 277.03125, 292.50000, 307.96875, 323.43750, 338.90625, 354.37500, 9.84375, 25.31250, 40.78125, + 56.25000, 71.71875, 87.18750, 102.65625, 118.12500, 133.59375, 149.06250, 164.53125, 180.00000, 195.46875, 210.93750, 226.40625, 241.87500, 257.34375, 272.81250, 288.28125, 303.75000, 319.21875, 334.68750, 350.15625, 5.62500, 21.09375, 36.56250, 52.03125, + 67.50000, 82.96875, 98.43750, 113.90625, 129.37500, 144.84375, 160.31250, 175.78125, 191.25000, 206.71875, 222.18750, 237.65625, 253.12500, 268.59375, 284.06250, 299.53125, 315.00000, 330.46875, 345.93750, 1.40625, 16.87500, 32.34375, 47.81250, 63.28125, + 78.75000, 94.21875, 109.68750, 125.15625, 140.62500, 156.09375, 171.56250, 187.03125, 202.50000, 217.96875, 233.43750, 248.90625, 264.37500, 279.84375, 295.31250, 310.78125, 326.25000, 341.71875, 357.18750, 12.65625, 28.12500, 43.59375, 59.06250, 74.53125, + 90.00000, 105.46875, 120.93750, 136.40625, 151.87500, 167.34375, 182.81250, 198.28125, 213.75000, 229.21875, 244.68750, 260.15625, 275.62500, 291.09375, 306.56250, 322.03125, 337.50000, 352.96875, 8.43750, 23.90625, 39.37500, 54.84375, 70.31250, 85.78125, + 101.25000, 116.71875, 132.18750, 147.65625, 163.12500, 178.59375, 194.06250, 209.53125, 225.00000, 240.46875, 255.93750, 271.40625, 286.87500, 302.34375, 317.81250, 333.28125, 348.75000, 4.21875, 19.68750, 35.15625, 50.62500, 66.09375, 81.56250, 97.03125, + 112.50000, 127.96875, 143.43750, 158.90625, 174.37500, 189.84375, 205.31250, 220.78125, 236.25000, 251.71875, 267.18750, 282.65625, 298.12500, 313.59375, 329.06250, 344.53125 + }; + + // Ensure that the angle_meas and expected_angles are of the same size + if (angle_meas.size() != expected_angles.size()) { + // Handle size mismatch error + return -1; + } + + vector angle_meas_rad(angle_meas.size()); // Convert measured angles to radians + vector expected_angles_rad(expected_angles.size()); // Convert expected angles to radians + + // Convert measured and expected angles to radians + for (int i = 0; i < angle_meas.size(); i++) { angle_meas_rad[i] = angle_meas[i] * M_PI / 180.0; + expected_angles_rad[i] = expected_angles[i] * M_PI / 180.0; + } - // unwrap angle (extracted from decompiled Angle GSF Unit + // Unwrap the measured angles + vector angle_meas_rad_unwrap(angle_meas.size()); double num = 0.0; angle_meas_rad_unwrap[0] = angle_meas_rad[0]; - for (int i = 1; i < angle_meas_rad.size(); i++) - { - double num2 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1]); - double num3 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] + M_PI * 2.0); - double num4 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] - M_PI * 2.0); - if (num3 < num2 && num3 < num4) - num += M_PI * 2.0; - - else if (num4 < num2 && num4 < num3) - num -= M_PI * 2.0; - + for (int i = 1; i < angle_meas.size(); i++) { + double diff = angle_meas_rad[i] - angle_meas_rad[i - 1]; + if (diff > M_PI) { + num -= 2.0 * M_PI; + } else if (diff < -M_PI) { + num += 2.0 * M_PI; + } angle_meas_rad_unwrap[i] = angle_meas_rad[i] + num; } - // set initial point to zero + // Set the initial point to zero double offset = angle_meas_rad_unwrap[0]; - for (int i = 0; i < angle_meas_rad_unwrap.size(); ++i) + for (int i = 0; i < angle_meas.size(); i++) { angle_meas_rad_unwrap[i] -= offset; - - /* Generate xdata for polynomial fitting */ - iota(x_data.begin(), x_data.end(), 1); - - // linear angle fitting (generated coefficients not same with matlab and python) - // expecting 0.26 -0.26 - // getting ~0.27 ~-0.27 as of 4/2/2024 - /* input args: x, y, *slope, *intercept */ - linear_fit(x_data, angle_meas_rad_unwrap, &coeff_a, &coeff_b); - - //cout << coeff_a << " " << coeff_b << "\n"; - - // generate data using coefficients from polynomial fitting - for (int i = 0; i < angle_fit.size(); i++) { - angle_fit[i] = coeff_a * x_data[i]; - //cout << "angle_fit " << angle_fit[i] << "\n"; } - // get angle error using pass by ref angle_error_ret - for (int i = 0; i < angle_error_ret.size(); i++) { - angle_error_ret[i] = angle_meas_rad_unwrap[i] - angle_fit[i]; - //cout << "angle_err_ret " << angle_error_ret[i] << "\n"; + // Calculate the angle error using the expected angles (unwrap vs expected) + angle_error_ret.resize(angle_meas.size()); + for (int i = 0; i < angle_meas.size(); i++) { + angle_error_ret[i] = angle_meas_rad_unwrap[i] - expected_angles_rad[i]; } - // Find the offset for error and subtract (using angle_error_ret) + // Find the min/max error for offset correction auto minmax = minmax_element(angle_error_ret.begin(), angle_error_ret.end()); double angle_err_offset = (*minmax.first + *minmax.second) / 2; - for (int i = 0; i < angle_error_ret.size(); i++) + // Subtract the error offset + for (int i = 0; i < angle_meas.size(); i++) { angle_error_ret[i] -= angle_err_offset; + } - // Convert back to degrees (angle_error_ret) - for (int i = 0; i < angle_meas.size(); i++) - angle_error_ret[i] *= (180 / M_PI); + // Convert angle errors back to degrees + for (int i = 0; i < angle_meas.size(); i++) { + angle_error_ret[i] *= (180.0 / M_PI); + } // Find maximum absolute angle error - *max_angle_err = *minmax.second; + *max_angle_err = max(fabs(*minmax.first), fabs(*minmax.second)) * (180.0 / M_PI); return 0; } -QString ADMTController::calibrate(vector PANG, int cycles, int samplesPerCycle){ - int CCW = 0, circshiftData = 0; - QString result = ""; - - // original script data (measured data: from data capture using GUI or other medium i.e., csv) - //PANG = { 0.175781,11.5137,20.0391,39.0234,52.998,65.0391,76.4648,84.8145,98.7012,112.061,130.693,145.195,166.816,182.021,193.799,210.938,0.175781,11.5137,20.0391,39.0234,52.998,65.0391,76.4648,84.8145,98.7012,112.061,130.693,145.195,166.816,182.021,193.799,210.938 }; +QString ADMTController::calibrate(vector PANG, int cycles, int samplesPerCycle) { + int CCW = 0, circshiftData = 0; + QString result = ""; /* Check CCW flag to know if array is to be reversed */ if (CCW) reverse(PANG.begin(), PANG.end()); - /* Randomize starting point of array */ if (circshiftData) { int shift = rand() % PANG.size(); - rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); } - // Calculate the angular errors for ideal and measured - double max_err = 0; - vector angle_errors(PANG.size()); - - /* Calculate angle errors */ - calculate_angle_error(PANG, angle_errors, &max_err); - - //for (int i = 0; i < angle_errors.size(); i++) - // cout << "angle_err " << angle_errors[i] << "\n"; - - /* Caluclate FFT of angle errors */ - /* FFT based on implementation from https://www.oreilly.com/library/view/c-cookbook/0596007612/ch11s18.html */ - vector angle_errors_fft_temp(PANG.size()); - vector angle_errors_fft_phase_temp(PANG.size()); - angle_errors_fft = vector(PANG.size() / 2); - angle_errors_fft_phase = vector(PANG.size() / 2); - typedef complex cx; - - /* array declaration must be constant so hardcoded as of now */ - cx fft_in[samplesPerCycle*cycles]; - cx fft_out[samplesPerCycle*cycles]; - - /* Format angle errros to match data type used in fft function */ - for (int i = 0; i < PANG.size(); i++) - fft_in[i] = cx(angle_errors[i], 0); - - /* Invoke FFT function */ - fft(fft_in, fft_out, 8); - - /* Extract magnitude and phase from complex fft_out array */ - for (int i = 0; i < PANG.size(); i++) { - //cout << "fft_out[" << i << "] = " << fft_out[i].real() / 256 << " " << fft_out[i].imag() / 256 << "\n"; + // Declare vectors for pre-calibration FFT results + vector angle_errors_fft_pre(PANG.size() / 2); + vector angle_errors_fft_phase_pre(PANG.size() / 2); - angle_errors_fft_temp[i] = pow((pow(fft_out[i].real() / PANG.size(), 2) + pow(-fft_out[i].imag() / PANG.size(), 2)), 0.5); - angle_errors_fft_temp[i] *= 2; + // Call the new function for pre-calibration FFT + getPreCalibrationFFT(PANG, cycles, samplesPerCycle, angle_errors_fft_pre, angle_errors_fft_phase_pre); - angle_errors_fft_phase_temp[i] = atan2(fft_out[i].imag(), fft_out[i].real()); - } - - /* get upper half only */ - for (int i = 0; i < PANG.size() / 2; i++) { - angle_errors_fft[i] = angle_errors_fft_temp[i]; - angle_errors_fft_phase[i] = angle_errors_fft_phase_temp[i]; - } - - /* end code for FFT of angle errors */ // Extract HMag parameters - double H1Mag = angle_errors_fft[cycles]; - double H2Mag = angle_errors_fft[2 * cycles]; - double H3Mag = angle_errors_fft[3 * cycles]; - double H8Mag = angle_errors_fft[8 * cycles]; + double H1Mag = angle_errors_fft_pre[cycles]; + double H2Mag = angle_errors_fft_pre[2 * cycles]; + double H3Mag = angle_errors_fft_pre[3 * cycles]; + double H8Mag = angle_errors_fft_pre[8 * cycles]; /* Display HMAG values */ - result.append("H1Mag = " + QString::number(H1Mag) + "\n"); - result.append("H2Mag = " + QString::number(H2Mag) + "\n"); - result.append("H3Mag = " + QString::number(H3Mag) + "\n"); - result.append("H8Mag = " + QString::number(H8Mag) + "\n"); - // cout << "H1Mag = " << H1Mag << "\n"; - // cout << "H2Mag = " << H2Mag << "\n"; - // cout << "H3Mag = " << H3Mag << "\n"; - // cout << "H8Mag = " << H8Mag << "\n"; + result.append("H1Mag = " + QString::number(H1Mag) + "\n"); + result.append("H2Mag = " + QString::number(H2Mag) + "\n"); + result.append("H3Mag = " + QString::number(H3Mag) + "\n"); + result.append("H8Mag = " + QString::number(H8Mag) + "\n"); // Extract HPhase parameters - double H1Phase = (180 / M_PI) * (angle_errors_fft_phase[cycles]); - double H2Phase = (180 / M_PI) * (angle_errors_fft_phase[2 * cycles]); - double H3Phase = (180 / M_PI) * (angle_errors_fft_phase[3 * cycles]); - double H8Phase = (180 / M_PI) * (angle_errors_fft_phase[8 * cycles]); + double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycles]); + double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycles]); + double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycles]); + double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycles]); /* Display HPHASE values */ - result.append("H1Phase = " + QString::number(H1Phase) + "\n"); - result.append("H2Phase = " + QString::number(H2Phase) + "\n"); - result.append("H3Phase = " + QString::number(H3Phase) + "\n"); - result.append("H8Phase = " + QString::number(H8Phase) + "\n"); - // cout << "H1Phase = " << H1Phase << "\n"; - // cout << "H2Phase = " << H2Phase << "\n"; - // cout << "H3Phase = " << H3Phase << "\n"; - // cout << "H8Phase = " << H8Phase << "\n"; - - // cout << "\n\n"; + result.append("H1Phase = " + QString::number(H1Phase) + "\n"); + result.append("H2Phase = " + QString::number(H2Phase) + "\n"); + result.append("H3Phase = " + QString::number(H3Phase) + "\n"); + result.append("H8Phase = " + QString::number(H8Phase) + "\n"); double H1 = H1Mag * cos(M_PI / 180 * (H1Phase)); double H2 = H2Mag * cos(M_PI / 180 * (H2Phase)); @@ -548,7 +498,7 @@ QString ADMTController::calibrate(vector PANG, int cycles, int samplesPe double init_angle = PANG[0] - init_err; double H1PHcor, H2PHcor, H3PHcor, H8PHcor; - /* Counterclock wise, slope of error FIT is negative */ + /* Counterclockwise, slope of error FIT is negative */ if (CCW) { H1Phase *= -1; H2Phase *= -1; @@ -576,8 +526,7 @@ QString ADMTController::calibrate(vector PANG, int cycles, int samplesPe vector HXcorrection(PANG.size()); ///* Apply correction and check if working on original data */ - for (int i = 0; i < PANG.size(); i++) - { + for (int i = 0; i < PANG.size(); i++) { H1c[i] = H1Mag * sin(M_PI / 180 * (PANG[i]) + M_PI / 180 * (H1PHcor)); H2c[i] = H2Mag * sin(2 * M_PI / 180 * (PANG[i]) + M_PI / 180 * (H2PHcor)); H3c[i] = H3Mag * sin(3 * M_PI / 180 * (PANG[i]) + M_PI / 180 * (H3PHcor)); @@ -586,20 +535,6 @@ QString ADMTController::calibrate(vector PANG, int cycles, int samplesPe HXcorrection[i] = H1c[i] + H2c[i] + H3c[i] + H8c[i]; } - // These are the results to be programmed into the device - // Magnitude scaling factor of 0.6072 is needed due to internal ADMT4000 - // CORDIC calculation scaling - - // Hardcoded value for comparison / reference - //H1Mag = 0.3259; - //H2Mag = 0.1275; - //H3Mag = 3.4849e-03; - //H8Mag = 0.088172; - //H1PHcor = 202.58; - //H2PHcor = 342.78; - //H3PHcor = 303.40; - //H8PHcor = 179.97; - // HMag Scaling H1Mag = H1Mag * 0.6072; H2Mag = H2Mag * 0.6072; @@ -621,34 +556,97 @@ QString ADMTController::calibrate(vector PANG, int cycles, int samplesPe HAR_PHASE_3 = (int)(H3PHcor / pha_scale_factor_12bit) & (0xFFF);// 12bit number HAR_PHASE_8 = (int)(H8PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - result.append("HMAG1: " + QString::number(HAR_MAG_1) + "\n"); - result.append("HMAG2: " + QString::number(HAR_MAG_2) + "\n"); - result.append("HMAG3: " + QString::number(HAR_MAG_3) + "\n"); - result.append("HMAG8: " + QString::number(HAR_MAG_8) + "\n"); + result.append("HMAG1: " + QString::number(HAR_MAG_1) + "\n"); + result.append("HMAG2: " + QString::number(HAR_MAG_2) + "\n"); + result.append("HMAG3: " + QString::number(HAR_MAG_3) + "\n"); + result.append("HMAG8: " + QString::number(HAR_MAG_8) + "\n"); - result.append("HPHASE1: " + QString::number(HAR_PHASE_1) + "\n"); - result.append("HPHASE2: " + QString::number(HAR_PHASE_2) + "\n"); - result.append("HPHASE3: " + QString::number(HAR_PHASE_3) + "\n"); - result.append("HPHASE8: " + QString::number(HAR_PHASE_8) + "\n"); + result.append("HPHASE1: " + QString::number(HAR_PHASE_1) + "\n"); + result.append("HPHASE2: " + QString::number(HAR_PHASE_2) + "\n"); + result.append("HPHASE3: " + QString::number(HAR_PHASE_3) + "\n"); + result.append("HPHASE8: " + QString::number(HAR_PHASE_8) + "\n"); - // cout << "HMAG1: " << HAR_MAG_1 << "\n"; - // cout << "HMAG2: " << HAR_MAG_2 << "\n"; - // cout << "HMAG3: " << HAR_MAG_3 << "\n"; - // cout << "HMAG8: " << HAR_MAG_8 << "\n"; + return result; +} + +void ADMTController::getPreCalibrationFFT(const vector& PANG, int cycles, int samplesPerCycle, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre) { + // Calculate the angle errors before calibration + double max_err_pre = 0; + vector angle_errors_pre(PANG.size()); + + // Calculate angle errors + calculate_angle_error(PANG, angle_errors_pre, &max_err_pre); + + // Perform FFT on pre-calibration angle errors + performFFT(angle_errors_pre, samplesPerCycle, cycles, angle_errors_fft_pre, angle_errors_fft_phase_pre); +} + +QString ADMTController::postcalibrate(vector PANG, int cycles, int samplesPerCycle){ + int CCW = 0, circshiftData = 0; + QString result = ""; - // cout << "HPHASE1: " << HAR_PHASE_1 << "\n"; - // cout << "HPHASE2: " << HAR_PHASE_2 << "\n"; - // cout << "HPHASE3: " << HAR_PHASE_3 << "\n"; - // cout << "HPHASE8: " << HAR_PHASE_8 << "\n"; + /* Check CCW flag to know if array is to be reversed */ + if (CCW) + reverse(PANG.begin(), PANG.end()); + + /* Randomize starting point of array */ + if (circshiftData) { + int shift = rand() % PANG.size(); + rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); + } + + // Declare vectors for pre-calibration FFT results + vector angle_errors_fft_post(PANG.size() / 2); + vector angle_errors_fft_phase_post(PANG.size() / 2); + + // Call the new function for post-calibration FFT + getPostCalibrationFFT(PANG, cycles, samplesPerCycle, angle_errors_fft_post, angle_errors_fft_phase_post); +} - // cout << "\n\n"; +void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, int cycles, int samplesPerCycle, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post) { + // Calculate the angle errors after calibration + double max_err_post = 0; + vector angle_errors_post(updated_PANG.size()); - // /* Sanity check */ - // cout << "Hello World" << "\n"; + // Calculate angle errors + calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post); - return result; + // Perform FFT on post-calibration angle errors + performFFT(angle_errors_post, samplesPerCycle, cycles, angle_errors_fft_post, angle_errors_fft_phase_post); } +void performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase) { + typedef complex cx; + + int size = angle_errors.size(); + cx fft_in[size]; + cx fft_out[size]; + + // Format angle errors to match data type used in fft function + for (int i = 0; i < size; i++) { + fft_in[i] = cx(angle_errors[i], 0); + } + + // Invoke FFT function + fft(fft_in, fft_out, 8); + + // Extract magnitude and phase from complex fft_out array + vector angle_errors_fft_temp(size); + vector angle_errors_fft_phase_temp(size); + + for (int i = 0; i < size; i++) { + angle_errors_fft_temp[i] = sqrt(pow(fft_out[i].real() / size, 2) + pow(fft_out[i].imag() / size, 2)) * 2; + angle_errors_fft_phase_temp[i] = atan2(fft_out[i].imag(), fft_out[i].real()); + } + + // Get upper half only + for (int i = 0; i < size / 2; i++) { + angle_errors_fft[i] = angle_errors_fft_temp[i]; + angle_errors_fft_phase[i] = angle_errors_fft_phase_temp[i]; + } +} + + void ADMTController::computeSineCosineOfAngles(const vector& angles) { // Vectors to store sine and cosine values calibration_samples_sine = vector(angles.size()); From 3d4b2edc249ed4369ec6dc753d4e4421e685b856 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 26 Sep 2024 09:33:39 +0800 Subject: [PATCH 028/112] admt: Implemented sequence read and write - Modified get and set register maps - Renamed sequence dropdown items Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 9 +- .../admt/include/admt/harmoniccalibration.h | 14 +- plugins/admt/src/admtcontroller.cpp | 113 +++++++++++---- plugins/admt/src/harmoniccalibration.cpp | 132 +++++++++++++++--- 4 files changed, 215 insertions(+), 53 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 9bba860f61..caa4b072ea 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -120,6 +120,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject "ramp_mode"}; const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = { 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C }; const uint32_t ConfigurationRegisters[CONFIGURATION_REGISTER_COUNT] = { 0x01, 0x04, 0x06, 0x10, 0x12, 0x13, 0x1D, 0x23 }; + const uint32_t ConfigurationPages[CONFIGURATION_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x02, 0x02, 0x02, 0x02, 0x02 }; const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = { 0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14 }; const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }; @@ -128,6 +129,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject const char* getMotorAttribute(MotorAttribute attribute); const uint32_t getHarmonicRegister(HarmonicRegister registerID); const uint32_t getConfigurationRegister(ConfigurationRegister registerID); + const uint32_t getConfigurationPage(ConfigurationRegister registerID); const uint32_t getSensorRegister(SensorRegister registerID); const uint32_t getSensorPage(SensorRegister registerID); @@ -145,11 +147,13 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject uint16_t calculateHarmonicCoefficientPhase(double harmonicCoefficient, uint16_t originalValue); double getActualHarmonicRegisterValue(uint16_t registerValue, const string key); map getFaultRegisterBitMapping(uint16_t registerValue); - map getGeneralRegisterBitMapping(uint16_t registerValue); + map getGeneralRegisterBitMapping(uint16_t registerValue); map getDigioenRegisterBitMapping(uint16_t registerValue); map getDiag1RegisterBitMapping_Register(uint16_t registerValue); map getDiag1RegisterBitMapping_Afe(uint16_t registerValue); map getDiag2RegisterBitMapping(uint16_t registerValue); + uint16_t setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings); + QString postcalibrate(vector PANG); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; @@ -159,8 +163,11 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject unsigned int bitReverse(unsigned int x, int log2n); template void fft(Iter_T a, Iter_T b, int log2n); + void performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase); int linear_fit(vector x, vector y, double* slope, double* intercept); int calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err); + void getPreCalibrationFFT(const vector& PANG, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre); + void getPostCalibrationFFT(const vector& updated_PANG, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post); }; } // namespace scopy::admt diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index d902e15cf3..910cce6b4d 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -65,6 +65,8 @@ public Q_SLOTS: void utilityTask(); void clearCommandLog(); void canCalibrate(bool); + void applySequence(); + void readSequence(); Q_SIGNALS: void runningChanged(bool); void canCalibrateChanged(bool); @@ -81,7 +83,7 @@ public Q_SLOTS: afeDiag0, afeDiag1, afeDiag2; QPushButton *openLastMenuButton, *calibrationStartMotorButton, *applyCalibrationDataButton, *calibrateDataButton, *extractDataButton, - *clearCommandLogButton; + *clearCommandLogButton, *applySequenceButton; QButtonGroup *rightMenuButtonGroup; QLineEdit *graphUpdateIntervalLineEdit, *dataSampleSizeLineEdit, @@ -112,7 +114,8 @@ public Q_SLOTS: MenuSectionWidget *rightMenuSectionWidget; MenuCollapseSection *rotationCollapse, *angleCollapse, *countCollapse, *tempCollapse; - MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo; + MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo, + *sequenceTypeMenuCombo, *conversionTypeMenuCombo, *cnvSourceMenuCombo, *convertSynchronizationMenuCombo, *angleFilterMenuCombo, *eighthHarmonicMenuCombo; QTabWidget *tabWidget; @@ -141,8 +144,10 @@ public Q_SLOTS: void connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit = ""); void connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph); void connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph); - void changeGraphColorByChannelName(Sismograph* graph, const char* channelName); void connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph); + void connectMenuComboToNumber(MenuCombo* menuCombo, double& variable); + void connectMenuComboToNumber(MenuCombo* menuCombo, int& variable); + void changeGraphColorByChannelName(Sismograph* graph, const char* channelName); ToolTemplate* createCalibrationWidget(); ToolTemplate* createRegistersWidget(); ToolTemplate* createUtilityWidget(); @@ -176,7 +181,6 @@ public Q_SLOTS: double convertAMAXtoAccelTime(double amax); void updateCalculatedCoeff(); void resetCalculatedCoeff(); - void connectMenuComboToNumber(MenuCombo* menuCombo, double& variable); void appendSamplesToPlotCurve(PlotWidget *plotWidget, QVector& newYData); void applyTabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor = "ScopyBlue"); MenuControlButton *createStatusLEDWidget(const QString title, QColor color, QWidget *parent = nullptr); @@ -186,6 +190,8 @@ public Q_SLOTS: void updateFaultRegister(); void updateMTDiagnostics(); void changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked = true); + bool changeCNVPage(uint32_t page, QString registerName); + void toggleWidget(QPushButton *widget, bool value); QTimer *timer, *calibrationTimer, *motorCalibrationAcquisitionTimer, *utilityTimer; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 91df8bb117..010602b18a 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -89,6 +89,14 @@ const uint32_t ADMTController::getConfigurationRegister(ConfigurationRegister re return UINT32_MAX; } +const uint32_t ADMTController::getConfigurationPage(ConfigurationRegister registerID) +{ + if(registerID >= 0 && registerID < CONFIGURATION_REGISTER_COUNT){ + return ConfigurationPages[registerID]; + } + return UINT32_MAX; +} + const uint32_t ADMTController::getSensorRegister(SensorRegister registerID) { if(registerID >= 0 && registerID < SENSOR_REGISTER_COUNT){ @@ -463,7 +471,7 @@ QString ADMTController::calibrate(vector PANG, int cycles, int samplesPe vector angle_errors_fft_phase_pre(PANG.size() / 2); // Call the new function for pre-calibration FFT - getPreCalibrationFFT(PANG, cycles, samplesPerCycle, angle_errors_fft_pre, angle_errors_fft_phase_pre); + getPreCalibrationFFT(PANG, angle_errors_fft_pre, angle_errors_fft_phase_pre); // Extract HMag parameters double H1Mag = angle_errors_fft_pre[cycles]; @@ -569,7 +577,7 @@ QString ADMTController::calibrate(vector PANG, int cycles, int samplesPe return result; } -void ADMTController::getPreCalibrationFFT(const vector& PANG, int cycles, int samplesPerCycle, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre) { +void ADMTController::getPreCalibrationFFT(const vector& PANG, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre) { // Calculate the angle errors before calibration double max_err_pre = 0; vector angle_errors_pre(PANG.size()); @@ -578,10 +586,10 @@ void ADMTController::getPreCalibrationFFT(const vector& PANG, int cycles calculate_angle_error(PANG, angle_errors_pre, &max_err_pre); // Perform FFT on pre-calibration angle errors - performFFT(angle_errors_pre, samplesPerCycle, cycles, angle_errors_fft_pre, angle_errors_fft_phase_pre); + performFFT(angle_errors_pre, angle_errors_fft_pre, angle_errors_fft_phase_pre); } -QString ADMTController::postcalibrate(vector PANG, int cycles, int samplesPerCycle){ +QString ADMTController::postcalibrate(vector PANG){ int CCW = 0, circshiftData = 0; QString result = ""; @@ -600,10 +608,10 @@ QString ADMTController::postcalibrate(vector PANG, int cycles, int sampl vector angle_errors_fft_phase_post(PANG.size() / 2); // Call the new function for post-calibration FFT - getPostCalibrationFFT(PANG, cycles, samplesPerCycle, angle_errors_fft_post, angle_errors_fft_phase_post); + getPostCalibrationFFT(PANG, angle_errors_fft_post, angle_errors_fft_phase_post); } -void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, int cycles, int samplesPerCycle, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post) { +void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post) { // Calculate the angle errors after calibration double max_err_post = 0; vector angle_errors_post(updated_PANG.size()); @@ -612,10 +620,10 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, i calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post); // Perform FFT on post-calibration angle errors - performFFT(angle_errors_post, samplesPerCycle, cycles, angle_errors_fft_post, angle_errors_fft_phase_post); + performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post); } -void performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase) { +void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase) { typedef complex cx; int size = angle_errors.size(); @@ -789,62 +797,62 @@ map ADMTController::getFaultRegisterBitMapping(uint16_t registerVa // std::cout << pair.first << ": " << (pair.second ? "Set" : "Not Set") << std::endl; // } -map ADMTController::getGeneralRegisterBitMapping(uint16_t registerValue) { - map result; +map ADMTController::getGeneralRegisterBitMapping(uint16_t registerValue) { + map result; // Bit 15: STORAGE[7] - result["STORAGE[7]"] = ((registerValue >> 15) & 0x01) ? "Set" : "Not Set"; + result["STORAGE[7]"] = ((registerValue >> 15) & 0x01) ? 1 : 0; // ? "Set" : "Not Set"; // Bits 14:13: Convert Synchronization uint16_t convertSync = (registerValue >> 13) & 0x03; switch (convertSync) { case 0x00: - result["Convert Synchronization"] = "Disabled"; + result["Convert Synchronization"] = 0; // "Disabled"; break; case 0x03: - result["Convert Synchronization"] = "Enabled"; + result["Convert Synchronization"] = 1; // "Enabled"; break; default: - result["Convert Synchronization"] = "Reserved"; + result["Convert Synchronization"] = -1; // "Reserved"; break; } // Bit 12: Angle Filter - result["Angle Filter"] = ((registerValue >> 12) & 0x01) ? "Enabled" : "Disabled"; + result["Angle Filter"] = ((registerValue >> 12) & 0x01) ? 1 : 0; // ? "Enabled" : "Disabled"; // Bit 11: STORAGE[6] - result["STORAGE[6]"] = ((registerValue >> 11) & 0x01) ? "Set" : "Not Set"; + result["STORAGE[6]"] = ((registerValue >> 11) & 0x01) ? 1 : 0; // ? "Set" : "Not Set"; // Bit 10: 8th Harmonic - result["8th Harmonic"] = ((registerValue >> 10) & 0x01) ? "User-Supplied Values" : "ADI Factory Values"; + result["8th Harmonic"] = ((registerValue >> 10) & 0x01) ? 1 : 0; // ? "User-Supplied Values" : "ADI Factory Values"; // // Bit 9: Reserved (skipped) // result["Reserved"] = "Reserved"; // Bits 8:6: STORAGE[5:3] - uint16_t storage_5_3 = (registerValue >> 6) & 0x07; - result["STORAGE[5:3]"] = std::to_string(storage_5_3); + // uint16_t storage_5_3 = (registerValue >> 6) & 0x07; + // result["STORAGE[5:3]"] = std::to_string(storage_5_3); // Bits 5:4: Sequence Type uint16_t sequenceType = (registerValue >> 4) & 0x03; switch (sequenceType) { case 0x00: - result["Sequence Type"] = "Mode 2"; + result["Sequence Type"] = 1; // "Mode 2"; break; case 0x03: - result["Sequence Type"] = "Mode 1"; + result["Sequence Type"] = 0; // "Mode 1"; break; default: - result["Sequence Type"] = "Reserved"; + result["Sequence Type"] = -1; // "Reserved"; break; } // Bits 3:1: STORAGE[2:0] - uint16_t storage_2_0 = (registerValue >> 1) & 0x07; - result["STORAGE[2:0]"] = std::to_string(storage_2_0); + // uint16_t storage_2_0 = (registerValue >> 1) & 0x07; + // result["STORAGE[2:0]"] = std::to_string(storage_2_0); // Bit 0: Conversion Type - result["Conversion Type"] = (registerValue & 0x01) ? "One-shot conversion" : "Continuous conversions"; + result["Conversion Type"] = (registerValue & 0x01) ? 1 : 0; // ? "One-shot conversion" : "Continuous conversions"; return result; } @@ -957,4 +965,59 @@ map ADMTController::getDiag2RegisterBitMapping(uint16_t register result["AFE Diagnostic 0 (-57%)"] = diagnostic0Voltage; return result; +} + +uint16_t ADMTController::setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings) { + uint16_t registerValue = currentRegisterValue; // Start with the current register value + + // Bit 15: STORAGE[7] (preserve original value) + // Do nothing, as STORAGE[7] is preserved. + + // Bits 14:13: Convert Synchronization + if (settings["Convert Synchronization"] == 1) { // Enabled + registerValue |= (0x03 << 13); // Set bits 14:13 to 0b11 + } else if (settings["Convert Synchronization"] == 0) { // Disabled + registerValue &= ~(0x03 << 13); // Clear bits 14:13 (set to 0b00) + } + + // Bit 12: Angle Filter + if (settings["Angle Filter"] == 1) { // Enabled + registerValue |= (1 << 12); // Set bit 12 + } else if (settings["Angle Filter"] == 0) { // Disabled + registerValue &= ~(1 << 12); // Clear bit 12 + } + + // Bit 11: STORAGE[6] (preserve original value) + // Do nothing, as STORAGE[6] is preserved. + + // Bit 10: 8th Harmonic + if (settings["8th Harmonic"] == 1) { // User-Supplied Values + registerValue |= (1 << 10); // Set bit 10 + } else if (settings["8th Harmonic"] == 0) { // ADI Factory Values + registerValue &= ~(1 << 10); // Clear bit 10 + } + + // Bit 9: Reserved (no change) + + // Bits 8:6: STORAGE[5:3] (preserve original value) + // Do nothing, as STORAGE[5:3] is preserved. + + // Bits 5:4: Sequence Type + if (settings["Sequence Type"] == 0) { // Mode 1 + registerValue |= (0x03 << 4); // Set bits 5:4 to 0b11 + } else if (settings["Sequence Type"] == 1) { // Mode 2 + registerValue &= ~(0x03 << 4); // Clear bits 5:4 (set to 0b00) + } + + // Bits 3:1: STORAGE[2:0] (preserve original value) + // Do nothing, as STORAGE[2:0] is preserved. + + // Bit 0: Conversion Type + if (settings["Conversion Type"] == 1) { // One-shot conversion + registerValue |= (1 << 0); // Set bit 0 + } else if (settings["Conversion Type"] == 0) { // Continuous conversions + registerValue &= ~(1 << 0); // Clear bit 0 + } + + return registerValue; } \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 9deee33554..0ce1ef3a84 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -222,51 +222,48 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool sequenceWidget->contentLayout()->addWidget(sequenceSection); sequenceSection->contentLayout()->setSpacing(8); - MenuCombo *sequenceTypeMenuCombo = new MenuCombo("Sequence Type", sequenceSection); + sequenceTypeMenuCombo = new MenuCombo("Sequence Type", sequenceSection); QComboBox *sequenceTypeComboBox = sequenceTypeMenuCombo->combo(); sequenceTypeComboBox->addItem("Mode 1", QVariant(0)); sequenceTypeComboBox->addItem("Mode 2", QVariant(1)); - sequenceTypeComboBox->setCurrentIndex(1); applyComboBoxStyle(sequenceTypeComboBox); - MenuCombo *conversionTypeMenuCombo = new MenuCombo("Conversion Type", sequenceSection); + conversionTypeMenuCombo = new MenuCombo("Conversion Type", sequenceSection); QComboBox *conversionTypeComboBox = conversionTypeMenuCombo->combo(); - conversionTypeComboBox->addItem("Continuous", QVariant(0)); - conversionTypeComboBox->addItem("One Shot", QVariant(1)); + conversionTypeComboBox->addItem("Continuous conversions", QVariant(0)); + conversionTypeComboBox->addItem("One-shot conversion", QVariant(1)); applyComboBoxStyle(conversionTypeComboBox); - MenuCombo *cnvSourceMenuCombo = new MenuCombo("CNV Source", sequenceSection); - QComboBox *cnvSourceComboBox = cnvSourceMenuCombo->combo(); - cnvSourceComboBox->addItem("External", QVariant(0)); - cnvSourceComboBox->addItem("Software", QVariant(1)); - applyComboBoxStyle(cnvSourceComboBox); - - MenuCombo *convertSynchronizationMenuCombo = new MenuCombo("Convert Synchronization", sequenceSection); + convertSynchronizationMenuCombo = new MenuCombo("Convert Synchronization", sequenceSection); QComboBox *convertSynchronizationComboBox = convertSynchronizationMenuCombo->combo(); - convertSynchronizationComboBox->addItem("Enabled", QVariant(0)); - convertSynchronizationComboBox->addItem("Disabled", QVariant(1)); - convertSynchronizationComboBox->setCurrentIndex(1); + convertSynchronizationComboBox->addItem("Enabled", QVariant(1)); + convertSynchronizationComboBox->addItem("Disabled", QVariant(0)); applyComboBoxStyle(convertSynchronizationComboBox); - MenuCombo *angleFilterMenuCombo = new MenuCombo("Angle Filter", sequenceSection); + angleFilterMenuCombo = new MenuCombo("Angle Filter", sequenceSection); QComboBox *angleFilterComboBox = angleFilterMenuCombo->combo(); - angleFilterComboBox->addItem("Enabled", QVariant(0)); - angleFilterComboBox->addItem("Disabled", QVariant(1)); - angleFilterComboBox->setCurrentIndex(1); + angleFilterComboBox->addItem("Enabled", QVariant(1)); + angleFilterComboBox->addItem("Disabled", QVariant(0)); applyComboBoxStyle(angleFilterComboBox); - MenuCombo *eighthHarmonicMenuCombo = new MenuCombo("8th Harmonic", sequenceSection); + eighthHarmonicMenuCombo = new MenuCombo("8th Harmonic", sequenceSection); QComboBox *eighthHarmonicComboBox = eighthHarmonicMenuCombo->combo(); - eighthHarmonicComboBox->addItem("Factory Set", QVariant(0)); - eighthHarmonicComboBox->addItem("User", QVariant(1)); + eighthHarmonicComboBox->addItem("User-Supplied Values", QVariant(1)); + eighthHarmonicComboBox->addItem("ADI Factory Values", QVariant(0)); applyComboBoxStyle(eighthHarmonicComboBox); + readSequence(); + + applySequenceButton = new QPushButton("Apply", sequenceSection); + StyleHelper::BlueButton(applySequenceButton, "applySequenceButton"); + connect(applySequenceButton, &QPushButton::clicked, this, &HarmonicCalibration::applySequence); + sequenceSection->contentLayout()->addWidget(sequenceTypeMenuCombo); sequenceSection->contentLayout()->addWidget(conversionTypeMenuCombo); - sequenceSection->contentLayout()->addWidget(cnvSourceMenuCombo); sequenceSection->contentLayout()->addWidget(convertSynchronizationMenuCombo); sequenceSection->contentLayout()->addWidget(angleFilterMenuCombo); sequenceSection->contentLayout()->addWidget(eighthHarmonicMenuCombo); + sequenceSection->contentLayout()->addWidget(applySequenceButton); // Data Graph Setting Widget MenuSectionWidget *dataGraphWidget = new MenuSectionWidget(generalSettingWidget); @@ -1313,6 +1310,87 @@ void HarmonicCalibration::timerTask(){ tempGraph->plot(temp); } +void HarmonicCalibration::applySequence(){ + toggleWidget(applySequenceButton, false); + applySequenceButton->setText("Writing..."); + QTimer::singleShot(2000, this, [this](){ + this->toggleWidget(applySequenceButton, true); + applySequenceButton->setText("Apply"); + }); + uint32_t *generalRegValue = new uint32_t; + uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); + std::map settings; + + settings["Convert Synchronization"] = qvariant_cast(convertSynchronizationMenuCombo->combo()->currentData()); // convertSync; + settings["Angle Filter"] = qvariant_cast(angleFilterMenuCombo->combo()->currentData()); // angleFilter; + settings["8th Harmonic"] = qvariant_cast(eighthHarmonicMenuCombo->combo()->currentData()); // eighthHarmonic; + settings["Sequence Type"] = qvariant_cast(sequenceTypeMenuCombo->combo()->currentData()); // sequenceType; + settings["Conversion Type"] = qvariant_cast(conversionTypeMenuCombo->combo()->currentData()); // conversionType; + + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + generalRegisterAddress, generalRegValue); + + uint32_t newGeneralRegValue = m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings); + uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); + + if(changeCNVPage(generalRegisterPage, "GENERAL")){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, newGeneralRegValue) != -1){ + //StatusBarManager::pushMessage("WRITE GENERAL: 0x" + QString::number(static_cast(newGeneralRegValue), 2).rightJustified(16, '0')); + + readSequence(); + } + else{ StatusBarManager::pushMessage("Failed to write GENERAL Register"); } + } +} + +void HarmonicCalibration::toggleWidget(QPushButton *widget, bool value){ + widget->setEnabled(value); +} + +void HarmonicCalibration::readSequence(){ + uint32_t *generalRegValue = new uint32_t; + uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); + uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); + + if(changeCNVPage(generalRegisterPage, "GENERAL")){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ + if(*generalRegValue != UINT32_MAX){ + std::map generalBitMapping = m_admtController->getGeneralRegisterBitMapping(static_cast(*generalRegValue)); + + if(generalBitMapping.at("Sequence Type") == -1){ sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); } + else{ sequenceTypeMenuCombo->combo()->setCurrentIndex(sequenceTypeMenuCombo->combo()->findData(generalBitMapping.at("Sequence Type"))); } + conversionTypeMenuCombo->combo()->setCurrentIndex(conversionTypeMenuCombo->combo()->findData(generalBitMapping.at("Conversion Type"))); + // cnvSourceMenuCombo->combo()->setCurrentValue(generalBitMapping.at("Sequence Type")); + if(generalBitMapping.at("Convert Synchronization") == -1){ convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); } + else{ convertSynchronizationMenuCombo->combo()->setCurrentIndex(convertSynchronizationMenuCombo->combo()->findData(generalBitMapping.at("Convert Synchronization"))); } + angleFilterMenuCombo->combo()->setCurrentIndex(angleFilterMenuCombo->combo()->findData(generalBitMapping.at("Angle Filter"))); + eighthHarmonicMenuCombo->combo()->setCurrentIndex(eighthHarmonicMenuCombo->combo()->findData(generalBitMapping.at("8th Harmonic"))); + + //StatusBarManager::pushMessage("READ GENERAL: 0x" + QString::number(static_cast(*generalRegValue), 2).rightJustified(16, '0')); + } + } + else{ StatusBarManager::pushMessage("Failed to read GENERAL Register"); } + } +} + +bool HarmonicCalibration::changeCNVPage(uint32_t page, QString registerName){ + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, page) != -1){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ + if(*cnvPageRegValue == page){ + return true; + } + else{ StatusBarManager::pushMessage("CNVPAGE for " + registerName + " is a different value, abort reading"); } + } + else{ StatusBarManager::pushMessage("Failed to read CNVPAGE for " + registerName); } + } + else{ StatusBarManager::pushMessage("Failed to write CNVPAGE for " + registerName); } + + return false; +} + void HarmonicCalibration::utilityTask(){ updateDigioMonitor(); updateFaultRegister(); @@ -1601,6 +1679,14 @@ void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, double& }); } +void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, int& variable) +{ + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), [=, &variable]() { + variable = qvariant_cast(combo->currentData()); + }); +} + void HarmonicCalibration::changeGraphColorByChannelName(Sismograph* graph, const char* channelName) { int index = m_admtController->getChannelIndex(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), channelName); From 8d2358a5e26be526e6fdea4586efb912c4d75999 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 26 Sep 2024 10:34:11 +0800 Subject: [PATCH 029/112] admt: Corrected string output for binary and hex values Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/widgets/registerblockwidget.h | 11 +++++++++ plugins/admt/src/harmoniccalibration.cpp | 12 +++++----- .../admt/src/widgets/registerblockwidget.cpp | 24 +++++++++++++++---- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/plugins/admt/include/admt/widgets/registerblockwidget.h b/plugins/admt/include/admt/widgets/registerblockwidget.h index e0f5775cb3..f94b1e6e21 100644 --- a/plugins/admt/include/admt/widgets/registerblockwidget.h +++ b/plugins/admt/include/admt/widgets/registerblockwidget.h @@ -26,6 +26,7 @@ namespace scopy::admt { QPushButton *m_readButton, *m_writeButton; RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t defaultValue, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent = nullptr); + virtual ~RegisterBlockWidget(); QPushButton *readButton(); QPushButton *writeButton(); uint32_t getAddress(); @@ -45,6 +46,16 @@ namespace scopy::admt { void applyLineEditStyle(QLineEdit *widget); void applySpinBoxStyle(QSpinBox *widget); }; + + class SCOPY_ADMT_EXPORT PaddedSpinBox : public QSpinBox + { + Q_OBJECT + public: + PaddedSpinBox(QWidget *parent = nullptr); + virtual ~PaddedSpinBox(); + protected: + QString textFromValue(int value) const override; + }; } // namespace scopy::admt #endif // REGISTERBLOCKWIDGET_H \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 0ce1ef3a84..85d1b3db90 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -1335,7 +1335,7 @@ void HarmonicCalibration::applySequence(){ if(changeCNVPage(generalRegisterPage, "GENERAL")){ if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, newGeneralRegValue) != -1){ - //StatusBarManager::pushMessage("WRITE GENERAL: 0x" + QString::number(static_cast(newGeneralRegValue), 2).rightJustified(16, '0')); + //StatusBarManager::pushMessage("WRITE GENERAL: 0b" + QString::number(static_cast(newGeneralRegValue), 2).rightJustified(16, '0')); readSequence(); } @@ -1366,7 +1366,7 @@ void HarmonicCalibration::readSequence(){ angleFilterMenuCombo->combo()->setCurrentIndex(angleFilterMenuCombo->combo()->findData(generalBitMapping.at("Angle Filter"))); eighthHarmonicMenuCombo->combo()->setCurrentIndex(eighthHarmonicMenuCombo->combo()->findData(generalBitMapping.at("8th Harmonic"))); - //StatusBarManager::pushMessage("READ GENERAL: 0x" + QString::number(static_cast(*generalRegValue), 2).rightJustified(16, '0')); + //StatusBarManager::pushMessage("READ GENERAL: 0b" + QString::number(static_cast(*generalRegValue), 2).rightJustified(16, '0')); } } else{ StatusBarManager::pushMessage("Failed to read GENERAL Register"); } @@ -1417,7 +1417,7 @@ void HarmonicCalibration::updateDigioMonitor(){ else { changeStatusLEDColor(DIGIOFaultStatusLED, faultLEDColor); } if(digioBitMapping.at("DIGIO5EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("BOOTLOAD")); } else { changeStatusLEDColor(DIGIOBootloaderStatusLED, faultLEDColor); } - commandLogWrite("DIGIO: 0x" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); + commandLogWrite("DIGIO: 0b" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); } else{ commandLogWrite("Failed to read DIGIO Register"); } } @@ -1442,7 +1442,7 @@ void HarmonicCalibration::updateMTDiagRegister(){ changeStatusLEDColor(R5StatusLED, statusLEDColor, mtDiag1BitMapping.at("R5")); changeStatusLEDColor(R6StatusLED, statusLEDColor, mtDiag1BitMapping.at("R6")); changeStatusLEDColor(R7StatusLED, statusLEDColor, mtDiag1BitMapping.at("R7")); - commandLogWrite("DIAG1: 0x" + QString::number(static_cast(*mtDiag1RegValue), 2).rightJustified(16, '0')); + commandLogWrite("DIAG1: 0b" + QString::number(static_cast(*mtDiag1RegValue), 2).rightJustified(16, '0')); } else{ commandLogWrite("Failed to read MT Diagnostic 1 Register"); } } @@ -1476,7 +1476,7 @@ void HarmonicCalibration::updateFaultRegister(){ changeStatusLEDColor(RadiusCheckStatusLED, faultLEDColor, faultBitMapping.at("AMR Radius Check")); changeStatusLEDColor(SequencerWatchdogStatusLED, faultLEDColor, faultBitMapping.at("Sequencer Watchdog")); - commandLogWrite("FAULT: 0x" + QString::number(static_cast(*faultRegValue), 2).rightJustified(16, '0')); + commandLogWrite("FAULT: 0b" + QString::number(static_cast(*faultRegValue), 2).rightJustified(16, '0')); } else{ commandLogWrite("Failed to read FAULT Register"); } } @@ -1522,7 +1522,7 @@ void HarmonicCalibration::updateMTDiagnostics(){ AFEDIAG0LineEdit->setText(QString::number(afeDiag0) + " V"); AFEDIAG1LineEdit->setText(QString::number(afeDiag1) + " V"); - commandLogWrite("DIAG2: 0x" + QString::number(static_cast(*mtDiag2RegValue), 2).rightJustified(16, '0')); + commandLogWrite("DIAG2: 0b" + QString::number(static_cast(*mtDiag2RegValue), 2).rightJustified(16, '0')); } else{ commandLogWrite("Failed to read MT Diagnostic 2 Register"); } } diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp index ccaa4a8db8..d65a9b41ae 100644 --- a/plugins/admt/src/widgets/registerblockwidget.cpp +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -43,12 +43,9 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui // QLineEdit *lineEdit = new QLineEdit(menuSectionWidget); // applyLineEditStyle(lineEdit); - m_spinBox = new QSpinBox(menuSectionWidget); + m_spinBox = new PaddedSpinBox(menuSectionWidget); applySpinBoxStyle(m_spinBox); - m_spinBox->setDisplayIntegerBase(16); - m_spinBox->setMinimum(0); - m_spinBox->setMaximum(INT_MAX); - m_spinBox->setPrefix("0x"); + m_value = defaultValue; m_spinBox->setValue(m_value); @@ -84,6 +81,8 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui connect(m_spinBox, QOverload::of(&QSpinBox::valueChanged), this, &RegisterBlockWidget::onValueChanged); } +RegisterBlockWidget::~RegisterBlockWidget() {} + void RegisterBlockWidget::onValueChanged(int newValue){ m_value = static_cast(newValue); } uint32_t RegisterBlockWidget::getValue() { return m_value; } @@ -152,4 +151,19 @@ void RegisterBlockWidget::applySpinBoxStyle(QSpinBox *widget) widget->setAlignment(Qt::AlignRight); widget->setContentsMargins(12, 4, 12, 4); widget->setButtonSymbols(widget->ButtonSymbols::NoButtons); +} + +PaddedSpinBox::PaddedSpinBox(QWidget *parent) + : QSpinBox(parent) +{ + setDisplayIntegerBase(16); + setMinimum(0); + setMaximum(INT_MAX); +} + +PaddedSpinBox::~PaddedSpinBox() {} + +QString PaddedSpinBox::textFromValue(int value) const +{ + return QString("0x%1").arg(value, 4, 16, QChar('0')); } \ No newline at end of file From 12c2529359376a3be03c33487f01440eeb9590ae Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 26 Sep 2024 15:17:03 +0800 Subject: [PATCH 030/112] admt: Fixed pre-calibration FFT calculation Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 19 ++- .../admt/include/admt/harmoniccalibration.h | 6 +- plugins/admt/src/admtcontroller.cpp | 86 ++++++------- plugins/admt/src/harmoniccalibration.cpp | 118 +++++++++++------- 4 files changed, 133 insertions(+), 96 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index caa4b072ea..54a6168195 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -33,7 +33,14 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject int HAR_MAG_1, HAR_MAG_2, HAR_MAG_3, HAR_MAG_8 ,HAR_PHASE_1 ,HAR_PHASE_2 ,HAR_PHASE_3 ,HAR_PHASE_8; - vector angle_errors_fft, angle_errors_fft_phase, calibration_samples_sine, calibration_samples_cosine, calibration_samples_sine_scaled, calibration_samples_cosine_scaled; + vector angle_errors_fft_pre, + angle_errors_fft_phase_pre, + angle_errors_fft_post, + angle_errors_fft_phase_post, + calibration_samples_sine, + calibration_samples_cosine, + calibration_samples_sine_scaled, + calibration_samples_cosine_scaled; enum Channel { @@ -153,7 +160,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject map getDiag1RegisterBitMapping_Afe(uint16_t registerValue); map getDiag2RegisterBitMapping(uint16_t registerValue); uint16_t setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings); - QString postcalibrate(vector PANG); + void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; @@ -163,11 +170,11 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject unsigned int bitReverse(unsigned int x, int log2n); template void fft(Iter_T a, Iter_T b, int log2n); - void performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase); + void performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount); int linear_fit(vector x, vector y, double* slope, double* intercept); - int calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err); - void getPreCalibrationFFT(const vector& PANG, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre); - void getPostCalibrationFFT(const vector& updated_PANG, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post); + int calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err, int cycleCount, int samplesPerCycle); + void getPreCalibrationFFT(const vector& PANG, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre, int cycleCount, int samplesPerCycle); + void getPostCalibrationFFT(const vector& updated_PANG, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post, int cycleCount, int samplesPerCycle); }; } // namespace scopy::admt diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 910cce6b4d..f1172fab1a 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -125,9 +125,9 @@ public Q_SLOTS: QCheckBox *autoCalibrateCheckBox; - PlotWidget *calibrationFFTDataPlotWidget, *calibrationRawDataPlotWidget; - PlotAxis *calibrationFFTXPlotAxis, *calibrationFFTYPlotAxis, *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis; - PlotChannel *calibrationFFTPlotChannel, *calibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel; + PlotWidget *preCalibrationFFTPlotWidget, *calibrationRawDataPlotWidget; + PlotAxis *preCalibrationFFTXPlotAxis, *preCalibrationFFTYPlotAxis, *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis; + PlotChannel *preCalibrationFFTMagnitudePlotChannel, *preCalibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel; HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, *motorMaxDisplacementSpinBox, *motorTargetPositionSpinBox; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 010602b18a..be84a582c0 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -374,22 +374,18 @@ int ADMTController::linear_fit(vector x, vector y, double* slope } /* Calculate angle error based on MATLAB and C# implementation */ -int ADMTController::calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err) +/* Calculate angle error based on MATLAB and C# implementation */ +int ADMTController::calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err, int cycleCount, int samplesPerCycle) { - // Ideal angles - vector expected_angles = { - 0.00000, 15.46875, 30.93750, 46.40625, 61.87500, 77.34375, 92.81250, 108.28125, 123.75000, 139.21875, 154.68750, 170.15625, 185.62500, 201.09375, 216.56250, 232.03125, 247.50000, 262.96875, 278.43750, 293.90625, 309.37500, 324.84375, 340.31250, 355.78125, - 11.25000, 26.71875, 42.18750, 57.65625, 73.12500, 88.59375, 104.06250, 119.53125, 135.00000, 150.46875, 165.93750, 181.40625, 196.87500, 212.34375, 227.81250, 243.28125, 258.75000, 274.21875, 289.68750, 305.15625, 320.62500, 336.09375, 351.56250, 7.03125, - 22.50000, 37.96875, 53.43750, 68.90625, 84.37500, 99.84375, 115.31250, 130.78125, 146.25000, 161.71875, 177.18750, 192.65625, 208.12500, 223.59375, 239.06250, 254.53125, 270.00000, 285.46875, 300.93750, 316.40625, 331.87500, 347.34375, 2.81250, 18.28125, - 33.75000, 49.21875, 64.68750, 80.15625, 95.62500, 111.09375, 126.56250, 142.03125, 157.50000, 172.96875, 188.43750, 203.90625, 219.37500, 234.84375, 250.31250, 265.78125, 281.25000, 296.71875, 312.18750, 327.65625, 343.12500, 358.59375, 14.06250, 29.53125, - 45.00000, 60.46875, 75.93750, 91.40625, 106.87500, 122.34375, 137.81250, 153.28125, 168.75000, 184.21875, 199.68750, 215.15625, 230.62500, 246.09375, 261.56250, 277.03125, 292.50000, 307.96875, 323.43750, 338.90625, 354.37500, 9.84375, 25.31250, 40.78125, - 56.25000, 71.71875, 87.18750, 102.65625, 118.12500, 133.59375, 149.06250, 164.53125, 180.00000, 195.46875, 210.93750, 226.40625, 241.87500, 257.34375, 272.81250, 288.28125, 303.75000, 319.21875, 334.68750, 350.15625, 5.62500, 21.09375, 36.56250, 52.03125, - 67.50000, 82.96875, 98.43750, 113.90625, 129.37500, 144.84375, 160.31250, 175.78125, 191.25000, 206.71875, 222.18750, 237.65625, 253.12500, 268.59375, 284.06250, 299.53125, 315.00000, 330.46875, 345.93750, 1.40625, 16.87500, 32.34375, 47.81250, 63.28125, - 78.75000, 94.21875, 109.68750, 125.15625, 140.62500, 156.09375, 171.56250, 187.03125, 202.50000, 217.96875, 233.43750, 248.90625, 264.37500, 279.84375, 295.31250, 310.78125, 326.25000, 341.71875, 357.18750, 12.65625, 28.12500, 43.59375, 59.06250, 74.53125, - 90.00000, 105.46875, 120.93750, 136.40625, 151.87500, 167.34375, 182.81250, 198.28125, 213.75000, 229.21875, 244.68750, 260.15625, 275.62500, 291.09375, 306.56250, 322.03125, 337.50000, 352.96875, 8.43750, 23.90625, 39.37500, 54.84375, 70.31250, 85.78125, - 101.25000, 116.71875, 132.18750, 147.65625, 163.12500, 178.59375, 194.06250, 209.53125, 225.00000, 240.46875, 255.93750, 271.40625, 286.87500, 302.34375, 317.81250, 333.28125, 348.75000, 4.21875, 19.68750, 35.15625, 50.62500, 66.09375, 81.56250, 97.03125, - 112.50000, 127.96875, 143.43750, 158.90625, 174.37500, 189.84375, 205.31250, 220.78125, 236.25000, 251.71875, 267.18750, 282.65625, 298.12500, 313.59375, 329.06250, 344.53125 - }; + // Adjust the expected angles based on samples per cycle and cycle count + vector expected_angles; + double increment = 360.0 / samplesPerCycle; + + for (int cycle = 0; cycle < cycleCount; ++cycle) { + for (int sample = 0; sample < samplesPerCycle; ++sample) { + expected_angles.push_back(sample * increment); + } + } // Ensure that the angle_meas and expected_angles are of the same size if (angle_meas.size() != expected_angles.size()) { @@ -452,7 +448,7 @@ int ADMTController::calculate_angle_error(vector angle_meas, vector PANG, int cycles, int samplesPerCycle) { +QString ADMTController::calibrate(vector PANG, int cycleCount, int samplesPerCycle) { int CCW = 0, circshiftData = 0; QString result = ""; @@ -467,17 +463,17 @@ QString ADMTController::calibrate(vector PANG, int cycles, int samplesPe } // Declare vectors for pre-calibration FFT results - vector angle_errors_fft_pre(PANG.size() / 2); - vector angle_errors_fft_phase_pre(PANG.size() / 2); + angle_errors_fft_pre = vector(PANG.size() / 2); + angle_errors_fft_phase_pre = vector(PANG.size() / 2); // Call the new function for pre-calibration FFT - getPreCalibrationFFT(PANG, angle_errors_fft_pre, angle_errors_fft_phase_pre); + getPreCalibrationFFT(PANG, angle_errors_fft_pre, angle_errors_fft_phase_pre, cycleCount, samplesPerCycle); // Extract HMag parameters - double H1Mag = angle_errors_fft_pre[cycles]; - double H2Mag = angle_errors_fft_pre[2 * cycles]; - double H3Mag = angle_errors_fft_pre[3 * cycles]; - double H8Mag = angle_errors_fft_pre[8 * cycles]; + double H1Mag = angle_errors_fft_pre[cycleCount]; + double H2Mag = angle_errors_fft_pre[2 * cycleCount]; + double H3Mag = angle_errors_fft_pre[3 * cycleCount]; + double H8Mag = angle_errors_fft_pre[8 * cycleCount]; /* Display HMAG values */ result.append("H1Mag = " + QString::number(H1Mag) + "\n"); @@ -486,10 +482,10 @@ QString ADMTController::calibrate(vector PANG, int cycles, int samplesPe result.append("H8Mag = " + QString::number(H8Mag) + "\n"); // Extract HPhase parameters - double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycles]); - double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycles]); - double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycles]); - double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycles]); + double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycleCount]); + double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycleCount]); + double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycleCount]); + double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycleCount]); /* Display HPHASE values */ result.append("H1Phase = " + QString::number(H1Phase) + "\n"); @@ -577,19 +573,19 @@ QString ADMTController::calibrate(vector PANG, int cycles, int samplesPe return result; } -void ADMTController::getPreCalibrationFFT(const vector& PANG, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre) { +void ADMTController::getPreCalibrationFFT(const vector& PANG, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre, int cycleCount, int samplesPerCycle) { // Calculate the angle errors before calibration double max_err_pre = 0; vector angle_errors_pre(PANG.size()); - + // Calculate angle errors - calculate_angle_error(PANG, angle_errors_pre, &max_err_pre); + calculate_angle_error(PANG, angle_errors_pre, &max_err_pre, cycleCount, samplesPerCycle); // Perform FFT on pre-calibration angle errors - performFFT(angle_errors_pre, angle_errors_fft_pre, angle_errors_fft_phase_pre); + performFFT(angle_errors_pre, angle_errors_fft_pre, angle_errors_fft_phase_pre, cycleCount); } -QString ADMTController::postcalibrate(vector PANG){ +void ADMTController::postcalibrate(vector PANG, int cycleCount, int samplesPerCycle){ int CCW = 0, circshiftData = 0; QString result = ""; @@ -604,26 +600,26 @@ QString ADMTController::postcalibrate(vector PANG){ } // Declare vectors for pre-calibration FFT results - vector angle_errors_fft_post(PANG.size() / 2); - vector angle_errors_fft_phase_post(PANG.size() / 2); + angle_errors_fft_post = vector(PANG.size() / 2); + angle_errors_fft_phase_post = vector(PANG.size() / 2); // Call the new function for post-calibration FFT - getPostCalibrationFFT(PANG, angle_errors_fft_post, angle_errors_fft_phase_post); + getPostCalibrationFFT(PANG, angle_errors_fft_post, angle_errors_fft_phase_post, cycleCount, samplesPerCycle); } -void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post) { +void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post, int cycleCount, int samplesPerCycle) { // Calculate the angle errors after calibration double max_err_post = 0; vector angle_errors_post(updated_PANG.size()); // Calculate angle errors - calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post); + calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post, cycleCount, samplesPerCycle); // Perform FFT on post-calibration angle errors - performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post); + performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post, cycleCount); } -void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase) { +void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount) { typedef complex cx; int size = angle_errors.size(); @@ -647,11 +643,17 @@ void ADMTController::performFFT(const vector& angle_errors, vector angle_errors_fft_upper_half(size / cycleCount); + vector angle_errors_fft_phase_upper_half(size / cycleCount); + // Get upper half only - for (int i = 0; i < size / 2; i++) { - angle_errors_fft[i] = angle_errors_fft_temp[i]; - angle_errors_fft_phase[i] = angle_errors_fft_phase_temp[i]; + for (int i = 0; i < size / cycleCount; i++) { + angle_errors_fft_upper_half[i] = angle_errors_fft_temp[i]; + angle_errors_fft_phase_upper_half[i] = angle_errors_fft_phase_temp[i]; } + + angle_errors_fft = angle_errors_fft_upper_half; + angle_errors_fft_phase = angle_errors_fft_phase_upper_half; } diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 85d1b3db90..c620737b15 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -456,35 +456,59 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTDataGraphSectionWidget->contentLayout()->setSpacing(8); FFTDataGraphSectionWidget->contentLayout()->addWidget(FFTDataGraphTabWidget); - // FFT Plot Widget - calibrationFFTDataPlotWidget = new PlotWidget(); - calibrationFFTDataPlotWidget->setContentsMargins(10, 20, 10, 10); - calibrationFFTDataPlotWidget->xAxis()->setVisible(false); - calibrationFFTDataPlotWidget->yAxis()->setVisible(false); - QPen calibrationFFTPen = QPen(StyleHelper::getColor("ScopyBlue")); - QPen calibrationFFTPhasePen = QPen(StyleHelper::getColor("CH0")); - - calibrationFFTXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationFFTDataPlotWidget, calibrationFFTPen); - calibrationFFTYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationFFTDataPlotWidget, calibrationFFTPen); - calibrationFFTYPlotAxis->setInterval(-4, 4); - - calibrationFFTPlotChannel = new PlotChannel("FFT", calibrationFFTPen, calibrationFFTXPlotAxis, calibrationFFTYPlotAxis); - calibrationFFTPhasePlotChannel = new PlotChannel("FFT Phase", calibrationFFTPhasePen, calibrationFFTXPlotAxis, calibrationFFTYPlotAxis); - calibrationFFTDataPlotWidget->addPlotChannel(calibrationFFTPlotChannel); - calibrationFFTDataPlotWidget->addPlotChannel(calibrationFFTPhasePlotChannel); - - calibrationFFTPlotChannel->setEnabled(true); - calibrationFFTPhasePlotChannel->setEnabled(true); - calibrationFFTDataPlotWidget->selectChannel(calibrationFFTPlotChannel); - calibrationFFTDataPlotWidget->replot(); - - calibrationFFTDataPlotWidget->setShowXAxisLabels(true); - calibrationFFTDataPlotWidget->setShowYAxisLabels(true); - calibrationFFTDataPlotWidget->showAxisLabels(); + #pragma region Pre-Calibration FFT Data Graph Widget + QWidget *preCalibrationFFTWidget = new QWidget(); + QVBoxLayout *preCalibrationFFTLayout = new QVBoxLayout(preCalibrationFFTWidget); + preCalibrationFFTWidget->setLayout(preCalibrationFFTLayout); + preCalibrationFFTLayout->setMargin(0); + preCalibrationFFTLayout->setSpacing(0); + + preCalibrationFFTPlotWidget = new PlotWidget(); + preCalibrationFFTPlotWidget->setContentsMargins(10, 20, 10, 10); + preCalibrationFFTPlotWidget->xAxis()->setVisible(false); + preCalibrationFFTPlotWidget->yAxis()->setVisible(false); + QPen calibrationFFTMagnitudePen = QPen(StyleHelper::getColor("CH0")); + QPen calibrationFFTPhasePen = QPen(StyleHelper::getColor("CH1")); + + preCalibrationFFTXPlotAxis = new PlotAxis(QwtAxis::XBottom, preCalibrationFFTPlotWidget, calibrationFFTMagnitudePen); + preCalibrationFFTYPlotAxis = new PlotAxis(QwtAxis::YLeft, preCalibrationFFTPlotWidget, calibrationFFTMagnitudePen); + preCalibrationFFTYPlotAxis->setInterval(-4, 4); + + preCalibrationFFTMagnitudePlotChannel = new PlotChannel("FFT Magnitude", calibrationFFTMagnitudePen, preCalibrationFFTXPlotAxis, preCalibrationFFTYPlotAxis); + preCalibrationFFTPhasePlotChannel = new PlotChannel("FFT Phase", calibrationFFTPhasePen, preCalibrationFFTXPlotAxis, preCalibrationFFTYPlotAxis); + preCalibrationFFTPlotWidget->addPlotChannel(preCalibrationFFTMagnitudePlotChannel); + preCalibrationFFTPlotWidget->addPlotChannel(preCalibrationFFTPhasePlotChannel); + + preCalibrationFFTMagnitudePlotChannel->setEnabled(true); + preCalibrationFFTPhasePlotChannel->setEnabled(true); + preCalibrationFFTPlotWidget->selectChannel(preCalibrationFFTMagnitudePlotChannel); + preCalibrationFFTPlotWidget->replot(); + + preCalibrationFFTPlotWidget->setShowXAxisLabels(true); + preCalibrationFFTPlotWidget->setShowYAxisLabels(true); + preCalibrationFFTPlotWidget->showAxisLabels(); + + QWidget *preCalibrationFFTChannelsWidget = new QWidget(); + QHBoxLayout *preCalibrationFFTChannelsLayout = new QHBoxLayout(preCalibrationFFTChannelsWidget); + preCalibrationFFTChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); + preCalibrationFFTChannelsWidget->setLayout(preCalibrationFFTChannelsLayout); + preCalibrationFFTChannelsLayout->setContentsMargins(20, 13, 20, 5); + preCalibrationFFTChannelsLayout->setSpacing(20); + + MenuControlButton *togglePreCalibrationMagnitudeButton = createChannelToggleWidget("Magnitude", QColor(StyleHelper::getColor("CH0")), preCalibrationFFTChannelsWidget); + MenuControlButton *togglePreCalibrationPhaseButton = createChannelToggleWidget("Phase", QColor(StyleHelper::getColor("CH1")), preCalibrationFFTChannelsWidget); + + preCalibrationFFTChannelsLayout->addWidget(togglePreCalibrationMagnitudeButton); + preCalibrationFFTChannelsLayout->addWidget(togglePreCalibrationPhaseButton); + preCalibrationFFTChannelsLayout->addStretch(); + + preCalibrationFFTLayout->addWidget(preCalibrationFFTPlotWidget); + preCalibrationFFTLayout->addWidget(preCalibrationFFTChannelsWidget); + #pragma endregion PlotWidget *postCalibrationAngularErrorPlotWidget = new PlotWidget(); - FFTDataGraphTabWidget->addTab(calibrationFFTDataPlotWidget, "Pre-Calibration Angular Error"); + FFTDataGraphTabWidget->addTab(preCalibrationFFTWidget, "Pre-Calibration Angular Error"); FFTDataGraphTabWidget->addTab(postCalibrationAngularErrorPlotWidget, "Post-Calibration Angular Error"); calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget, 0, 0); @@ -517,10 +541,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDisplayFormatSwitch->setOffText("Hex"); calibrationDisplayFormatSwitch->setOnText("Angle"); calibrationDisplayFormatSwitch->setProperty("bigBtn", true); - applyCalibrationDataButton = new QPushButton(calibrationCoeffSectionWidget); - applyCalibrationDataButton->setText("Apply"); - StyleHelper::BlueButton(applyCalibrationDataButton, "applyCalibrationDataButton"); - applyCalibrationDataButton->setEnabled(false); // Calculated Coefficients Widget QWidget *calibrationCalculatedCoeffWidget = new QWidget(calibrationCoeffSectionWidget); @@ -638,7 +658,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatSwitch); calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffLabel); calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffWidget); - calibrationCoeffSectionWidget->contentLayout()->addWidget(applyCalibrationDataButton); + // calibrationCoeffSectionWidget->contentLayout()->addWidget(applyCalibrationDataButton); #pragma endregion #pragma region Calibration Dataset Configuration @@ -803,11 +823,11 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma endregion calibrationSettingsLayout->setMargin(0); - calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); calibrationSettingsLayout->addWidget(motorControlSectionWidget); + calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); calibrationSettingsLayout->addWidget(logsSectionWidget); calibrationSettingsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); #pragma endregion @@ -829,7 +849,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::calibrateData); connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); connect(importDataButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); - connect(applyCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::registerCalibrationData); + //connect(applyCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::registerCalibrationData); connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::clearRawDataList); connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); @@ -852,6 +872,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataPlotWidget->selectChannel(calibrationCosineDataPlotChannel); calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); }); + connect(togglePreCalibrationMagnitudeButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + preCalibrationFFTPlotWidget->selectChannel(preCalibrationFFTMagnitudePlotChannel); + preCalibrationFFTPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(togglePreCalibrationPhaseButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + preCalibrationFFTPlotWidget->selectChannel(preCalibrationFFTPhasePlotChannel); + preCalibrationFFTPlotWidget->selectedChannel()->setEnabled(b); + }); return tool; } @@ -2066,8 +2094,8 @@ void HarmonicCalibration::calibrateData() updateCalculatedCoeff(); - vector calibrationAngleErrorsFFT = m_admtController->angle_errors_fft; - vector calibrationAngleErrorsFFTPhase = m_admtController->angle_errors_fft_phase; + vector calibrationAngleErrorsFFT = m_admtController->angle_errors_fft_pre; + vector calibrationAngleErrorsFFTPhase = m_admtController->angle_errors_fft_phase_pre; // Frequency axis (assuming sampling rate of 1 Hz for simplicity) std::vector frequencyAxis(calibrationAngleErrorsFFT.size()); @@ -2076,9 +2104,9 @@ void HarmonicCalibration::calibrateData() frequencyAxis[i] = i; // Replace with actual frequency values if needed } - calibrationFFTPlotChannel->curve()->setSamples(frequencyAxis.data(), calibrationAngleErrorsFFT.data(), (calibrationAngleErrorsFFT.size() / 2)); // divide size by 2 for now, will be half the size - calibrationFFTPhasePlotChannel->curve()->setSamples(frequencyAxis.data(), calibrationAngleErrorsFFTPhase.data(), calibrationAngleErrorsFFTPhase.size()); - calibrationFFTXPlotAxis->setInterval(0, (calibrationAngleErrorsFFT.size() / 2)); // divide size by 2 for now, will be half the size + preCalibrationFFTMagnitudePlotChannel->curve()->setSamples(frequencyAxis.data(), calibrationAngleErrorsFFT.data(), (calibrationAngleErrorsFFT.size())); // divide size by 2 for now, will be half the size + preCalibrationFFTPhasePlotChannel->curve()->setSamples(frequencyAxis.data(), calibrationAngleErrorsFFTPhase.data(), calibrationAngleErrorsFFTPhase.size()); + preCalibrationFFTXPlotAxis->setInterval(0, (calibrationAngleErrorsFFT.size())); // divide size by 2 for now, will be half the size } void HarmonicCalibration::updateCalculatedCoeff() @@ -2091,7 +2119,7 @@ void HarmonicCalibration::updateCalculatedCoeff() calibrationH2PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_2)); calibrationH3PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_3)); calibrationH8PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_8)); - applyCalibrationDataButton->setEnabled(true); + //applyCalibrationDataButton->setEnabled(true); } void HarmonicCalibration::resetCalculatedCoeff() @@ -2104,7 +2132,7 @@ void HarmonicCalibration::resetCalculatedCoeff() calibrationH2PhaseLabel->setText("Φ --.--"); calibrationH3PhaseLabel->setText("Φ --.--"); calibrationH8PhaseLabel->setText("Φ --.--"); - applyCalibrationDataButton->setEnabled(false); + //applyCalibrationDataButton->setEnabled(false); } void HarmonicCalibration::registerCalibrationData() @@ -2178,8 +2206,8 @@ void HarmonicCalibration::extractCalibrationData() QVector rawData(rawDataList.begin(), rawDataList.end()); - QVector angleErrorsFFT(m_admtController->angle_errors_fft.begin(), m_admtController->angle_errors_fft.end()); - QVector angleErrorsFFTPhase(m_admtController->angle_errors_fft_phase.begin(), m_admtController->angle_errors_fft_phase.end()); + QVector angleErrorsFFT(m_admtController->angle_errors_fft_pre.begin(), m_admtController->angle_errors_fft_pre.end()); + QVector angleErrorsFFTPhase(m_admtController->angle_errors_fft_phase_pre.begin(), m_admtController->angle_errors_fft_phase_pre.end()); QVector h1Mag = { static_cast(m_admtController->HAR_MAG_1) }; QVector h2Mag = { static_cast(m_admtController->HAR_MAG_2) }; @@ -2284,9 +2312,9 @@ void HarmonicCalibration::clearRawDataList() calibrationCosineDataPlotChannel->curve()->setData(nullptr); calibrationRawDataPlotWidget->replot(); - calibrationFFTPlotChannel->curve()->setData(nullptr); - calibrationFFTPhasePlotChannel->curve()->setData(nullptr); - calibrationFFTDataPlotWidget->replot(); + preCalibrationFFTMagnitudePlotChannel->curve()->setData(nullptr); + preCalibrationFFTPhasePlotChannel->curve()->setData(nullptr); + preCalibrationFFTPlotWidget->replot(); resetCalculatedCoeff(); } From 044e5645b3cd6d83ba568c85a6a18bea7dc359c1 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 26 Sep 2024 15:29:49 +0800 Subject: [PATCH 031/112] admt: Fixed replot pre-calibration FFT graph after clear Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/harmoniccalibration.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index c620737b15..cdaa235f31 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -2104,9 +2104,10 @@ void HarmonicCalibration::calibrateData() frequencyAxis[i] = i; // Replace with actual frequency values if needed } - preCalibrationFFTMagnitudePlotChannel->curve()->setSamples(frequencyAxis.data(), calibrationAngleErrorsFFT.data(), (calibrationAngleErrorsFFT.size())); // divide size by 2 for now, will be half the size + preCalibrationFFTMagnitudePlotChannel->curve()->setSamples(frequencyAxis.data(), calibrationAngleErrorsFFT.data(), (calibrationAngleErrorsFFT.size())); preCalibrationFFTPhasePlotChannel->curve()->setSamples(frequencyAxis.data(), calibrationAngleErrorsFFTPhase.data(), calibrationAngleErrorsFFTPhase.size()); - preCalibrationFFTXPlotAxis->setInterval(0, (calibrationAngleErrorsFFT.size())); // divide size by 2 for now, will be half the size + preCalibrationFFTXPlotAxis->setInterval(0, (calibrationAngleErrorsFFT.size())); + preCalibrationFFTPlotWidget->replot(); } void HarmonicCalibration::updateCalculatedCoeff() @@ -2206,8 +2207,8 @@ void HarmonicCalibration::extractCalibrationData() QVector rawData(rawDataList.begin(), rawDataList.end()); - QVector angleErrorsFFT(m_admtController->angle_errors_fft_pre.begin(), m_admtController->angle_errors_fft_pre.end()); - QVector angleErrorsFFTPhase(m_admtController->angle_errors_fft_phase_pre.begin(), m_admtController->angle_errors_fft_phase_pre.end()); + QVector preCalibrationAngleErrorsFFTMagnitude(m_admtController->angle_errors_fft_pre.begin(), m_admtController->angle_errors_fft_pre.end()); + QVector preCalibrationAngleErrorsFFTPhase(m_admtController->angle_errors_fft_phase_pre.begin(), m_admtController->angle_errors_fft_phase_pre.end()); QVector h1Mag = { static_cast(m_admtController->HAR_MAG_1) }; QVector h2Mag = { static_cast(m_admtController->HAR_MAG_2) }; @@ -2219,8 +2220,8 @@ void HarmonicCalibration::extractCalibrationData() QVector h8Phase = { static_cast(m_admtController->HAR_PHASE_8) }; fm.save(rawData, "Raw Data"); - fm.save(angleErrorsFFT, "Angle Errors FFT"); - fm.save(angleErrorsFFTPhase, "Angle Errors FFT Phase"); + fm.save(preCalibrationAngleErrorsFFTMagnitude, "Pre-Calibration Angle Errors FFT Magnitude"); + fm.save(preCalibrationAngleErrorsFFTPhase, "Pre-Calibration Angle Errors FFT Phase"); fm.save(h1Mag, "H1 Mag"); fm.save(h2Mag, "H2 Mag"); fm.save(h3Mag, "H3 Mag"); From 7daae5c0321ef7e3140708d6e03de56b7eb89cc2 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 27 Sep 2024 13:45:48 +0800 Subject: [PATCH 032/112] admt: Implemented GMR reset Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 24 ++++- .../admt/include/admt/harmoniccalibration.h | 2 + plugins/admt/src/admtcontroller.cpp | 25 +++++ plugins/admt/src/harmoniccalibration.cpp | 97 +++++++++++++++++-- 4 files changed, 134 insertions(+), 14 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 54a6168195..9149395b10 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -58,6 +58,19 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject DEVICE_COUNT }; + enum DeviceAttribute + { + PAGE, + SEQUENCER_MODE, + ANGLE_FILT, + CONVERSION_MODE, + H8_CTRL, + SDP_GPIO_CTRL, + SDP_GPIO0_BUSY, + SDP_COIL_RS, + DEVICE_ATTR_COUNT + }; + enum MotorAttribute { AMAX, @@ -120,11 +133,12 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject SENSOR_REGISTER_COUNT }; - const char* ChannelIds[CHANNEL_COUNT] = {"rot", "angl", "count", "temp"}; - const char* DeviceIds[DEVICE_COUNT] = {"admt4000", "tmc5240"}; - const char* MotorAttributes[MOTOR_ATTR_COUNT] = {"amax", "rotate_vmax", "dmax", + const char* ChannelIds[CHANNEL_COUNT] = { "rot", "angl", "count", "temp" }; + const char* DeviceIds[DEVICE_COUNT] = { "admt4000", "tmc5240" }; + const char* DeviceAttributes[DEVICE_ATTR_COUNT] = { "page", "sequencer_mode", "angle_filt", "conversion_mode", "h8_ctrl", "sdp_gpio_ctrl", "sdp_gpio0_busy", "sdp_coil_rs" }; + const char* MotorAttributes[MOTOR_ATTR_COUNT] = { "amax", "rotate_vmax", "dmax", "disable", "target_pos", "current_pos", - "ramp_mode"}; + "ramp_mode" }; const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = { 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C }; const uint32_t ConfigurationRegisters[CONFIGURATION_REGISTER_COUNT] = { 0x01, 0x04, 0x06, 0x10, 0x12, 0x13, 0x1D, 0x23 }; const uint32_t ConfigurationPages[CONFIGURATION_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x02, 0x02, 0x02, 0x02, 0x02 }; @@ -133,6 +147,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject const char* getChannelId(Channel channel); const char* getDeviceId(Device device); + const char* getDeviceAttribute(DeviceAttribute attribute); const char* getMotorAttribute(MotorAttribute attribute); const uint32_t getHarmonicRegister(HarmonicRegister registerID); const uint32_t getConfigurationRegister(ConfigurationRegister registerID); @@ -161,6 +176,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject map getDiag2RegisterBitMapping(uint16_t registerValue); uint16_t setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings); void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle); + int getAbsAngleTurnCount(uint16_t registerValue); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index f1172fab1a..481e5ef234 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -192,6 +192,8 @@ public Q_SLOTS: void changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked = true); bool changeCNVPage(uint32_t page, QString registerName); void toggleWidget(QPushButton *widget, bool value); + void GMRReset(); + void updateCountValue(); QTimer *timer, *calibrationTimer, *motorCalibrationAcquisitionTimer, *utilityTimer; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index be84a582c0..97c2bb6da7 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -65,6 +65,14 @@ const char* ADMTController::getDeviceId(Device device) return "Unknown"; } +const char* ADMTController::getDeviceAttribute(DeviceAttribute attribute) +{ + if(attribute >= 0 && attribute < DEVICE_ATTR_COUNT){ + return DeviceAttributes[attribute]; + } + return "Unknown"; +} + const char* ADMTController::getMotorAttribute(MotorAttribute attribute) { if(attribute >= 0 && attribute < MOTOR_ATTR_COUNT){ @@ -1022,4 +1030,21 @@ uint16_t ADMTController::setGeneralRegisterBitMapping(uint16_t currentRegisterVa } return registerValue; +} + +int ADMTController::getAbsAngleTurnCount(uint16_t registerValue) { + // Bits 15:8: Turn count in quarter turns + uint8_t turnCount = (registerValue & 0xFF00) >> 8; + + if (turnCount <= 0xD5) { + // Straight binary turn count + return turnCount / 4; // Convert from quarter turns to whole turns + } else if (turnCount == 0xD6) { + // Invalid turn count + return -1; + } else { + // 2's complement turn count + int8_t signedTurnCount = static_cast(turnCount); // Handle as signed value + return signedTurnCount / 4; // Convert from quarter turns to whole turns + } } \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index cdaa235f31..9fc4531f9f 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -78,6 +78,35 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool runButton = new RunBtn(this); + QPushButton *resetGMRButton = new QPushButton(this); + resetGMRButton->setText("GMR Reset"); + QString topContainerButtonStyle = QString(R"css( + QPushButton { + width: 88px; + height: 48px; + border-radius: 2px; + padding-left: 20px; + padding-right: 20px; + color: white; + font-weight: 700; + font-size: 14px; + background-color: &&ScopyBlue&&; + } + + QPushButton:disabled { + background-color:#727273; /* design token - uiElement*/ + } + + QPushButton:checked { + background-color:#272730; /* design token - scopy blue*/ + } + QPushButton:pressed { + background-color:#272730; + } + })css"); + topContainerButtonStyle.replace("&&ScopyBlue&&", StyleHelper::getColor("ScopyBlue")); + resetGMRButton->setStyleSheet(topContainerButtonStyle); + connect(resetGMRButton, &QPushButton::clicked, this, &HarmonicCalibration::GMRReset); rightMenuButtonGroup->addButton(settingsButton); @@ -339,6 +368,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool tool->openTopContainerHelper(false); tool->addWidgetToTopContainerMenuControlHelper(openLastMenuButton, TTA_RIGHT); tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); + tool->addWidgetToTopContainerHelper(resetGMRButton, TTA_RIGHT); tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); tool->leftStack()->add("rawDataScroll", rawDataScroll); tool->rightStack()->add("generalSettingScroll", generalSettingScroll); @@ -506,10 +536,24 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() preCalibrationFFTLayout->addWidget(preCalibrationFFTChannelsWidget); #pragma endregion - PlotWidget *postCalibrationAngularErrorPlotWidget = new PlotWidget(); + #pragma region Post-Calibration Angular Error Plot Widget + QWidget *postCalibrationFFTWidget = new QWidget(); + QVBoxLayout *postCalibrationFFTLayout = new QVBoxLayout(postCalibrationFFTWidget); + postCalibrationFFTWidget->setLayout(postCalibrationFFTLayout); + postCalibrationFFTLayout->setMargin(0); + postCalibrationFFTLayout->setSpacing(0); + + PlotWidget *postCalibrationFFTPlotWidget = new PlotWidget(); + preCalibrationFFTPlotWidget->setContentsMargins(10, 20, 10, 10); + preCalibrationFFTPlotWidget->xAxis()->setVisible(false); + preCalibrationFFTPlotWidget->yAxis()->setVisible(false); + + postCalibrationFFTLayout->addWidget(postCalibrationFFTPlotWidget); + + #pragma endregion FFTDataGraphTabWidget->addTab(preCalibrationFFTWidget, "Pre-Calibration Angular Error"); - FFTDataGraphTabWidget->addTab(postCalibrationAngularErrorPlotWidget, "Post-Calibration Angular Error"); + FFTDataGraphTabWidget->addTab(postCalibrationFFTWidget, "Post-Calibration Angular Error"); calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget, 0, 0); calibrationDataGraphLayout->addWidget(FFTDataGraphSectionWidget, 1, 0); @@ -1285,6 +1329,31 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() return tool; } +void HarmonicCalibration::GMRReset() +{ + // Set Motor Angle to 315 degrees + target_pos = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); + + // Write 1 to ADMT IIO Attribute coil_rs + m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getDeviceAttribute(ADMTController::DeviceAttribute::SDP_COIL_RS), 1); + + // Write 0xc000 to CNVPAGE + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0xc000) != -1) + { + // Write 0x0000 to CNVPAGE + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0x0000) != -1) + { + // Read ABSANGLE + + StatusBarManager::pushMessage("GMR Reset Done"); + } + else { StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); } + } + else { StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); } +} + void HarmonicCalibration::restart() { if(m_running) { @@ -1568,10 +1637,19 @@ void HarmonicCalibration::clearCommandLog(){ void HarmonicCalibration::updateChannelValues(){ rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, bufferSize); angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, bufferSize); - count = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, bufferSize); + updateCountValue(); temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, bufferSize); } +void HarmonicCalibration::updateCountValue(){ + uint32_t *absAngleRegValue = new uint32_t; + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0x0000) != -1){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), absAngleRegValue) != -1){ + count = m_admtController->getAbsAngleTurnCount(static_cast(*absAngleRegValue)); + } + } +} + void HarmonicCalibration::updateLineEditValues(){ rotationValueLabel->setText(QString::number(rotation) + "°"); angleValueLabel->setText(QString::number(angle) + "°"); @@ -2268,15 +2346,14 @@ void HarmonicCalibration::importCalibrationData() void HarmonicCalibration::initializeMotor() { - amax = 1200; - writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - - rotate_vmax = 600000; + rotate_vmax = 53687.1; writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + + amax = 439.805; + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); dmax = 3000; writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); From 72cd7bf9b8f41af6ee08a3137d8963b02e4cbc30 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 7 Oct 2024 09:33:49 +0800 Subject: [PATCH 033/112] admt: Added min and max for line edit - Added digio register bit mapping and unwrap angles Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 2 + .../admt/include/admt/harmoniccalibration.h | 4 +- plugins/admt/src/admtcontroller.cpp | 100 ++++++++++++++++++ plugins/admt/src/harmoniccalibration.cpp | 24 ++--- 4 files changed, 116 insertions(+), 14 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 9149395b10..d3e6988af3 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -177,6 +177,8 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject uint16_t setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings); void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle); int getAbsAngleTurnCount(uint16_t registerValue); + uint16_t setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings); + vector unwrapAngles(const vector& wrappedAngles); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 481e5ef234..1d5ff97925 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -140,9 +140,9 @@ public Q_SLOTS: void updateChannelValues(); void updateLineEditValues(); void updateGeneralSettingEnabled(bool value); - void connectLineEditToNumber(QLineEdit* lineEdit, int& variable); + void connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max); void connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit = ""); - void connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph); + void connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph, int min, int max); void connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph); void connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph); void connectMenuComboToNumber(MenuCombo* menuCombo, double& variable); diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 97c2bb6da7..54eb74bcd9 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -1047,4 +1047,104 @@ int ADMTController::getAbsAngleTurnCount(uint16_t registerValue) { int8_t signedTurnCount = static_cast(turnCount); // Handle as signed value return signedTurnCount / 4; // Convert from quarter turns to whole turns } +} + +uint16_t ADMTController::setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings) { + uint16_t registerValue = currentRegisterValue; // Start with the current register value + + // Bits 15:14: (preserve original value) + + // Bit 13: DIGIO5EN + if (settings["DIGIO5EN"] == 1) // "Enabled" + { + registerValue |= (1 << 13); // Set bit 13 to 1 (Enabled) + } + else if (settings["DIGIO5EN"] == 0) // "Disabled" + { + registerValue &= ~(1 << 13); // Clear bit 13 (Disabled) + } + + // Bit 12: DIGIO4EN + if (settings["DIGIO4EN"] == 1) // "Enabled" + { + registerValue |= (1 << 12); // Set bit 12 to 1 (Enabled) + } + else if (settings["DIGIO4EN"] == 0) // "Disabled" + { + registerValue &= ~(1 << 12); // Clear bit 12 (Disabled) + } + + // Bit 11: DIGIO3EN + if (settings["DIGIO3EN"] == 1) // "Enabled" + { + registerValue |= (1 << 11); // Set bit 11 to 1 (Enabled) + } + else if (settings["DIGIO3EN"] == 0) // "Disabled" + { + registerValue &= ~(1 << 11); // Clear bit 11 (Disabled) + } + + // Bit 10: DIGIO2EN + if (settings["DIGIO2EN"] == 1) // "Enabled" + { + registerValue |= (1 << 10); // Set bit 10 to 1 (Enabled) + } + else if (settings["DIGIO2EN"] == 0) // "Disabled" + { + registerValue &= ~(1 << 10); // Clear bit 10 (Disabled) + } + + // Bit 9: DIGIO1EN + if (settings["DIGIO1EN"] == 1) // "Enabled" + { + registerValue |= (1 << 9); // Set bit 9 to 1 (Enabled) + } + else if (settings["DIGIO1EN"] == 0) // "Disabled" + { + registerValue &= ~(1 << 9); // Clear bit 9 (Disabled) + } + + // Bit 8: DIGIO0EN + if (settings["DIGIO0EN"] == 1) // "Enabled" + { + registerValue |= (1 << 8); // Set bit 8 to 1 (Enabled) + } + else if (settings["DIGIO0EN"] == 0) // "Disabled" + { + registerValue &= ~(1 << 8); // Clear bit 8 (Disabled) + } + + // Bits 7:0: (preserve original value) + + return registerValue; +} + +vector unwrapAngles(const vector& wrappedAngles) { + vector unwrappedAngles; + unwrappedAngles.reserve(wrappedAngles.size()); + + // Start with the first angle as it is + double previousAngle = wrappedAngles[0]; + unwrappedAngles.push_back(previousAngle); + + // Initialize an offset for unwrapping + double offset = 0.0; + + for (size_t i = 1; i < wrappedAngles.size(); ++i) { + double currentAngle = wrappedAngles[i]; + double delta = currentAngle - previousAngle; + + // Adjust the current angle if it wraps around + if (delta < -180.0) { + offset += 360.0; // Increment offset for negative wrap + } else if (delta > 180.0) { + offset -= 360.0; // Decrement offset for positive wrap + } + + // Add the offset to the current angle + unwrappedAngles.push_back(currentAngle + offset); + previousAngle = currentAngle; // Update previous angle + } + + return unwrappedAngles; } \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 9fc4531f9f..85f77eb583 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -228,7 +228,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool applyLineEditStyle(graphUpdateIntervalLineEdit); graphUpdateIntervalLineEdit->setText(QString::number(sampleRate)); - connectLineEditToNumber(graphUpdateIntervalLineEdit, sampleRate); + connectLineEditToNumber(graphUpdateIntervalLineEdit, sampleRate, 20, 5000); generalSection->contentLayout()->addWidget(graphUpdateIntervalLabel); generalSection->contentLayout()->addWidget(graphUpdateIntervalLineEdit); @@ -241,7 +241,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool applyLineEditStyle(dataSampleSizeLineEdit); dataSampleSizeLineEdit->setText(QString::number(bufferSize)); - connectLineEditToNumber(dataSampleSizeLineEdit, bufferSize); + connectLineEditToNumber(dataSampleSizeLineEdit, bufferSize, 1, 2048); generalSection->contentLayout()->addWidget(dataSampleSizeLabel); generalSection->contentLayout()->addWidget(dataSampleSizeLineEdit); @@ -320,7 +320,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool applyLineEditStyle(dataGraphSamplesLineEdit); dataGraphSamplesLineEdit->setText(QString::number(dataGraphSamples)); - connectLineEditToGraphSamples(dataGraphSamplesLineEdit, dataGraphSamples, dataGraph); + connectLineEditToGraphSamples(dataGraphSamplesLineEdit, dataGraphSamples, dataGraph, 1, 5000); dataGraphSection->contentLayout()->addWidget(dataGraphSamplesLabel); dataGraphSection->contentLayout()->addWidget(dataGraphSamplesLineEdit); @@ -343,7 +343,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLabel); tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLineEdit); - connectLineEditToGraphSamples(tempGraphSamplesLineEdit, tempGraphSamples, tempGraph); + connectLineEditToGraphSamples(tempGraphSamplesLineEdit, tempGraphSamples, tempGraph, 1, 5000); tempGraphWidget->contentLayout()->addWidget(tempGraphSection); @@ -716,14 +716,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(calibrationDatasetConfigCollapseSection); applyLineEditStyle(calibrationCycleCountLineEdit); calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); - connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount); + connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 1000); QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", calibrationDatasetConfigCollapseSection); StyleHelper::MenuSmallLabel(calibrationSamplesPerCycleLabel); QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationDatasetConfigCollapseSection); applyLineEditStyle(calibrationSamplesPerCycleLineEdit); calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); - connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle); + connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, 1, 5000); calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(8); calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountLabel); @@ -1702,12 +1702,12 @@ MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString return menuControlButton; } -void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable) +void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max) { - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, min, max]() { bool ok; int value = lineEdit->text().toInt(&ok); - if (ok) { + if (ok && value >= min && value <= max) { variable = value; } else { lineEdit->setText(QString::number(variable)); @@ -1744,12 +1744,12 @@ void HarmonicCalibration::connectLineEditToNumberWrite(QLineEdit* lineEdit, doub }); } -void HarmonicCalibration::connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph) +void HarmonicCalibration::connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph, int min, int max) { - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, graph]() { + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, graph, min, max]() { bool ok; int value = lineEdit->text().toInt(&ok); - if (ok) { + if (ok && value >= min && value <= max) { variable = value; graph->setNumSamples(variable); } else { From 49d30680762b8bd29dc00fcab78b56328e559e55 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Mon, 7 Oct 2024 10:19:35 +0800 Subject: [PATCH 034/112] Update admtcontroller.cpp - Updated angle error calculation to take into account unwrapped angles for expected values. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 54eb74bcd9..ab4957309f 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -330,7 +330,6 @@ unsigned int ADMTController::bitReverse(unsigned int x, int log2n) { } template -/* fft from example codes online */ void ADMTController::fft(Iter_T a, Iter_T b, int log2n) { typedef typename iterator_traits::value_type complex; @@ -381,7 +380,6 @@ int ADMTController::linear_fit(vector x, vector y, double* slope return 0; } -/* Calculate angle error based on MATLAB and C# implementation */ /* Calculate angle error based on MATLAB and C# implementation */ int ADMTController::calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err, int cycleCount, int samplesPerCycle) { @@ -391,7 +389,7 @@ int ADMTController::calculate_angle_error(vector angle_meas, vector Date: Mon, 7 Oct 2024 10:33:03 +0800 Subject: [PATCH 035/112] Update admtcontroller.cpp - Added option to change value for computation based on voltage level. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index ab4957309f..da9700effe 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -933,14 +933,14 @@ map ADMTController::getDiag1RegisterBitMapping_Register(uint16_t r return result; } -map ADMTController::getDiag1RegisterBitMapping_Afe(uint16_t registerValue) { +map ADMTController::getDiag1RegisterBitMapping_Afe(uint16_t registerValue, bool is5V = false) { map result; // Bits 7:0: AFE Diagnostic 2 - Measurement of Fixed voltage (stored in 2's complement) int8_t afeDiagnostic = static_cast(registerValue & 0x00FF); // Interpret as signed 8-bit // Choose the correct resolution based on the voltage level (5V or 3.3V part) - double resolution = 0.003222; // 0.0048828 if 5V + double resolution = is5V ? 0.0048828 : 0.003222; // 0.0048828 for 5V, 0.003222 for 3.3V // Convert the AFE Diagnostic value to a voltage double diagnosticVoltage = static_cast(afeDiagnostic) * resolution; From d545759c3994f992c759a297387aa2bacd0ab492 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 8 Oct 2024 13:56:00 +0800 Subject: [PATCH 036/112] admt: Implemented GPIO Control - Added device identifiers Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 22 +- .../admt/include/admt/harmoniccalibration.h | 7 + plugins/admt/src/admtcontroller.cpp | 158 +++++++-- plugins/admt/src/harmoniccalibration.cpp | 329 ++++++++++++++++-- 4 files changed, 468 insertions(+), 48 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index d3e6988af3..761cbafdec 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -133,6 +134,15 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject SENSOR_REGISTER_COUNT }; + enum UniqueIDRegister + { + UNIQID0, + UNIQID1, + UNIQID2, + UNIQID3, + UNIQID_REGISTER_COUNT + }; + const char* ChannelIds[CHANNEL_COUNT] = { "rot", "angl", "count", "temp" }; const char* DeviceIds[DEVICE_COUNT] = { "admt4000", "tmc5240" }; const char* DeviceAttributes[DEVICE_ATTR_COUNT] = { "page", "sequencer_mode", "angle_filt", "conversion_mode", "h8_ctrl", "sdp_gpio_ctrl", "sdp_gpio0_busy", "sdp_coil_rs" }; @@ -144,6 +154,8 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject const uint32_t ConfigurationPages[CONFIGURATION_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x02, 0x02, 0x02, 0x02, 0x02 }; const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = { 0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14 }; const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }; + const uint32_t UniqueIdRegisters[UNIQID_REGISTER_COUNT] = { 0x1E, 0x1F, 0x20, 0x21 }; + const uint32_t UniqueIdPages[UNIQID_REGISTER_COUNT] = { 0x02, 0x02, 0x02, 0x02 }; const char* getChannelId(Channel channel); const char* getDeviceId(Device device); @@ -154,6 +166,8 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject const uint32_t getConfigurationPage(ConfigurationRegister registerID); const uint32_t getSensorRegister(SensorRegister registerID); const uint32_t getSensorPage(SensorRegister registerID); + const uint32_t getUniqueIdRegister(UniqueIDRegister registerID); + const uint32_t getUniqueIdPage(UniqueIDRegister registerID); void connectADMT(); void disconnectADMT(); @@ -170,15 +184,17 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject double getActualHarmonicRegisterValue(uint16_t registerValue, const string key); map getFaultRegisterBitMapping(uint16_t registerValue); map getGeneralRegisterBitMapping(uint16_t registerValue); - map getDigioenRegisterBitMapping(uint16_t registerValue); + map getDIGIOENRegisterBitMapping(uint16_t registerValue); map getDiag1RegisterBitMapping_Register(uint16_t registerValue); - map getDiag1RegisterBitMapping_Afe(uint16_t registerValue); + map getDiag1RegisterBitMapping_Afe(uint16_t registerValue, bool is5V); map getDiag2RegisterBitMapping(uint16_t registerValue); uint16_t setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings); void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle); int getAbsAngleTurnCount(uint16_t registerValue); - uint16_t setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings); + uint16_t setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings); vector unwrapAngles(const vector& wrappedAngles); + map getUNIQID3RegisterMapping(uint16_t registerValue); + vector wrapAngles(const vector& unwrappedAngles); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 1d5ff97925..76a20e9422 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -137,6 +137,8 @@ public Q_SLOTS: *AFEDIAGStatusLED, *NVMCRCFaultStatusLED, *ECCDoubleBitErrorStatusLED, *OscillatorDriftStatusLED, *CountSensorFalseStateStatusLED, *AngleCrossCheckStatusLED, *TurnCountSensorLevelsStatusLED, *MTDIAGStatusLED, *TurnCounterCrossCheckStatusLED, *RadiusCheckStatusLED, *SequencerWatchdogStatusLED; + CustomSwitch *DIGIOBUSYToggleSwitch, *DIGIOCNVToggleSwitch, *DIGIOSENTToggleSwitch, *DIGIOACALCToggleSwitch, *DIGIOFAULTToggleSwitch, *DIGIOBOOTLOADERToggleSwitch, *DIGIOALLToggleSwitch; + void updateChannelValues(); void updateLineEditValues(); void updateGeneralSettingEnabled(bool value); @@ -194,6 +196,11 @@ public Q_SLOTS: void toggleWidget(QPushButton *widget, bool value); void GMRReset(); void updateCountValue(); + void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel); + void readDeviceProperties(); + void toggleAllDIGIO(bool value); + void toggleUtilityTask(bool run); + void toggleDIGIOEN(string DIGIOENName, bool value); QTimer *timer, *calibrationTimer, *motorCalibrationAcquisitionTimer, *utilityTimer; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index da9700effe..727ec9f390 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -26,7 +26,6 @@ ADMTController::ADMTController(QString uri, QObject *parent) :QObject(parent) , uri(uri) { - } ADMTController::~ADMTController() {} @@ -121,6 +120,22 @@ const uint32_t ADMTController::getSensorPage(SensorRegister registerID) return UINT32_MAX; } +const uint32_t ADMTController::getUniqueIdRegister(UniqueIDRegister registerID) +{ + if(registerID >= 0 && registerID < UNIQID_REGISTER_COUNT){ + return UniqueIdRegisters[registerID]; + } + return UINT32_MAX; +} + +const uint32_t ADMTController::getUniqueIdPage(UniqueIDRegister registerID) +{ + if(registerID >= 0 && registerID < UNIQID_REGISTER_COUNT){ + return UniqueIdPages[registerID]; + } + return UINT32_MAX; +} + int ADMTController::getChannelIndex(const char *deviceName, const char *channelName) { iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); @@ -586,9 +601,11 @@ void ADMTController::getPreCalibrationFFT(const vector& PANG, vector PANG, int cycleCount, int samplesPerCycle){ @@ -620,9 +637,12 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, v // Calculate angle errors calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post, cycleCount, samplesPerCycle); + // Corrected Error (angle_errors_post) // Perform FFT on post-calibration angle errors performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post, cycleCount); + // FFT Corrected Error (angle_errors_post) + // FFT Corrected Error Phase (angle_errors_fft_phase_post) } void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount) { @@ -869,7 +889,7 @@ map ADMTController::getGeneralRegisterBitMapping(uint16_t registerV // std::cout << pair.first << ": " << pair.second << std::endl; // } -map ADMTController::getDigioenRegisterBitMapping(uint16_t registerValue) { +map ADMTController::getDIGIOENRegisterBitMapping(uint16_t registerValue) { map result; // // Bits 15:14: Reserved (skipped) @@ -897,22 +917,22 @@ map ADMTController::getDigioenRegisterBitMapping(uint16_t register // result["Reserved (7:6)"] = "Reserved"; // Bit 5: Bootload - result["BOOTLOAD"] = ((registerValue >> 5) & 0x01) ? false : true; // ? "GPIO5" : "Bootload (Output only)"; + result["BOOTLOAD"] = ((registerValue >> 5) & 0x01) ? true : false; // ? "GPIO5" : "Bootload (Output only)"; // Bit 4: Fault - result["FAULT"] = ((registerValue >> 4) & 0x01) ? false : true; // ? "GPIO4" : "Fault (Output only)"; + result["FAULT"] = ((registerValue >> 4) & 0x01) ? true : false; // ? "GPIO4" : "Fault (Output only)"; // Bit 3: Acalc - result["ACALC"] = ((registerValue >> 3) & 0x01) ? false : true; // ? "GPIO3" : "Acalc (Output only)"; + result["ACALC"] = ((registerValue >> 3) & 0x01) ? true : false; // ? "GPIO3" : "Acalc (Output only)"; // Bit 2: Sent - result["SENT"] = ((registerValue >> 2) & 0x01) ? false : true; // ? "GPIO2" : "Sent (Output only)"; + result["SENT"] = ((registerValue >> 2) & 0x01) ? true : false; // ? "GPIO2" : "Sent (Output only)"; // Bit 1: Cnv - result["CNV"] = ((registerValue >> 1) & 0x01) ? false : true; // ? "GPIO1" : "Cnv (Output only)"; + result["CNV"] = ((registerValue >> 1) & 0x01) ? true : false; // ? "GPIO1" : "Cnv (Output only)"; // Bit 0: Busy - result["BUSY"] = (registerValue & 0x01) ? false : true; // ? "GPIO0" : "Busy (Output only)"; + result["BUSY"] = (registerValue & 0x01) ? true : false; // ? "GPIO0" : "Busy (Output only)"; return result; } @@ -933,7 +953,7 @@ map ADMTController::getDiag1RegisterBitMapping_Register(uint16_t r return result; } -map ADMTController::getDiag1RegisterBitMapping_Afe(uint16_t registerValue, bool is5V = false) { +map ADMTController::getDiag1RegisterBitMapping_Afe(uint16_t registerValue, bool is5V) { map result; // Bits 7:0: AFE Diagnostic 2 - Measurement of Fixed voltage (stored in 2's complement) @@ -1047,67 +1067,67 @@ int ADMTController::getAbsAngleTurnCount(uint16_t registerValue) { } } -uint16_t ADMTController::setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings) { +uint16_t ADMTController::setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings) { uint16_t registerValue = currentRegisterValue; // Start with the current register value // Bits 15:14: (preserve original value) // Bit 13: DIGIO5EN - if (settings["DIGIO5EN"] == 1) // "Enabled" + if (settings["DIGIO5EN"]) // "Enabled" { registerValue |= (1 << 13); // Set bit 13 to 1 (Enabled) } - else if (settings["DIGIO5EN"] == 0) // "Disabled" + else // "Disabled" { registerValue &= ~(1 << 13); // Clear bit 13 (Disabled) } // Bit 12: DIGIO4EN - if (settings["DIGIO4EN"] == 1) // "Enabled" + if (settings["DIGIO4EN"]) // "Enabled" { registerValue |= (1 << 12); // Set bit 12 to 1 (Enabled) } - else if (settings["DIGIO4EN"] == 0) // "Disabled" + else // "Disabled" { registerValue &= ~(1 << 12); // Clear bit 12 (Disabled) } // Bit 11: DIGIO3EN - if (settings["DIGIO3EN"] == 1) // "Enabled" + if (settings["DIGIO3EN"]) // "Enabled" { registerValue |= (1 << 11); // Set bit 11 to 1 (Enabled) } - else if (settings["DIGIO3EN"] == 0) // "Disabled" + else // "Disabled" { registerValue &= ~(1 << 11); // Clear bit 11 (Disabled) } // Bit 10: DIGIO2EN - if (settings["DIGIO2EN"] == 1) // "Enabled" + if (settings["DIGIO2EN"]) // "Enabled" { registerValue |= (1 << 10); // Set bit 10 to 1 (Enabled) } - else if (settings["DIGIO2EN"] == 0) // "Disabled" + else // "Disabled" { registerValue &= ~(1 << 10); // Clear bit 10 (Disabled) } // Bit 9: DIGIO1EN - if (settings["DIGIO1EN"] == 1) // "Enabled" + if (settings["DIGIO1EN"]) // "Enabled" { registerValue |= (1 << 9); // Set bit 9 to 1 (Enabled) } - else if (settings["DIGIO1EN"] == 0) // "Disabled" + else // "Disabled" { registerValue &= ~(1 << 9); // Clear bit 9 (Disabled) } // Bit 8: DIGIO0EN - if (settings["DIGIO0EN"] == 1) // "Enabled" + if (settings["DIGIO0EN"]) // "Enabled" { registerValue |= (1 << 8); // Set bit 8 to 1 (Enabled) } - else if (settings["DIGIO0EN"] == 0) // "Disabled" + else // "Disabled" { registerValue &= ~(1 << 8); // Clear bit 8 (Disabled) } @@ -1117,7 +1137,7 @@ uint16_t ADMTController::setDIGIOENRegisterBitMapping(uint16_t currentRegisterVa return registerValue; } -vector unwrapAngles(const vector& wrappedAngles) { +vector ADMTController::unwrapAngles(const vector& wrappedAngles) { vector unwrappedAngles; unwrappedAngles.reserve(wrappedAngles.size()); @@ -1145,4 +1165,96 @@ vector unwrapAngles(const vector& wrappedAngles) { } return unwrappedAngles; +} + +vector ADMTController::wrapAngles(const vector& unwrappedAngles) { + vector wrapped_angles; + wrapped_angles.reserve(unwrappedAngles.size()); + + for (const auto& angle : unwrappedAngles) { + // Wrap angle to be within [0, 360) + double wrapped_angle = fmod(angle, 360.0); + + // Ensure wrapped_angle is positive + if (wrapped_angle < 0) { + wrapped_angle += 360.0; + } + + wrapped_angles.push_back(wrapped_angle); + } + + return wrapped_angles; +} + +map ADMTController::getUNIQID3RegisterMapping(uint16_t registerValue) { + map result; + + // Bits 15:11 - Reserved (ignore) + + // Bits 10:08 - Product ID (3 bits) + uint8_t productID = (registerValue >> 8) & 0x07; + switch (productID) { + case 0x00: + result["Product ID"] = "ADMT4000"; + break; + case 0x01: + result["Product ID"] = "ADMT4001"; + break; + default: + result["Product ID"] = "Unidentified"; + break; + } + + // Bits 7:06 - Supply ID (2 bits) + uint8_t supplyID = (registerValue >> 6) & 0x03; + switch (supplyID) { + case 0x00: + result["Supply ID"] = "3.3V"; + break; + case 0x02: + result["Supply ID"] = "5V"; + break; + default: + result["Supply ID"] = "Unknown"; + break; + } + + // Bits 5:03 - ASIL ID (3 bits) + uint8_t asilID = (registerValue >> 3) & 0x07; // Show both Seq 1 & 2 if unknown + switch (asilID) { + case 0x00: + result["ASIL ID"] = "ASIL QM"; + break; + case 0x01: + result["ASIL ID"] = "ASIL A"; + break; + case 0x02: + result["ASIL ID"] = "ASIL B"; + break; + case 0x03: + result["ASIL ID"] = "ASIL C"; + break; + case 0x04: + result["ASIL ID"] = "ASIL D"; + break; + default: + result["ASIL ID"] = "Unidentified ASIL"; + break; + } + + // Bits 2:00 - Revision ID (3 bits) + uint8_t revisionID = registerValue & 0x07; + switch (revisionID) { + case 0x01: + result["Revision ID"] = "S1"; + break; + case 0x02: + result["Revision ID"] = "S2"; + break; + default: + result["Revision ID"] = "Unknown"; + break; + } + + return result; } \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 85f77eb583..4d5250425c 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -43,6 +43,11 @@ static const QColor cosineColor = QColor("#91e6cf"); static const QColor faultLEDColor = QColor("#c81a28"); static const QColor statusLEDColor = QColor("#2e9e6f"); +static map deviceRegisterMap; +static QString deviceName = ""; +static QString deviceType = ""; +static bool is5V = false; + using namespace scopy; using namespace scopy::admt; using namespace scopy::grutil; @@ -52,6 +57,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool , isDebug(isDebug) , m_admtController(m_admtController) { + readDeviceProperties(); rotationChannelName = m_admtController->getChannelId(ADMTController::Channel::ROTATION); angleChannelName = m_admtController->getChannelId(ADMTController::Channel::ANGLE); countChannelName = m_admtController->getChannelId(ADMTController::Channel::COUNT); @@ -211,7 +217,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool generalSettingLayout->setMargin(0); generalSettingWidget->setLayout(generalSettingLayout); - header = new MenuHeaderWidget("ADMT4000", QPen(StyleHelper::getColor("ScopyBlue")), this); + header = new MenuHeaderWidget(deviceName + " " + deviceType, QPen(StyleHelper::getColor("ScopyBlue")), this); // General Setting Widget MenuSectionWidget *generalWidget = new MenuSectionWidget(generalSettingWidget); @@ -1164,8 +1170,17 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() centerUtilityLayout->setSpacing(8); // centerUtilityLayout->setAlignment(Qt::AlignTop); + QScrollArea *DIGIOScrollArea = new QScrollArea(centerUtilityWidget); + QWidget *DIGIOWidget = new QWidget(DIGIOScrollArea); + DIGIOScrollArea->setWidget(DIGIOWidget); + DIGIOScrollArea->setWidgetResizable(true); + QVBoxLayout *DIGIOLayout = new QVBoxLayout(DIGIOWidget); + DIGIOWidget->setLayout(DIGIOLayout); + DIGIOLayout->setMargin(0); + DIGIOLayout->setSpacing(5); + #pragma region DIGIO Monitor - MenuSectionWidget *DIGIOMonitorSectionWidget = new MenuSectionWidget(centerUtilityWidget); + MenuSectionWidget *DIGIOMonitorSectionWidget = new MenuSectionWidget(DIGIOWidget); MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection("DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, DIGIOMonitorSectionWidget); DIGIOMonitorSectionWidget->contentLayout()->addWidget(DIGIOMonitorCollapseSection); @@ -1184,6 +1199,112 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBootloaderStatusLED); #pragma endregion + #pragma region DIGIO Control + MenuSectionWidget *DIGIOControlSectionWidget = new MenuSectionWidget(DIGIOWidget); + MenuCollapseSection *DIGIOControlCollapseSection = new MenuCollapseSection("GPIO Control", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, DIGIOControlSectionWidget); + DIGIOControlSectionWidget->contentLayout()->addWidget(DIGIOControlCollapseSection); + + QWidget *DIGIOControlGridWidget = new QWidget(DIGIOControlSectionWidget); + QGridLayout *DIGIOControlGridLayout = new QGridLayout(DIGIOControlGridWidget); + DIGIOControlGridWidget->setLayout(DIGIOControlGridLayout); + DIGIOControlGridLayout->setMargin(0); + DIGIOControlGridLayout->setSpacing(8); + + QLabel *DIGIOBUSYLabel = new QLabel("GPIO0", DIGIOControlGridWidget); + StyleHelper::MenuSmallLabel(DIGIOBUSYLabel, "DIGIOBUSYLabel"); + QLabel *DIGIOCNVLabel = new QLabel("GPIO1", DIGIOControlGridWidget); + StyleHelper::MenuSmallLabel(DIGIOCNVLabel, "DIGIOCNVLabel"); + QLabel *DIGIOSENTLabel = new QLabel("GPIO2", DIGIOControlGridWidget); + StyleHelper::MenuSmallLabel(DIGIOSENTLabel, "DIGIOSENTLabel"); + QLabel *DIGIOACALCLabel = new QLabel("GPIO3", DIGIOControlGridWidget); + StyleHelper::MenuSmallLabel(DIGIOACALCLabel, "DIGIOACALCLabel"); + QLabel *DIGIOFAULTLabel = new QLabel("GPIO4", DIGIOControlGridWidget); + StyleHelper::MenuSmallLabel(DIGIOFAULTLabel, "DIGIOFAULTLabel"); + QLabel *DIGIOBOOTLOADERLabel = new QLabel("GPIO5", DIGIOControlGridWidget); + StyleHelper::MenuSmallLabel(DIGIOBOOTLOADERLabel, "DIGIOBOOTLOADERLabel"); + QLabel *DIGIOALLLabel = new QLabel("GPIO Output", DIGIOControlGridWidget); + StyleHelper::MenuSmallLabel(DIGIOALLLabel, "DIGIOALLLabel"); + + DIGIOBUSYToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIOBUSYToggleSwitch, "On", "Off"); + connect(DIGIOBUSYToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("DIGIO0EN", value); + }); + + DIGIOCNVToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIOCNVToggleSwitch, "On", "Off"); + connect(DIGIOCNVToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("DIGIO1EN", value); + }); + + DIGIOSENTToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIOSENTToggleSwitch, "On", "Off"); + connect(DIGIOSENTToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("DIGIO2EN", value); + }); + + DIGIOACALCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIOACALCToggleSwitch, "On", "Off"); + connect(DIGIOACALCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("DIGIO3EN", value); + }); + + DIGIOFAULTToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIOFAULTToggleSwitch, "On", "Off"); + connect(DIGIOFAULTToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("DIGIO4EN", value); + }); + + DIGIOBOOTLOADERToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIOBOOTLOADERToggleSwitch, "On", "Off"); + connect(DIGIOBOOTLOADERToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("DIGIO5EN", value); + }); + + DIGIOALLToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIOALLToggleSwitch, "On", "Off"); + connect(DIGIOALLToggleSwitch, &CustomSwitch::toggled, [=](bool value){ + toggleAllDIGIO(value); + }); + + DIGIOControlGridLayout->addWidget(DIGIOALLLabel, 0, 0); + DIGIOControlGridLayout->addWidget(DIGIOALLToggleSwitch, 0, 1); + + DIGIOControlGridLayout->addItem(new QSpacerItem(0, 8, QSizePolicy::Fixed, QSizePolicy::Expanding), 1, 0, 1, 2); + QFrame *line = new QFrame(); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Plain); + line->setFixedHeight(1); + QString lineStyle = QString(R"css( + QFrame { + border: 1px solid white; + } + )css"); + line->setStyleSheet(lineStyle); + DIGIOControlGridLayout->addWidget(line, 2, 0, 1, 2); + + DIGIOControlGridLayout->addItem(new QSpacerItem(0, 8, QSizePolicy::Fixed, QSizePolicy::Expanding), 3, 0, 1, 2); + + DIGIOControlGridLayout->addWidget(DIGIOBUSYLabel, 4, 0); + DIGIOControlGridLayout->addWidget(DIGIOBUSYToggleSwitch, 4, 1); + DIGIOControlGridLayout->addWidget(DIGIOCNVLabel, 5, 0); + DIGIOControlGridLayout->addWidget(DIGIOCNVToggleSwitch, 5, 1); + DIGIOControlGridLayout->addWidget(DIGIOSENTLabel, 6, 0); + DIGIOControlGridLayout->addWidget(DIGIOSENTToggleSwitch, 6, 1); + DIGIOControlGridLayout->addWidget(DIGIOACALCLabel, 7, 0); + DIGIOControlGridLayout->addWidget(DIGIOACALCToggleSwitch, 7, 1); + DIGIOControlGridLayout->addWidget(DIGIOFAULTLabel, 8, 0); + DIGIOControlGridLayout->addWidget(DIGIOFAULTToggleSwitch, 8, 1); + DIGIOControlGridLayout->addWidget(DIGIOBOOTLOADERLabel, 9, 0); + DIGIOControlGridLayout->addWidget(DIGIOBOOTLOADERToggleSwitch, 9, 1); + + DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOControlGridWidget); + #pragma endregion + + DIGIOLayout->addWidget(DIGIOMonitorSectionWidget); + DIGIOLayout->addWidget(DIGIOControlSectionWidget); + DIGIOLayout->addStretch(); + #pragma region MTDIAG1 Widget MenuSectionWidget *MTDIAG1SectionWidget = new MenuSectionWidget(centerUtilityWidget); MenuCollapseSection *MTDIAG1CollapseSection = new MenuCollapseSection("MT Diagnostic Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MTDIAG1SectionWidget); @@ -1214,6 +1335,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MTDiagnosticsScrollArea->setWidget(MTDiagnosticsWidget); MTDiagnosticsScrollArea->setWidgetResizable(true); QVBoxLayout *MTDiagnosticsLayout = new QVBoxLayout(MTDiagnosticsWidget); + MTDiagnosticsWidget->setLayout(MTDiagnosticsLayout); MTDiagnosticsLayout->setMargin(0); MTDiagnosticsLayout->setSpacing(5); @@ -1254,7 +1376,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MTDiagnosticsLayout->addStretch(); #pragma endregion - centerUtilityLayout->addWidget(DIGIOMonitorSectionWidget, 1, Qt::AlignTop); + centerUtilityLayout->addWidget(DIGIOScrollArea); centerUtilityLayout->addWidget(MTDiagnosticsScrollArea); // centerUtilityLayout->addWidget(MTDIAG1SectionWidget, 0, Qt::AlignTop); // centerUtilityLayout->addWidget(MTDiagnosticsSectionWidget, 0, Qt::AlignTop); @@ -1329,6 +1451,164 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() return tool; } +void HarmonicCalibration::toggleUtilityTask(bool run) +{ + if(run){ + utilityTimer->start(utilityTimerRate); + } + else{ + utilityTimer->stop(); + } +} + +void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) +{ + toggleUtilityTask(false); + + uint32_t *DIGIOENRegisterValue = new uint32_t; + uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + + if(changeCNVPage(DIGIOENPage, "DIGIOEN")) + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) + { + map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); + DIGIOSettings[DIGIOENName] = value; + + uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); + + changeCNVPage(DIGIOENPage, "DIGIOEN"); + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + static_cast(newRegisterValue)) != -1) + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) + { + map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); + DIGIOBUSYToggleSwitch->setChecked(DIGIOSettings["DIGIO0EN"]); + DIGIOCNVToggleSwitch->setChecked(DIGIOSettings["DIGIO1EN"]); + DIGIOSENTToggleSwitch->setChecked(DIGIOSettings["DIGIO2EN"]); + DIGIOACALCToggleSwitch->setChecked(DIGIOSettings["DIGIO3EN"]); + DIGIOFAULTToggleSwitch->setChecked(DIGIOSettings["DIGIO4EN"]); + DIGIOBOOTLOADERToggleSwitch->setChecked(DIGIOSettings["DIGIO5EN"]); + //StatusBarManager::pushMessage(QString::fromStdString(DIGIOENName) + " is " + QString(value ? "enabled" : "disabled")); + } + else{ StatusBarManager::pushMessage("Failed to read DIGIOEN Register"); } + } + else{ StatusBarManager::pushMessage("Failed to write DIGIOEN Register"); } + } + } + + toggleUtilityTask(true); +} + +void HarmonicCalibration::toggleAllDIGIO(bool value) +{ + toggleUtilityTask(false); + uint32_t *DIGIOENRegisterValue = new uint32_t; + uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) + { + map DIGIOSettings; + DIGIOSettings["DIGIO5EN"] = value; + DIGIOSettings["DIGIO4EN"] = value; + DIGIOSettings["DIGIO3EN"] = value; + DIGIOSettings["DIGIO2EN"] = value; + DIGIOSettings["DIGIO1EN"] = value; + DIGIOSettings["DIGIO0EN"] = value; + uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); + + changeCNVPage(DIGIOENPage, "DIGIOEN"); + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + static_cast(newRegisterValue)) != -1) + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) + { + map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); + DIGIOBUSYToggleSwitch->setChecked(DIGIOSettings["DIGIO0EN"]); + DIGIOCNVToggleSwitch->setChecked(DIGIOSettings["DIGIO1EN"]); + DIGIOSENTToggleSwitch->setChecked(DIGIOSettings["DIGIO2EN"]); + DIGIOACALCToggleSwitch->setChecked(DIGIOSettings["DIGIO3EN"]); + DIGIOFAULTToggleSwitch->setChecked(DIGIOSettings["DIGIO4EN"]); + DIGIOBOOTLOADERToggleSwitch->setChecked(DIGIOSettings["DIGIO5EN"]); + StatusBarManager::pushMessage("GPIO Outputs are " + QString(value ? "enabled" : "disabled")); + } + else{ StatusBarManager::pushMessage("Failed to read DIGIOEN Register"); } + + } + else{ StatusBarManager::pushMessage("Failed to write DIGIOEN Register"); } + } + toggleUtilityTask(true); +} + +void HarmonicCalibration::readDeviceProperties() +{ + uint32_t *uniqId3RegisterValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t page = m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3); + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, page) != -1){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ + if(*cnvPageRegValue == page){ + + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID3), uniqId3RegisterValue) != -1){ + deviceRegisterMap = m_admtController->getUNIQID3RegisterMapping(static_cast(*uniqId3RegisterValue)); + + if(deviceRegisterMap.at("Supply ID") == "5V") + { + is5V = true; + } + else if(deviceRegisterMap.at("Supply ID") == "3.3V") + { + is5V = false; + } + else + { + is5V = false; + } + + deviceName = QString::fromStdString(deviceRegisterMap.at("Product ID")); + + if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") + { + deviceType = QString::fromStdString("Industrial"); + } + else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") + { + deviceType = QString::fromStdString("Automotive"); + } + else{ + deviceType = QString::fromStdString(deviceRegisterMap.at("ASIL ID")); + } + } + else{ StatusBarManager::pushMessage("Failed to read UNIQID3 register"); } + + } + else{ StatusBarManager::pushMessage("CNVPAGE for UNIQID3 is a different value, abort reading"); } + } + else{ StatusBarManager::pushMessage("Failed to read CNVPAGE for UNIQID3"); } + } + else{ StatusBarManager::pushMessage("Failed to write CNVPAGE for UNIQID3"); } +} + +void HarmonicCalibration::changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel) +{ + customSwitch->setOnText(onLabel); + customSwitch->setOffText(offLabel); +} + void HarmonicCalibration::GMRReset() { // Set Motor Angle to 315 degrees @@ -1498,25 +1778,30 @@ void HarmonicCalibration::utilityTask(){ void HarmonicCalibration::updateDigioMonitor(){ uint32_t *digioRegValue = new uint32_t; - uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIO); - - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), digioRegisterAddress, digioRegValue) != -1){ - std::map digioBitMapping = m_admtController->getDigioenRegisterBitMapping(static_cast(*digioRegValue)); - if(digioBitMapping.at("DIGIO0EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("BUSY")); } - else { changeStatusLEDColor(DIGIOBusyStatusLED, faultLEDColor); } - if(digioBitMapping.at("DIGIO1EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("CNV")); } - else { changeStatusLEDColor(DIGIOCNVStatusLED, faultLEDColor); } - if(digioBitMapping.at("DIGIO2EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("SENT")); } - else { changeStatusLEDColor(DIGIOSENTStatusLED, faultLEDColor); } - if(digioBitMapping.at("DIGIO3EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("ACALC")); } - else { changeStatusLEDColor(DIGIOACALCStatusLED, faultLEDColor); } - if(digioBitMapping.at("DIGIO4EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("FAULT")); } - else { changeStatusLEDColor(DIGIOFaultStatusLED, faultLEDColor); } - if(digioBitMapping.at("DIGIO5EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("BOOTLOAD")); } - else { changeStatusLEDColor(DIGIOBootloaderStatusLED, faultLEDColor); } - commandLogWrite("DIGIO: 0b" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); + uint32_t digioEnPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + if(changeCNVPage(digioEnPage, "DIGIOEN")) + { + uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN); + + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), digioRegisterAddress, digioRegValue) != -1){ + std::map digioBitMapping = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*digioRegValue)); + if(digioBitMapping.at("DIGIO0EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("BUSY")); } + else { changeStatusLEDColor(DIGIOBusyStatusLED, faultLEDColor); } + if(digioBitMapping.at("DIGIO1EN")){ changeStatusLEDColor(DIGIOCNVStatusLED, statusLEDColor, digioBitMapping.at("CNV")); } + else { changeStatusLEDColor(DIGIOCNVStatusLED, faultLEDColor); } + if(digioBitMapping.at("DIGIO2EN")){ changeStatusLEDColor(DIGIOSENTStatusLED, statusLEDColor, digioBitMapping.at("SENT")); } + else { changeStatusLEDColor(DIGIOSENTStatusLED, faultLEDColor); } + if(digioBitMapping.at("DIGIO3EN")){ changeStatusLEDColor(DIGIOACALCStatusLED, statusLEDColor, digioBitMapping.at("ACALC")); } + else { changeStatusLEDColor(DIGIOACALCStatusLED, faultLEDColor); } + if(digioBitMapping.at("DIGIO4EN")){ changeStatusLEDColor(DIGIOFaultStatusLED, statusLEDColor, digioBitMapping.at("FAULT")); } + else { changeStatusLEDColor(DIGIOFaultStatusLED, faultLEDColor); } + if(digioBitMapping.at("DIGIO5EN")){ changeStatusLEDColor(DIGIOBootloaderStatusLED, statusLEDColor, digioBitMapping.at("BOOTLOAD")); } + else { changeStatusLEDColor(DIGIOBootloaderStatusLED, faultLEDColor); } + commandLogWrite("DIGIOEN: 0b" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); + } + else{ commandLogWrite("Failed to read DIGIOEN Register"); } } - else{ commandLogWrite("Failed to read DIGIO Register"); } + } void HarmonicCalibration::updateMTDiagRegister(){ @@ -1595,7 +1880,7 @@ void HarmonicCalibration::updateMTDiagnostics(){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ if(*cnvPageRegValue == mtDiag1PageValue){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1){ - std::map mtDiag1BitMapping = m_admtController->getDiag1RegisterBitMapping_Afe(static_cast(*mtDiag1RegValue)); + std::map mtDiag1BitMapping = m_admtController->getDiag1RegisterBitMapping_Afe(static_cast(*mtDiag1RegValue), is5V); afeDiag2 = mtDiag1BitMapping.at("AFE Diagnostic 2"); AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); From 27b8d15b1d6cc4fb07dfb02302034d8d8f2d9ffa Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 10 Oct 2024 09:29:05 +0800 Subject: [PATCH 037/112] admt: Implemented multithread for calibration data sampling - Added graphs for angle error, corrected error, and FFTs - Added post calibration routine Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 8 +- .../admt/include/admt/harmoniccalibration.h | 33 +- plugins/admt/src/admtcontroller.cpp | 9 +- plugins/admt/src/harmoniccalibration.cpp | 773 ++++++++++++------ 4 files changed, 560 insertions(+), 263 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 761cbafdec..49feac7071 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -41,7 +41,13 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject calibration_samples_sine, calibration_samples_cosine, calibration_samples_sine_scaled, - calibration_samples_cosine_scaled; + calibration_samples_cosine_scaled, + angleError, + FFTAngleErrorMagnitude, + FFTAngleErrorPhase, + correctedError, + FFTCorrectedErrorMagnitude, + FFTCorrectedErrorPhase; enum Channel { diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 76a20e9422..048b5ab9c5 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -61,7 +61,6 @@ public Q_SLOTS: void restart(); void timerTask(); void calibrationTask(); - void motorCalibrationAcquisitionTask(); void utilityTask(); void clearCommandLog(); void canCalibrate(bool); @@ -117,7 +116,7 @@ public Q_SLOTS: MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo, *sequenceTypeMenuCombo, *conversionTypeMenuCombo, *cnvSourceMenuCombo, *convertSynchronizationMenuCombo, *angleFilterMenuCombo, *eighthHarmonicMenuCombo; - QTabWidget *tabWidget; + QTabWidget *tabWidget, *calibrationDataGraphTabWidget; QListWidget *rawDataListWidget; @@ -125,9 +124,17 @@ public Q_SLOTS: QCheckBox *autoCalibrateCheckBox; - PlotWidget *preCalibrationFFTPlotWidget, *calibrationRawDataPlotWidget; - PlotAxis *preCalibrationFFTXPlotAxis, *preCalibrationFFTYPlotAxis, *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis; - PlotChannel *preCalibrationFFTMagnitudePlotChannel, *preCalibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel; + PlotWidget *angleErrorPlotWidget, *calibrationRawDataPlotWidget, *FFTAngleErrorPlotWidget, + *correctedErrorPlotWidget, *postCalibrationRawDataPlotWidget, *FFTCorrectedErrorPlotWidget; + PlotAxis *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis, + *angleErrorXPlotAxis, *angleErrorYPlotAxis, *FFTAngleErrorXPlotAxis, *FFTAngleErrorYPlotAxis, + *correctedErrorXPlotAxis, *correctedErrorYPlotAxis, *FFTCorrectedErrorXPlotAxis, *FFTCorrectedErrorYPlotAxis, + *postCalibrationRawDataXPlotAxis, *postCalibrationRawDataYPlotAxis; + PlotChannel *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel, + *FFTAngleErrorMagnitudeChannel, *FFTAngleErrorPhaseChannel, + *correctedErrorPlotChannel, + *postCalibrationRawDataPlotChannel, *postCalibrationSineDataPlotChannel, *postCalibrationCosineDataPlotChannel, + *FFTCorrectedErrorMagnitudeChannel, *FFTCorrectedErrorPhaseChannel; HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, *motorMaxDisplacementSpinBox, *motorTargetPositionSpinBox; @@ -156,13 +163,11 @@ public Q_SLOTS: void updateLabelValue(QLabel* label, int channelIndex); void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); void updateChannelValue(int channelIndex); - void addAngleToRawDataList(); void calibrateData(); void registerCalibrationData(); void extractCalibrationData(); void importCalibrationData(); - void calibrationLogWrite(QString message); - void calibrationLogWriteLn(QString message = ""); + void calibrationLogWrite(QString message = ""); void commandLogWrite(QString message); void readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value); void writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); @@ -183,7 +188,6 @@ public Q_SLOTS: double convertAMAXtoAccelTime(double amax); void updateCalculatedCoeff(); void resetCalculatedCoeff(); - void appendSamplesToPlotCurve(PlotWidget *plotWidget, QVector& newYData); void applyTabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor = "ScopyBlue"); MenuControlButton *createStatusLEDWidget(const QString title, QColor color, QWidget *parent = nullptr); MenuControlButton *createChannelToggleWidget(const QString title, QColor color, QWidget *parent = nullptr); @@ -201,8 +205,15 @@ public Q_SLOTS: void toggleAllDIGIO(bool value); void toggleUtilityTask(bool run); void toggleDIGIOEN(string DIGIOENName, bool value); - - QTimer *timer, *calibrationTimer, *motorCalibrationAcquisitionTimer, *utilityTimer; + void getCalibrationSamples(); + void startMotor(); + void computeSineCosineOfAngles(QVector graphDataList); + void postCalibrateData(); + void canStartMotor(bool value); + void resetCurrentPositionToZero(); + void flashHarmonicValues(); + + QTimer *timer, *calibrationTimer, *utilityTimer; int uuid = 0; const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 727ec9f390..a92900c1c2 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -602,10 +602,14 @@ void ADMTController::getPreCalibrationFFT(const vector& PANG, vector PANG, int cycleCount, int samplesPerCycle){ @@ -638,11 +642,14 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, v // Calculate angle errors calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post, cycleCount, samplesPerCycle); // Corrected Error (angle_errors_post) + correctedError = angle_errors_post; // Perform FFT on post-calibration angle errors performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post, cycleCount); // FFT Corrected Error (angle_errors_post) + FFTCorrectedErrorMagnitude = angle_errors_post; // FFT Corrected Error Phase (angle_errors_fft_phase_post) + FFTCorrectedErrorPhase = angle_errors_fft_phase_post; } void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount) { diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 4d5250425c..29950ab8e4 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -1,11 +1,13 @@ #include "harmoniccalibration.h" -#include +#include "qtconcurrentrun.h" +#include #include +#include + static int sampleRate = 50; -static int calibrationTimerRate = 100; -static int motorCalibrationAcquisitionTimerRate = 20; +static int calibrationTimerRate = 1000; static int utilityTimerRate = 1000; static int bufferSize = 1; @@ -17,9 +19,8 @@ static double *dataGraphValue; static int cycleCount = 11; static int samplesPerCycle = 256; static int totalSamplesCount = cycleCount * samplesPerCycle; -static bool startMotor = false; - -static bool isCalibrated = false; +static bool isStartMotor = false; +static bool isPostCalibration = false; static double motorTimeUnit = 1.048576; // t = 2^24/16Mhz static int motorMicrostepPerRevolution = 51200; @@ -36,13 +37,18 @@ static uint32_t h2PhaseDeviceRegister = 0x18; static uint32_t h3PhaseDeviceRegister = 0x1A; static uint32_t h8PhaseDeviceRegister = 0x1C; -static vector rawDataList; +static QVector graphDataList, graphPostDataList; +static const QColor scopyBlueColor = scopy::StyleHelper::getColor("ScopyBlue"); static const QColor sineColor = QColor("#85e94c"); static const QColor cosineColor = QColor("#91e6cf"); static const QColor faultLEDColor = QColor("#c81a28"); static const QColor statusLEDColor = QColor("#2e9e6f"); +static const QPen scopyBluePen(scopyBlueColor); +static const QPen sinePen(sineColor); +static const QPen cosinePen(cosineColor); + static map deviceRegisterMap; static QString deviceName = ""; static QString deviceType = ""; @@ -217,7 +223,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool generalSettingLayout->setMargin(0); generalSettingWidget->setLayout(generalSettingLayout); - header = new MenuHeaderWidget(deviceName + " " + deviceType, QPen(StyleHelper::getColor("ScopyBlue")), this); + header = new MenuHeaderWidget(deviceName + " " + deviceType, scopyBluePen, this); // General Setting Widget MenuSectionWidget *generalWidget = new MenuSectionWidget(generalSettingWidget); @@ -260,7 +266,10 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool sequenceTypeMenuCombo = new MenuCombo("Sequence Type", sequenceSection); QComboBox *sequenceTypeComboBox = sequenceTypeMenuCombo->combo(); sequenceTypeComboBox->addItem("Mode 1", QVariant(0)); - sequenceTypeComboBox->addItem("Mode 2", QVariant(1)); + if(deviceType.toStdString() == "Automotive") + { + sequenceTypeComboBox->addItem("Mode 2", QVariant(1)); + } applyComboBoxStyle(sequenceTypeComboBox); conversionTypeMenuCombo = new MenuCombo("Conversion Type", sequenceSection); @@ -390,9 +399,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool calibrationTimer = new QTimer(this); connect(calibrationTimer, &QTimer::timeout, this, &HarmonicCalibration::calibrationTask); - motorCalibrationAcquisitionTimer = new QTimer(this); - connect(motorCalibrationAcquisitionTimer, &QTimer::timeout, this, &HarmonicCalibration::motorCalibrationAcquisitionTask); - utilityTimer = new QTimer(this); connect(utilityTimer, &QTimer::timeout, this, &HarmonicCalibration::utilityTask); @@ -413,6 +419,32 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool HarmonicCalibration::~HarmonicCalibration() {} +void HarmonicCalibration::initializeMotor() +{ + rotate_vmax = 53687.0912; + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + + amax = 439.8046511104; + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + + dmax = 3000; + writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); + + ramp_mode = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + + target_pos = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); + + current_pos = 0; + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); +} + ToolTemplate* HarmonicCalibration::createCalibrationWidget() { initializeMotor(); @@ -426,31 +458,35 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDataGraphLayout->setSpacing(5); MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); - QTabWidget *calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); + calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); applyTabWidgetStyle(calibrationDataGraphTabWidget); calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); + calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); + + #pragma region Calibration Samples + QWidget *calibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); + QVBoxLayout *calibrationSamplesLayout = new QVBoxLayout(calibrationSamplesWidget); + calibrationSamplesWidget->setLayout(calibrationSamplesLayout); + calibrationSamplesLayout->setMargin(0); + calibrationSamplesLayout->setSpacing(0); - // Raw Data Plot Widget calibrationRawDataPlotWidget = new PlotWidget(); calibrationRawDataPlotWidget->setContentsMargins(10, 20, 10, 10); calibrationRawDataPlotWidget->xAxis()->setVisible(false); calibrationRawDataPlotWidget->yAxis()->setVisible(false); - QPen calibrationRawDataPen = QPen(StyleHelper::getColor("ScopyBlue")); - QPen calibrationSineDataPen = QPen(sineColor); - QPen calibrationCosineDataPen = QPen(cosineColor); - calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, calibrationRawDataPen); - calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, calibrationRawDataPen); + calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, scopyBluePen); + calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, scopyBluePen); calibrationRawDataYPlotAxis->setInterval(0, 400); - calibrationRawDataPlotChannel = new PlotChannel("Samples", calibrationRawDataPen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - calibrationSineDataPlotChannel = new PlotChannel("Sine", calibrationSineDataPen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - calibrationCosineDataPlotChannel = new PlotChannel("Cosine", calibrationCosineDataPen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + calibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + calibrationRawDataPlotChannel->xAxis()->setMin(0); + calibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + calibrationCosineDataPlotChannel = new PlotChannel("Cosine", cosinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); calibrationRawDataPlotWidget->addPlotChannel(calibrationSineDataPlotChannel); calibrationRawDataPlotWidget->addPlotChannel(calibrationCosineDataPlotChannel); - // calibrationRawDataPlotChannel->setStyle(PlotChannel::PCS_DOTS); calibrationRawDataPlotChannel->setEnabled(true); calibrationSineDataPlotChannel->setEnabled(true); calibrationCosineDataPlotChannel->setEnabled(true); @@ -461,9 +497,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataPlotWidget->setShowYAxisLabels(true); calibrationRawDataPlotWidget->showAxisLabels(); - calibrationDataGraphTabWidget->addTab(calibrationRawDataPlotWidget, "Calibration Samples"); - - QWidget *calibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphSectionWidget); + QWidget *calibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); QHBoxLayout *calibrationDataGraphChannelsLayout = new QHBoxLayout(calibrationDataGraphChannelsWidget); calibrationDataGraphChannelsWidget->setLayout(calibrationDataGraphChannelsLayout); QString calibrationDataGraphChannelsStyle = QString(R"css( @@ -471,98 +505,252 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() )css"); calibrationDataGraphChannelsStyle.replace(QString("&&colorname&&"), StyleHelper::getColor("UIElementBackground")); calibrationDataGraphChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); - calibrationDataGraphChannelsLayout->setContentsMargins(20, 5, 20, 5); + calibrationDataGraphChannelsLayout->setContentsMargins(20, 13, 20, 5); calibrationDataGraphChannelsLayout->setSpacing(20); - MenuControlButton *toggleAngleButton = createChannelToggleWidget("Angle", QColor(StyleHelper::getColor("ScopyBlue")), calibrationDataGraphChannelsWidget); + MenuControlButton *toggleAngleButton = createChannelToggleWidget("Angle", scopyBlueColor, calibrationDataGraphChannelsWidget); MenuControlButton *toggleSineButton = createChannelToggleWidget("Sine", sineColor, calibrationDataGraphChannelsWidget); MenuControlButton *toggleCosineButton = createChannelToggleWidget("Cosine", cosineColor, calibrationDataGraphChannelsWidget); calibrationDataGraphChannelsLayout->addWidget(toggleAngleButton); calibrationDataGraphChannelsLayout->addWidget(toggleSineButton); calibrationDataGraphChannelsLayout->addWidget(toggleCosineButton); - calibrationDataGraphChannelsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred)); + calibrationDataGraphChannelsLayout->addStretch(); - calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); - calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphChannelsWidget); - - MenuSectionWidget *FFTDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); - QTabWidget *FFTDataGraphTabWidget = new QTabWidget(FFTDataGraphSectionWidget); - applyTabWidgetStyle(FFTDataGraphTabWidget); - FFTDataGraphSectionWidget->contentLayout()->setSpacing(8); - FFTDataGraphSectionWidget->contentLayout()->addWidget(FFTDataGraphTabWidget); - - #pragma region Pre-Calibration FFT Data Graph Widget - QWidget *preCalibrationFFTWidget = new QWidget(); - QVBoxLayout *preCalibrationFFTLayout = new QVBoxLayout(preCalibrationFFTWidget); - preCalibrationFFTWidget->setLayout(preCalibrationFFTLayout); - preCalibrationFFTLayout->setMargin(0); - preCalibrationFFTLayout->setSpacing(0); - - preCalibrationFFTPlotWidget = new PlotWidget(); - preCalibrationFFTPlotWidget->setContentsMargins(10, 20, 10, 10); - preCalibrationFFTPlotWidget->xAxis()->setVisible(false); - preCalibrationFFTPlotWidget->yAxis()->setVisible(false); - QPen calibrationFFTMagnitudePen = QPen(StyleHelper::getColor("CH0")); - QPen calibrationFFTPhasePen = QPen(StyleHelper::getColor("CH1")); - - preCalibrationFFTXPlotAxis = new PlotAxis(QwtAxis::XBottom, preCalibrationFFTPlotWidget, calibrationFFTMagnitudePen); - preCalibrationFFTYPlotAxis = new PlotAxis(QwtAxis::YLeft, preCalibrationFFTPlotWidget, calibrationFFTMagnitudePen); - preCalibrationFFTYPlotAxis->setInterval(-4, 4); - - preCalibrationFFTMagnitudePlotChannel = new PlotChannel("FFT Magnitude", calibrationFFTMagnitudePen, preCalibrationFFTXPlotAxis, preCalibrationFFTYPlotAxis); - preCalibrationFFTPhasePlotChannel = new PlotChannel("FFT Phase", calibrationFFTPhasePen, preCalibrationFFTXPlotAxis, preCalibrationFFTYPlotAxis); - preCalibrationFFTPlotWidget->addPlotChannel(preCalibrationFFTMagnitudePlotChannel); - preCalibrationFFTPlotWidget->addPlotChannel(preCalibrationFFTPhasePlotChannel); - - preCalibrationFFTMagnitudePlotChannel->setEnabled(true); - preCalibrationFFTPhasePlotChannel->setEnabled(true); - preCalibrationFFTPlotWidget->selectChannel(preCalibrationFFTMagnitudePlotChannel); - preCalibrationFFTPlotWidget->replot(); - - preCalibrationFFTPlotWidget->setShowXAxisLabels(true); - preCalibrationFFTPlotWidget->setShowYAxisLabels(true); - preCalibrationFFTPlotWidget->showAxisLabels(); - - QWidget *preCalibrationFFTChannelsWidget = new QWidget(); - QHBoxLayout *preCalibrationFFTChannelsLayout = new QHBoxLayout(preCalibrationFFTChannelsWidget); - preCalibrationFFTChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); - preCalibrationFFTChannelsWidget->setLayout(preCalibrationFFTChannelsLayout); - preCalibrationFFTChannelsLayout->setContentsMargins(20, 13, 20, 5); - preCalibrationFFTChannelsLayout->setSpacing(20); - - MenuControlButton *togglePreCalibrationMagnitudeButton = createChannelToggleWidget("Magnitude", QColor(StyleHelper::getColor("CH0")), preCalibrationFFTChannelsWidget); - MenuControlButton *togglePreCalibrationPhaseButton = createChannelToggleWidget("Phase", QColor(StyleHelper::getColor("CH1")), preCalibrationFFTChannelsWidget); - - preCalibrationFFTChannelsLayout->addWidget(togglePreCalibrationMagnitudeButton); - preCalibrationFFTChannelsLayout->addWidget(togglePreCalibrationPhaseButton); - preCalibrationFFTChannelsLayout->addStretch(); - - preCalibrationFFTLayout->addWidget(preCalibrationFFTPlotWidget); - preCalibrationFFTLayout->addWidget(preCalibrationFFTChannelsWidget); + calibrationSamplesLayout->addWidget(calibrationRawDataPlotWidget); + calibrationSamplesLayout->addWidget(calibrationDataGraphChannelsWidget); #pragma endregion - #pragma region Post-Calibration Angular Error Plot Widget - QWidget *postCalibrationFFTWidget = new QWidget(); - QVBoxLayout *postCalibrationFFTLayout = new QVBoxLayout(postCalibrationFFTWidget); - postCalibrationFFTWidget->setLayout(postCalibrationFFTLayout); - postCalibrationFFTLayout->setMargin(0); - postCalibrationFFTLayout->setSpacing(0); + #pragma region Post Calibration Samples + QWidget *postCalibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); + QVBoxLayout *postCalibrationSamplesLayout = new QVBoxLayout(postCalibrationSamplesWidget); + postCalibrationSamplesWidget->setLayout(postCalibrationSamplesLayout); + postCalibrationSamplesLayout->setMargin(0); + postCalibrationSamplesLayout->setSpacing(0); + + postCalibrationRawDataPlotWidget = new PlotWidget(); + postCalibrationRawDataPlotWidget->setContentsMargins(10, 20, 10, 10); + postCalibrationRawDataPlotWidget->xAxis()->setVisible(false); + postCalibrationRawDataPlotWidget->yAxis()->setVisible(false); + + postCalibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, postCalibrationRawDataPlotWidget, scopyBluePen); + postCalibrationRawDataXPlotAxis->setMin(0); + postCalibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, postCalibrationRawDataPlotWidget, scopyBluePen); + postCalibrationRawDataYPlotAxis->setInterval(0, 400); + + postCalibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); + postCalibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); + postCalibrationCosineDataPlotChannel = new PlotChannel("Cosine", cosinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); + + postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationRawDataPlotChannel); + postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationSineDataPlotChannel); + postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationCosineDataPlotChannel); + + postCalibrationRawDataPlotChannel->setEnabled(true); + postCalibrationSineDataPlotChannel->setEnabled(true); + postCalibrationCosineDataPlotChannel->setEnabled(true); + postCalibrationRawDataPlotWidget->selectChannel(postCalibrationRawDataPlotChannel); + postCalibrationRawDataPlotWidget->replot(); + + postCalibrationRawDataPlotWidget->setShowXAxisLabels(true); + postCalibrationRawDataPlotWidget->setShowYAxisLabels(true); + postCalibrationRawDataPlotWidget->showAxisLabels(); + + QWidget *postCalibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); + QHBoxLayout *postCalibrationDataGraphChannelsLayout = new QHBoxLayout(postCalibrationDataGraphChannelsWidget); + postCalibrationDataGraphChannelsWidget->setLayout(postCalibrationDataGraphChannelsLayout); + postCalibrationDataGraphChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); + postCalibrationDataGraphChannelsLayout->setContentsMargins(20, 13, 20, 5); + postCalibrationDataGraphChannelsLayout->setSpacing(20); + + MenuControlButton *togglePostAngleButton = createChannelToggleWidget("Angle", scopyBlueColor, postCalibrationDataGraphChannelsWidget); + MenuControlButton *togglePostSineButton = createChannelToggleWidget("Sine", sineColor, postCalibrationDataGraphChannelsWidget); + MenuControlButton *togglePostCosineButton = createChannelToggleWidget("Cosine", cosineColor, postCalibrationDataGraphChannelsWidget); + + postCalibrationDataGraphChannelsLayout->addWidget(togglePostAngleButton); + postCalibrationDataGraphChannelsLayout->addWidget(togglePostSineButton); + postCalibrationDataGraphChannelsLayout->addWidget(togglePostCosineButton); + postCalibrationDataGraphChannelsLayout->addStretch(); + + postCalibrationSamplesLayout->addWidget(postCalibrationRawDataPlotWidget); + postCalibrationSamplesLayout->addWidget(postCalibrationDataGraphChannelsWidget); + #pragma endregion + + calibrationDataGraphTabWidget->addTab(calibrationSamplesWidget, "Calibration Samples"); + calibrationDataGraphTabWidget->addTab(postCalibrationSamplesWidget, "Post Calibration Samples"); + + MenuSectionWidget *resultDataSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); + QTabWidget *resultDataTabWidget = new QTabWidget(resultDataSectionWidget); + applyTabWidgetStyle(resultDataTabWidget); + resultDataSectionWidget->contentLayout()->setSpacing(8); + resultDataSectionWidget->contentLayout()->addWidget(resultDataTabWidget); + + QPen magnitudePen = QPen(StyleHelper::getColor("CH0")); + QPen phasePen = QPen(StyleHelper::getColor("CH1")); + + #pragma region Angle Error Widget + QWidget *angleErrorWidget = new QWidget(); + QVBoxLayout *angleErrorLayout = new QVBoxLayout(angleErrorWidget); + angleErrorWidget->setLayout(angleErrorLayout); + angleErrorLayout->setMargin(0); + angleErrorLayout->setSpacing(0); + + angleErrorPlotWidget = new PlotWidget(); + angleErrorPlotWidget->setContentsMargins(10, 20, 10, 10); + angleErrorPlotWidget->xAxis()->setVisible(false); + angleErrorPlotWidget->yAxis()->setVisible(false); + + angleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, angleErrorPlotWidget, scopyBluePen); + angleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, angleErrorPlotWidget, scopyBluePen); + angleErrorYPlotAxis->setInterval(-4, 4); + + angleErrorPlotChannel = new PlotChannel("Angle Error", scopyBluePen, angleErrorXPlotAxis, angleErrorYPlotAxis); + angleErrorPlotWidget->addPlotChannel(angleErrorPlotChannel); - PlotWidget *postCalibrationFFTPlotWidget = new PlotWidget(); - preCalibrationFFTPlotWidget->setContentsMargins(10, 20, 10, 10); - preCalibrationFFTPlotWidget->xAxis()->setVisible(false); - preCalibrationFFTPlotWidget->yAxis()->setVisible(false); + angleErrorPlotChannel->setEnabled(true); + angleErrorPlotWidget->selectChannel(angleErrorPlotChannel); + angleErrorPlotWidget->replot(); - postCalibrationFFTLayout->addWidget(postCalibrationFFTPlotWidget); + angleErrorPlotWidget->setShowXAxisLabels(true); + angleErrorPlotWidget->setShowYAxisLabels(true); + angleErrorPlotWidget->showAxisLabels(); + angleErrorLayout->addWidget(angleErrorPlotWidget); #pragma endregion - FFTDataGraphTabWidget->addTab(preCalibrationFFTWidget, "Pre-Calibration Angular Error"); - FFTDataGraphTabWidget->addTab(postCalibrationFFTWidget, "Post-Calibration Angular Error"); + #pragma region FFT Angle Error Widget + QWidget *FFTAngleErrorWidget = new QWidget(); + QVBoxLayout *FFTAngleErrorLayout = new QVBoxLayout(FFTAngleErrorWidget); + FFTAngleErrorWidget->setLayout(FFTAngleErrorLayout); + FFTAngleErrorLayout->setMargin(0); + FFTAngleErrorLayout->setSpacing(0); + + FFTAngleErrorPlotWidget = new PlotWidget(); + FFTAngleErrorPlotWidget->setContentsMargins(10, 20, 10, 10); + FFTAngleErrorPlotWidget->xAxis()->setVisible(false); + FFTAngleErrorPlotWidget->yAxis()->setVisible(false); + + FFTAngleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTAngleErrorPlotWidget, scopyBluePen); + FFTAngleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTAngleErrorPlotWidget, scopyBluePen); + FFTAngleErrorYPlotAxis->setInterval(-4, 4); + + FFTAngleErrorMagnitudeChannel = new PlotChannel("FFT Angle Error Magnitude", magnitudePen, FFTAngleErrorXPlotAxis, FFTAngleErrorYPlotAxis); + FFTAngleErrorPhaseChannel = new PlotChannel("FFT Angle Error Phase", phasePen, FFTAngleErrorXPlotAxis, FFTAngleErrorYPlotAxis); + FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorMagnitudeChannel); + FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorPhaseChannel); + + FFTAngleErrorMagnitudeChannel->setEnabled(true); + FFTAngleErrorPhaseChannel->setEnabled(true); + FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); + FFTAngleErrorPlotWidget->replot(); + + FFTAngleErrorPlotWidget->setShowXAxisLabels(true); + FFTAngleErrorPlotWidget->setShowYAxisLabels(true); + FFTAngleErrorPlotWidget->showAxisLabels(); + + QWidget *FFTAngleErrorChannelsWidget = new QWidget(); + QHBoxLayout *FFTAngleErrorChannelsLayout = new QHBoxLayout(FFTAngleErrorChannelsWidget); + FFTAngleErrorChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); + FFTAngleErrorChannelsWidget->setLayout(FFTAngleErrorChannelsLayout); + FFTAngleErrorChannelsLayout->setContentsMargins(20, 13, 20, 5); + FFTAngleErrorChannelsLayout->setSpacing(20); + + MenuControlButton *toggleFFTAngleErrorMagnitudeButton = createChannelToggleWidget("Magnitude", QColor(StyleHelper::getColor("CH0")), FFTAngleErrorChannelsWidget); + MenuControlButton *toggleFFTAngleErrorPhaseButton = createChannelToggleWidget("Phase", QColor(StyleHelper::getColor("CH1")), FFTAngleErrorChannelsWidget); + + FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorMagnitudeButton); + FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorPhaseButton); + FFTAngleErrorChannelsLayout->addStretch(); + + FFTAngleErrorLayout->addWidget(FFTAngleErrorPlotWidget); + FFTAngleErrorLayout->addWidget(FFTAngleErrorChannelsWidget); + #pragma endregion + + #pragma region Corrected Error Widget + QWidget *correctedErrorWidget = new QWidget(); + QVBoxLayout *correctedErrorLayout = new QVBoxLayout(correctedErrorWidget); + correctedErrorWidget->setLayout(correctedErrorLayout); + correctedErrorLayout->setMargin(0); + correctedErrorLayout->setSpacing(0); + + correctedErrorPlotWidget = new PlotWidget(); + correctedErrorPlotWidget->setContentsMargins(10, 20, 10, 10); + correctedErrorPlotWidget->xAxis()->setVisible(false); + correctedErrorPlotWidget->yAxis()->setVisible(false); + + correctedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, correctedErrorPlotWidget, scopyBluePen); + correctedErrorXPlotAxis->setMin(0); + correctedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, correctedErrorPlotWidget, scopyBluePen); + correctedErrorYPlotAxis->setInterval(-4, 4); + + correctedErrorPlotChannel = new PlotChannel("Corrected Error", scopyBluePen, correctedErrorXPlotAxis, correctedErrorYPlotAxis); + correctedErrorPlotWidget->addPlotChannel(correctedErrorPlotChannel); + + correctedErrorPlotChannel->setEnabled(true); + correctedErrorPlotWidget->selectChannel(correctedErrorPlotChannel); + correctedErrorPlotWidget->replot(); + + correctedErrorPlotWidget->setShowXAxisLabels(true); + correctedErrorPlotWidget->setShowYAxisLabels(true); + correctedErrorPlotWidget->showAxisLabels(); + + correctedErrorLayout->addWidget(correctedErrorPlotWidget); + #pragma endregion + + #pragma region FFT Corrected Error Widget + QWidget *FFTCorrectedErrorWidget = new QWidget(); + QVBoxLayout *FFTCorrectedErrorLayout = new QVBoxLayout(FFTCorrectedErrorWidget); + FFTCorrectedErrorWidget->setLayout(FFTCorrectedErrorLayout); + FFTCorrectedErrorLayout->setMargin(0); + FFTCorrectedErrorLayout->setSpacing(0); + + FFTCorrectedErrorPlotWidget = new PlotWidget(); + FFTCorrectedErrorPlotWidget->setContentsMargins(10, 20, 10, 10); + FFTCorrectedErrorPlotWidget->xAxis()->setVisible(false); + FFTCorrectedErrorPlotWidget->yAxis()->setVisible(false); + + FFTCorrectedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTCorrectedErrorPlotWidget, scopyBluePen); + FFTCorrectedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTCorrectedErrorPlotWidget, scopyBluePen); + FFTCorrectedErrorYPlotAxis->setInterval(0, 360); + + FFTCorrectedErrorMagnitudeChannel = new PlotChannel("FFT Corrected Error Magnitude", magnitudePen, FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); + FFTCorrectedErrorPhaseChannel = new PlotChannel("FFT Corrected Error Phase", phasePen, FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); + FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorMagnitudeChannel); + FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorPhaseChannel); + + FFTCorrectedErrorMagnitudeChannel->setEnabled(true); + FFTCorrectedErrorPhaseChannel->setEnabled(true); + FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); + FFTCorrectedErrorPlotWidget->replot(); + + FFTCorrectedErrorPlotWidget->setShowXAxisLabels(true); + FFTCorrectedErrorPlotWidget->setShowYAxisLabels(true); + FFTCorrectedErrorPlotWidget->showAxisLabels(); + + QWidget *FFTCorrectedErrorChannelsWidget = new QWidget(); + QHBoxLayout *FFTCorrectedErrorChannelsLayout = new QHBoxLayout(FFTCorrectedErrorChannelsWidget); + FFTCorrectedErrorChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); + FFTCorrectedErrorChannelsLayout->setContentsMargins(20, 13, 20, 5); + FFTCorrectedErrorChannelsLayout->setSpacing(20); + + MenuControlButton *toggleFFTCorrectedErrorMagnitudeButton = createChannelToggleWidget("Magnitude", QColor(StyleHelper::getColor("CH0")), FFTCorrectedErrorChannelsWidget); + MenuControlButton *toggleFFTCorrectedErrorPhaseButton = createChannelToggleWidget("Phase", QColor(StyleHelper::getColor("CH1")), FFTCorrectedErrorChannelsWidget); + + FFTCorrectedErrorChannelsLayout->addWidget(toggleFFTCorrectedErrorMagnitudeButton); + FFTCorrectedErrorChannelsLayout->addWidget(toggleFFTCorrectedErrorPhaseButton); + FFTCorrectedErrorChannelsLayout->addStretch(); + + FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorPlotWidget); + FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorChannelsWidget); + #pragma endregion + + resultDataTabWidget->addTab(angleErrorWidget, "Angle Error"); + resultDataTabWidget->addTab(FFTAngleErrorWidget, "FFT Angle Error"); + resultDataTabWidget->addTab(correctedErrorWidget, "Corrected Error"); + resultDataTabWidget->addTab(FFTCorrectedErrorWidget, "FFT Corrected Error"); calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget, 0, 0); - calibrationDataGraphLayout->addWidget(FFTDataGraphSectionWidget, 1, 0); + calibrationDataGraphLayout->addWidget(resultDataSectionWidget, 1, 0); calibrationDataGraphLayout->setColumnStretch(0, 1); calibrationDataGraphLayout->setRowStretch(0, 1); @@ -767,7 +955,9 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() motorConfigurationSectionWidget->contentLayout()->addWidget(motorConfigurationCollapseSection); motorMaxVelocitySpinBox = new HorizontalSpinBox("Max Velocity", convertVMAXtoRPS(rotate_vmax), "rps", motorConfigurationSectionWidget); + motorMaxVelocitySpinBox->setValue(1); motorAccelTimeSpinBox = new HorizontalSpinBox("Acceleration Time", convertAMAXtoAccelTime(amax), "sec", motorConfigurationSectionWidget); + motorAccelTimeSpinBox->setValue(1); motorMaxDisplacementSpinBox = new HorizontalSpinBox("Max Displacement", dmax, "", motorConfigurationSectionWidget); MenuCombo *m_calibrationMotorRampModeMenuCombo = new MenuCombo("Ramp Mode", motorConfigurationSectionWidget); @@ -805,12 +995,10 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(calibrationStartMotorButton, &QPushButton::toggled, this, [=](bool b) { calibrationStartMotorButton->setText(b ? " Stop Motor" : " Start Motor"); totalSamplesCount = cycleCount * samplesPerCycle; - startMotor = b; + isStartMotor = b; if(b){ - motorCalibrationAcquisitionTimer->start(motorCalibrationAcquisitionTimerRate); - } - else{ - motorCalibrationAcquisitionTimer->stop(); + isPostCalibration = false; + startMotor(); } }); QString calibrationStartMotorButtonStyle = QString(R"css( @@ -844,10 +1032,11 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrateDataButton = new QPushButton(motorControlSectionWidget); calibrateDataButton->setText("Calibrate"); + calibrateDataButton->setEnabled(false); StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); - autoCalibrateCheckBox = new QCheckBox("Auto Calibrate", motorControlSectionWidget); - StyleHelper::BlueSquareCheckbox(autoCalibrateCheckBox, "autoCalibrateCheckBox"); + // autoCalibrateCheckBox = new QCheckBox("Auto Calibrate", motorControlSectionWidget); + // StyleHelper::BlueSquareCheckbox(autoCalibrateCheckBox, "autoCalibrateCheckBox"); motorControlCollapseSection->contentLayout()->setSpacing(8); motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); @@ -855,7 +1044,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionSpinBox); motorControlCollapseSection->contentLayout()->addWidget(calibrationStartMotorButton); motorControlCollapseSection->contentLayout()->addWidget(calibrateDataButton); - motorControlCollapseSection->contentLayout()->addWidget(autoCalibrateCheckBox); + // motorControlCollapseSection->contentLayout()->addWidget(autoCalibrateCheckBox); #pragma endregion #pragma region Logs Section Widget @@ -899,17 +1088,16 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::calibrateData); connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); connect(importDataButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); - //connect(applyCalibrationDataButton, &QPushButton::clicked, this, &HarmonicCalibration::registerCalibrationData); connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::clearRawDataList); connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); connectLineEditToNumberWrite(motorMaxDisplacementSpinBox->lineEdit(), dmax, ADMTController::MotorAttribute::DMAX); connectLineEditToNumberWrite(motorTargetPositionSpinBox->lineEdit(), target_pos, ADMTController::MotorAttribute::TARGET_POS); connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); - connect(autoCalibrateCheckBox, &QCheckBox::toggled, [=](bool toggled){ - autoCalibrate = toggled; - StatusBarManager::pushMessage(QString("Auto Calibrate: ") + QString((toggled ? "True" : "False"))); - }); + // connect(autoCalibrateCheckBox, &QCheckBox::toggled, [=](bool toggled){ + // autoCalibrate = toggled; + // StatusBarManager::pushMessage(QString("Auto Calibrate: ") + QString((toggled ? "True" : "False"))); + // }); connect(toggleAngleButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); @@ -922,13 +1110,21 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataPlotWidget->selectChannel(calibrationCosineDataPlotChannel); calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); }); - connect(togglePreCalibrationMagnitudeButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - preCalibrationFFTPlotWidget->selectChannel(preCalibrationFFTMagnitudePlotChannel); - preCalibrationFFTPlotWidget->selectedChannel()->setEnabled(b); + connect(toggleFFTAngleErrorMagnitudeButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); + FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleFFTAngleErrorPhaseButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorPhaseChannel); + FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); }); - connect(togglePreCalibrationPhaseButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - preCalibrationFFTPlotWidget->selectChannel(preCalibrationFFTPhasePlotChannel); - preCalibrationFFTPlotWidget->selectedChannel()->setEnabled(b); + connect(toggleFFTCorrectedErrorMagnitudeButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); + FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleFFTCorrectedErrorPhaseButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorPhaseChannel); + FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); }); return tool; @@ -1676,7 +1872,6 @@ void HarmonicCalibration::run(bool b) void HarmonicCalibration::canCalibrate(bool value) { calibrateDataButton->setEnabled(value); - } void HarmonicCalibration::timerTask(){ @@ -2238,7 +2433,7 @@ void HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute int result = m_admtController->getDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), m_admtController->getMotorAttribute(attribute), &value); - if(result != 0) { calibrationLogWriteLn(QString(m_admtController->getMotorAttribute(attribute)) + ": Read Error " + QString::number(result)); } + if(result != 0) { calibrationLogWrite(QString(m_admtController->getMotorAttribute(attribute)) + ": Read Error " + QString::number(result)); } } } @@ -2248,7 +2443,7 @@ void HarmonicCalibration::writeMotorAttributeValue(ADMTController::MotorAttribut int result = m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), m_admtController->getMotorAttribute(attribute), value); - if(result != 0) { calibrationLogWriteLn(QString(m_admtController->getMotorAttribute(attribute)) + ": Write Error " + QString::number(result)); } + if(result != 0) { calibrationLogWrite(QString(m_admtController->getMotorAttribute(attribute)) + ": Write Error " + QString::number(result)); } } } @@ -2286,57 +2481,142 @@ void HarmonicCalibration::calibrationTask() if(!isDebug){ readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); updateLabelValue(calibrationMotorCurrentPositionLabel, ADMTController::MotorAttribute::CURRENT_POS); + + if(isStartMotor) + { + if(isPostCalibration){ + postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); + postCalibrationRawDataPlotChannel->xAxis()->setMax(graphPostDataList.size()); + postCalibrationRawDataPlotWidget->replot(); + } + else{ + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotChannel->xAxis()->setMax(graphDataList.size()); + calibrationRawDataPlotWidget->replot(); + } + } } } -void HarmonicCalibration::motorCalibrationAcquisitionTask() +void HarmonicCalibration::getCalibrationSamples() { - if(startMotor && rawDataList.size() < totalSamplesCount){ - stepMotorAcquisition(); - updateChannelValue(ADMTController::Channel::ANGLE); - double currentAngle = angle; - QVector angles = { currentAngle }; - appendSamplesToPlotCurve(calibrationRawDataPlotWidget, angles); - rawDataList.push_back(currentAngle); + resetCurrentPositionToZero(); + if(isPostCalibration){ + while(isStartMotor && graphPostDataList.size() < totalSamplesCount){ + stepMotorAcquisition(); + updateChannelValue(ADMTController::Channel::ANGLE); + graphPostDataList.append(angle); + } } - else if(rawDataList.size() == totalSamplesCount) - { - startMotor = false; - calibrationStartMotorButton->setChecked(false); + else{ + while(isStartMotor && graphDataList.size() < totalSamplesCount){ + stepMotorAcquisition(); + updateChannelValue(ADMTController::Channel::ANGLE); + graphDataList.append(angle); + } } } -void HarmonicCalibration::appendSamplesToPlotCurve(PlotWidget *plotWidget, QVector& newYData) +void HarmonicCalibration::resetCurrentPositionToZero() { - const QwtSeriesData *seriesData = plotWidget->selectedChannel()->curve()->data(); - QVector yData; - - if(seriesData != nullptr){ - for (int i = 0; i < seriesData->size(); ++i) { - calibrationLogWriteLn("append: " + QString::number(seriesData->sample(i).y())); - yData.append(seriesData->sample(i).y()); - } + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + while(current_pos != 0){ + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); } +} - yData.append(newYData); - calibrationLogWriteLn("yData Size: " + QString::number(yData.size())); - plotWidget->selectedChannel()->curve()->setSamples(yData); - plotWidget->selectedChannel()->xAxis()->setMax(yData.size()); +void HarmonicCalibration::startMotor() +{ + QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getCalibrationSamples); + QFutureWatcher *watcher = new QFutureWatcher(this); + + connect(watcher, &QFutureWatcher::finished, this, [=]() { + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotChannel->xAxis()->setMax(graphDataList.size()); + calibrationRawDataPlotWidget->replot(); + isStartMotor = false; + calibrationStartMotorButton->setChecked(false); + + if(isPostCalibration) + { + if(graphPostDataList.size() == totalSamplesCount) + { + computeSineCosineOfAngles(graphPostDataList); + m_admtController->postcalibrate(vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, samplesPerCycle); + isPostCalibration = false; + isStartMotor = false; + canStartMotor(true); + QVector correctedError(m_admtController->correctedError.begin(), m_admtController->correctedError.end()); + correctedErrorPlotChannel->curve()->setSamples(correctedError); + auto correctedErrorMagnitudeMinMax = std::minmax_element(correctedError.begin(), correctedError.end()); + correctedErrorYPlotAxis->setInterval(*correctedErrorMagnitudeMinMax.first, *correctedErrorMagnitudeMinMax.second); + correctedErrorXPlotAxis->setMax(correctedError.size()); + correctedErrorPlotWidget->replot(); + + QVector FFTCorrectedErrorMagnitude(m_admtController->FFTCorrectedErrorMagnitude.begin(), m_admtController->FFTCorrectedErrorMagnitude.end()); + QVector FFTCorrectedErrorPhase(m_admtController->FFTCorrectedErrorPhase.begin(), m_admtController->FFTCorrectedErrorPhase.end()); + FFTCorrectedErrorMagnitudeChannel->curve()->setSamples(FFTCorrectedErrorMagnitude); + FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); + auto FFTCorrectedErrorMagnitudeMinMax = std::minmax_element(FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); + auto FFTCorrectedErrorPhaseMinMax = std::minmax_element(FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); + double FFTCorrectedErrorPlotMin = *FFTCorrectedErrorMagnitudeMinMax.first < *FFTCorrectedErrorPhaseMinMax.first ? *FFTCorrectedErrorMagnitudeMinMax.first : *FFTCorrectedErrorPhaseMinMax.first; + double FFTCorrectedErrorPlotMax = *FFTCorrectedErrorMagnitudeMinMax.second > *FFTCorrectedErrorPhaseMinMax.second ? *FFTCorrectedErrorMagnitudeMinMax.second : *FFTCorrectedErrorPhaseMinMax.second; + FFTCorrectedErrorYPlotAxis->setInterval(FFTCorrectedErrorPlotMin, FFTCorrectedErrorPlotMax); + FFTCorrectedErrorXPlotAxis->setMax(FFTCorrectedErrorMagnitude.size()); + FFTCorrectedErrorPlotWidget->replot(); + } + } + else{ + if(graphDataList.size() == totalSamplesCount) + { + computeSineCosineOfAngles(graphDataList); + canCalibrate(true); + } + } + }); + connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater())); + watcher->setFuture(future); } -void HarmonicCalibration::addAngleToRawDataList() +void HarmonicCalibration::canStartMotor(bool value) { - QVector angles = { angle }; - appendSamplesToPlotCurve(calibrationRawDataPlotWidget, angles); - rawDataList.push_back(angle); + calibrationStartMotorButton->setEnabled(value); } void HarmonicCalibration::calibrateData() { - calibrationLogWrite("==== Calibration Start ====\n"); + calibrationLogWrite("==== Calibration Start ===="); + + calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); - calibrationLogWriteLn(m_admtController->calibrate(rawDataList, cycleCount, samplesPerCycle)); + flashHarmonicValues(); + QVector angleError = QVector(m_admtController->angleError.begin(), m_admtController->angleError.end()); + QVector FFTAngleErrorMagnitude = QVector(m_admtController->FFTAngleErrorMagnitude.begin(), m_admtController->FFTAngleErrorMagnitude.end()); + QVector FFTAngleErrorPhase = QVector(m_admtController->FFTAngleErrorPhase.begin(), m_admtController->FFTAngleErrorPhase.end()); + + angleErrorPlotChannel->curve()->setSamples(angleError); + auto angleErrorMinMax = std::minmax_element(angleError.begin(), angleError.end()); + angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, *angleErrorMinMax.second); + angleErrorXPlotAxis->setInterval(0, angleError.size()); + angleErrorPlotWidget->replot(); + + FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); + auto angleErrorMagnitudeMinMax = std::minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); + FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); + auto angleErrorPhaseMinMax = std::minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); + double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first ? *angleErrorMagnitudeMinMax.first : *angleErrorPhaseMinMax.first; + double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second ? *angleErrorMagnitudeMinMax.second : *angleErrorPhaseMinMax.second; + FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); + FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); + FFTAngleErrorPlotWidget->replot(); + + postCalibrateData(); +} + +void HarmonicCalibration::flashHarmonicValues() +{ uint32_t *h1MagCurrent = new uint32_t, *h1PhaseCurrent = new uint32_t, *h2MagCurrent = new uint32_t, @@ -2371,15 +2651,15 @@ void HarmonicCalibration::calibrateData() m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); - calibrationLogWriteLn(); - calibrationLogWrite("H1 Mag Current: " + QString::number(*h1MagCurrent) + "\n"); - calibrationLogWrite("H1 Phase Current: " + QString::number(*h1PhaseCurrent) + "\n"); - calibrationLogWrite("H2 Mag Current: " + QString::number(*h2MagCurrent) + "\n"); - calibrationLogWrite("H2 Phase Current: " + QString::number(*h2PhaseCurrent) + "\n"); - calibrationLogWrite("H3 Mag Current: " + QString::number(*h3MagCurrent) + "\n"); - calibrationLogWrite("H3 Phase Current: " + QString::number(*h3PhaseCurrent) + "\n"); - calibrationLogWrite("H8 Mag Current: " + QString::number(*h8MagCurrent) + "\n"); - calibrationLogWrite("H8 Phase Current: " + QString::number(*h8PhaseCurrent) + "\n"); + calibrationLogWrite(); + calibrationLogWrite("H1 Mag Current: " + QString::number(*h1MagCurrent)); + calibrationLogWrite("H1 Phase Current: " + QString::number(*h1PhaseCurrent)); + calibrationLogWrite("H2 Mag Current: " + QString::number(*h2MagCurrent)); + calibrationLogWrite("H2 Phase Current: " + QString::number(*h2PhaseCurrent)); + calibrationLogWrite("H3 Mag Current: " + QString::number(*h3MagCurrent)); + calibrationLogWrite("H3 Phase Current: " + QString::number(*h3PhaseCurrent)); + calibrationLogWrite("H8 Mag Current: " + QString::number(*h8MagCurrent)); + calibrationLogWrite("H8 Phase Current: " + QString::number(*h8PhaseCurrent)); h1MagScaled = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(m_admtController->HAR_MAG_1, static_cast(*h1MagCurrent), "h1")); h1PhaseScaled = static_cast(m_admtController->calculateHarmonicCoefficientPhase(m_admtController->HAR_PHASE_1, static_cast(*h1PhaseCurrent))); @@ -2390,15 +2670,15 @@ void HarmonicCalibration::calibrateData() h8MagScaled = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(m_admtController->HAR_MAG_8, static_cast(*h8MagCurrent), "h8")); h8PhaseScaled = static_cast(m_admtController->calculateHarmonicCoefficientPhase(m_admtController->HAR_PHASE_8, static_cast(*h8PhaseCurrent))); - calibrationLogWriteLn(); - calibrationLogWrite("H1 Mag Scaled: " + QString::number(h1MagScaled) + "\n"); - calibrationLogWrite("H1 Phase Scaled: " + QString::number(h1PhaseScaled) + "\n"); - calibrationLogWrite("H2 Mag Scaled: " + QString::number(h2MagScaled) + "\n"); - calibrationLogWrite("H2 Phase Scaled: " + QString::number(h2PhaseScaled) + "\n"); - calibrationLogWrite("H3 Mag Scaled: " + QString::number(h3MagScaled) + "\n"); - calibrationLogWrite("H3 Phase Scaled: " + QString::number(h3PhaseScaled) + "\n"); - calibrationLogWrite("H8 Mag Scaled: " + QString::number(h8MagScaled) + "\n"); - calibrationLogWrite("H8 Phase Scaled: " + QString::number(h8PhaseScaled) + "\n"); + calibrationLogWrite(); + calibrationLogWrite("H1 Mag Scaled: " + QString::number(h1MagScaled)); + calibrationLogWrite("H1 Phase Scaled: " + QString::number(h1PhaseScaled)); + calibrationLogWrite("H2 Mag Scaled: " + QString::number(h2MagScaled)); + calibrationLogWrite("H2 Phase Scaled: " + QString::number(h2PhaseScaled)); + calibrationLogWrite("H3 Mag Scaled: " + QString::number(h3MagScaled)); + calibrationLogWrite("H3 Phase Scaled: " + QString::number(h3PhaseScaled)); + calibrationLogWrite("H8 Mag Scaled: " + QString::number(h8MagScaled)); + calibrationLogWrite("H8 Phase Scaled: " + QString::number(h8PhaseScaled)); m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), 0x01, 0x02); @@ -2436,6 +2716,16 @@ void HarmonicCalibration::calibrateData() m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); + calibrationLogWrite(); + calibrationLogWrite("H1 Mag After Flash: " + QString::number(*h1MagCurrent)); + calibrationLogWrite("H1 Phase After Flash: " + QString::number(*h1PhaseCurrent)); + calibrationLogWrite("H2 Mag After Flash: " + QString::number(*h2MagCurrent)); + calibrationLogWrite("H2 Phase After Flash: " + QString::number(*h2PhaseCurrent)); + calibrationLogWrite("H3 Mag After Flash: " + QString::number(*h3MagCurrent)); + calibrationLogWrite("H3 Phase After Flash: " + QString::number(*h3PhaseCurrent)); + calibrationLogWrite("H8 Mag After Flash: " + QString::number(*h8MagCurrent)); + calibrationLogWrite("H8 Phase After Flash: " + QString::number(*h8PhaseCurrent)); + h1MagConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h1MagCurrent), "h1mag"); h1PhaseConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h1PhaseCurrent), "h1phase"); h2MagConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h2MagCurrent), "h2mag"); @@ -2445,32 +2735,28 @@ void HarmonicCalibration::calibrateData() h8MagConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h8MagCurrent), "h8mag"); h8PhaseConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h8PhaseCurrent), "h8phase"); - calibrationLogWriteLn(); - calibrationLogWrite("H1 Mag Converted: " + QString::number(h1MagConverted) + "\n"); - calibrationLogWrite("H1 Phase Converted: " + QString::number(h1PhaseConverted) + "\n"); - calibrationLogWrite("H2 Mag Converted: " + QString::number(h2MagConverted) + "\n"); - calibrationLogWrite("H2 Phase Converted: " + QString::number(h2PhaseConverted) + "\n"); - calibrationLogWrite("H3 Mag Converted: " + QString::number(h3MagConverted) + "\n"); - calibrationLogWrite("H3 Phase Converted: " + QString::number(h3PhaseConverted) + "\n"); - calibrationLogWrite("H8 Mag Converted: " + QString::number(h8MagConverted) + "\n"); + calibrationLogWrite(); + calibrationLogWrite("H1 Mag Converted: " + QString::number(h1MagConverted)); + calibrationLogWrite("H1 Phase Converted: " + QString::number(h1PhaseConverted)); + calibrationLogWrite("H2 Mag Converted: " + QString::number(h2MagConverted)); + calibrationLogWrite("H2 Phase Converted: " + QString::number(h2PhaseConverted)); + calibrationLogWrite("H3 Mag Converted: " + QString::number(h3MagConverted)); + calibrationLogWrite("H3 Phase Converted: " + QString::number(h3PhaseConverted)); + calibrationLogWrite("H8 Mag Converted: " + QString::number(h8MagConverted)); calibrationLogWrite("H8 Phase Converted: " + QString::number(h8PhaseConverted)); updateCalculatedCoeff(); +} - vector calibrationAngleErrorsFFT = m_admtController->angle_errors_fft_pre; - vector calibrationAngleErrorsFFTPhase = m_admtController->angle_errors_fft_phase_pre; - - // Frequency axis (assuming sampling rate of 1 Hz for simplicity) - std::vector frequencyAxis(calibrationAngleErrorsFFT.size()); - for (size_t i = 0; i < frequencyAxis.size(); ++i) - { - frequencyAxis[i] = i; // Replace with actual frequency values if needed - } - - preCalibrationFFTMagnitudePlotChannel->curve()->setSamples(frequencyAxis.data(), calibrationAngleErrorsFFT.data(), (calibrationAngleErrorsFFT.size())); - preCalibrationFFTPhasePlotChannel->curve()->setSamples(frequencyAxis.data(), calibrationAngleErrorsFFTPhase.data(), calibrationAngleErrorsFFTPhase.size()); - preCalibrationFFTXPlotAxis->setInterval(0, (calibrationAngleErrorsFFT.size())); - preCalibrationFFTPlotWidget->replot(); +void HarmonicCalibration::postCalibrateData() +{ + calibrationLogWrite("==== Post Calibration Start ====\n"); + canCalibrate(false); + canStartMotor(false); + calibrationDataGraphTabWidget->setCurrentIndex(1); + isPostCalibration = true; + isStartMotor = true; + startMotor(); } void HarmonicCalibration::updateCalculatedCoeff() @@ -2496,7 +2782,6 @@ void HarmonicCalibration::resetCalculatedCoeff() calibrationH2PhaseLabel->setText("Φ --.--"); calibrationH3PhaseLabel->setText("Φ --.--"); calibrationH8PhaseLabel->setText("Φ --.--"); - //applyCalibrationDataButton->setEnabled(false); } void HarmonicCalibration::registerCalibrationData() @@ -2505,28 +2790,28 @@ void HarmonicCalibration::registerCalibrationData() if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), h1MagDeviceRegister, m_admtController->HAR_MAG_1) != 0) - { calibrationLogWriteLn("Failed to write to H1 Mag Register"); } + { calibrationLogWrite("Failed to write to H1 Mag Register"); } if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), h2MagDeviceRegister, m_admtController->HAR_MAG_2) != 0) - { calibrationLogWriteLn("Failed to write to H2 Mag Register"); } + { calibrationLogWrite("Failed to write to H2 Mag Register"); } if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), h3MagDeviceRegister, m_admtController->HAR_MAG_3) != 0) - { calibrationLogWriteLn("Failed to write to H3 Mag Register"); } + { calibrationLogWrite("Failed to write to H3 Mag Register"); } if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), h8MagDeviceRegister, m_admtController->HAR_MAG_8) != 0) - { calibrationLogWriteLn("Failed to write to H8 Mag Register"); } + { calibrationLogWrite("Failed to write to H8 Mag Register"); } if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), h1PhaseDeviceRegister, m_admtController->HAR_PHASE_1) != 0) - { calibrationLogWriteLn("Failed to write to H1 Phase Register"); } + { calibrationLogWrite("Failed to write to H1 Phase Register"); } if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), h2PhaseDeviceRegister, m_admtController->HAR_PHASE_2) != 0) - { calibrationLogWriteLn("Failed to write to H2 Phase Register"); } + { calibrationLogWrite("Failed to write to H2 Phase Register"); } if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), h3PhaseDeviceRegister, m_admtController->HAR_PHASE_3) != 0) - { calibrationLogWriteLn("Failed to write to H3 Phase Register"); } + { calibrationLogWrite("Failed to write to H3 Phase Register"); } if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), h8PhaseDeviceRegister, m_admtController->HAR_PHASE_8) != 0) - { calibrationLogWriteLn("Failed to write to H8 Phase Register"); } + { calibrationLogWrite("Failed to write to H8 Phase Register"); } calibrationLogWrite("=== Calibration Complete ===\n"); } @@ -2536,11 +2821,6 @@ void HarmonicCalibration::calibrationLogWrite(QString message) logsPlainTextEdit->appendPlainText(message); } -void HarmonicCalibration::calibrationLogWriteLn(QString message) -{ - logsPlainTextEdit->appendPlainText("\n" + message); -} - void HarmonicCalibration::commandLogWrite(QString message) { commandLogPlainTextEdit->appendPlainText(message); @@ -2568,8 +2848,6 @@ void HarmonicCalibration::extractCalibrationData() FileManager fm("HarmonicCalibration"); fm.open(fileName, FileManager::EXPORT); - QVector rawData(rawDataList.begin(), rawDataList.end()); - QVector preCalibrationAngleErrorsFFTMagnitude(m_admtController->angle_errors_fft_pre.begin(), m_admtController->angle_errors_fft_pre.end()); QVector preCalibrationAngleErrorsFFTPhase(m_admtController->angle_errors_fft_phase_pre.begin(), m_admtController->angle_errors_fft_phase_pre.end()); @@ -2582,7 +2860,7 @@ void HarmonicCalibration::extractCalibrationData() QVector h3Phase = { static_cast(m_admtController->HAR_PHASE_3) }; QVector h8Phase = { static_cast(m_admtController->HAR_PHASE_8) }; - fm.save(rawData, "Raw Data"); + fm.save(graphDataList, "Raw Data"); fm.save(preCalibrationAngleErrorsFFTMagnitude, "Pre-Calibration Angle Errors FFT Magnitude"); fm.save(preCalibrationAngleErrorsFFTPhase, "Pre-Calibration Angle Errors FFT Phase"); fm.save(h1Mag, "H1 Mag"); @@ -2611,56 +2889,40 @@ void HarmonicCalibration::importCalibrationData() try { fm.open(fileName, FileManager::IMPORT); - QVector data = fm.read(0); - if(data.size() > 0) + graphDataList = fm.read(0); + if(graphDataList.size() > 0) { - calibrationRawDataPlotChannel->curve()->setSamples(data.data(), data.size()); - calibrationRawDataXPlotAxis->setInterval(0, data.size()); - m_admtController->computeSineCosineOfAngles(vector(data.begin(), data.end())); - calibrationSineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_sine_scaled.data(), m_admtController->calibration_samples_sine_scaled.size()); - calibrationCosineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_cosine_scaled.data(), m_admtController->calibration_samples_cosine_scaled.size()); - for(int i = 0; i < data.size(); ++i) { - rawDataList.push_back(data[i]); - } + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataXPlotAxis->setInterval(0, graphDataList.size()); + computeSineCosineOfAngles(graphDataList); calibrationRawDataPlotWidget->replot(); + canCalibrate(true); } } catch(FileManagerException &ex) { - calibrationLogWriteLn(QString(ex.what())); + calibrationLogWrite(QString(ex.what())); } } -void HarmonicCalibration::initializeMotor() +void HarmonicCalibration::computeSineCosineOfAngles(QVector graphDataList) { - rotate_vmax = 53687.1; - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - - amax = 439.805; - writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - - dmax = 3000; - writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - - ramp_mode = 0; - writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - - target_pos = 0; - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - - current_pos = 0; - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + m_admtController->computeSineCosineOfAngles(vector(graphDataList.begin(), graphDataList.end())); + if(isPostCalibration){ + postCalibrationSineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_sine_scaled.data(), m_admtController->calibration_samples_sine_scaled.size()); + postCalibrationCosineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_cosine_scaled.data(), m_admtController->calibration_samples_cosine_scaled.size()); + postCalibrationRawDataPlotWidget->replot(); + } + else{ + calibrationSineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_sine_scaled.data(), m_admtController->calibration_samples_sine_scaled.size()); + calibrationCosineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_cosine_scaled.data(), m_admtController->calibration_samples_cosine_scaled.size()); + calibrationRawDataPlotWidget->replot(); + } } void HarmonicCalibration::stepMotorAcquisition(double step) { - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); target_pos = current_pos + step; writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); while(target_pos != current_pos) { readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); } @@ -2668,16 +2930,27 @@ void HarmonicCalibration::stepMotorAcquisition(double step) void HarmonicCalibration::clearRawDataList() { - rawDataList.clear(); + graphDataList.clear(); + graphPostDataList.clear(); calibrationRawDataPlotChannel->curve()->setData(nullptr); calibrationSineDataPlotChannel->curve()->setData(nullptr); calibrationCosineDataPlotChannel->curve()->setData(nullptr); calibrationRawDataPlotWidget->replot(); - preCalibrationFFTMagnitudePlotChannel->curve()->setData(nullptr); - preCalibrationFFTPhasePlotChannel->curve()->setData(nullptr); - preCalibrationFFTPlotWidget->replot(); + angleErrorPlotChannel->curve()->setData(nullptr); + angleErrorPlotWidget->replot(); + FFTAngleErrorMagnitudeChannel->curve()->setData(nullptr); + FFTAngleErrorPhaseChannel->curve()->setData(nullptr); + FFTAngleErrorPlotWidget->replot(); + correctedErrorPlotChannel->curve()->setData(nullptr); + correctedErrorPlotWidget->replot(); + FFTCorrectedErrorMagnitudeChannel->curve()->setData(nullptr); + FFTCorrectedErrorPhaseChannel->curve()->setData(nullptr); + FFTCorrectedErrorPlotWidget->replot(); + + canCalibrate(false); + canStartMotor(true); resetCalculatedCoeff(); } From b0c1cc2291791ede08612d707bd91957610691af Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 10 Oct 2024 10:05:11 +0800 Subject: [PATCH 038/112] Update admtcontroller.cpp - Updated Angle error calculation. - Updated FFT calculation. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 127 ++++++++++------------------ 1 file changed, 44 insertions(+), 83 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index a92900c1c2..82df691317 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -395,7 +395,6 @@ int ADMTController::linear_fit(vector x, vector y, double* slope return 0; } -/* Calculate angle error based on MATLAB and C# implementation */ int ADMTController::calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err, int cycleCount, int samplesPerCycle) { // Adjust the expected angles based on samples per cycle and cycle count @@ -410,8 +409,7 @@ int ADMTController::calculate_angle_error(vector angle_meas, vector angle_meas_rad(angle_meas.size()); // Convert measured angles to radians @@ -423,30 +421,19 @@ int ADMTController::calculate_angle_error(vector angle_meas, vector angle_meas_rad_unwrap(angle_meas.size()); - double num = 0.0; - angle_meas_rad_unwrap[0] = angle_meas_rad[0]; - for (int i = 1; i < angle_meas.size(); i++) { - double diff = angle_meas_rad[i] - angle_meas_rad[i - 1]; - if (diff > M_PI) { - num -= 2.0 * M_PI; - } else if (diff < -M_PI) { - num += 2.0 * M_PI; - } - angle_meas_rad_unwrap[i] = angle_meas_rad[i] + num; - } + // Unwrap the measured angles (in radians) to remove any discontinuity + unwrap_angles(angle_meas_rad); - // Set the initial point to zero - double offset = angle_meas_rad_unwrap[0]; + // Set the initial point to zero (optional, to normalize the measurement) + double offset = angle_meas_rad[0]; for (int i = 0; i < angle_meas.size(); i++) { - angle_meas_rad_unwrap[i] -= offset; + angle_meas_rad[i] -= offset; } // Calculate the angle error using the expected angles (unwrap vs expected) angle_error_ret.resize(angle_meas.size()); for (int i = 0; i < angle_meas.size(); i++) { - angle_error_ret[i] = angle_meas_rad_unwrap[i] - expected_angles_rad[i]; + angle_error_ret[i] = angle_meas_rad[i] - expected_angles_rad[i]; } // Find the min/max error for offset correction @@ -469,6 +456,23 @@ int ADMTController::calculate_angle_error(vector angle_meas, vector& angles_rad) { + for (size_t i = 1; i < angles_rad.size(); ++i) { + // Calculate the difference between the current angle and the previous one + double diff = angles_rad[i] - angles_rad[i-1]; + + // If the difference is greater than pi, subtract 2*pi (unwrap backward) + if (diff > M_PI) { + angles_rad[i] -= 2 * M_PI; + } + // If the difference is less than -pi, add 2*pi (unwrap forward) + else if (diff < -M_PI) { + angles_rad[i] += 2 * M_PI; + } + } +} + QString ADMTController::calibrate(vector PANG, int cycleCount, int samplesPerCycle) { int CCW = 0, circshiftData = 0; QString result = ""; @@ -656,35 +660,41 @@ void ADMTController::performFFT(const vector& angle_errors, vector cx; int size = angle_errors.size(); - cx fft_in[size]; - cx fft_out[size]; + int N = pow(2, ceil(log2(size))); // Ensure size is a power of 2 (padding if necessary) - // Format angle errors to match data type used in fft function + vector fft_in(N, cx(0, 0)); // Input signal (zero-padded if necessary) + vector fft_out(N); // Output signal (complex) + + // Format angle errors into the fft_in vector for (int i = 0; i < size; i++) { fft_in[i] = cx(angle_errors[i], 0); } - // Invoke FFT function - fft(fft_in, fft_out, 8); + // Perform FFT + fft(fft_in.data(), fft_out.data(), log2(N)); - // Extract magnitude and phase from complex fft_out array - vector angle_errors_fft_temp(size); - vector angle_errors_fft_phase_temp(size); + // Temporary vectors to store magnitude and phase + vector angle_errors_fft_temp(N); + vector angle_errors_fft_phase_temp(N); - for (int i = 0; i < size; i++) { - angle_errors_fft_temp[i] = sqrt(pow(fft_out[i].real() / size, 2) + pow(fft_out[i].imag() / size, 2)) * 2; + // Calculate magnitude and phase for all values + for (int i = 0; i < N; i++) { + // Magnitude: Normalize by N (to avoid amplitude increase) + angle_errors_fft_temp[i] = abs(fft_out[i]) * 2.0 / N; angle_errors_fft_phase_temp[i] = atan2(fft_out[i].imag(), fft_out[i].real()); } - vector angle_errors_fft_upper_half(size / cycleCount); - vector angle_errors_fft_phase_upper_half(size / cycleCount); + // Prepare vectors for upper half of FFT (positive frequencies) + vector angle_errors_fft_upper_half(N / 2); + vector angle_errors_fft_phase_upper_half(N / 2); - // Get upper half only - for (int i = 0; i < size / cycleCount; i++) { + // Get upper half only (due to symmetry in real-valued signal FFT) + for (int i = 0; i < N / 2; i++) { angle_errors_fft_upper_half[i] = angle_errors_fft_temp[i]; angle_errors_fft_phase_upper_half[i] = angle_errors_fft_phase_temp[i]; } + // Resize final vectors based on cycle count (if needed) angle_errors_fft = angle_errors_fft_upper_half; angle_errors_fft_phase = angle_errors_fft_phase_upper_half; } @@ -1144,55 +1154,6 @@ uint16_t ADMTController::setDIGIOENRegisterBitMapping(uint16_t currentRegisterVa return registerValue; } -vector ADMTController::unwrapAngles(const vector& wrappedAngles) { - vector unwrappedAngles; - unwrappedAngles.reserve(wrappedAngles.size()); - - // Start with the first angle as it is - double previousAngle = wrappedAngles[0]; - unwrappedAngles.push_back(previousAngle); - - // Initialize an offset for unwrapping - double offset = 0.0; - - for (size_t i = 1; i < wrappedAngles.size(); ++i) { - double currentAngle = wrappedAngles[i]; - double delta = currentAngle - previousAngle; - - // Adjust the current angle if it wraps around - if (delta < -180.0) { - offset += 360.0; // Increment offset for negative wrap - } else if (delta > 180.0) { - offset -= 360.0; // Decrement offset for positive wrap - } - - // Add the offset to the current angle - unwrappedAngles.push_back(currentAngle + offset); - previousAngle = currentAngle; // Update previous angle - } - - return unwrappedAngles; -} - -vector ADMTController::wrapAngles(const vector& unwrappedAngles) { - vector wrapped_angles; - wrapped_angles.reserve(unwrappedAngles.size()); - - for (const auto& angle : unwrappedAngles) { - // Wrap angle to be within [0, 360) - double wrapped_angle = fmod(angle, 360.0); - - // Ensure wrapped_angle is positive - if (wrapped_angle < 0) { - wrapped_angle += 360.0; - } - - wrapped_angles.push_back(wrapped_angle); - } - - return wrapped_angles; -} - map ADMTController::getUNIQID3RegisterMapping(uint16_t registerValue) { map result; From 828a02b0df65fffc8a9e76255473ed663c6948b5 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 10 Oct 2024 11:30:12 +0800 Subject: [PATCH 039/112] admt: Fixed controls for post calibration data - Fixed references for controller Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 3 +-- plugins/admt/src/admtcontroller.cpp | 4 ++-- plugins/admt/src/harmoniccalibration.cpp | 12 ++++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 49feac7071..12542b5e67 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -198,9 +198,8 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle); int getAbsAngleTurnCount(uint16_t registerValue); uint16_t setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings); - vector unwrapAngles(const vector& wrappedAngles); + void unwrapAngles(vector& angles_rad); map getUNIQID3RegisterMapping(uint16_t registerValue); - vector wrapAngles(const vector& unwrappedAngles); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 82df691317..cced279501 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -422,7 +422,7 @@ int ADMTController::calculate_angle_error(vector angle_meas, vector angle_meas, vector& angles_rad) { +void ADMTController::unwrapAngles(vector& angles_rad) { for (size_t i = 1; i < angles_rad.size(); ++i) { // Calculate the difference between the current angle and the previous one double diff = angles_rad[i] - angles_rad[i-1]; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 29950ab8e4..506e81f1e8 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -1110,6 +1110,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataPlotWidget->selectChannel(calibrationCosineDataPlotChannel); calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); }); + connect(togglePostAngleButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + postCalibrationRawDataPlotWidget->selectChannel(postCalibrationRawDataPlotChannel); + postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(togglePostSineButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + postCalibrationRawDataPlotWidget->selectChannel(postCalibrationSineDataPlotChannel); + postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(togglePostCosineButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ + postCalibrationRawDataPlotWidget->selectChannel(postCalibrationCosineDataPlotChannel); + postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); connect(toggleFFTAngleErrorMagnitudeButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); From 87d3e5f08655b54273cfc5dce0e10910ccb051a1 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 10 Oct 2024 12:07:17 +0800 Subject: [PATCH 040/112] Update admtcontroller.cpp - fixed loading of value of correct fft magnitude. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index cced279501..a3f5cb9d60 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -650,8 +650,8 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, v // Perform FFT on post-calibration angle errors performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post, cycleCount); - // FFT Corrected Error (angle_errors_post) - FFTCorrectedErrorMagnitude = angle_errors_post; + // FFT Corrected Error (angle_errors_fft_post) + FFTCorrectedErrorMagnitude = angle_errors_fft_post; // FFT Corrected Error Phase (angle_errors_fft_phase_post) FFTCorrectedErrorPhase = angle_errors_fft_phase_post; } From d8de5542786f83c72b1bdf6f91e8b7479b4d99a4 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 10 Oct 2024 16:06:42 +0800 Subject: [PATCH 041/112] Update admtcontroller.cpp - Normalize the fft based on the original length. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index a3f5cb9d60..5291b5965d 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -659,14 +659,14 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, v void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount) { typedef complex cx; - int size = angle_errors.size(); - int N = pow(2, ceil(log2(size))); // Ensure size is a power of 2 (padding if necessary) + int L = angle_errors.size(); // Original signal length (L) + int N = pow(2, ceil(log2(L))); // Ensure size is a power of 2 (padding if necessary) - vector fft_in(N, cx(0, 0)); // Input signal (zero-padded if necessary) - vector fft_out(N); // Output signal (complex) + vector fft_in(N, cx(0, 0)); // Input signal (zero-padded if necessary) + vector fft_out(N); // Output signal (complex) // Format angle errors into the fft_in vector - for (int i = 0; i < size; i++) { + for (int i = 0; i < L; i++) { fft_in[i] = cx(angle_errors[i], 0); } @@ -679,8 +679,8 @@ void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors, vector& angles) { // Vectors to store sine and cosine values calibration_samples_sine = vector(angles.size()); From 31a1b5a6e58aa640c90f8c384a6db5c00531dacc Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Fri, 11 Oct 2024 09:10:36 +0800 Subject: [PATCH 042/112] Mag FFT and Harmonic Cal Algorithm adjustments. - Fixed harmonic calculation algorithm to handle values as hex to bit instead of decimal. - Adjusted FFT for magnitude to return values after with the proper complex number scaling. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 81 +++++++++++------------------ 1 file changed, 29 insertions(+), 52 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 5291b5965d..027f9a4980 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -495,10 +495,10 @@ QString ADMTController::calibrate(vector PANG, int cycleCount, int sampl getPreCalibrationFFT(PANG, angle_errors_fft_pre, angle_errors_fft_phase_pre, cycleCount, samplesPerCycle); // Extract HMag parameters - double H1Mag = angle_errors_fft_pre[cycleCount]; - double H2Mag = angle_errors_fft_pre[2 * cycleCount]; - double H3Mag = angle_errors_fft_pre[3 * cycleCount]; - double H8Mag = angle_errors_fft_pre[8 * cycleCount]; + double H1Mag = angle_errors_fft_pre[cycleCount + 1]; + double H2Mag = angle_errors_fft_pre[2 * cycleCount + 1]; + double H3Mag = angle_errors_fft_pre[3 * cycleCount + 1]; + double H8Mag = angle_errors_fft_pre[8 * cycleCount + 1]; /* Display HMAG values */ result.append("H1Mag = " + QString::number(H1Mag) + "\n"); @@ -507,10 +507,10 @@ QString ADMTController::calibrate(vector PANG, int cycleCount, int sampl result.append("H8Mag = " + QString::number(H8Mag) + "\n"); // Extract HPhase parameters - double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycleCount]); - double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycleCount]); - double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycleCount]); - double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycleCount]); + double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycleCount + 1]); + double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycleCount + 1]); + double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycleCount + 1]); + double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycleCount + 1]); /* Display HPHASE values */ result.append("H1Phase = " + QString::number(H1Phase) + "\n"); @@ -524,7 +524,8 @@ QString ADMTController::calibrate(vector PANG, int cycleCount, int sampl double H8 = H8Mag * cos(M_PI / 180 * (H8Phase)); double init_err = H1 + H2 + H3 + H8; - double init_angle = PANG[0] - init_err; + double init_angle = PANG[1] - init_err; + double H1PHcor, H2PHcor, H3PHcor, H8PHcor; /* Counterclockwise, slope of error FIT is negative */ @@ -547,23 +548,6 @@ QString ADMTController::calibrate(vector PANG, int cycleCount, int sampl H3PHcor = (int)H3PHcor % 360; H8PHcor = (int)H8PHcor % 360; - /* Variables declaration for data correction */ - vector H1c(PANG.size()); - vector H2c(PANG.size()); - vector H3c(PANG.size()); - vector H8c(PANG.size()); - vector HXcorrection(PANG.size()); - - ///* Apply correction and check if working on original data */ - for (int i = 0; i < PANG.size(); i++) { - H1c[i] = H1Mag * sin(M_PI / 180 * (PANG[i]) + M_PI / 180 * (H1PHcor)); - H2c[i] = H2Mag * sin(2 * M_PI / 180 * (PANG[i]) + M_PI / 180 * (H2PHcor)); - H3c[i] = H3Mag * sin(3 * M_PI / 180 * (PANG[i]) + M_PI / 180 * (H3PHcor)); - H8c[i] = H8Mag * sin(8 * M_PI / 180 * (PANG[i]) + M_PI / 180 * (H8PHcor)); - - HXcorrection[i] = H1c[i] + H2c[i] + H3c[i] + H8c[i]; - } - // HMag Scaling H1Mag = H1Mag * 0.6072; H2Mag = H2Mag * 0.6072; @@ -605,15 +589,20 @@ void ADMTController::getPreCalibrationFFT(const vector& PANG, vector PANG, int cycleCount, int samplesPerCycle){ @@ -721,47 +710,35 @@ void ADMTController::computeSineCosineOfAngles(const vector& angles) { } } -// Function to calculate the scaled harmonic coefficient magnitude and return a 16-bit unsigned integer -uint16_t ADMTController::calculateHarmonicCoefficientMagnitude(double harmonicCoefficient, uint16_t originalValue, string key) { - // CORDIC scaler - const double cordicScaler = 0.6072; - - // LSB value (0.005493 degrees) - const double LSB = 0.005493; - - // Multiply the harmonic coefficient by the CORDIC scaler - double scaledValue = harmonicCoefficient * cordicScaler; - +// Function to insert the harmonic coefficient magnitude directly into the register +uint16_t ADMTController::calculateHarmonicCoefficientMagnitude(uint16_t harmonicCoefficient, uint16_t originalValue, const string& key) { uint16_t result = 0; // Switch case for different bitmapping based on the key if (key == "h1" || key == "h2") { // For h1 and h2: [15:11 reserved], [10:0 write] - result = static_cast(scaledValue / LSB) & 0x07FF; + result = harmonicCoefficient & 0x07FF; originalValue = (originalValue & 0xF800) | result; } else if (key == "h3" || key == "h8") { // For h3 and h8: [15:8 reserved], [7:0 write] - result = static_cast(scaledValue / LSB) & 0x00FF; + result = harmonicCoefficient & 0x00FF; originalValue = (originalValue & 0xFF00) | result; } else { - // Handle invalid key, here we return the original value unchanged + // Handle invalid key, return the original value unchanged return originalValue; } - return result; + + return originalValue; // Return the updated original value } -// Function to calculate the scaled harmonic coefficient phase and return a 16-bit unsigned integer -uint16_t ADMTController::calculateHarmonicCoefficientPhase(double harmonicCoefficient, uint16_t originalValue) { - // LSB value (0.087891 degrees) - const double LSB = 0.087891; - +// Function to insert the harmonic coefficient phase directly into the register +uint16_t ADMTController::calculateHarmonicCoefficientPhase(uint16_t harmonicPhase, uint16_t originalValue) { uint16_t result = 0; - // Convert the result to an unsigned integer by dividing by LSB, fitting into 12 bits - // Mask to keep only bits 11:0 - result = static_cast(harmonicCoefficient / LSB) & 0x0FFF; + // Mask to keep only bits 11:0 (since phase is represented in 12 bits) + result = harmonicPhase & 0x0FFF; // Clear bits 11:0 of the original value, keeping bits 15:12 intact uint16_t preservedValue = (originalValue & 0xF000) | result; From 54d1aa5800355fbdcb163a052aa61077b566be48 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 14 Oct 2024 10:31:03 +0800 Subject: [PATCH 043/112] admt: Adjusted calibration and post calibration behaviors - Added styles for disabled status - Implemented angle and hex views for calculated coefficients Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 4 +- .../admt/include/admt/harmoniccalibration.h | 14 +- .../include/admt/widgets/horizontalspinbox.h | 5 +- plugins/admt/src/harmoniccalibration.cpp | 548 +++++++++++------- .../admt/src/widgets/horizontalspinbox.cpp | 101 ++-- 5 files changed, 409 insertions(+), 263 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 12542b5e67..6eba95b664 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -185,8 +185,8 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject int writeDeviceRegistry(const char *deviceName, uint32_t address, uint32_t value); int readDeviceRegistry(const char *deviceName, uint32_t address, uint32_t *returnValue); void computeSineCosineOfAngles(const vector& angles); - uint16_t calculateHarmonicCoefficientMagnitude(double harmonicCoefficient, uint16_t originalValue, string key); - uint16_t calculateHarmonicCoefficientPhase(double harmonicCoefficient, uint16_t originalValue); + uint16_t calculateHarmonicCoefficientMagnitude(uint16_t harmonicCoefficient, uint16_t originalValue, const string& key); + uint16_t calculateHarmonicCoefficientPhase(uint16_t harmonicPhase, uint16_t originalValue); double getActualHarmonicRegisterValue(uint16_t registerValue, const string key); map getFaultRegisterBitMapping(uint16_t registerValue); map getGeneralRegisterBitMapping(uint16_t registerValue); diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 048b5ab9c5..a991b3d6b8 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -113,7 +113,7 @@ public Q_SLOTS: MenuSectionWidget *rightMenuSectionWidget; MenuCollapseSection *rotationCollapse, *angleCollapse, *countCollapse, *tempCollapse; - MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo, + MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo, *m_calibrationMotorRampModeMenuCombo, *sequenceTypeMenuCombo, *conversionTypeMenuCombo, *cnvSourceMenuCombo, *convertSynchronizationMenuCombo, *angleFilterMenuCombo, *eighthHarmonicMenuCombo; QTabWidget *tabWidget, *calibrationDataGraphTabWidget; @@ -144,7 +144,7 @@ public Q_SLOTS: *AFEDIAGStatusLED, *NVMCRCFaultStatusLED, *ECCDoubleBitErrorStatusLED, *OscillatorDriftStatusLED, *CountSensorFalseStateStatusLED, *AngleCrossCheckStatusLED, *TurnCountSensorLevelsStatusLED, *MTDIAGStatusLED, *TurnCounterCrossCheckStatusLED, *RadiusCheckStatusLED, *SequencerWatchdogStatusLED; - CustomSwitch *DIGIOBUSYToggleSwitch, *DIGIOCNVToggleSwitch, *DIGIOSENTToggleSwitch, *DIGIOACALCToggleSwitch, *DIGIOFAULTToggleSwitch, *DIGIOBOOTLOADERToggleSwitch, *DIGIOALLToggleSwitch; + CustomSwitch *calibrationDisplayFormatSwitch, *DIGIOBUSYToggleSwitch, *DIGIOCNVToggleSwitch, *DIGIOSENTToggleSwitch, *DIGIOACALCToggleSwitch, *DIGIOFAULTToggleSwitch, *DIGIOBOOTLOADERToggleSwitch, *DIGIOALLToggleSwitch; void updateChannelValues(); void updateLineEditValues(); @@ -164,7 +164,6 @@ public Q_SLOTS: void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); void updateChannelValue(int channelIndex); void calibrateData(); - void registerCalibrationData(); void extractCalibrationData(); void importCalibrationData(); void calibrationLogWrite(QString message = ""); @@ -186,8 +185,8 @@ public Q_SLOTS: void connectRegisterBlockToRegistry(RegisterBlockWidget* widget); double convertAccelTimetoAMAX(double accelTime); double convertAMAXtoAccelTime(double amax); - void updateCalculatedCoeff(); - void resetCalculatedCoeff(); + void updateCalculatedCoeffAngle(); + void resetCalculatedCoeffAngle(); void applyTabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor = "ScopyBlue"); MenuControlButton *createStatusLEDWidget(const QString title, QColor color, QWidget *parent = nullptr); MenuControlButton *createChannelToggleWidget(const QString title, QColor color, QWidget *parent = nullptr); @@ -212,6 +211,11 @@ public Q_SLOTS: void canStartMotor(bool value); void resetCurrentPositionToZero(); void flashHarmonicValues(); + void updateCalculatedCoeffHex(); + void resetCalculatedCoeffHex(); + void displayCalculatedCoeff(); + void toggleMotorControls(bool value); + void clearCalibrationSamples(); QTimer *timer, *calibrationTimer, *utilityTimer; diff --git a/plugins/admt/include/admt/widgets/horizontalspinbox.h b/plugins/admt/include/admt/widgets/horizontalspinbox.h index 957b96a221..e28d3446a5 100644 --- a/plugins/admt/include/admt/widgets/horizontalspinbox.h +++ b/plugins/admt/include/admt/widgets/horizontalspinbox.h @@ -18,6 +18,7 @@ namespace scopy::admt { public: HorizontalSpinBox(QString header = "", double initialValue = 0.0, QString unit = "", QWidget *parent = nullptr); QLineEdit *lineEdit(); + void setEnabled(double value); public Q_SLOTS: void setValue(double); protected Q_SLOTS: @@ -28,9 +29,11 @@ namespace scopy::admt { double m_value = 0; QString m_unit = ""; QLineEdit *m_lineEdit; + QPushButton *m_minusButton, *m_plusButton; + QLabel *m_unitLabel; void applyLineEditStyle(QLineEdit *widget); void applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius = 0, int topRightBorderRadius = 0, int bottomLeftBorderRadius = 0, int bottomRightBorderRadius = 0); - void applyUnitLabelStyle(QLabel *widget); + void applyUnitLabelStyle(QLabel *widget, bool isEnabled = true); }; } // namespace scopy::admt diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 506e81f1e8..178e2bd3c0 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -21,12 +21,15 @@ static int samplesPerCycle = 256; static int totalSamplesCount = cycleCount * samplesPerCycle; static bool isStartMotor = false; static bool isPostCalibration = false; +static bool isCalculatedCoeff = false; +static bool isAngleDisplayFormat = false; +static bool resetToZero = true; static double motorTimeUnit = 1.048576; // t = 2^24/16Mhz static int motorMicrostepPerRevolution = 51200; static int motorfCLK = 16000000; // 16Mhz -static bool autoCalibrate = false; +// static bool autoCalibrate = false; static uint32_t h1MagDeviceRegister = 0x15; static uint32_t h2MagDeviceRegister = 0x17; @@ -54,6 +57,9 @@ static QString deviceName = ""; static QString deviceType = ""; static bool is5V = false; +static double H1_MAG_ANGLE, H2_MAG_ANGLE, H3_MAG_ANGLE, H8_MAG_ANGLE, H1_PHASE_ANGLE, H2_PHASE_ANGLE, H3_PHASE_ANGLE, H8_PHASE_ANGLE; +static uint32_t H1_MAG_HEX, H2_MAG_HEX, H3_MAG_HEX, H8_MAG_HEX, H1_PHASE_HEX, H2_PHASE_HEX, H3_PHASE_HEX, H8_PHASE_HEX; + using namespace scopy; using namespace scopy::admt; using namespace scopy::grutil; @@ -409,6 +415,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connect(tabWidget, &QTabWidget::currentChanged, [=](int index){ tabWidget->setCurrentIndex(index); + if(index == 0) { readSequence(); } + if(index == 1) { calibrationTimer->start(calibrationTimerRate); } else { calibrationTimer->stop(); } @@ -601,6 +609,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() angleErrorPlotWidget->yAxis()->setVisible(false); angleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, angleErrorPlotWidget, scopyBluePen); + angleErrorXPlotAxis->setMin(0); angleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, angleErrorPlotWidget, scopyBluePen); angleErrorYPlotAxis->setInterval(-4, 4); @@ -631,6 +640,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTAngleErrorPlotWidget->yAxis()->setVisible(false); FFTAngleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTAngleErrorPlotWidget, scopyBluePen); + FFTAngleErrorXPlotAxis->setMin(0); FFTAngleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTAngleErrorPlotWidget, scopyBluePen); FFTAngleErrorYPlotAxis->setInterval(-4, 4); @@ -710,8 +720,9 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTCorrectedErrorPlotWidget->yAxis()->setVisible(false); FFTCorrectedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTCorrectedErrorPlotWidget, scopyBluePen); + FFTCorrectedErrorXPlotAxis->setMin(0); FFTCorrectedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTCorrectedErrorPlotWidget, scopyBluePen); - FFTCorrectedErrorYPlotAxis->setInterval(0, 360); + FFTCorrectedErrorYPlotAxis->setInterval(-4, 4); FFTCorrectedErrorMagnitudeChannel = new PlotChannel("FFT Corrected Error Magnitude", magnitudePen, FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); FFTCorrectedErrorPhaseChannel = new PlotChannel("FFT Corrected Error Phase", phasePen, FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); @@ -775,7 +786,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationCalculatedCoeffLabel->setText("Calculated Coefficients"); StyleHelper::MenuCollapseHeaderLabel(calibrationCalculatedCoeffLabel, "calibrationCalculatedCoeffLabel"); - CustomSwitch *calibrationDisplayFormatSwitch = new CustomSwitch(); + calibrationDisplayFormatSwitch = new CustomSwitch(); calibrationDisplayFormatSwitch->setOffText("Hex"); calibrationDisplayFormatSwitch->setOnText("Angle"); calibrationDisplayFormatSwitch->setProperty("bigBtn", true); @@ -807,8 +818,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() h1RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); h1RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH1Label = new QLabel("H1", calibrationCalculatedCoeffWidget); - calibrationH1MagLabel = new QLabel("--.--°", calibrationCalculatedCoeffWidget); - calibrationH1PhaseLabel = new QLabel("Φ --.--", calibrationCalculatedCoeffWidget); + calibrationH1MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH1PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); applyTextStyle(calibrationH1Label, "LabelText", true); applyTextStyle(calibrationH1MagLabel, "CH0"); applyTextStyle(calibrationH1PhaseLabel, "CH1"); @@ -829,8 +840,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() h2RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); h2RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH2Label = new QLabel("H2", calibrationCalculatedCoeffWidget); - calibrationH2MagLabel = new QLabel("--.--°", calibrationCalculatedCoeffWidget); - calibrationH2PhaseLabel = new QLabel("Φ --.--", calibrationCalculatedCoeffWidget); + calibrationH2MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH2PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); applyTextStyle(calibrationH2Label, "LabelText", true); applyTextStyle(calibrationH2MagLabel, "CH0"); applyTextStyle(calibrationH2PhaseLabel, "CH1"); @@ -851,8 +862,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() h3RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); h3RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH3Label = new QLabel("H3", calibrationCalculatedCoeffWidget); - calibrationH3MagLabel = new QLabel("--.--°", calibrationCalculatedCoeffWidget); - calibrationH3PhaseLabel = new QLabel("Φ --.--", calibrationCalculatedCoeffWidget); + calibrationH3MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH3PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); applyTextStyle(calibrationH3Label, "LabelText", true); applyTextStyle(calibrationH3MagLabel, "CH0"); applyTextStyle(calibrationH3PhaseLabel, "CH1"); @@ -873,8 +884,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() h8RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); h8RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH8Label = new QLabel("H8", calibrationCalculatedCoeffWidget); - calibrationH8MagLabel = new QLabel("--.--°", calibrationCalculatedCoeffWidget); - calibrationH8PhaseLabel = new QLabel("Φ --.--", calibrationCalculatedCoeffWidget); + calibrationH8MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH8PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); applyTextStyle(calibrationH8Label, "LabelText", true); applyTextStyle(calibrationH8MagLabel, "CH0"); applyTextStyle(calibrationH8PhaseLabel, "CH1"); @@ -917,6 +928,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationDatasetConfigCollapseSection); applyLineEditStyle(calibrationSamplesPerCycleLineEdit); calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); + calibrationSamplesPerCycleLineEdit->setReadOnly(true); connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, 1, 5000); calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(8); @@ -933,9 +945,9 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDataSectionWidget->contentLayout()->setSpacing(8); calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); - QPushButton *importDataButton = new QPushButton(calibrationDataCollapseSection); - importDataButton->setText("Import from CSV"); - StyleHelper::BlueButton(importDataButton, "importDataButton"); + // QPushButton *importDataButton = new QPushButton(calibrationDataCollapseSection); + // importDataButton->setText("Import from CSV"); + // StyleHelper::BlueButton(importDataButton, "importDataButton"); QPushButton *extractDataButton = new QPushButton(calibrationDataCollapseSection); extractDataButton->setText("Extract to CSV"); StyleHelper::BlueButton(extractDataButton, "extractDataButton"); @@ -944,7 +956,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() StyleHelper::BlueButton(clearCalibrateDataButton, "clearCalibrateDataButton"); calibrationDataCollapseSection->contentLayout()->setSpacing(8); - calibrationDataCollapseSection->contentLayout()->addWidget(importDataButton); + // calibrationDataCollapseSection->contentLayout()->addWidget(importDataButton); calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); calibrationDataCollapseSection->contentLayout()->addWidget(clearCalibrateDataButton); #pragma endregion @@ -952,6 +964,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Motor Configuration Section Widget MenuSectionWidget *motorConfigurationSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); MenuCollapseSection *motorConfigurationCollapseSection = new MenuCollapseSection("Motor Configuration", MenuCollapseSection::MHCW_NONE, motorConfigurationSectionWidget); + motorConfigurationCollapseSection->header()->toggle(); motorConfigurationSectionWidget->contentLayout()->addWidget(motorConfigurationCollapseSection); motorMaxVelocitySpinBox = new HorizontalSpinBox("Max Velocity", convertVMAXtoRPS(rotate_vmax), "rps", motorConfigurationSectionWidget); @@ -960,7 +973,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() motorAccelTimeSpinBox->setValue(1); motorMaxDisplacementSpinBox = new HorizontalSpinBox("Max Displacement", dmax, "", motorConfigurationSectionWidget); - MenuCombo *m_calibrationMotorRampModeMenuCombo = new MenuCombo("Ramp Mode", motorConfigurationSectionWidget); + m_calibrationMotorRampModeMenuCombo = new MenuCombo("Ramp Mode", motorConfigurationSectionWidget); auto calibrationMotorRampModeCombo = m_calibrationMotorRampModeMenuCombo->combo(); calibrationMotorRampModeCombo->addItem("Position", QVariant(ADMTController::MotorRampMode::POSITION)); calibrationMotorRampModeCombo->addItem("Ramp Mode 1", QVariant(ADMTController::MotorRampMode::RAMP_MODE_1)); @@ -1050,6 +1063,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Logs Section Widget MenuSectionWidget *logsSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); MenuCollapseSection *logsCollapseSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, logsSectionWidget); + logsCollapseSection->header()->toggle(); logsSectionWidget->contentLayout()->setSpacing(8); logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); @@ -1063,9 +1077,9 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationSettingsLayout->setMargin(0); calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); - calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); calibrationSettingsLayout->addWidget(motorControlSectionWidget); + calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); calibrationSettingsLayout->addWidget(logsSectionWidget); calibrationSettingsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); @@ -1085,9 +1099,9 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() tool->addWidgetToCentralContainerHelper(calibrationDataGraphWidget); tool->rightStack()->add("calibrationSettingsScrollArea", calibrationSettingsScrollArea); - connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::calibrateData); + connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::postCalibrateData); connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); - connect(importDataButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); + // connect(importDataButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::clearRawDataList); connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); @@ -1138,6 +1152,10 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorPhaseChannel); FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); }); + connect(calibrationDisplayFormatSwitch, &CustomSwitch::toggled, this, [=](bool b){ + isAngleDisplayFormat = b; + displayCalculatedCoeff(); + }); return tool; } @@ -1418,20 +1436,35 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() DIGIOControlGridLayout->setMargin(0); DIGIOControlGridLayout->setSpacing(8); + QString labelStyle = QString(R"css( + QLabel { + color: white; + background-color: rgba(255,255,255,0); + font-weight: 500; + font-family: Open Sans; + font-size: 12px; + font-style: normal; + } + QLabel:disabled { + color: grey; + } + )css"); + QLabel *DIGIOBUSYLabel = new QLabel("GPIO0", DIGIOControlGridWidget); - StyleHelper::MenuSmallLabel(DIGIOBUSYLabel, "DIGIOBUSYLabel"); QLabel *DIGIOCNVLabel = new QLabel("GPIO1", DIGIOControlGridWidget); - StyleHelper::MenuSmallLabel(DIGIOCNVLabel, "DIGIOCNVLabel"); QLabel *DIGIOSENTLabel = new QLabel("GPIO2", DIGIOControlGridWidget); - StyleHelper::MenuSmallLabel(DIGIOSENTLabel, "DIGIOSENTLabel"); QLabel *DIGIOACALCLabel = new QLabel("GPIO3", DIGIOControlGridWidget); - StyleHelper::MenuSmallLabel(DIGIOACALCLabel, "DIGIOACALCLabel"); QLabel *DIGIOFAULTLabel = new QLabel("GPIO4", DIGIOControlGridWidget); - StyleHelper::MenuSmallLabel(DIGIOFAULTLabel, "DIGIOFAULTLabel"); QLabel *DIGIOBOOTLOADERLabel = new QLabel("GPIO5", DIGIOControlGridWidget); - StyleHelper::MenuSmallLabel(DIGIOBOOTLOADERLabel, "DIGIOBOOTLOADERLabel"); QLabel *DIGIOALLLabel = new QLabel("GPIO Output", DIGIOControlGridWidget); - StyleHelper::MenuSmallLabel(DIGIOALLLabel, "DIGIOALLLabel"); + + DIGIOBUSYLabel->setStyleSheet(labelStyle); + DIGIOCNVLabel->setStyleSheet(labelStyle); + DIGIOSENTLabel->setStyleSheet(labelStyle); + DIGIOACALCLabel->setStyleSheet(labelStyle); + DIGIOFAULTLabel->setStyleSheet(labelStyle); + DIGIOBOOTLOADERLabel->setStyleSheet(labelStyle); + DIGIOALLLabel->setStyleSheet(labelStyle); DIGIOBUSYToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIOBUSYToggleSwitch, "On", "Off"); @@ -1478,20 +1511,20 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() DIGIOControlGridLayout->addWidget(DIGIOALLLabel, 0, 0); DIGIOControlGridLayout->addWidget(DIGIOALLToggleSwitch, 0, 1); - DIGIOControlGridLayout->addItem(new QSpacerItem(0, 8, QSizePolicy::Fixed, QSizePolicy::Expanding), 1, 0, 1, 2); + DIGIOControlGridLayout->addItem(new QSpacerItem(0, 4, QSizePolicy::Fixed, QSizePolicy::Expanding), 1, 0, 1, 2); QFrame *line = new QFrame(); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Plain); line->setFixedHeight(1); QString lineStyle = QString(R"css( QFrame { - border: 1px solid white; + border: 1px solid #808085; } )css"); line->setStyleSheet(lineStyle); DIGIOControlGridLayout->addWidget(line, 2, 0, 1, 2); - DIGIOControlGridLayout->addItem(new QSpacerItem(0, 8, QSizePolicy::Fixed, QSizePolicy::Expanding), 3, 0, 1, 2); + DIGIOControlGridLayout->addItem(new QSpacerItem(0, 4, QSizePolicy::Fixed, QSizePolicy::Expanding), 3, 0, 1, 2); DIGIOControlGridLayout->addWidget(DIGIOBUSYLabel, 4, 0); DIGIOControlGridLayout->addWidget(DIGIOBUSYToggleSwitch, 4, 1); @@ -1506,7 +1539,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() DIGIOControlGridLayout->addWidget(DIGIOBOOTLOADERLabel, 9, 0); DIGIOControlGridLayout->addWidget(DIGIOBOOTLOADERToggleSwitch, 9, 1); - DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOControlGridWidget); + DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOControlGridWidget, 1); #pragma endregion DIGIOLayout->addWidget(DIGIOMonitorSectionWidget); @@ -1559,9 +1592,9 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() QLabel *AFEDIAG2Label = new QLabel("AFEDIAG2 (V)"); StyleHelper::MenuSmallLabel(AFEDIAG2Label, "AFEDIAG2Label"); - AFEDIAG0LineEdit = new QLineEdit("-57.0312", MTDiagnosticsSectionWidget); - AFEDIAG1LineEdit = new QLineEdit("56.25", MTDiagnosticsSectionWidget); - AFEDIAG2LineEdit = new QLineEdit("-312.499m", MTDiagnosticsSectionWidget); + AFEDIAG0LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); + AFEDIAG1LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); + AFEDIAG2LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); applyLineEditStyle(AFEDIAG0LineEdit); applyLineEditStyle(AFEDIAG1LineEdit); applyLineEditStyle(AFEDIAG2LineEdit); @@ -1659,6 +1692,15 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() return tool; } +void HarmonicCalibration::toggleMotorControls(bool value) +{ + motorMaxVelocitySpinBox->setEnabled(value); + motorAccelTimeSpinBox->setEnabled(value); + motorMaxDisplacementSpinBox->setEnabled(value); + m_calibrationMotorRampModeMenuCombo->setEnabled(value); + motorTargetPositionSpinBox->setEnabled(value); +} + void HarmonicCalibration::toggleUtilityTask(bool run) { if(run){ @@ -2512,7 +2554,9 @@ void HarmonicCalibration::calibrationTask() void HarmonicCalibration::getCalibrationSamples() { - resetCurrentPositionToZero(); + if(resetToZero){ + resetCurrentPositionToZero(); + } if(isPostCalibration){ while(isStartMotor && graphPostDataList.size() < totalSamplesCount){ stepMotorAcquisition(); @@ -2536,14 +2580,22 @@ void HarmonicCalibration::resetCurrentPositionToZero() while(current_pos != 0){ readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); } + resetToZero = false; } void HarmonicCalibration::startMotor() { + toggleMotorControls(false); + + if(resetToZero && !isPostCalibration){ + clearCalibrationSamples(); + } QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getCalibrationSamples); QFutureWatcher *watcher = new QFutureWatcher(this); connect(watcher, &QFutureWatcher::finished, this, [=]() { + toggleMotorControls(true); + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); calibrationRawDataPlotChannel->xAxis()->setMax(graphDataList.size()); calibrationRawDataPlotWidget->replot(); @@ -2584,6 +2636,33 @@ void HarmonicCalibration::startMotor() { computeSineCosineOfAngles(graphDataList); canCalibrate(true); + + calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); + + flashHarmonicValues(); + + QVector angleError = QVector(m_admtController->angleError.begin(), m_admtController->angleError.end()); + QVector FFTAngleErrorMagnitude = QVector(m_admtController->FFTAngleErrorMagnitude.begin(), m_admtController->FFTAngleErrorMagnitude.end()); + QVector FFTAngleErrorPhase = QVector(m_admtController->FFTAngleErrorPhase.begin(), m_admtController->FFTAngleErrorPhase.end()); + + angleErrorPlotChannel->curve()->setSamples(angleError); + auto angleErrorMinMax = std::minmax_element(angleError.begin(), angleError.end()); + angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, *angleErrorMinMax.second); + angleErrorXPlotAxis->setInterval(0, angleError.size()); + angleErrorPlotWidget->replot(); + + FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); + auto angleErrorMagnitudeMinMax = std::minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); + FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); + auto angleErrorPhaseMinMax = std::minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); + double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first ? *angleErrorMagnitudeMinMax.first : *angleErrorPhaseMinMax.first; + double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second ? *angleErrorMagnitudeMinMax.second : *angleErrorPhaseMinMax.second; + FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); + FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); + FFTAngleErrorPlotWidget->replot(); + } + else{ + resetToZero = true; } } }); @@ -2623,8 +2702,6 @@ void HarmonicCalibration::calibrateData() FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); FFTAngleErrorPlotWidget->replot(); - - postCalibrateData(); } void HarmonicCalibration::flashHarmonicValues() @@ -2636,128 +2713,119 @@ void HarmonicCalibration::flashHarmonicValues() *h3MagCurrent = new uint32_t, *h3PhaseCurrent = new uint32_t, *h8MagCurrent = new uint32_t, - *h8PhaseCurrent = new uint32_t, - h1MagScaled, - h1PhaseScaled, - h2MagScaled, - h2PhaseScaled, - h3MagScaled, - h3PhaseScaled, - h8MagScaled, - h8PhaseScaled; - double h1MagConverted, - h1PhaseConverted, - h2MagConverted, - h2PhaseConverted, - h3MagConverted, - h3PhaseConverted, - h8MagConverted, - h8PhaseConverted; - - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); - - calibrationLogWrite(); - calibrationLogWrite("H1 Mag Current: " + QString::number(*h1MagCurrent)); - calibrationLogWrite("H1 Phase Current: " + QString::number(*h1PhaseCurrent)); - calibrationLogWrite("H2 Mag Current: " + QString::number(*h2MagCurrent)); - calibrationLogWrite("H2 Phase Current: " + QString::number(*h2PhaseCurrent)); - calibrationLogWrite("H3 Mag Current: " + QString::number(*h3MagCurrent)); - calibrationLogWrite("H3 Phase Current: " + QString::number(*h3PhaseCurrent)); - calibrationLogWrite("H8 Mag Current: " + QString::number(*h8MagCurrent)); - calibrationLogWrite("H8 Phase Current: " + QString::number(*h8PhaseCurrent)); - - h1MagScaled = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(m_admtController->HAR_MAG_1, static_cast(*h1MagCurrent), "h1")); - h1PhaseScaled = static_cast(m_admtController->calculateHarmonicCoefficientPhase(m_admtController->HAR_PHASE_1, static_cast(*h1PhaseCurrent))); - h2MagScaled = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(m_admtController->HAR_MAG_2, static_cast(*h2MagCurrent), "h2")); - h2PhaseScaled = static_cast(m_admtController->calculateHarmonicCoefficientPhase(m_admtController->HAR_PHASE_2, static_cast(*h2PhaseCurrent))); - h3MagScaled = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(m_admtController->HAR_MAG_3, static_cast(*h3MagCurrent), "h3")); - h3PhaseScaled = static_cast(m_admtController->calculateHarmonicCoefficientPhase(m_admtController->HAR_PHASE_3, static_cast(*h3PhaseCurrent))); - h8MagScaled = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(m_admtController->HAR_MAG_8, static_cast(*h8MagCurrent), "h8")); - h8PhaseScaled = static_cast(m_admtController->calculateHarmonicCoefficientPhase(m_admtController->HAR_PHASE_8, static_cast(*h8PhaseCurrent))); - - calibrationLogWrite(); - calibrationLogWrite("H1 Mag Scaled: " + QString::number(h1MagScaled)); - calibrationLogWrite("H1 Phase Scaled: " + QString::number(h1PhaseScaled)); - calibrationLogWrite("H2 Mag Scaled: " + QString::number(h2MagScaled)); - calibrationLogWrite("H2 Phase Scaled: " + QString::number(h2PhaseScaled)); - calibrationLogWrite("H3 Mag Scaled: " + QString::number(h3MagScaled)); - calibrationLogWrite("H3 Phase Scaled: " + QString::number(h3PhaseScaled)); - calibrationLogWrite("H8 Mag Scaled: " + QString::number(h8MagScaled)); - calibrationLogWrite("H8 Phase Scaled: " + QString::number(h8PhaseScaled)); - - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), 0x01, 0x02); - - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), - h1MagScaled); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), - h1PhaseScaled); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), - h2MagScaled); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), - h2PhaseScaled); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), - h3MagScaled); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), - h3PhaseScaled); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), - h8MagScaled); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), - h8PhaseScaled); - - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); - - calibrationLogWrite(); - calibrationLogWrite("H1 Mag After Flash: " + QString::number(*h1MagCurrent)); - calibrationLogWrite("H1 Phase After Flash: " + QString::number(*h1PhaseCurrent)); - calibrationLogWrite("H2 Mag After Flash: " + QString::number(*h2MagCurrent)); - calibrationLogWrite("H2 Phase After Flash: " + QString::number(*h2PhaseCurrent)); - calibrationLogWrite("H3 Mag After Flash: " + QString::number(*h3MagCurrent)); - calibrationLogWrite("H3 Phase After Flash: " + QString::number(*h3PhaseCurrent)); - calibrationLogWrite("H8 Mag After Flash: " + QString::number(*h8MagCurrent)); - calibrationLogWrite("H8 Phase After Flash: " + QString::number(*h8PhaseCurrent)); - - h1MagConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h1MagCurrent), "h1mag"); - h1PhaseConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h1PhaseCurrent), "h1phase"); - h2MagConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h2MagCurrent), "h2mag"); - h2PhaseConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h2PhaseCurrent), "h2phase"); - h3MagConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h3MagCurrent), "h3mag"); - h3PhaseConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h3PhaseCurrent), "h3phase"); - h8MagConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h8MagCurrent), "h8mag"); - h8PhaseConverted = m_admtController->getActualHarmonicRegisterValue(static_cast(*h8PhaseCurrent), "h8phase"); - - calibrationLogWrite(); - calibrationLogWrite("H1 Mag Converted: " + QString::number(h1MagConverted)); - calibrationLogWrite("H1 Phase Converted: " + QString::number(h1PhaseConverted)); - calibrationLogWrite("H2 Mag Converted: " + QString::number(h2MagConverted)); - calibrationLogWrite("H2 Phase Converted: " + QString::number(h2PhaseConverted)); - calibrationLogWrite("H3 Mag Converted: " + QString::number(h3MagConverted)); - calibrationLogWrite("H3 Phase Converted: " + QString::number(h3PhaseConverted)); - calibrationLogWrite("H8 Mag Converted: " + QString::number(h8MagConverted)); - calibrationLogWrite("H8 Phase Converted: " + QString::number(h8PhaseConverted)); - - updateCalculatedCoeff(); + *h8PhaseCurrent = new uint32_t; + + if(changeCNVPage(0x02, "Harmonic Registers")){ + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); + + calibrationLogWrite(); + calibrationLogWrite("H1 Mag Current: " + QString::number(*h1MagCurrent)); + calibrationLogWrite("H1 Phase Current: " + QString::number(*h1PhaseCurrent)); + calibrationLogWrite("H2 Mag Current: " + QString::number(*h2MagCurrent)); + calibrationLogWrite("H2 Phase Current: " + QString::number(*h2PhaseCurrent)); + calibrationLogWrite("H3 Mag Current: " + QString::number(*h3MagCurrent)); + calibrationLogWrite("H3 Phase Current: " + QString::number(*h3PhaseCurrent)); + calibrationLogWrite("H8 Mag Current: " + QString::number(*h8MagCurrent)); + calibrationLogWrite("H8 Phase Current: " + QString::number(*h8PhaseCurrent)); + + H1_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_1), static_cast(*h1MagCurrent), "h1")); + H1_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_1), static_cast(*h1PhaseCurrent))); + H2_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_2), static_cast(*h2MagCurrent), "h2")); + H2_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_2), static_cast(*h2PhaseCurrent))); + H3_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_3), static_cast(*h3MagCurrent), "h3")); + H3_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_3), static_cast(*h3PhaseCurrent))); + H8_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_8), static_cast(*h8MagCurrent), "h8")); + H8_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_8), static_cast(*h8PhaseCurrent))); + + calibrationLogWrite(); + calibrationLogWrite("H1 Mag Scaled: " + QString::number(H1_MAG_HEX)); + calibrationLogWrite("H1 Phase Scaled: " + QString::number(H1_PHASE_HEX)); + calibrationLogWrite("H2 Mag Scaled: " + QString::number(H2_MAG_HEX)); + calibrationLogWrite("H2 Phase Scaled: " + QString::number(H2_PHASE_HEX)); + calibrationLogWrite("H3 Mag Scaled: " + QString::number(H3_MAG_HEX)); + calibrationLogWrite("H3 Phase Scaled: " + QString::number(H3_PHASE_HEX)); + calibrationLogWrite("H8 Mag Scaled: " + QString::number(H8_MAG_HEX)); + calibrationLogWrite("H8 Phase Scaled: " + QString::number(H8_PHASE_HEX)); + + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), 0x01, 0x02); + + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), + H1_MAG_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), + H1_PHASE_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), + H2_MAG_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), + H2_PHASE_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), + H3_MAG_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), + H3_PHASE_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), + H8_MAG_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), + H8_PHASE_HEX); + + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); + + calibrationLogWrite(); + calibrationLogWrite("H1 Mag After Flash: " + QString::number(*h1MagCurrent)); + calibrationLogWrite("H1 Phase After Flash: " + QString::number(*h1PhaseCurrent)); + calibrationLogWrite("H2 Mag After Flash: " + QString::number(*h2MagCurrent)); + calibrationLogWrite("H2 Phase After Flash: " + QString::number(*h2PhaseCurrent)); + calibrationLogWrite("H3 Mag After Flash: " + QString::number(*h3MagCurrent)); + calibrationLogWrite("H3 Phase After Flash: " + QString::number(*h3PhaseCurrent)); + calibrationLogWrite("H8 Mag After Flash: " + QString::number(*h8MagCurrent)); + calibrationLogWrite("H8 Phase After Flash: " + QString::number(*h8PhaseCurrent)); + + H1_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h1MagCurrent), "h1mag"); + H1_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h1PhaseCurrent), "h1phase"); + H2_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h2MagCurrent), "h2mag"); + H2_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h2PhaseCurrent), "h2phase"); + H3_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h3MagCurrent), "h3mag"); + H3_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h3PhaseCurrent), "h3phase"); + H8_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h8MagCurrent), "h8mag"); + H8_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h8PhaseCurrent), "h8phase"); + + calibrationLogWrite(); + calibrationLogWrite("H1 Mag Converted: " + QString::number(H1_MAG_ANGLE)); + calibrationLogWrite("H1 Phase Converted: " + QString::number(H1_PHASE_ANGLE)); + calibrationLogWrite("H2 Mag Converted: " + QString::number(H2_MAG_ANGLE)); + calibrationLogWrite("H2 Phase Converted: " + QString::number(H2_PHASE_ANGLE)); + calibrationLogWrite("H3 Mag Converted: " + QString::number(H3_MAG_ANGLE)); + calibrationLogWrite("H3 Phase Converted: " + QString::number(H3_PHASE_ANGLE)); + calibrationLogWrite("H8 Mag Converted: " + QString::number(H8_MAG_ANGLE)); + calibrationLogWrite("H8 Phase Converted: " + QString::number(H8_PHASE_ANGLE)); + + isCalculatedCoeff = true; + + displayCalculatedCoeff(); + } + else{ + calibrationLogWrite("Unabled to flash Harmonic Registers!"); + } } void HarmonicCalibration::postCalibrateData() @@ -2768,23 +2836,23 @@ void HarmonicCalibration::postCalibrateData() calibrationDataGraphTabWidget->setCurrentIndex(1); isPostCalibration = true; isStartMotor = true; + resetToZero = true; startMotor(); } -void HarmonicCalibration::updateCalculatedCoeff() +void HarmonicCalibration::updateCalculatedCoeffAngle() { - calibrationH1MagLabel->setText(QString::number(m_admtController->HAR_MAG_1) + "°"); - calibrationH2MagLabel->setText(QString::number(m_admtController->HAR_MAG_2) + "°"); - calibrationH3MagLabel->setText(QString::number(m_admtController->HAR_MAG_3) + "°"); - calibrationH8MagLabel->setText(QString::number(m_admtController->HAR_MAG_8) + "°"); - calibrationH1PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_1)); - calibrationH2PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_2)); - calibrationH3PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_3)); - calibrationH8PhaseLabel->setText("Φ " + QString::number(m_admtController->HAR_PHASE_8)); - //applyCalibrationDataButton->setEnabled(true); + calibrationH1MagLabel->setText(QString::number(H1_MAG_ANGLE) + "°"); + calibrationH2MagLabel->setText(QString::number(H2_MAG_ANGLE) + "°"); + calibrationH3MagLabel->setText(QString::number(H3_MAG_ANGLE) + "°"); + calibrationH8MagLabel->setText(QString::number(H8_MAG_ANGLE) + "°"); + calibrationH1PhaseLabel->setText("Φ " + QString::number(H1_PHASE_ANGLE)); + calibrationH2PhaseLabel->setText("Φ " + QString::number(H2_PHASE_ANGLE)); + calibrationH3PhaseLabel->setText("Φ " + QString::number(H3_PHASE_ANGLE)); + calibrationH8PhaseLabel->setText("Φ " + QString::number(H8_PHASE_ANGLE)); } -void HarmonicCalibration::resetCalculatedCoeff() +void HarmonicCalibration::resetCalculatedCoeffAngle() { calibrationH1MagLabel->setText("--.--°"); calibrationH2MagLabel->setText("--.--°"); @@ -2796,36 +2864,48 @@ void HarmonicCalibration::resetCalculatedCoeff() calibrationH8PhaseLabel->setText("Φ --.--"); } -void HarmonicCalibration::registerCalibrationData() -{ - calibrationLogWrite("=== Apply Calibration ===\n"); - - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - h1MagDeviceRegister, m_admtController->HAR_MAG_1) != 0) - { calibrationLogWrite("Failed to write to H1 Mag Register"); } - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - h2MagDeviceRegister, m_admtController->HAR_MAG_2) != 0) - { calibrationLogWrite("Failed to write to H2 Mag Register"); } - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - h3MagDeviceRegister, m_admtController->HAR_MAG_3) != 0) - { calibrationLogWrite("Failed to write to H3 Mag Register"); } - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - h8MagDeviceRegister, m_admtController->HAR_MAG_8) != 0) - { calibrationLogWrite("Failed to write to H8 Mag Register"); } - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - h1PhaseDeviceRegister, m_admtController->HAR_PHASE_1) != 0) - { calibrationLogWrite("Failed to write to H1 Phase Register"); } - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - h2PhaseDeviceRegister, m_admtController->HAR_PHASE_2) != 0) - { calibrationLogWrite("Failed to write to H2 Phase Register"); } - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - h3PhaseDeviceRegister, m_admtController->HAR_PHASE_3) != 0) - { calibrationLogWrite("Failed to write to H3 Phase Register"); } - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - h8PhaseDeviceRegister, m_admtController->HAR_PHASE_8) != 0) - { calibrationLogWrite("Failed to write to H8 Phase Register"); } - - calibrationLogWrite("=== Calibration Complete ===\n"); +void HarmonicCalibration::updateCalculatedCoeffHex() +{ + calibrationH1MagLabel->setText(QString("0x%1").arg(H1_MAG_HEX, 4, 16, QChar('0'))); + calibrationH2MagLabel->setText(QString("0x%1").arg(H2_MAG_HEX, 4, 16, QChar('0'))); + calibrationH3MagLabel->setText(QString("0x%1").arg(H3_MAG_HEX, 4, 16, QChar('0'))); + calibrationH8MagLabel->setText(QString("0x%1").arg(H8_MAG_HEX, 4, 16, QChar('0'))); + calibrationH1PhaseLabel->setText(QString("0x%1").arg(H1_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH2PhaseLabel->setText(QString("0x%1").arg(H2_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH3PhaseLabel->setText(QString("0x%1").arg(H3_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH8PhaseLabel->setText(QString("0x%1").arg(H8_PHASE_HEX, 4, 16, QChar('0'))); +} + +void HarmonicCalibration::resetCalculatedCoeffHex() +{ + calibrationH1MagLabel->setText("0x----"); + calibrationH2MagLabel->setText("0x----"); + calibrationH3MagLabel->setText("0x----"); + calibrationH8MagLabel->setText("0x----"); + calibrationH1PhaseLabel->setText("0x----"); + calibrationH2PhaseLabel->setText("0x----"); + calibrationH3PhaseLabel->setText("0x----"); + calibrationH8PhaseLabel->setText("0x----"); +} + +void HarmonicCalibration::displayCalculatedCoeff() +{ + if(isAngleDisplayFormat){ + if(isCalculatedCoeff){ + updateCalculatedCoeffAngle(); + } + else{ + resetCalculatedCoeffAngle(); + } + } + else{ + if(isCalculatedCoeff){ + updateCalculatedCoeffHex(); + } + else{ + resetCalculatedCoeffHex(); + } + } } void HarmonicCalibration::calibrationLogWrite(QString message) @@ -2863,14 +2943,14 @@ void HarmonicCalibration::extractCalibrationData() QVector preCalibrationAngleErrorsFFTMagnitude(m_admtController->angle_errors_fft_pre.begin(), m_admtController->angle_errors_fft_pre.end()); QVector preCalibrationAngleErrorsFFTPhase(m_admtController->angle_errors_fft_phase_pre.begin(), m_admtController->angle_errors_fft_phase_pre.end()); - QVector h1Mag = { static_cast(m_admtController->HAR_MAG_1) }; - QVector h2Mag = { static_cast(m_admtController->HAR_MAG_2) }; - QVector h3Mag = { static_cast(m_admtController->HAR_MAG_3) }; - QVector h8Mag = { static_cast(m_admtController->HAR_MAG_8) }; - QVector h1Phase = { static_cast(m_admtController->HAR_PHASE_1) }; - QVector h2Phase = { static_cast(m_admtController->HAR_PHASE_2) }; - QVector h3Phase = { static_cast(m_admtController->HAR_PHASE_3) }; - QVector h8Phase = { static_cast(m_admtController->HAR_PHASE_8) }; + QVector h1Mag = { H1_MAG_ANGLE }; + QVector h2Mag = { H2_MAG_ANGLE }; + QVector h3Mag = { H3_MAG_ANGLE }; + QVector h8Mag = { H8_MAG_ANGLE }; + QVector h1Phase = { H1_PHASE_ANGLE }; + QVector h2Phase = { H2_PHASE_ANGLE }; + QVector h3Phase = { H3_PHASE_ANGLE }; + QVector h8Phase = { H8_PHASE_ANGLE }; fm.save(graphDataList, "Raw Data"); fm.save(preCalibrationAngleErrorsFFTMagnitude, "Pre-Calibration Angle Errors FFT Magnitude"); @@ -2942,13 +3022,13 @@ void HarmonicCalibration::stepMotorAcquisition(double step) void HarmonicCalibration::clearRawDataList() { - graphDataList.clear(); - graphPostDataList.clear(); + clearCalibrationSamples(); - calibrationRawDataPlotChannel->curve()->setData(nullptr); - calibrationSineDataPlotChannel->curve()->setData(nullptr); - calibrationCosineDataPlotChannel->curve()->setData(nullptr); - calibrationRawDataPlotWidget->replot(); + graphPostDataList.clear(); + postCalibrationRawDataPlotChannel->curve()->setData(nullptr); + postCalibrationSineDataPlotChannel->curve()->setData(nullptr); + postCalibrationCosineDataPlotChannel->curve()->setData(nullptr); + postCalibrationRawDataPlotWidget->replot(); angleErrorPlotChannel->curve()->setData(nullptr); angleErrorPlotWidget->replot(); @@ -2963,20 +3043,43 @@ void HarmonicCalibration::clearRawDataList() canCalibrate(false); canStartMotor(true); + isPostCalibration = false; + isCalculatedCoeff = false; + resetToZero = true; + displayCalculatedCoeff(); +} - resetCalculatedCoeff(); +void HarmonicCalibration::clearCalibrationSamples() +{ + graphDataList.clear(); + calibrationRawDataPlotChannel->curve()->setData(nullptr); + calibrationSineDataPlotChannel->curve()->setData(nullptr); + calibrationCosineDataPlotChannel->curve()->setData(nullptr); + calibrationRawDataPlotWidget->replot(); } void HarmonicCalibration::applyLineEditStyle(QLineEdit *widget) { - applyTextStyle(widget); - QString existingStyle = widget->styleSheet(); QString style = QString(R"css( - background-color: black; - border-radius: 4px; - border: none; + QLineEdit { + font-family: Open Sans; + font-size: 16px; + font-weight: normal; + text-align: right; + color: &&colorname&&; + + background-color: black; + border-radius: 4px; + border: none; + } + + QLineEdit:disabled { + background-color: #18181d; + color: #9c4600; + } )css"); - widget->setStyleSheet(existingStyle + style); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + widget->setStyleSheet(style); widget->setFixedHeight(30); widget->setContentsMargins(0, 0, 0, 0); widget->setTextMargins(12, 4, 12, 4); @@ -3000,7 +3103,10 @@ void HarmonicCalibration::applyComboBoxStyle(QComboBox *widget, const QString& s font-size: 16px; background-color: black; } - QComboBox:disabled, QLineEdit:disabled { color: #555555; } + QComboBox:disabled, QLineEdit:disabled { + background-color: #18181d; + color: #9c4600; + } QComboBox QAbstractItemView { border: none; color: transparent; diff --git a/plugins/admt/src/widgets/horizontalspinbox.cpp b/plugins/admt/src/widgets/horizontalspinbox.cpp index 0b7e8d9209..feb1f6a1e8 100644 --- a/plugins/admt/src/widgets/horizontalspinbox.cpp +++ b/plugins/admt/src/widgets/horizontalspinbox.cpp @@ -35,36 +35,36 @@ HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, QStrin lineEditLayout->setMargin(0); lineEditLayout->setSpacing(0); - QLabel *unitLabel = new QLabel(m_unit, controlWidget); - applyUnitLabelStyle(unitLabel); + m_unitLabel = new QLabel(m_unit, controlWidget); + applyUnitLabelStyle(m_unitLabel); m_lineEdit->setTextMargins(12, 4, 0, 4); lineEditLayout->addWidget(m_lineEdit); - lineEditLayout->addWidget(unitLabel); + lineEditLayout->addWidget(m_unitLabel); controlLayout->addWidget(lineEditContainer); } else{ controlLayout->addWidget(m_lineEdit); } - QPushButton *minusButton = new QPushButton(controlWidget); - minusButton->setIcon(QIcon(":/admt/minus.svg")); - applyPushButtonStyle(minusButton); + m_minusButton = new QPushButton(controlWidget); + m_minusButton->setIcon(QIcon(":/admt/minus.svg")); + applyPushButtonStyle(m_minusButton); - QPushButton *plusButton = new QPushButton(controlWidget); - plusButton->setIcon(QIcon(":/admt/plus.svg")); - applyPushButtonStyle(plusButton, 0, 4, 0, 4); + m_plusButton = new QPushButton(controlWidget); + m_plusButton->setIcon(QIcon(":/admt/plus.svg")); + applyPushButtonStyle(m_plusButton, 0, 4, 0, 4); - controlLayout->addWidget(minusButton); - controlLayout->addWidget(plusButton); + controlLayout->addWidget(m_minusButton); + controlLayout->addWidget(m_plusButton); container->addWidget(controlWidget); setValue(m_value); connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(onLineEditTextEdited())); - connect(minusButton, SIGNAL(clicked()), SLOT(onMinusButtonPressed())); - connect(plusButton, SIGNAL(clicked()), SLOT(onPlusButtonPressed())); + connect(m_minusButton, SIGNAL(clicked()), SLOT(onMinusButtonPressed())); + connect(m_plusButton, SIGNAL(clicked()), SLOT(onPlusButtonPressed())); } void HorizontalSpinBox::onMinusButtonPressed() @@ -97,17 +97,37 @@ void HorizontalSpinBox::setValue(double value) m_lineEdit->setText(QString::number(value)); } +void HorizontalSpinBox::setEnabled(double value) +{ + m_lineEdit->setEnabled(value); + m_minusButton->setEnabled(value); + m_plusButton->setEnabled(value); + if(QString::compare(m_unit, "") != 0){ + applyUnitLabelStyle(m_unitLabel, value); + } +} + void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) { QString style = QString(R"css( - background-color: black; - font-family: Open Sans; - font-size: 16px; - color: &&colorname&&; - border: none; - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - qproperty-frame: false; + QLineEdit { + font-family: Open Sans; + font-size: 16px; + font-weight: normal; + text-align: right; + color: &&colorname&&; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + + background-color: black; + border: none; + qproperty-frame: false; + } + + QLineEdit:disabled { + background-color: #18181d; + color: #9c4600; + } )css"); style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); widget->setStyleSheet(style); @@ -120,16 +140,22 @@ void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) void HorizontalSpinBox::applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius, int topRightBorderRadius, int bottomLeftBorderRadius, int bottomRightBorderRadius) { QString style = QString(R"css( - background-color: black; - font-family: Open Sans; - font-size: 32px; - font-weight: bold; - text-align: center center; - color: &&colorname&&; - border-top-left-radius: &&topLeftBorderRadius&&px; - border-top-right-radius: &&topRightBorderRadius&&px; - border-bottom-left-radius: &&bottomLeftBorderRadius&&px; - border-bottom-right-radius: &&bottomRightBorderRadius&&px; + QPushButton{ + background-color: black; + font-family: Open Sans; + font-size: 32px; + font-weight: bold; + text-align: center center; + color: &&colorname&&; + border-top-left-radius: &&topLeftBorderRadius&&px; + border-top-right-radius: &&topRightBorderRadius&&px; + border-bottom-left-radius: &&bottomLeftBorderRadius&&px; + border-bottom-right-radius: &&bottomRightBorderRadius&&px; + } + QPushButton:disabled{ + background-color: #18181d; + color: #2d3d9c; + } )css"); style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("ScopyBlue")); style = style.replace(QString("&&topLeftBorderRadius&&"), QString::number(topLeftBorderRadius)); @@ -141,17 +167,24 @@ void HorizontalSpinBox::applyPushButtonStyle(QPushButton *widget, int topLeftBor widget->setFixedWidth(38); } -void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget) +void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget, bool isEnabled) { QString style = QString(R"css( - background-color: black; + background-color: &&backgroundcolor&&; font-family: Open Sans; font-size: 16px; text-align: right; color: &&colorname&&; border: none; )css"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + if(isEnabled){ + style = style.replace(QString("&&backgroundcolor&&"), "black"); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + } + else{ + style = style.replace(QString("&&backgroundcolor&&"), "#18181d"); + style = style.replace(QString("&&colorname&&"), "#9c4600"); + } widget->setStyleSheet(style); widget->setFixedHeight(30); widget->setAlignment(Qt::AlignRight); From 1bcae9ad85da58ec73ba193a1a9bc76f00662b4a Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 15 Oct 2024 13:57:18 +0800 Subject: [PATCH 044/112] =?UTF-8?q?Wrap=20angle=20errors=20to=20[-=CF=80,?= =?UTF-8?q?=20=CF=80]=20range?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 027f9a4980..9d6fbffa70 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -438,17 +438,20 @@ int ADMTController::calculate_angle_error(vector angle_meas, vector Date: Tue, 15 Oct 2024 15:58:21 +0800 Subject: [PATCH 045/112] Update admtcontroller.cpp Updated Calculate_Angle_Error Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 100 +++++++++++++++------------- 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 9d6fbffa70..08779258ed 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -7,7 +7,7 @@ #include #include #include - +#include #include #include #include @@ -17,6 +17,7 @@ #include #include + static const size_t maxAttrSize = 512; using namespace scopy::admt; @@ -395,66 +396,73 @@ int ADMTController::linear_fit(vector x, vector y, double* slope return 0; } -int ADMTController::calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err, int cycleCount, int samplesPerCycle) +int ADMTController::calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err) { - // Adjust the expected angles based on samples per cycle and cycle count - vector expected_angles; - double increment = 360.0 / samplesPerCycle; + vector angle_meas_rad(angle_meas.size()); // radian converted input + vector angle_meas_rad_unwrap(angle_meas.size()); // unwrapped radian input + vector angle_fit(angle_meas.size()); // array for polynomial fitted data + vector x_data(angle_meas.size()); + double coeff_a, coeff_b; // coefficients generated by polynomial fitting + + // convert to radian + for (int i = 0; i < angle_meas_rad.size(); i++) + angle_meas_rad[i] = angle_meas[i] * M_PI / 180.0; - for (int cycle = 0; cycle < cycleCount; ++cycle) { - for (int sample = 0; sample < samplesPerCycle; ++sample) { - expected_angles.push_back((cycle * 360.0) + (sample * increment)); - } - } + // unwrap angle (extracted from decompiled Angle GSF Unit) + double num = 0.0; + angle_meas_rad_unwrap[0] = angle_meas_rad[0]; + for (int i = 1; i < angle_meas_rad.size(); i++) + { + double num2 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1]); + double num3 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] + M_PI * 2.0); + double num4 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] - M_PI * 2.0); + if (num3 < num2 && num3 < num4) + num += M_PI * 2.0; - // Ensure that the angle_meas and expected_angles are of the same size - if (angle_meas.size() != expected_angles.size()) { - return -1; // Handle size mismatch error + else if (num4 < num2 && num4 < num3) + num -= M_PI * 2.0; + + angle_meas_rad_unwrap[i] = angle_meas_rad[i] + num; } - vector angle_meas_rad(angle_meas.size()); // Convert measured angles to radians - vector expected_angles_rad(expected_angles.size()); // Convert expected angles to radians + // set initial point to zero + double offset = angle_meas_rad_unwrap[0]; + for (int i = 0; i < angle_meas_rad_unwrap.size(); ++i) + angle_meas_rad_unwrap[i] -= offset; - // Convert measured and expected angles to radians - for (int i = 0; i < angle_meas.size(); i++) { - angle_meas_rad[i] = angle_meas[i] * M_PI / 180.0; - expected_angles_rad[i] = expected_angles[i] * M_PI / 180.0; - } + /* Generate xdata for polynomial fitting */ + iota(x_data.begin(), x_data.end(), 1); - // Unwrap the measured angles (in radians) to remove any discontinuity - unwrapAngles(angle_meas_rad); + // linear angle fitting (generated coefficients not same with matlab and python) + // expecting 0.26 -0.26 + // getting ~0.27 ~-0.27 as of 4/2/2024 + /* input args: x, y, *slope, *intercept */ + linear_fit(x_data, angle_meas_rad_unwrap, &coeff_a, &coeff_b); - // Set the initial point to zero (optional, to normalize the measurement) - double offset = angle_meas_rad[0]; - for (int i = 0; i < angle_meas.size(); i++) { - angle_meas_rad[i] -= offset; + // generate data using coefficients from polynomial fitting + for (int i = 0; i < angle_fit.size(); i++) { + angle_fit[i] = coeff_a * x_data[i]; } - // Calculate the angle error using the expected angles (unwrap vs expected) - angle_error_ret.resize(angle_meas.size()); - for (int i = 0; i < angle_meas.size(); i++) { - angle_error_ret[i] = angle_meas_rad[i] - expected_angles_rad[i]; + // get angle error using pass by ref angle_error_ret + for (int i = 0; i < angle_error_ret.size(); i++) { + angle_error_ret[i] = angle_meas_rad_unwrap[i] - angle_fit[i]; + //cout << "angle_err_ret " << angle_error_ret[i] << "\n"; } - // Find the min/max error for offset correction + // Find the offset for error and subtract (using angle_error_ret) auto minmax = minmax_element(angle_error_ret.begin(), angle_error_ret.end()); - // double angle_err_offset = (*minmax.first + *minmax.second) / 2; + double angle_err_offset = (*minmax.first + *minmax.second) / 2; - // Wrap the angle errors to [-Ï€, Ï€] - for (int i = 0; i < angle_error_ret.size(); i++) { - angle_error_ret[i] = fmod(angle_error_ret[i] + M_PI, 2 * M_PI); - if (angle_error_ret[i] < 0) - angle_error_ret[i] += 2 * M_PI; - angle_error_ret[i] -= M_PI; // Wrap to [-Ï€, Ï€] - } + for (int i = 0; i < angle_error_ret.size(); i++) + angle_error_ret[i] -= angle_err_offset; - // // Convert angle errors back to degrees - // for (int i = 0; i < angle_error_ret.size(); i++) { - // angle_error_ret[i] *= (180.0 / M_PI); - // } + // Convert back to degrees (angle_error_ret) + for (int i = 0; i < angle_meas.size(); i++) + angle_error_ret[i] *= (180 / M_PI); // Find maximum absolute angle error - *max_angle_err = max(fabs(*minmax.first), fabs(*minmax.second)) * (180.0 / M_PI); + *max_angle_err = *minmax.second; return 0; } @@ -591,7 +599,7 @@ void ADMTController::getPreCalibrationFFT(const vector& PANG, vector angle_errors_pre(PANG.size()); // Calculate angle errors - calculate_angle_error(PANG, angle_errors_pre, &max_err_pre, cycleCount, samplesPerCycle); + calculate_angle_error(PANG, angle_errors_pre, &max_err_pre); // Store the calculated angle errors (angle_errors_pre) angleError = angle_errors_pre; @@ -636,7 +644,7 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, v vector angle_errors_post(updated_PANG.size()); // Calculate angle errors - calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post, cycleCount, samplesPerCycle); + calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post); // Corrected Error (angle_errors_post) correctedError = angle_errors_post; From 33f3a420f9b5cd0948f0632ad4f6a3d7b054b24e Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Wed, 16 Oct 2024 10:25:57 +0800 Subject: [PATCH 046/112] Update admtcontroller.cpp Adjusted FFT function to mostly reflect original C# code and implementation. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 63 ++++++++++++----------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 08779258ed..83b3816ce3 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -610,10 +610,10 @@ void ADMTController::getPreCalibrationFFT(const vector& PANG, vector PANG, int cycleCount, int samplesPerCycle){ @@ -656,47 +656,36 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, v FFTCorrectedErrorPhase = angle_errors_fft_phase_post; } -void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount) { - typedef complex cx; - - int L = angle_errors.size(); // Original signal length (L) - int N = pow(2, ceil(log2(L))); // Ensure size is a power of 2 (padding if necessary) - - vector fft_in(N, cx(0, 0)); // Input signal (zero-padded if necessary) - vector fft_out(N); // Output signal (complex) - - // Format angle errors into the fft_in vector - for (int i = 0; i < L; i++) { - fft_in[i] = cx(angle_errors[i], 0); +void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase) { + // Step 1: Prepare the input for FFT, converting real numbers to complex (real, imaginary=0) + std::vector> complex_input(angle_errors.size()); + + for (size_t i = 0; i < angle_errors.size(); ++i) { + complex_input[i] = std::complex(angle_errors[i], 0.0); } - // Perform FFT - fft(fft_in.data(), fft_out.data(), log2(N)); + // Step 2: Perform FFT (this assumes an FFT function you have implemented) + std::vector> fft_result = FFT(complex_input); // FFT function must be defined elsewhere - // Temporary vectors to store magnitude and phase - vector angle_errors_fft_temp(N); - vector angle_errors_fft_phase_temp(N); + size_t N = fft_result.size(); - // Calculate magnitude and phase for all values - for (int i = 0; i < N; i++) { - // Magnitude: Normalize by L (original signal length) - angle_errors_fft_temp[i] = abs(fft_out[i]) * 2.0 / L; - angle_errors_fft_phase_temp[i] = atan2(fft_out[i].imag(), fft_out[i].real()); - } + // Step 3: Resize the output vectors to match the expected size (N / 2 + 1 for positive frequencies) + angle_errors_fft.resize(N / 2 + 1); + angle_errors_fft_phase.resize(N / 2 + 1); - // Prepare vectors for upper half of FFT (positive frequencies) - vector angle_errors_fft_upper_half(N / 2); - vector angle_errors_fft_phase_upper_half(N / 2); + // Step 4: Compute magnitudes and phases from the FFT results, scaling appropriately + for (size_t k = 0; k <= N / 2; ++k) { + // Magnitude: sqrt(real^2 + imag^2) + angle_errors_fft[k] = 2.0 * std::abs(fft_result[k]); // Scaling magnitude by 2 - // Get upper half only (due to symmetry in real-valued signal FFT) - for (int i = 0; i < N / 2; i++) { - angle_errors_fft_upper_half[i] = angle_errors_fft_temp[i]; - angle_errors_fft_phase_upper_half[i] = angle_errors_fft_phase_temp[i]; + // Phase: atan2(imaginary, real) + angle_errors_fft_phase[k] = std::atan2(fft_result[k].imag(), fft_result[k].real()) * 180.0 / M_PI; // Convert to degrees } - // Resize final vectors based on cycle count (if needed) - angle_errors_fft = angle_errors_fft_upper_half; - angle_errors_fft_phase = angle_errors_fft_phase_upper_half; + // Optional: Normalize phases to the [0, 360] degree range + for (auto& phase : angle_errors_fft_phase) { + if (phase < 0) phase += 360.0; // Wrap phase to be positive, within [0, 360] + } } void ADMTController::computeSineCosineOfAngles(const vector& angles) { From a8d75ac7e3ab70139487118310fb6d0a20343def Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 16 Oct 2024 10:44:21 +0800 Subject: [PATCH 047/112] Refactor angle error calculations and FFT in ADMTController Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 4 ++-- plugins/admt/src/admtcontroller.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 6eba95b664..93d8cc5c16 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -209,9 +209,9 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject unsigned int bitReverse(unsigned int x, int log2n); template void fft(Iter_T a, Iter_T b, int log2n); - void performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount); + void performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase); int linear_fit(vector x, vector y, double* slope, double* intercept); - int calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err, int cycleCount, int samplesPerCycle); + int calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err); void getPreCalibrationFFT(const vector& PANG, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre, int cycleCount, int samplesPerCycle); void getPostCalibrationFFT(const vector& updated_PANG, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post, int cycleCount, int samplesPerCycle); }; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 83b3816ce3..8fc674a8c7 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -604,7 +604,7 @@ void ADMTController::getPreCalibrationFFT(const vector& PANG, vector& updated_PANG, v correctedError = angle_errors_post; // Perform FFT on post-calibration angle errors - performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post, cycleCount); + performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post); // FFT Corrected Error (angle_errors_fft_post) FFTCorrectedErrorMagnitude = angle_errors_fft_post; // FFT Corrected Error Phase (angle_errors_fft_phase_post) @@ -665,7 +665,7 @@ void ADMTController::performFFT(const vector& angle_errors, vector> fft_result = FFT(complex_input); // FFT function must be defined elsewhere + std::vector> fft_result = FFT(complex_input); size_t N = fft_result.size(); From d065bf9bde5aa513edc4c0b76e1fcb690fb3e7b2 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Wed, 16 Oct 2024 10:48:51 +0800 Subject: [PATCH 048/112] Update admtcontroller.cpp adjusted code for handing FFT to reuse old function available. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 8fc674a8c7..0dfaaca4c7 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -657,29 +657,30 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, v } void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase) { - // Step 1: Prepare the input for FFT, converting real numbers to complex (real, imaginary=0) - std::vector> complex_input(angle_errors.size()); + int n = angle_errors.size(); + int log2n = std::log2(n); + + // Step 1: Prepare the input for FFT, converting real numbers to complex (real, imaginary=0) + std::vector> complex_input(n), complex_output(n); - for (size_t i = 0; i < angle_errors.size(); ++i) { + for (int i = 0; i < n; ++i) { complex_input[i] = std::complex(angle_errors[i], 0.0); } - // Step 2: Perform FFT (this assumes an FFT function you have implemented) - std::vector> fft_result = FFT(complex_input); - - size_t N = fft_result.size(); + // Step 2: Perform FFT using your provided 'fft' function + fft(complex_input.begin(), complex_output.begin(), log2n); // Step 3: Resize the output vectors to match the expected size (N / 2 + 1 for positive frequencies) - angle_errors_fft.resize(N / 2 + 1); - angle_errors_fft_phase.resize(N / 2 + 1); + angle_errors_fft.resize(n / 2 + 1); + angle_errors_fft_phase.resize(n / 2 + 1); - // Step 4: Compute magnitudes and phases from the FFT results, scaling appropriately - for (size_t k = 0; k <= N / 2; ++k) { + // Step 4: Compute magnitudes and phases from the FFT results + for (int k = 0; k <= n / 2; ++k) { // Magnitude: sqrt(real^2 + imag^2) - angle_errors_fft[k] = 2.0 * std::abs(fft_result[k]); // Scaling magnitude by 2 + angle_errors_fft[k] = 2.0 * std::abs(complex_output[k]); // Scaling magnitude by 2 // Phase: atan2(imaginary, real) - angle_errors_fft_phase[k] = std::atan2(fft_result[k].imag(), fft_result[k].real()) * 180.0 / M_PI; // Convert to degrees + angle_errors_fft_phase[k] = std::atan2(complex_output[k].imag(), complex_output[k].real()) * 180.0 / M_PI; // Convert to degrees } // Optional: Normalize phases to the [0, 360] degree range From 73dca00032d6778dfcd2697575711e0293e823d3 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Wed, 16 Oct 2024 12:32:04 +0800 Subject: [PATCH 049/112] Update admtcontroller.cpp code cleanup Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 0dfaaca4c7..4708220557 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -630,7 +630,7 @@ void ADMTController::postcalibrate(vector PANG, int cycleCount, int samp rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); } - // Declare vectors for pre-calibration FFT results + // Declare vectors for post-calibration FFT results angle_errors_fft_post = vector(PANG.size() / 2); angle_errors_fft_phase_post = vector(PANG.size() / 2); @@ -650,9 +650,9 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, v // Perform FFT on post-calibration angle errors performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post); - // FFT Corrected Error (angle_errors_fft_post) + + // Store the FFT Angle Error Magnitude and Phase FFTCorrectedErrorMagnitude = angle_errors_fft_post; - // FFT Corrected Error Phase (angle_errors_fft_phase_post) FFTCorrectedErrorPhase = angle_errors_fft_phase_post; } From c04c573e7a5ef167deaac5d0e14028134a6c61dd Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Wed, 16 Oct 2024 12:50:17 +0800 Subject: [PATCH 050/112] Update admtcontroller.cpp Refactored calibrate to retain implementation based on C# code. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 126 ++++++++++++++-------------- 1 file changed, 65 insertions(+), 61 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 4708220557..beac44824a 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -485,24 +485,27 @@ void ADMTController::unwrapAngles(vector& angles_rad) { } QString ADMTController::calibrate(vector PANG, int cycleCount, int samplesPerCycle) { - int CCW = 0, circshiftData = 0; - QString result = ""; + // Initialize variables + int CCW = 0; // Counterclockwise flag + int circshiftData = 0; // Circular shift flag + QString result; - /* Check CCW flag to know if array is to be reversed */ - if (CCW) + // Check CCW flag to know if the array needs to be reversed + if (CCW) { reverse(PANG.begin(), PANG.end()); + } - /* Randomize starting point of array */ + // Randomize starting point of the array if needed if (circshiftData) { int shift = rand() % PANG.size(); rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); } // Declare vectors for pre-calibration FFT results - angle_errors_fft_pre = vector(PANG.size() / 2); - angle_errors_fft_phase_pre = vector(PANG.size() / 2); + vector angle_errors_fft_pre(PANG.size() / 2); + vector angle_errors_fft_phase_pre(PANG.size() / 2); - // Call the new function for pre-calibration FFT + // Call the existing FFT function for pre-calibration getPreCalibrationFFT(PANG, angle_errors_fft_pre, angle_errors_fft_phase_pre, cycleCount, samplesPerCycle); // Extract HMag parameters @@ -511,35 +514,34 @@ QString ADMTController::calibrate(vector PANG, int cycleCount, int sampl double H3Mag = angle_errors_fft_pre[3 * cycleCount + 1]; double H8Mag = angle_errors_fft_pre[8 * cycleCount + 1]; - /* Display HMAG values */ - result.append("H1Mag = " + QString::number(H1Mag) + "\n"); - result.append("H2Mag = " + QString::number(H2Mag) + "\n"); - result.append("H3Mag = " + QString::number(H3Mag) + "\n"); - result.append("H8Mag = " + QString::number(H8Mag) + "\n"); - - // Extract HPhase parameters - double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycleCount + 1]); - double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycleCount + 1]); - double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycleCount + 1]); - double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycleCount + 1]); - - /* Display HPHASE values */ - result.append("H1Phase = " + QString::number(H1Phase) + "\n"); - result.append("H2Phase = " + QString::number(H2Phase) + "\n"); - result.append("H3Phase = " + QString::number(H3Phase) + "\n"); - result.append("H8Phase = " + QString::number(H8Phase) + "\n"); - - double H1 = H1Mag * cos(M_PI / 180 * (H1Phase)); - double H2 = H2Mag * cos(M_PI / 180 * (H2Phase)); - double H3 = H3Mag * cos(M_PI / 180 * (H3Phase)); - double H8 = H8Mag * cos(M_PI / 180 * (H8Phase)); - + // // Display HMAG values + // result.append("H1Mag = " + QString::number(H1Mag) + "\n"); + // result.append("H2Mag = " + QString::number(H2Mag) + "\n"); + // result.append("H3Mag = " + QString::number(H3Mag) + "\n"); + // result.append("H8Mag = " + QString::number(H8Mag) + "\n"); + + // Extract HPhase parameters and convert to degrees + double H1Phase = (180 / M_PI) * angle_errors_fft_phase_pre[cycleCount + 1]; + double H2Phase = (180 / M_PI) * angle_errors_fft_phase_pre[2 * cycleCount + 1]; + double H3Phase = (180 / M_PI) * angle_errors_fft_phase_pre[3 * cycleCount + 1]; + double H8Phase = (180 / M_PI) * angle_errors_fft_phase_pre[8 * cycleCount + 1]; + + // // Display HPHASE values + // result.append("H1Phase = " + QString::number(H1Phase) + "\n"); + // result.append("H2Phase = " + QString::number(H2Phase) + "\n"); + // result.append("H3Phase = " + QString::number(H3Phase) + "\n"); + // result.append("H8Phase = " + QString::number(H8Phase) + "\n"); + + // Compute initial errors + double H1 = H1Mag * cos(M_PI / 180 * H1Phase); + double H2 = H2Mag * cos(M_PI / 180 * H2Phase); + double H3 = H3Mag * cos(M_PI / 180 * H3Phase); + double H8 = H8Mag * cos(M_PI / 180 * H8Phase); + double init_err = H1 + H2 + H3 + H8; double init_angle = PANG[1] - init_err; - - double H1PHcor, H2PHcor, H3PHcor, H8PHcor; - /* Counterclockwise, slope of error FIT is negative */ + // Phase correction for counterclockwise or clockwise direction if (CCW) { H1Phase *= -1; H2Phase *= -1; @@ -547,39 +549,41 @@ QString ADMTController::calibrate(vector PANG, int cycleCount, int sampl H8Phase *= -1; } - /* Clockwise */ - H1PHcor = H1Phase - (1 * init_angle - 90); - H2PHcor = H2Phase - (2 * init_angle - 90); - H3PHcor = H3Phase - (3 * init_angle - 90); - H8PHcor = H8Phase - (8 * init_angle - 90); + // Apply phase correction + double H1PHcor = H1Phase - (1 * init_angle - 90); + double H2PHcor = H2Phase - (2 * init_angle - 90); + double H3PHcor = H3Phase - (3 * init_angle - 90); + double H8PHcor = H8Phase - (8 * init_angle - 90); - /* Get modulo from 360 */ - H1PHcor = (int)H1PHcor % 360; - H2PHcor = (int)H2PHcor % 360; - H3PHcor = (int)H3PHcor % 360; - H8PHcor = (int)H8PHcor % 360; + // Get modulo from 360 + H1PHcor = fmod(H1PHcor, 360); + H2PHcor = fmod(H2PHcor, 360); + H3PHcor = fmod(H3PHcor, 360); + H8PHcor = fmod(H8PHcor, 360); // HMag Scaling - H1Mag = H1Mag * 0.6072; - H2Mag = H2Mag * 0.6072; - H3Mag = H3Mag * 0.6072; - H8Mag = H8Mag * 0.6072; + const double scalingFactor = 0.6072; + H1Mag *= scalingFactor; + H2Mag *= scalingFactor; + H3Mag *= scalingFactor; + H8Mag *= scalingFactor; - // Derive register compatible HMAG values + // Derive register-compatible HMAG values double mag_scale_factor_11bit = 11.2455 / (1 << 11); double mag_scale_factor_8bit = 1.40076 / (1 << 8); - HAR_MAG_1 = (int)(H1Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit - HAR_MAG_2 = (int)(H2Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit - HAR_MAG_3 = (int)(H3Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit - HAR_MAG_8 = (int)(H8Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit - - // Derive register compatible HPHASE values - double pha_scale_factor_12bit = 360.0 / (1 << 12); // in Deg - HAR_PHASE_1 = (int)(H1PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - HAR_PHASE_2 = (int)(H2PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - HAR_PHASE_3 = (int)(H3PHcor / pha_scale_factor_12bit) & (0xFFF);// 12bit number - HAR_PHASE_8 = (int)(H8PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - + HAR_MAG_1 = static_cast(H1Mag / mag_scale_factor_11bit) & 0x7FF; // 11 bit + HAR_MAG_2 = static_cast(H2Mag / mag_scale_factor_11bit) & 0x7FF; // 11 bit + HAR_MAG_3 = static_cast(H3Mag / mag_scale_factor_8bit) & 0xFF; // 8 bit + HAR_MAG_8 = static_cast(H8Mag / mag_scale_factor_8bit) & 0xFF; // 8 bit + + // Derive register-compatible HPHASE values + double pha_scale_factor_12bit = 360.0 / (1 << 12); // in degrees + HAR_PHASE_1 = static_cast(H1PHcor / pha_scale_factor_12bit) & 0xFFF; // 12 bit + HAR_PHASE_2 = static_cast(H2PHcor / pha_scale_factor_12bit) & 0xFFF; // 12 bit + HAR_PHASE_3 = static_cast(H3PHcor / pha_scale_factor_12bit) & 0xFFF; // 12 bit + HAR_PHASE_8 = static_cast(H8PHcor / pha_scale_factor_12bit) & 0xFFF; // 12 bit + + // Append results to the output result.append("HMAG1: " + QString::number(HAR_MAG_1) + "\n"); result.append("HMAG2: " + QString::number(HAR_MAG_2) + "\n"); result.append("HMAG3: " + QString::number(HAR_MAG_3) + "\n"); From 6ebd3a910180783f3789171da16f6e9fa9e442d0 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 17 Oct 2024 16:28:31 +0800 Subject: [PATCH 051/112] Revert "Update admtcontroller.cpp" This reverts commit c0e5839492ca9d059682c000dc041a0f53c626b3. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 126 ++++++++++++++-------------- 1 file changed, 61 insertions(+), 65 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index beac44824a..4708220557 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -485,27 +485,24 @@ void ADMTController::unwrapAngles(vector& angles_rad) { } QString ADMTController::calibrate(vector PANG, int cycleCount, int samplesPerCycle) { - // Initialize variables - int CCW = 0; // Counterclockwise flag - int circshiftData = 0; // Circular shift flag - QString result; + int CCW = 0, circshiftData = 0; + QString result = ""; - // Check CCW flag to know if the array needs to be reversed - if (CCW) { + /* Check CCW flag to know if array is to be reversed */ + if (CCW) reverse(PANG.begin(), PANG.end()); - } - // Randomize starting point of the array if needed + /* Randomize starting point of array */ if (circshiftData) { int shift = rand() % PANG.size(); rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); } // Declare vectors for pre-calibration FFT results - vector angle_errors_fft_pre(PANG.size() / 2); - vector angle_errors_fft_phase_pre(PANG.size() / 2); + angle_errors_fft_pre = vector(PANG.size() / 2); + angle_errors_fft_phase_pre = vector(PANG.size() / 2); - // Call the existing FFT function for pre-calibration + // Call the new function for pre-calibration FFT getPreCalibrationFFT(PANG, angle_errors_fft_pre, angle_errors_fft_phase_pre, cycleCount, samplesPerCycle); // Extract HMag parameters @@ -514,34 +511,35 @@ QString ADMTController::calibrate(vector PANG, int cycleCount, int sampl double H3Mag = angle_errors_fft_pre[3 * cycleCount + 1]; double H8Mag = angle_errors_fft_pre[8 * cycleCount + 1]; - // // Display HMAG values - // result.append("H1Mag = " + QString::number(H1Mag) + "\n"); - // result.append("H2Mag = " + QString::number(H2Mag) + "\n"); - // result.append("H3Mag = " + QString::number(H3Mag) + "\n"); - // result.append("H8Mag = " + QString::number(H8Mag) + "\n"); - - // Extract HPhase parameters and convert to degrees - double H1Phase = (180 / M_PI) * angle_errors_fft_phase_pre[cycleCount + 1]; - double H2Phase = (180 / M_PI) * angle_errors_fft_phase_pre[2 * cycleCount + 1]; - double H3Phase = (180 / M_PI) * angle_errors_fft_phase_pre[3 * cycleCount + 1]; - double H8Phase = (180 / M_PI) * angle_errors_fft_phase_pre[8 * cycleCount + 1]; - - // // Display HPHASE values - // result.append("H1Phase = " + QString::number(H1Phase) + "\n"); - // result.append("H2Phase = " + QString::number(H2Phase) + "\n"); - // result.append("H3Phase = " + QString::number(H3Phase) + "\n"); - // result.append("H8Phase = " + QString::number(H8Phase) + "\n"); - - // Compute initial errors - double H1 = H1Mag * cos(M_PI / 180 * H1Phase); - double H2 = H2Mag * cos(M_PI / 180 * H2Phase); - double H3 = H3Mag * cos(M_PI / 180 * H3Phase); - double H8 = H8Mag * cos(M_PI / 180 * H8Phase); - + /* Display HMAG values */ + result.append("H1Mag = " + QString::number(H1Mag) + "\n"); + result.append("H2Mag = " + QString::number(H2Mag) + "\n"); + result.append("H3Mag = " + QString::number(H3Mag) + "\n"); + result.append("H8Mag = " + QString::number(H8Mag) + "\n"); + + // Extract HPhase parameters + double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycleCount + 1]); + double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycleCount + 1]); + double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycleCount + 1]); + double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycleCount + 1]); + + /* Display HPHASE values */ + result.append("H1Phase = " + QString::number(H1Phase) + "\n"); + result.append("H2Phase = " + QString::number(H2Phase) + "\n"); + result.append("H3Phase = " + QString::number(H3Phase) + "\n"); + result.append("H8Phase = " + QString::number(H8Phase) + "\n"); + + double H1 = H1Mag * cos(M_PI / 180 * (H1Phase)); + double H2 = H2Mag * cos(M_PI / 180 * (H2Phase)); + double H3 = H3Mag * cos(M_PI / 180 * (H3Phase)); + double H8 = H8Mag * cos(M_PI / 180 * (H8Phase)); + double init_err = H1 + H2 + H3 + H8; double init_angle = PANG[1] - init_err; + + double H1PHcor, H2PHcor, H3PHcor, H8PHcor; - // Phase correction for counterclockwise or clockwise direction + /* Counterclockwise, slope of error FIT is negative */ if (CCW) { H1Phase *= -1; H2Phase *= -1; @@ -549,41 +547,39 @@ QString ADMTController::calibrate(vector PANG, int cycleCount, int sampl H8Phase *= -1; } - // Apply phase correction - double H1PHcor = H1Phase - (1 * init_angle - 90); - double H2PHcor = H2Phase - (2 * init_angle - 90); - double H3PHcor = H3Phase - (3 * init_angle - 90); - double H8PHcor = H8Phase - (8 * init_angle - 90); + /* Clockwise */ + H1PHcor = H1Phase - (1 * init_angle - 90); + H2PHcor = H2Phase - (2 * init_angle - 90); + H3PHcor = H3Phase - (3 * init_angle - 90); + H8PHcor = H8Phase - (8 * init_angle - 90); - // Get modulo from 360 - H1PHcor = fmod(H1PHcor, 360); - H2PHcor = fmod(H2PHcor, 360); - H3PHcor = fmod(H3PHcor, 360); - H8PHcor = fmod(H8PHcor, 360); + /* Get modulo from 360 */ + H1PHcor = (int)H1PHcor % 360; + H2PHcor = (int)H2PHcor % 360; + H3PHcor = (int)H3PHcor % 360; + H8PHcor = (int)H8PHcor % 360; // HMag Scaling - const double scalingFactor = 0.6072; - H1Mag *= scalingFactor; - H2Mag *= scalingFactor; - H3Mag *= scalingFactor; - H8Mag *= scalingFactor; + H1Mag = H1Mag * 0.6072; + H2Mag = H2Mag * 0.6072; + H3Mag = H3Mag * 0.6072; + H8Mag = H8Mag * 0.6072; - // Derive register-compatible HMAG values + // Derive register compatible HMAG values double mag_scale_factor_11bit = 11.2455 / (1 << 11); double mag_scale_factor_8bit = 1.40076 / (1 << 8); - HAR_MAG_1 = static_cast(H1Mag / mag_scale_factor_11bit) & 0x7FF; // 11 bit - HAR_MAG_2 = static_cast(H2Mag / mag_scale_factor_11bit) & 0x7FF; // 11 bit - HAR_MAG_3 = static_cast(H3Mag / mag_scale_factor_8bit) & 0xFF; // 8 bit - HAR_MAG_8 = static_cast(H8Mag / mag_scale_factor_8bit) & 0xFF; // 8 bit - - // Derive register-compatible HPHASE values - double pha_scale_factor_12bit = 360.0 / (1 << 12); // in degrees - HAR_PHASE_1 = static_cast(H1PHcor / pha_scale_factor_12bit) & 0xFFF; // 12 bit - HAR_PHASE_2 = static_cast(H2PHcor / pha_scale_factor_12bit) & 0xFFF; // 12 bit - HAR_PHASE_3 = static_cast(H3PHcor / pha_scale_factor_12bit) & 0xFFF; // 12 bit - HAR_PHASE_8 = static_cast(H8PHcor / pha_scale_factor_12bit) & 0xFFF; // 12 bit - - // Append results to the output + HAR_MAG_1 = (int)(H1Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit + HAR_MAG_2 = (int)(H2Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit + HAR_MAG_3 = (int)(H3Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit + HAR_MAG_8 = (int)(H8Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit + + // Derive register compatible HPHASE values + double pha_scale_factor_12bit = 360.0 / (1 << 12); // in Deg + HAR_PHASE_1 = (int)(H1PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + HAR_PHASE_2 = (int)(H2PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + HAR_PHASE_3 = (int)(H3PHcor / pha_scale_factor_12bit) & (0xFFF);// 12bit number + HAR_PHASE_8 = (int)(H8PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + result.append("HMAG1: " + QString::number(HAR_MAG_1) + "\n"); result.append("HMAG2: " + QString::number(HAR_MAG_2) + "\n"); result.append("HMAG3: " + QString::number(HAR_MAG_3) + "\n"); From 71deaee58b9fea5e78339d362bc13f7a556736a7 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 17 Oct 2024 16:28:56 +0800 Subject: [PATCH 052/112] Revert "Update admtcontroller.cpp" This reverts commit 0e66c72e51c0da4e7abf9efe7a737ee5a43b9435. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 4708220557..0dfaaca4c7 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -630,7 +630,7 @@ void ADMTController::postcalibrate(vector PANG, int cycleCount, int samp rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); } - // Declare vectors for post-calibration FFT results + // Declare vectors for pre-calibration FFT results angle_errors_fft_post = vector(PANG.size() / 2); angle_errors_fft_phase_post = vector(PANG.size() / 2); @@ -650,9 +650,9 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, v // Perform FFT on post-calibration angle errors performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post); - - // Store the FFT Angle Error Magnitude and Phase + // FFT Corrected Error (angle_errors_fft_post) FFTCorrectedErrorMagnitude = angle_errors_fft_post; + // FFT Corrected Error Phase (angle_errors_fft_phase_post) FFTCorrectedErrorPhase = angle_errors_fft_phase_post; } From 8b03765f7fdc18d3021cd72997cb5ed17a16fed3 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 17 Oct 2024 16:29:00 +0800 Subject: [PATCH 053/112] Revert "Update admtcontroller.cpp" This reverts commit b2ecf9ffa06a53b13343138fd0a7ef47d1af29a3. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 0dfaaca4c7..8fc674a8c7 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -657,30 +657,29 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, v } void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase) { - int n = angle_errors.size(); - int log2n = std::log2(n); - - // Step 1: Prepare the input for FFT, converting real numbers to complex (real, imaginary=0) - std::vector> complex_input(n), complex_output(n); + // Step 1: Prepare the input for FFT, converting real numbers to complex (real, imaginary=0) + std::vector> complex_input(angle_errors.size()); - for (int i = 0; i < n; ++i) { + for (size_t i = 0; i < angle_errors.size(); ++i) { complex_input[i] = std::complex(angle_errors[i], 0.0); } - // Step 2: Perform FFT using your provided 'fft' function - fft(complex_input.begin(), complex_output.begin(), log2n); + // Step 2: Perform FFT (this assumes an FFT function you have implemented) + std::vector> fft_result = FFT(complex_input); + + size_t N = fft_result.size(); // Step 3: Resize the output vectors to match the expected size (N / 2 + 1 for positive frequencies) - angle_errors_fft.resize(n / 2 + 1); - angle_errors_fft_phase.resize(n / 2 + 1); + angle_errors_fft.resize(N / 2 + 1); + angle_errors_fft_phase.resize(N / 2 + 1); - // Step 4: Compute magnitudes and phases from the FFT results - for (int k = 0; k <= n / 2; ++k) { + // Step 4: Compute magnitudes and phases from the FFT results, scaling appropriately + for (size_t k = 0; k <= N / 2; ++k) { // Magnitude: sqrt(real^2 + imag^2) - angle_errors_fft[k] = 2.0 * std::abs(complex_output[k]); // Scaling magnitude by 2 + angle_errors_fft[k] = 2.0 * std::abs(fft_result[k]); // Scaling magnitude by 2 // Phase: atan2(imaginary, real) - angle_errors_fft_phase[k] = std::atan2(complex_output[k].imag(), complex_output[k].real()) * 180.0 / M_PI; // Convert to degrees + angle_errors_fft_phase[k] = std::atan2(fft_result[k].imag(), fft_result[k].real()) * 180.0 / M_PI; // Convert to degrees } // Optional: Normalize phases to the [0, 360] degree range From f134c33afcdd7cd9253d71e336181fa0bcb6b58f Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 17 Oct 2024 16:29:05 +0800 Subject: [PATCH 054/112] Revert "Refactor angle error calculations and FFT in ADMTController" This reverts commit 5d57caa087eb2d72f13d2fdf1342ae4cc9bef94f. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 4 ++-- plugins/admt/src/admtcontroller.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 93d8cc5c16..6eba95b664 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -209,9 +209,9 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject unsigned int bitReverse(unsigned int x, int log2n); template void fft(Iter_T a, Iter_T b, int log2n); - void performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase); + void performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount); int linear_fit(vector x, vector y, double* slope, double* intercept); - int calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err); + int calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err, int cycleCount, int samplesPerCycle); void getPreCalibrationFFT(const vector& PANG, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre, int cycleCount, int samplesPerCycle); void getPostCalibrationFFT(const vector& updated_PANG, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post, int cycleCount, int samplesPerCycle); }; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 8fc674a8c7..83b3816ce3 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -604,7 +604,7 @@ void ADMTController::getPreCalibrationFFT(const vector& PANG, vector& updated_PANG, v correctedError = angle_errors_post; // Perform FFT on post-calibration angle errors - performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post); + performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post, cycleCount); // FFT Corrected Error (angle_errors_fft_post) FFTCorrectedErrorMagnitude = angle_errors_fft_post; // FFT Corrected Error Phase (angle_errors_fft_phase_post) @@ -665,7 +665,7 @@ void ADMTController::performFFT(const vector& angle_errors, vector> fft_result = FFT(complex_input); + std::vector> fft_result = FFT(complex_input); // FFT function must be defined elsewhere size_t N = fft_result.size(); From 5b27bfc3adeb7cecdbfeb170541b62a72cdfdd6d Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 17 Oct 2024 16:29:11 +0800 Subject: [PATCH 055/112] Revert "Update admtcontroller.cpp" This reverts commit fe18eacfe674b3eb96a7b3202b0b431bfe7b7d2e. Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 63 +++++++++++++++++------------ 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 83b3816ce3..08779258ed 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -610,10 +610,10 @@ void ADMTController::getPreCalibrationFFT(const vector& PANG, vector PANG, int cycleCount, int samplesPerCycle){ @@ -656,36 +656,47 @@ void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, v FFTCorrectedErrorPhase = angle_errors_fft_phase_post; } -void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase) { - // Step 1: Prepare the input for FFT, converting real numbers to complex (real, imaginary=0) - std::vector> complex_input(angle_errors.size()); - - for (size_t i = 0; i < angle_errors.size(); ++i) { - complex_input[i] = std::complex(angle_errors[i], 0.0); - } +void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount) { + typedef complex cx; - // Step 2: Perform FFT (this assumes an FFT function you have implemented) - std::vector> fft_result = FFT(complex_input); // FFT function must be defined elsewhere + int L = angle_errors.size(); // Original signal length (L) + int N = pow(2, ceil(log2(L))); // Ensure size is a power of 2 (padding if necessary) - size_t N = fft_result.size(); + vector fft_in(N, cx(0, 0)); // Input signal (zero-padded if necessary) + vector fft_out(N); // Output signal (complex) - // Step 3: Resize the output vectors to match the expected size (N / 2 + 1 for positive frequencies) - angle_errors_fft.resize(N / 2 + 1); - angle_errors_fft_phase.resize(N / 2 + 1); + // Format angle errors into the fft_in vector + for (int i = 0; i < L; i++) { + fft_in[i] = cx(angle_errors[i], 0); + } - // Step 4: Compute magnitudes and phases from the FFT results, scaling appropriately - for (size_t k = 0; k <= N / 2; ++k) { - // Magnitude: sqrt(real^2 + imag^2) - angle_errors_fft[k] = 2.0 * std::abs(fft_result[k]); // Scaling magnitude by 2 + // Perform FFT + fft(fft_in.data(), fft_out.data(), log2(N)); - // Phase: atan2(imaginary, real) - angle_errors_fft_phase[k] = std::atan2(fft_result[k].imag(), fft_result[k].real()) * 180.0 / M_PI; // Convert to degrees + // Temporary vectors to store magnitude and phase + vector angle_errors_fft_temp(N); + vector angle_errors_fft_phase_temp(N); + + // Calculate magnitude and phase for all values + for (int i = 0; i < N; i++) { + // Magnitude: Normalize by L (original signal length) + angle_errors_fft_temp[i] = abs(fft_out[i]) * 2.0 / L; + angle_errors_fft_phase_temp[i] = atan2(fft_out[i].imag(), fft_out[i].real()); } - // Optional: Normalize phases to the [0, 360] degree range - for (auto& phase : angle_errors_fft_phase) { - if (phase < 0) phase += 360.0; // Wrap phase to be positive, within [0, 360] + // Prepare vectors for upper half of FFT (positive frequencies) + vector angle_errors_fft_upper_half(N / 2); + vector angle_errors_fft_phase_upper_half(N / 2); + + // Get upper half only (due to symmetry in real-valued signal FFT) + for (int i = 0; i < N / 2; i++) { + angle_errors_fft_upper_half[i] = angle_errors_fft_temp[i]; + angle_errors_fft_phase_upper_half[i] = angle_errors_fft_phase_temp[i]; } + + // Resize final vectors based on cycle count (if needed) + angle_errors_fft = angle_errors_fft_upper_half; + angle_errors_fft_phase = angle_errors_fft_phase_upper_half; } void ADMTController::computeSineCosineOfAngles(const vector& angles) { From 9111cf5e7fdcf06431ab8a97b05b125ec2f0dd32 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 22 Oct 2024 11:53:56 +0800 Subject: [PATCH 056/112] admt: Fixed admtcontroller.h Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 6eba95b664..afe71319ae 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -211,7 +211,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject void fft(Iter_T a, Iter_T b, int log2n); void performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount); int linear_fit(vector x, vector y, double* slope, double* intercept); - int calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err, int cycleCount, int samplesPerCycle); + int calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err); void getPreCalibrationFFT(const vector& PANG, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre, int cycleCount, int samplesPerCycle); void getPostCalibrationFFT(const vector& updated_PANG, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post, int cycleCount, int samplesPerCycle); }; From 3d28246e440118501918dfe2000a2bf5929f27e5 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 30 Oct 2024 11:21:47 +0800 Subject: [PATCH 057/112] admt: Adjusted UI to hide and show specific fault registers based on sequence mode Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 2 + plugins/admt/src/harmoniccalibration.cpp | 52 +++++++++++++++---- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index a991b3d6b8..cfdbe0aa96 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -216,6 +216,8 @@ public Q_SLOTS: void displayCalculatedCoeff(); void toggleMotorControls(bool value); void clearCalibrationSamples(); + void updateSequenceWidget(); + void toggleFaultRegisterMode(int mode); QTimer *timer, *calibrationTimer, *utilityTimer; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 178e2bd3c0..52de5698e2 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -53,6 +53,7 @@ static const QPen sinePen(sineColor); static const QPen cosinePen(cosineColor); static map deviceRegisterMap; +static map generalRegisterMap; static QString deviceName = ""; static QString deviceType = ""; static bool is5V = false; @@ -420,7 +421,12 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 1) { calibrationTimer->start(calibrationTimerRate); } else { calibrationTimer->stop(); } - if(index == 2) { utilityTimer->start(utilityTimerRate); } + if(index == 2) // Utility Tab + { + utilityTimer->start(utilityTimerRate); + readSequence(); + toggleFaultRegisterMode(generalRegisterMap.at("Sequence Type")); + } else { utilityTimer->stop(); } }); } @@ -1692,6 +1698,28 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() return tool; } +void HarmonicCalibration::toggleFaultRegisterMode(int mode) +{ + switch(mode){ + case 0: + AFEDIAGStatusLED->hide(); + OscillatorDriftStatusLED->hide(); + AngleCrossCheckStatusLED->hide(); + TurnCountSensorLevelsStatusLED->hide(); + MTDIAGStatusLED->hide(); + SequencerWatchdogStatusLED->hide(); + break; + case 1: + AFEDIAGStatusLED->show(); + OscillatorDriftStatusLED->show(); + AngleCrossCheckStatusLED->show(); + TurnCountSensorLevelsStatusLED->show(); + MTDIAGStatusLED->show(); + SequencerWatchdogStatusLED->show(); + break; + } +} + void HarmonicCalibration::toggleMotorControls(bool value) { motorMaxVelocitySpinBox->setEnabled(value); @@ -1981,16 +2009,9 @@ void HarmonicCalibration::readSequence(){ if(changeCNVPage(generalRegisterPage, "GENERAL")){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ if(*generalRegValue != UINT32_MAX){ - std::map generalBitMapping = m_admtController->getGeneralRegisterBitMapping(static_cast(*generalRegValue)); + generalRegisterMap = m_admtController->getGeneralRegisterBitMapping(static_cast(*generalRegValue)); - if(generalBitMapping.at("Sequence Type") == -1){ sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); } - else{ sequenceTypeMenuCombo->combo()->setCurrentIndex(sequenceTypeMenuCombo->combo()->findData(generalBitMapping.at("Sequence Type"))); } - conversionTypeMenuCombo->combo()->setCurrentIndex(conversionTypeMenuCombo->combo()->findData(generalBitMapping.at("Conversion Type"))); - // cnvSourceMenuCombo->combo()->setCurrentValue(generalBitMapping.at("Sequence Type")); - if(generalBitMapping.at("Convert Synchronization") == -1){ convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); } - else{ convertSynchronizationMenuCombo->combo()->setCurrentIndex(convertSynchronizationMenuCombo->combo()->findData(generalBitMapping.at("Convert Synchronization"))); } - angleFilterMenuCombo->combo()->setCurrentIndex(angleFilterMenuCombo->combo()->findData(generalBitMapping.at("Angle Filter"))); - eighthHarmonicMenuCombo->combo()->setCurrentIndex(eighthHarmonicMenuCombo->combo()->findData(generalBitMapping.at("8th Harmonic"))); + updateSequenceWidget(); //StatusBarManager::pushMessage("READ GENERAL: 0b" + QString::number(static_cast(*generalRegValue), 2).rightJustified(16, '0')); } @@ -1999,6 +2020,17 @@ void HarmonicCalibration::readSequence(){ } } +void HarmonicCalibration::updateSequenceWidget(){ + if(generalRegisterMap.at("Sequence Type") == -1){ sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); } + else{ sequenceTypeMenuCombo->combo()->setCurrentIndex(sequenceTypeMenuCombo->combo()->findData(generalRegisterMap.at("Sequence Type"))); } + conversionTypeMenuCombo->combo()->setCurrentIndex(conversionTypeMenuCombo->combo()->findData(generalRegisterMap.at("Conversion Type"))); + // cnvSourceMenuCombo->combo()->setCurrentValue(generalRegisterMap.at("Sequence Type")); + if(generalRegisterMap.at("Convert Synchronization") == -1){ convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); } + else{ convertSynchronizationMenuCombo->combo()->setCurrentIndex(convertSynchronizationMenuCombo->combo()->findData(generalRegisterMap.at("Convert Synchronization"))); } + angleFilterMenuCombo->combo()->setCurrentIndex(angleFilterMenuCombo->combo()->findData(generalRegisterMap.at("Angle Filter"))); + eighthHarmonicMenuCombo->combo()->setCurrentIndex(eighthHarmonicMenuCombo->combo()->findData(generalRegisterMap.at("8th Harmonic"))); +} + bool HarmonicCalibration::changeCNVPage(uint32_t page, QString registerName){ uint32_t *cnvPageRegValue = new uint32_t; uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); From bf20a45a6dd3a855b04220fd58eadac02dee3fa1 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 31 Oct 2024 14:56:44 +0800 Subject: [PATCH 058/112] admt: Included motor controls in acquisition tab - Changed timer to concurrent Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 9 +- plugins/admt/src/harmoniccalibration.cpp | 138 ++++++++++++++---- 2 files changed, 118 insertions(+), 29 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index cfdbe0aa96..06a8adaf71 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -59,7 +59,6 @@ public Q_SLOTS: void stop(); void start(); void restart(); - void timerTask(); void calibrationTask(); void utilityTask(); void clearCommandLog(); @@ -78,7 +77,7 @@ public Q_SLOTS: InfoBtn *infoButton; RunBtn *runButton; - double rotation, angle, count, temp, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode, + double rotation, angle, count, temp = 0.0, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode, afeDiag0, afeDiag1, afeDiag2; QPushButton *openLastMenuButton, *calibrationStartMotorButton, *applyCalibrationDataButton, *calibrateDataButton, *extractDataButton, @@ -94,6 +93,7 @@ public Q_SLOTS: *AFEDIAG0LineEdit, *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, + *acquisitionMotorCurrentPositionLabel, *calibrationMotorCurrentPositionLabel, *motorAmaxValueLabel, *motorRotateVmaxValueLabel, *motorDmaxValueLabel, *motorDisableValueLabel, *motorTargetPosValueLabel, *motorCurrentPosValueLabel, @@ -218,8 +218,11 @@ public Q_SLOTS: void clearCalibrationSamples(); void updateSequenceWidget(); void toggleFaultRegisterMode(int mode); + void startAcquisition(); + void getAcquisitionSamples(); + void acquisitionUITask(); - QTimer *timer, *calibrationTimer, *utilityTimer; + QTimer *acquisitionUITimer, *calibrationTimer, *utilityTimer; int uuid = 0; const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 52de5698e2..8a00b21ba1 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -6,7 +6,7 @@ #include -static int sampleRate = 50; +static int acquisitionUITimerRate = 50; static int calibrationTimerRate = 1000; static int utilityTimerRate = 1000; @@ -15,10 +15,12 @@ static int dataGraphSamples = 100; static int tempGraphSamples = 100; static bool running = false; static double *dataGraphValue; +static double *tempGraphValue; static int cycleCount = 11; static int samplesPerCycle = 256; static int totalSamplesCount = cycleCount * samplesPerCycle; +static bool isStartAcquisition = false; static bool isStartMotor = false; static bool isPostCalibration = false; static bool isCalculatedCoeff = false; @@ -71,6 +73,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool , m_admtController(m_admtController) { readDeviceProperties(); + initializeMotor(); + rotationChannelName = m_admtController->getChannelId(ADMTController::Channel::ROTATION); angleChannelName = m_admtController->getChannelId(ADMTController::Channel::ANGLE); countChannelName = m_admtController->getChannelId(ADMTController::Channel::COUNT); @@ -160,12 +164,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool countWidget->contentLayout()->addWidget(countSection); tempWidget->contentLayout()->addWidget(tempSection); - rawDataLayout->addWidget(rotationWidget); - rawDataLayout->addWidget(angleWidget); - rawDataLayout->addWidget(countWidget); - rawDataLayout->addWidget(tempWidget); - rawDataLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); - rotationValueLabel = new QLabel(rotationSection); StyleHelper::MenuControlLabel(rotationValueLabel, "rotationValueLabel"); angleValueLabel = new QLabel(angleSection); @@ -185,6 +183,58 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool countSection->contentLayout()->addWidget(countValueLabel); tempSection->contentLayout()->addWidget(tempValueLabel); + #pragma region Acquisition Motor Configuration Section Widget + MenuSectionWidget *motorConfigurationSectionWidget = new MenuSectionWidget(rawDataWidget); + MenuCollapseSection *motorConfigurationCollapseSection = new MenuCollapseSection("Motor Configuration", MenuCollapseSection::MHCW_NONE, motorConfigurationSectionWidget); + motorConfigurationCollapseSection->header()->toggle(); + motorConfigurationSectionWidget->contentLayout()->addWidget(motorConfigurationCollapseSection); + + motorMaxVelocitySpinBox = new HorizontalSpinBox("Max Velocity", convertVMAXtoRPS(rotate_vmax), "rps", motorConfigurationSectionWidget); + motorMaxVelocitySpinBox->setValue(1); + motorAccelTimeSpinBox = new HorizontalSpinBox("Acceleration Time", convertAMAXtoAccelTime(amax), "sec", motorConfigurationSectionWidget); + motorAccelTimeSpinBox->setValue(1); + motorMaxDisplacementSpinBox = new HorizontalSpinBox("Max Displacement", dmax, "", motorConfigurationSectionWidget); + + m_calibrationMotorRampModeMenuCombo = new MenuCombo("Ramp Mode", motorConfigurationSectionWidget); + auto calibrationMotorRampModeCombo = m_calibrationMotorRampModeMenuCombo->combo(); + calibrationMotorRampModeCombo->addItem("Position", QVariant(ADMTController::MotorRampMode::POSITION)); + calibrationMotorRampModeCombo->addItem("Ramp Mode 1", QVariant(ADMTController::MotorRampMode::RAMP_MODE_1)); + applyComboBoxStyle(calibrationMotorRampModeCombo); + + motorConfigurationCollapseSection->contentLayout()->setSpacing(8); + motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxVelocitySpinBox); + motorConfigurationCollapseSection->contentLayout()->addWidget(motorAccelTimeSpinBox); + motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxDisplacementSpinBox); + motorConfigurationCollapseSection->contentLayout()->addWidget(m_calibrationMotorRampModeMenuCombo); + #pragma endregion + + #pragma region Acquisition Motor Control Section Widget + MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(rawDataWidget); + MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection("Motor Control", MenuCollapseSection::MHCW_NONE, motorControlSectionWidget); + motorControlSectionWidget->contentLayout()->setSpacing(8); + motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); + QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); + StyleHelper::MenuSmallLabel(currentPositionLabel, "currentPositionLabel"); + acquisitionMotorCurrentPositionLabel = new QLabel("--.--", motorControlSectionWidget); + acquisitionMotorCurrentPositionLabel->setAlignment(Qt::AlignRight); + applyLabelStyle(acquisitionMotorCurrentPositionLabel); + + motorTargetPositionSpinBox = new HorizontalSpinBox("Target Position", target_pos, "", motorControlSectionWidget); + + motorControlCollapseSection->contentLayout()->setSpacing(8); + motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); + motorControlCollapseSection->contentLayout()->addWidget(acquisitionMotorCurrentPositionLabel); + motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionSpinBox); + #pragma endregion + + rawDataLayout->addWidget(rotationWidget); + rawDataLayout->addWidget(angleWidget); + rawDataLayout->addWidget(countWidget); + rawDataLayout->addWidget(tempWidget); + rawDataLayout->addWidget(motorConfigurationSectionWidget); + rawDataLayout->addWidget(motorControlSectionWidget); + rawDataLayout->addStretch(); + QWidget *historicalGraphWidget = new QWidget(); QVBoxLayout *historicalGraphLayout = new QVBoxLayout(this); @@ -198,7 +248,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool dataGraph->setUnitOfMeasure("Degree", "°"); dataGraph->setAutoscale(false); dataGraph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); - //dataGraph->setNumSamples(dataGraphSamples); dataGraph->setHistoryDuration(10.0); dataGraphValue = &rotation; @@ -211,8 +260,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool tempGraph->setPlotAxisXTitle("Celsius (°C)"); tempGraph->setUnitOfMeasure("Celsius", "°C"); tempGraph->setAutoscale(false); - tempGraph->addScale(0.0, 100.0, 25, 5); - tempGraph->setNumSamples(tempGraphSamples); + tempGraph->setAxisScale(QwtAxis::YLeft, 0.0, 100.0); + tempGraph->setHistoryDuration(10.0); + tempGraphValue = &temp; historicalGraphLayout->addWidget(dataGraphLabel); historicalGraphLayout->addWidget(dataGraph); @@ -236,6 +286,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool MenuSectionWidget *generalWidget = new MenuSectionWidget(generalSettingWidget); generalWidget->contentLayout()->setSpacing(8); MenuCollapseSection *generalSection = new MenuCollapseSection("Data Acquisition", MenuCollapseSection::MHCW_NONE, generalWidget); + generalSection->header()->toggle(); generalSection->contentLayout()->setSpacing(8); generalWidget->contentLayout()->addWidget(generalSection); @@ -245,9 +296,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool StyleHelper::MenuSmallLabel(graphUpdateIntervalLabel, "graphUpdateIntervalLabel"); graphUpdateIntervalLineEdit = new QLineEdit(generalSection); applyLineEditStyle(graphUpdateIntervalLineEdit); - graphUpdateIntervalLineEdit->setText(QString::number(sampleRate)); + graphUpdateIntervalLineEdit->setText(QString::number(acquisitionUITimerRate)); - connectLineEditToNumber(graphUpdateIntervalLineEdit, sampleRate, 20, 5000); + connectLineEditToNumber(graphUpdateIntervalLineEdit, acquisitionUITimerRate, 1, 5000); generalSection->contentLayout()->addWidget(graphUpdateIntervalLabel); generalSection->contentLayout()->addWidget(graphUpdateIntervalLineEdit); @@ -320,6 +371,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool MenuSectionWidget *dataGraphWidget = new MenuSectionWidget(generalSettingWidget); dataGraphWidget->contentLayout()->setSpacing(8); MenuCollapseSection *dataGraphSection = new MenuCollapseSection("Data Graph", MenuCollapseSection::MHCW_NONE, dataGraphWidget); + dataGraphSection->header()->toggle(); dataGraphSection->contentLayout()->setSpacing(8); // Graph Channel @@ -353,6 +405,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool MenuSectionWidget *tempGraphWidget = new MenuSectionWidget(generalSettingWidget); tempGraphWidget->contentLayout()->setSpacing(8); MenuCollapseSection *tempGraphSection = new MenuCollapseSection("Temperature Graph", MenuCollapseSection::MHCW_NONE, tempGraphWidget); + tempGraphSection->header()->toggle(); tempGraphSection->contentLayout()->setSpacing(8); // Graph Samples @@ -371,8 +424,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool generalSettingLayout->addWidget(header); generalSettingLayout->addSpacerItem(new QSpacerItem(0, 3, QSizePolicy::Fixed, QSizePolicy::Fixed)); - generalSettingLayout->addWidget(generalWidget); generalSettingLayout->addWidget(sequenceWidget); + generalSettingLayout->addWidget(generalWidget); generalSettingLayout->addWidget(dataGraphWidget); generalSettingLayout->addWidget(tempGraphWidget); generalSettingLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); @@ -399,9 +452,17 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connect(runButton, &QPushButton::toggled, this, &HarmonicCalibration::setRunning); connect(this, &HarmonicCalibration::runningChanged, this, &HarmonicCalibration::run); connect(this, &HarmonicCalibration::runningChanged, runButton, &QAbstractButton::setChecked); + connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); + connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); + connectLineEditToNumberWrite(motorMaxDisplacementSpinBox->lineEdit(), dmax, ADMTController::MotorAttribute::DMAX); + connectLineEditToNumberWrite(motorTargetPositionSpinBox->lineEdit(), target_pos, ADMTController::MotorAttribute::TARGET_POS); + connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); - timer = new QTimer(this); - connect(timer, &QTimer::timeout, this, &HarmonicCalibration::timerTask); + acquisitionUITimer = new QTimer(this); + connect(acquisitionUITimer, &QTimer::timeout, this, &HarmonicCalibration::acquisitionUITask); + + // timer = new QTimer(this); + // connect(timer, &QTimer::timeout, this, &HarmonicCalibration::timerTask); calibrationTimer = new QTimer(this); connect(calibrationTimer, &QTimer::timeout, this, &HarmonicCalibration::calibrationTask); @@ -416,10 +477,19 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connect(tabWidget, &QTabWidget::currentChanged, [=](int index){ tabWidget->setCurrentIndex(index); - if(index == 0) { readSequence(); } + if(index == 0) // Acquisition Tab + { + readSequence(); + } - if(index == 1) { calibrationTimer->start(calibrationTimerRate); } - else { calibrationTimer->stop(); } + if(index == 1) // Calibration Tab + { + calibrationTimer->start(calibrationTimerRate); + } + else + { + calibrationTimer->stop(); + } if(index == 2) // Utility Tab { @@ -433,6 +503,23 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool HarmonicCalibration::~HarmonicCalibration() {} +void HarmonicCalibration::startAcquisition() +{ + isStartAcquisition = true; + QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples); +} + +void HarmonicCalibration::getAcquisitionSamples() +{ + while(isStartAcquisition) + { + updateChannelValues(); + dataGraph->plot(*dataGraphValue); + tempGraph->plot(*tempGraphValue); + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + } +} + void HarmonicCalibration::initializeMotor() { rotate_vmax = 53687.0912; @@ -461,7 +548,6 @@ void HarmonicCalibration::initializeMotor() ToolTemplate* HarmonicCalibration::createCalibrationWidget() { - initializeMotor(); ToolTemplate *tool = new ToolTemplate(this); #pragma region Calibration Data Graph Widget @@ -1941,11 +2027,13 @@ void HarmonicCalibration::run(bool b) tim.start(); if(!b) { + isStartAcquisition = false; + acquisitionUITimer->stop(); runButton->setChecked(false); - timer->stop(); } else{ - timer->start(sampleRate); + acquisitionUITimer->start(acquisitionUITimerRate); + startAcquisition(); } updateGeneralSettingEnabled(!b); @@ -1956,12 +2044,10 @@ void HarmonicCalibration::canCalibrate(bool value) calibrateDataButton->setEnabled(value); } -void HarmonicCalibration::timerTask(){ - updateChannelValues(); +void HarmonicCalibration::acquisitionUITask() +{ updateLineEditValues(); - - dataGraph->plot(*dataGraphValue); - tempGraph->plot(temp); + updateLabelValue(acquisitionMotorCurrentPositionLabel, ADMTController::MotorAttribute::CURRENT_POS); } void HarmonicCalibration::applySequence(){ From 4bcbe2985a23d4ba2431b95b3ef313b57c795270 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 4 Nov 2024 10:50:48 +0800 Subject: [PATCH 059/112] admt: Merge to latest dev build - Removed Sismograph Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/CMakeLists.txt | 6 + plugins/admt/CMakeLists.txt | 32 ++- plugins/admt/include/admt/admtplugin.h | 137 +--------- .../admt/include/admt/harmoniccalibration.h | 21 +- plugins/admt/src/admtplugin.cpp | 72 +----- plugins/admt/src/harmoniccalibration.cpp | 240 +++++++++--------- .../admt/src/widgets/registerblockwidget.cpp | 2 +- 7 files changed, 168 insertions(+), 342 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 62b15af1a2..cfad0c99ad 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -33,6 +33,7 @@ option(ENABLE_PLUGIN_SWIOT "Enable SWIOT plugin" ON) option(ENABLE_PLUGIN_PQM "Enable PQM plugin" ON) option(ENABLE_PLUGIN_DATALOGGER "Enable DATALOGGER plugin" ON) option(ENABLE_PLUGIN_DAC "Enable DAC plugin" ON) +option(ENABLE_PLUGIN_ADMT "Enable ADMT plugin" ON) if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${SCOPY_PLUGIN_BUILD_PATH}) @@ -125,6 +126,11 @@ if(ENABLE_PLUGIN_M2K) endif() endif() +if(ENABLE_PLUGIN_ADMT) + add_subdirectory(admt) + list(APPEND PLUGINS ${ADMT_TARGET_NAME}) +endif() + install(TARGETS ${PLUGINS} LIBRARY DESTINATION ${SCOPY_PLUGIN_INSTALL_PATH}) set(PLUGINS ${PLUGINS} PARENT_SCOPE) diff --git a/plugins/admt/CMakeLists.txt b/plugins/admt/CMakeLists.txt index c9691bd935..4890cb7880 100644 --- a/plugins/admt/CMakeLists.txt +++ b/plugins/admt/CMakeLists.txt @@ -1,3 +1,23 @@ +# +# Copyright (c) 2024 Analog Devices Inc. +# +# This file is part of Scopy +# (see https://www.github.com/analogdevicesinc/scopy). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + cmake_minimum_required(VERSION 3.9) set(SCOPY_MODULE admt) @@ -50,14 +70,6 @@ endif() set(PROJECT_SOURCES ${SRC_LIST} ${HEADER_LIST} ${UI_LIST}) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS REQUIRED Widgets Core) -if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${SCOPY_PLUGIN_BUILD_PATH}) -elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Scopy.app/Contents/MacOS/plugins/plugins) -else() - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${SCOPY_PLUGIN_BUILD_PATH}) -endif() - qt_add_resources(PROJECT_RESOURCES res/resources.qrc) add_library(${PROJECT_NAME} SHARED ${PROJECT_SOURCES} ${PROJECT_RESOURCES}) @@ -91,6 +103,4 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") configureinstallersettings(${SCOPY_MODULE} ${INSTALLER_DESCRIPTION} TRUE) endif() -set(ADMT_TARGET_NAME ${PROJECT_NAME} PARENT_SCOPE) - -install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${SCOPY_PLUGIN_INSTALL_DIR}) \ No newline at end of file +set(ADMT_TARGET_NAME ${PROJECT_NAME} PARENT_SCOPE) \ No newline at end of file diff --git a/plugins/admt/include/admt/admtplugin.h b/plugins/admt/include/admt/admtplugin.h index add9ec0dc6..945d9afee6 100644 --- a/plugins/admt/include/admt/admtplugin.h +++ b/plugins/admt/include/admt/admtplugin.h @@ -12,138 +12,11 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include -namespace scopy::admt { -using namespace scopy::grutil; - -class SCOPY_ADMT_EXPORT ChannelIdProvider : public QObject -{ - Q_OBJECT -public: - ChannelIdProvider(QObject *parent) - : QObject(parent) - { - idx = 0; - } - virtual ~ChannelIdProvider() {} - - int next() { return idx++; } - QPen pen(int idx) { return QPen(StyleHelper::getColor("CH" + QString::number(idx))); } - - int idx; -}; - -class SCOPY_ADMT_EXPORT PlotProxy -{ -public: - virtual ToolAddon *getPlotAddon() = 0; - virtual ToolAddon *getPlotSettings() = 0; - virtual QList getDeviceAddons() = 0; - virtual QList getChannelAddons() = 0; - virtual QList getAddons() = 0; - - virtual void addDeviceAddon(ToolAddon *d) = 0; - virtual void removeDeviceAddon(ToolAddon *d) = 0; - virtual void addChannelAddon(ChannelAddon *c) = 0; - virtual void removeChannelAddon(ChannelAddon *c) = 0; - virtual void init() = 0; - - virtual ChannelIdProvider *getChannelIdProvider() = 0; -}; - -class SCOPY_ADMT_EXPORT GRTimePlotProxy : public QObject, public PlotProxy -{ - Q_OBJECT -public: - GRTimePlotProxy(QObject *parent = nullptr) - : QObject(parent) - { - chIdP = new ChannelIdProvider(this); - } - ~GRTimePlotProxy() {} - - void setPlotAddon(GRTimePlotAddon *p, GRTimePlotAddonSettings *s) - { - this->plotAddon = p; - this->plotSettingsAddon = s; - } - - void addDeviceAddon(ToolAddon *d) override { deviceAddons.append(d); } - - void removeDeviceAddon(ToolAddon *d) override { deviceAddons.removeAll(d); } - - void addChannelAddon(ChannelAddon *c) override { channelAddons.append(c); } - - void removeChannelAddon(ChannelAddon *c) override { channelAddons.removeAll(c); } - - ToolAddon *getPlotAddon() override { return plotAddon; } - - ToolAddon *getPlotSettings() override { return plotSettingsAddon; } - - QList getDeviceAddons() override { return deviceAddons; } - - QList getChannelAddons() override { return channelAddons; } - - QList getAddons() override - { - QList addons; - - addons.append(channelAddons); - addons.append(deviceAddons); - addons.append(plotSettingsAddon); - addons.append(plotAddon); - return addons; - } - - void init() override - { - for(auto *addon : getAddons()) { - if(dynamic_cast(addon)) { - auto GRAddon = dynamic_cast(addon); - connect(topBlock, &GRTopBlock::aboutToStart, this, [=]() { GRAddon->preFlowStart(); }); - connect(topBlock, &GRTopBlock::started, this, [=]() { GRAddon->postFlowStart(); }); - connect(topBlock, &GRTopBlock::aboutToStop, this, [=]() { GRAddon->preFlowStop(); }); - connect(topBlock, &GRTopBlock::stopped, this, [=]() { GRAddon->postFlowStop(); }); - connect(topBlock, &GRTopBlock::aboutToBuild, this, [=]() { GRAddon->preFlowBuild(); }); - connect(topBlock, &GRTopBlock::builtSignalPaths, this, - [=]() { GRAddon->postFlowBuild(); }); - connect(topBlock, &GRTopBlock::aboutToTeardown, this, - [=]() { GRAddon->preFlowTeardown(); }); - connect(topBlock, &GRTopBlock::teardownSignalPaths, this, - [=]() { GRAddon->postFlowTeardown(); }); - } - } - } - - ChannelIdProvider *getChannelIdProvider() override { return chIdP; } - - QString getPrefix() { return prefix; } - void setPrefix(QString p) { prefix = p; } - GRTopBlock *getTopBlock() const { return topBlock; } - void setTopBlock(GRTopBlock *newTopBlock) { topBlock = newTopBlock; } - -private: - GRTimePlotAddon *plotAddon; - GRTimePlotAddonSettings *plotSettingsAddon; - QList deviceAddons; - QList channelAddons; - GRTopBlock *topBlock; - ChannelIdProvider *chIdP; - - QString prefix; -}; +namespace scopy { +namespace admt { class SCOPY_ADMT_EXPORT ADMTPlugin : public QObject, public PluginBase { @@ -167,10 +40,10 @@ public Q_SLOTS: iio_context *m_ctx; QWidget *harmonicCalibration; QLineEdit *edit; - PlotProxy *createRecipe(iio_context *ctx); - GRTimePlotProxy *recipe; ADMTController *m_admtController; }; -} // namespace scopy::admt +} // namespace admt +} // namespace scopy + #endif // ADMTPLUGIN_H diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 06a8adaf71..746f547d24 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -2,7 +2,6 @@ #define HARMONICCALIBRATION_H #include "scopy-admt_export.h" -#include "sismograph.hpp" #include @@ -42,9 +41,14 @@ #include #include #include +#include +#include #include +#include +#include -namespace scopy::admt { +namespace scopy{ +namespace admt { class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget { @@ -107,8 +111,6 @@ public Q_SLOTS: *calibrationH8MagLabel, *calibrationH8PhaseLabel; - Sismograph *dataGraph, *tempGraph, *calibrationRawDataSismograph; - MenuHeaderWidget *header; MenuSectionWidget *rightMenuSectionWidget; @@ -151,12 +153,12 @@ public Q_SLOTS: void updateGeneralSettingEnabled(bool value); void connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max); void connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit = ""); - void connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph, int min, int max); - void connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph); - void connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph); + // void connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph, int min, int max); + // void connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph); + // void connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph); void connectMenuComboToNumber(MenuCombo* menuCombo, double& variable); void connectMenuComboToNumber(MenuCombo* menuCombo, int& variable); - void changeGraphColorByChannelName(Sismograph* graph, const char* channelName); + // void changeGraphColorByChannelName(Sismograph* graph, const char* channelName); ToolTemplate* createCalibrationWidget(); ToolTemplate* createRegistersWidget(); ToolTemplate* createUtilityWidget(); @@ -237,5 +239,6 @@ enum TABS -} // namespace scopy::admt +} // namespace admt +} // namespace scopy #endif // HARMONICCALIBRATION_H diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index aee3146a94..f2c36c4e7a 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -8,8 +8,10 @@ #include Q_LOGGING_CATEGORY(CAT_ADMTPLUGIN, "ADMTPlugin") +using namespace scopy; +// using namespace scopy::grutil; +// using namespace scopy::m2kgui; using namespace scopy::admt; -using namespace scopy::grutil; const bool isDebug = false; @@ -81,74 +83,6 @@ void ADMTPlugin::unload() { /*delete m_infoPage;*/ } QString ADMTPlugin::description() { return "Plugin for ADMT Harmonic Calibration"; } -PlotProxy *ADMTPlugin::createRecipe(iio_context *ctx) -{ - QStringList deviceList; - QMap devChannelMap; - int devCount = iio_context_get_devices_count(ctx); - qDebug(CAT_ADMTPLUGIN) << " Found " << devCount << "devices"; - for(int i = 0; i < devCount; i++) { - iio_device *dev = iio_context_get_device(ctx, i); - QString dev_name = QString::fromLocal8Bit(iio_device_get_name(dev)); - - qDebug(CAT_ADMTPLUGIN) << "Looking for scanelements in " << dev_name; - if(dev_name == "m2k-logic-analyzer-rx") - continue; - QStringList channelList; - for(int j = 0; j < iio_device_get_channels_count(dev); j++) { - - struct iio_channel *chn = iio_device_get_channel(dev, j); - QString chn_name = QString::fromLocal8Bit(iio_channel_get_id(chn)); - qDebug(CAT_ADMTPLUGIN) << "Verify if " << chn_name << "is scan element"; - if(chn_name == "timestamp" /*|| chn_name == "accel_z" || chn_name =="accel_y"*/) - continue; - if(!iio_channel_is_output(chn) && iio_channel_is_scan_element(chn)) { - channelList.append(chn_name); - } - } - if(channelList.isEmpty()) - continue; - deviceList.append(dev_name); - devChannelMap.insert(dev_name, channelList); - } - - // should this be wrapped to a register function (?) - GRTopBlock *top = new grutil::GRTopBlock("Time", this); - - recipe = new GRTimePlotProxy(this); - QString plotRecipePrefix = "time_"; - recipe->setPrefix(plotRecipePrefix); - - GRTimePlotAddon *p = new GRTimePlotAddon(plotRecipePrefix, top, this); - GRTimePlotAddonSettings *s = new GRTimePlotAddonSettings(p, this); - - recipe->setPlotAddon(p, s); - - ChannelIdProvider *chIdProvider = recipe->getChannelIdProvider(); - for(const QString &iio_dev : deviceList) { - GRIIODeviceSource *gr_dev = new GRIIODeviceSource(m_ctx, iio_dev, iio_dev, 0x400, this); - - top->registerIIODeviceSource(gr_dev); - - GRDeviceAddon *d = new GRDeviceAddon(gr_dev, this); - connect(s, &GRTimePlotAddonSettings::bufferSizeChanged, d, &GRDeviceAddon::updateBufferSize); - recipe->addDeviceAddon(d); - - for(const QString &ch : devChannelMap.value(iio_dev, {})) { - int idx = chIdProvider->next(); - GRTimeChannelAddon *t = new GRTimeChannelAddon(ch, d, p, chIdProvider->pen(idx), this); - top->registerSignalPath(t->signalPath()); - recipe->addChannelAddon(t); - } - } - recipe->setTopBlock(top); - - qDebug(CAT_ADMTPLUGIN) << deviceList; - qDebug(CAT_ADMTPLUGIN) << devChannelMap; - - return recipe; -} - bool ADMTPlugin::onConnect() { // This method is called when you try to connect to a device and the plugin is diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 8a00b21ba1..e3606b833f 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -5,6 +5,7 @@ #include #include +#include static int acquisitionUITimerRate = 50; static int calibrationTimerRate = 1000; @@ -65,7 +66,6 @@ static uint32_t H1_MAG_HEX, H2_MAG_HEX, H3_MAG_HEX, H8_MAG_HEX, H1_PHASE_HEX, H2 using namespace scopy; using namespace scopy::admt; -using namespace scopy::grutil; HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool isDebug, QWidget *parent) : QWidget(parent) @@ -150,10 +150,10 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool angleWidget->contentLayout()->setSpacing(8); countWidget->contentLayout()->setSpacing(8); tempWidget->contentLayout()->setSpacing(8); - MenuCollapseSection *rotationSection = new MenuCollapseSection("AMR Angle", MenuCollapseSection::MHCW_NONE, rotationWidget); - MenuCollapseSection *angleSection = new MenuCollapseSection("GMR Angle", MenuCollapseSection::MHCW_NONE, angleWidget); - MenuCollapseSection *countSection = new MenuCollapseSection("Count", MenuCollapseSection::MHCW_NONE, countWidget); - MenuCollapseSection *tempSection = new MenuCollapseSection("Sensor Temperature", MenuCollapseSection::MHCW_NONE, tempWidget); + MenuCollapseSection *rotationSection = new MenuCollapseSection("AMR Angle", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, rotationWidget); + MenuCollapseSection *angleSection = new MenuCollapseSection("GMR Angle", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, angleWidget); + MenuCollapseSection *countSection = new MenuCollapseSection("Count", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, countWidget); + MenuCollapseSection *tempSection = new MenuCollapseSection("Sensor Temperature", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, tempWidget); rotationSection->contentLayout()->setSpacing(8); angleSection->contentLayout()->setSpacing(8); countSection->contentLayout()->setSpacing(8); @@ -185,7 +185,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool #pragma region Acquisition Motor Configuration Section Widget MenuSectionWidget *motorConfigurationSectionWidget = new MenuSectionWidget(rawDataWidget); - MenuCollapseSection *motorConfigurationCollapseSection = new MenuCollapseSection("Motor Configuration", MenuCollapseSection::MHCW_NONE, motorConfigurationSectionWidget); + MenuCollapseSection *motorConfigurationCollapseSection = new MenuCollapseSection("Motor Configuration", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorConfigurationSectionWidget); motorConfigurationCollapseSection->header()->toggle(); motorConfigurationSectionWidget->contentLayout()->addWidget(motorConfigurationCollapseSection); @@ -210,7 +210,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool #pragma region Acquisition Motor Control Section Widget MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(rawDataWidget); - MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection("Motor Control", MenuCollapseSection::MHCW_NONE, motorControlSectionWidget); + MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection("Motor Control", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorControlSectionWidget); motorControlSectionWidget->contentLayout()->setSpacing(8); motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); @@ -242,32 +242,32 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool dataGraphLabel->setText("Phase"); StyleHelper::MenuSmallLabel(dataGraphLabel, "dataGraphLabel"); - dataGraph = new Sismograph(this); - changeGraphColorByChannelName(dataGraph, rotationChannelName); - dataGraph->setPlotAxisXTitle("Degree (°)"); - dataGraph->setUnitOfMeasure("Degree", "°"); - dataGraph->setAutoscale(false); - dataGraph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); - dataGraph->setHistoryDuration(10.0); - dataGraphValue = &rotation; + // dataGraph = new Sismograph(this); + // changeGraphColorByChannelName(dataGraph, rotationChannelName); + // dataGraph->setPlotAxisXTitle("Degree (°)"); + // dataGraph->setUnitOfMeasure("Degree", "°"); + // dataGraph->setAutoscale(false); + // dataGraph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); + // dataGraph->setHistoryDuration(10.0); + // dataGraphValue = &rotation; QLabel *tempGraphLabel = new QLabel(historicalGraphWidget); tempGraphLabel->setText("Temperature"); StyleHelper::MenuSmallLabel(tempGraphLabel, "tempGraphLabel"); - tempGraph = new Sismograph(this); - changeGraphColorByChannelName(tempGraph, temperatureChannelName); - tempGraph->setPlotAxisXTitle("Celsius (°C)"); - tempGraph->setUnitOfMeasure("Celsius", "°C"); - tempGraph->setAutoscale(false); - tempGraph->setAxisScale(QwtAxis::YLeft, 0.0, 100.0); - tempGraph->setHistoryDuration(10.0); - tempGraphValue = &temp; + // tempGraph = new Sismograph(this); + // changeGraphColorByChannelName(tempGraph, temperatureChannelName); + // tempGraph->setPlotAxisXTitle("Celsius (°C)"); + // tempGraph->setUnitOfMeasure("Celsius", "°C"); + // tempGraph->setAutoscale(false); + // tempGraph->setAxisScale(QwtAxis::YLeft, 0.0, 100.0); + // tempGraph->setHistoryDuration(10.0); + // tempGraphValue = &temp; historicalGraphLayout->addWidget(dataGraphLabel); - historicalGraphLayout->addWidget(dataGraph); + // historicalGraphLayout->addWidget(dataGraph); historicalGraphLayout->addWidget(tempGraphLabel); - historicalGraphLayout->addWidget(tempGraph); + // historicalGraphLayout->addWidget(tempGraph); historicalGraphWidget->setLayout(historicalGraphLayout); @@ -285,7 +285,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool // General Setting Widget MenuSectionWidget *generalWidget = new MenuSectionWidget(generalSettingWidget); generalWidget->contentLayout()->setSpacing(8); - MenuCollapseSection *generalSection = new MenuCollapseSection("Data Acquisition", MenuCollapseSection::MHCW_NONE, generalWidget); + MenuCollapseSection *generalSection = new MenuCollapseSection("Data Acquisition", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); generalSection->header()->toggle(); generalSection->contentLayout()->setSpacing(8); generalWidget->contentLayout()->addWidget(generalSection); @@ -317,7 +317,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool generalSection->contentLayout()->addWidget(dataSampleSizeLineEdit); MenuSectionWidget *sequenceWidget = new MenuSectionWidget(generalSettingWidget); - MenuCollapseSection *sequenceSection = new MenuCollapseSection("Sequence", MenuCollapseSection::MHCW_NONE, sequenceWidget); + MenuCollapseSection *sequenceSection = new MenuCollapseSection("Sequence", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, sequenceWidget); sequenceWidget->contentLayout()->addWidget(sequenceSection); sequenceSection->contentLayout()->setSpacing(8); @@ -370,7 +370,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool // Data Graph Setting Widget MenuSectionWidget *dataGraphWidget = new MenuSectionWidget(generalSettingWidget); dataGraphWidget->contentLayout()->setSpacing(8); - MenuCollapseSection *dataGraphSection = new MenuCollapseSection("Data Graph", MenuCollapseSection::MHCW_NONE, dataGraphWidget); + MenuCollapseSection *dataGraphSection = new MenuCollapseSection("Data Graph", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, dataGraphWidget); dataGraphSection->header()->toggle(); dataGraphSection->contentLayout()->setSpacing(8); @@ -382,7 +382,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool dataGraphChannelCombo->addItem("Count", QVariant::fromValue(reinterpret_cast(const_cast(countChannelName)))); applyComboBoxStyle(dataGraphChannelCombo); - connectMenuComboToGraphChannel(m_dataGraphChannelMenuCombo, dataGraph); + // connectMenuComboToGraphChannel(m_dataGraphChannelMenuCombo, dataGraph); dataGraphSection->contentLayout()->addWidget(m_dataGraphChannelMenuCombo); @@ -394,7 +394,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool applyLineEditStyle(dataGraphSamplesLineEdit); dataGraphSamplesLineEdit->setText(QString::number(dataGraphSamples)); - connectLineEditToGraphSamples(dataGraphSamplesLineEdit, dataGraphSamples, dataGraph, 1, 5000); + // connectLineEditToGraphSamples(dataGraphSamplesLineEdit, dataGraphSamples, dataGraph, 1, 5000); dataGraphSection->contentLayout()->addWidget(dataGraphSamplesLabel); dataGraphSection->contentLayout()->addWidget(dataGraphSamplesLineEdit); @@ -404,7 +404,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool // Temperature Graph MenuSectionWidget *tempGraphWidget = new MenuSectionWidget(generalSettingWidget); tempGraphWidget->contentLayout()->setSpacing(8); - MenuCollapseSection *tempGraphSection = new MenuCollapseSection("Temperature Graph", MenuCollapseSection::MHCW_NONE, tempGraphWidget); + MenuCollapseSection *tempGraphSection = new MenuCollapseSection("Temperature Graph", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, tempGraphWidget); tempGraphSection->header()->toggle(); tempGraphSection->contentLayout()->setSpacing(8); @@ -418,7 +418,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLabel); tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLineEdit); - connectLineEditToGraphSamples(tempGraphSamplesLineEdit, tempGraphSamples, tempGraph, 1, 5000); + // connectLineEditToGraphSamples(tempGraphSamplesLineEdit, tempGraphSamples, tempGraph, 1, 5000); tempGraphWidget->contentLayout()->addWidget(tempGraphSection); @@ -514,8 +514,8 @@ void HarmonicCalibration::getAcquisitionSamples() while(isStartAcquisition) { updateChannelValues(); - dataGraph->plot(*dataGraphValue); - tempGraph->plot(*tempGraphValue); + // dataGraph->plot(*dataGraphValue); + // tempGraph->plot(*tempGraphValue); readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); } } @@ -1004,7 +1004,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Calibration Dataset Configuration MenuSectionWidget *calibrationDatasetConfigSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - MenuCollapseSection *calibrationDatasetConfigCollapseSection = new MenuCollapseSection("Dataset Configuration", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, calibrationDatasetConfigSectionWidget); + MenuCollapseSection *calibrationDatasetConfigCollapseSection = new MenuCollapseSection("Dataset Configuration", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationDatasetConfigSectionWidget); calibrationDatasetConfigSectionWidget->contentLayout()->setSpacing(8); calibrationDatasetConfigSectionWidget->contentLayout()->addWidget(calibrationDatasetConfigCollapseSection); @@ -1033,7 +1033,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Calibration Data Section Widget MenuSectionWidget *calibrationDataSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection("Calibration Data", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, calibrationDataSectionWidget); + MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection("Calibration Data", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationDataSectionWidget); calibrationDataSectionWidget->contentLayout()->setSpacing(8); calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); @@ -1055,7 +1055,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Motor Configuration Section Widget MenuSectionWidget *motorConfigurationSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - MenuCollapseSection *motorConfigurationCollapseSection = new MenuCollapseSection("Motor Configuration", MenuCollapseSection::MHCW_NONE, motorConfigurationSectionWidget); + MenuCollapseSection *motorConfigurationCollapseSection = new MenuCollapseSection("Motor Configuration", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorConfigurationSectionWidget); motorConfigurationCollapseSection->header()->toggle(); motorConfigurationSectionWidget->contentLayout()->addWidget(motorConfigurationCollapseSection); @@ -1080,7 +1080,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Motor Control Section Widget MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection("Motor Control", MenuCollapseSection::MHCW_NONE, motorControlSectionWidget); + MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection("Motor Control", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorControlSectionWidget); motorControlSectionWidget->contentLayout()->setSpacing(8); motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); @@ -1154,7 +1154,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Logs Section Widget MenuSectionWidget *logsSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - MenuCollapseSection *logsCollapseSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, logsSectionWidget); + MenuCollapseSection *logsCollapseSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, logsSectionWidget); logsCollapseSection->header()->toggle(); logsSectionWidget->contentLayout()->setSpacing(8); logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); @@ -1457,7 +1457,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() leftUtilityLayout->setSpacing(8); #pragma region Command Log Widget MenuSectionWidget *commandLogSectionWidget = new MenuSectionWidget(leftUtilityWidget); - MenuCollapseSection *commandLogCollapseSection = new MenuCollapseSection("Command Log", MenuCollapseSection::MHCW_NONE, commandLogSectionWidget); + MenuCollapseSection *commandLogCollapseSection = new MenuCollapseSection("Command Log", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, commandLogSectionWidget); commandLogSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); commandLogSectionWidget->contentLayout()->addWidget(commandLogCollapseSection); commandLogCollapseSection->contentLayout()->setSpacing(8); @@ -1499,7 +1499,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() #pragma region DIGIO Monitor MenuSectionWidget *DIGIOMonitorSectionWidget = new MenuSectionWidget(DIGIOWidget); - MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection("DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, DIGIOMonitorSectionWidget); + MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection("DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOMonitorSectionWidget); DIGIOMonitorSectionWidget->contentLayout()->addWidget(DIGIOMonitorCollapseSection); DIGIOBusyStatusLED = createStatusLEDWidget("BUSY", statusLEDColor, DIGIOMonitorCollapseSection); @@ -1519,7 +1519,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() #pragma region DIGIO Control MenuSectionWidget *DIGIOControlSectionWidget = new MenuSectionWidget(DIGIOWidget); - MenuCollapseSection *DIGIOControlCollapseSection = new MenuCollapseSection("GPIO Control", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, DIGIOControlSectionWidget); + MenuCollapseSection *DIGIOControlCollapseSection = new MenuCollapseSection("GPIO Control", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOControlSectionWidget); DIGIOControlSectionWidget->contentLayout()->addWidget(DIGIOControlCollapseSection); QWidget *DIGIOControlGridWidget = new QWidget(DIGIOControlSectionWidget); @@ -1640,7 +1640,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() #pragma region MTDIAG1 Widget MenuSectionWidget *MTDIAG1SectionWidget = new MenuSectionWidget(centerUtilityWidget); - MenuCollapseSection *MTDIAG1CollapseSection = new MenuCollapseSection("MT Diagnostic Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MTDIAG1SectionWidget); + MenuCollapseSection *MTDIAG1CollapseSection = new MenuCollapseSection("MT Diagnostic Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, MTDIAG1SectionWidget); MTDIAG1SectionWidget->contentLayout()->addWidget(MTDIAG1CollapseSection); R0StatusLED = createStatusLEDWidget("R0", statusLEDColor, MTDIAG1SectionWidget); @@ -1673,7 +1673,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MTDiagnosticsLayout->setSpacing(5); MenuSectionWidget *MTDiagnosticsSectionWidget = new MenuSectionWidget(centerUtilityWidget); - MenuCollapseSection *MTDiagnosticsCollapseSection = new MenuCollapseSection("MT Diagnostics", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MTDiagnosticsSectionWidget); + MenuCollapseSection *MTDiagnosticsCollapseSection = new MenuCollapseSection("MT Diagnostics", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, MTDiagnosticsSectionWidget); MTDiagnosticsSectionWidget->contentLayout()->addWidget(MTDiagnosticsCollapseSection); MTDiagnosticsCollapseSection->contentLayout()->setSpacing(8); @@ -1727,7 +1727,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() rightUtilityLayout->setSpacing(8); MenuSectionWidget *faultRegisterSectionWidget = new MenuSectionWidget(rightUtilityWidget); - MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection("Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, faultRegisterSectionWidget); + MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection("Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, faultRegisterSectionWidget); faultRegisterSectionWidget->contentLayout()->addWidget(faultRegisterCollapseSection); VDDUnderVoltageStatusLED = createStatusLEDWidget("VDD Under Voltage", faultLEDColor, faultRegisterCollapseSection); @@ -2396,38 +2396,38 @@ void HarmonicCalibration::connectLineEditToNumberWrite(QLineEdit* lineEdit, doub }); } -void HarmonicCalibration::connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph, int min, int max) -{ - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, graph, min, max]() { - bool ok; - int value = lineEdit->text().toInt(&ok); - if (ok && value >= min && value <= max) { - variable = value; - graph->setNumSamples(variable); - } else { - lineEdit->setText(QString::number(variable)); - } - }); -} - -void HarmonicCalibration::connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph) -{ - QComboBox *combo = menuCombo->combo(); - connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [combo, graph]() { - int value = qvariant_cast(combo->currentData()); - switch(value) - { - case Sismograph::LEFT_TO_RIGHT: - graph->setPlotDirection(Sismograph::LEFT_TO_RIGHT); - graph->reset(); - break; - case Sismograph::RIGHT_TO_LEFT: - graph->setPlotDirection(Sismograph::RIGHT_TO_LEFT); - graph->reset(); - break; - } - }); -} +// void HarmonicCalibration::connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph, int min, int max) +// { +// connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, graph, min, max]() { +// bool ok; +// int value = lineEdit->text().toInt(&ok); +// if (ok && value >= min && value <= max) { +// variable = value; +// graph->setNumSamples(variable); +// } else { +// lineEdit->setText(QString::number(variable)); +// } +// }); +// } + +// void HarmonicCalibration::connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph) +// { +// QComboBox *combo = menuCombo->combo(); +// connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [combo, graph]() { +// int value = qvariant_cast(combo->currentData()); +// switch(value) +// { +// case Sismograph::LEFT_TO_RIGHT: +// graph->setPlotDirection(Sismograph::LEFT_TO_RIGHT); +// graph->reset(); +// break; +// case Sismograph::RIGHT_TO_LEFT: +// graph->setPlotDirection(Sismograph::RIGHT_TO_LEFT); +// graph->reset(); +// break; +// } +// }); +// } void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, double& variable) { @@ -2445,49 +2445,49 @@ void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, int& va }); } -void HarmonicCalibration::changeGraphColorByChannelName(Sismograph* graph, const char* channelName) -{ - int index = m_admtController->getChannelIndex(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), channelName); - if(index > -1){ - graph->setColor(StyleHelper::getColor( QString::fromStdString("CH" + std::to_string(index) ))); - } -} - -void HarmonicCalibration::connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph) -{ - QComboBox *combo = menuCombo->combo(); - connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [this, combo, graph]() { - int currentIndex = combo->currentIndex(); - QVariant currentData = combo->currentData(); - char *value = reinterpret_cast(currentData.value()); - switch(currentIndex) - { - case ADMTController::Channel::ROTATION: - dataGraphValue = &rotation; - graph->setUnitOfMeasure("Degree", "°"); - graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); - graph->setNumSamples(dataGraphSamples); - graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); - break; - case ADMTController::Channel::ANGLE: - dataGraphValue = ∠ - graph->setUnitOfMeasure("Degree", "°"); - graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); - graph->setNumSamples(dataGraphSamples); - graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); - break; - case ADMTController::Channel::COUNT: - dataGraphValue = &count; - graph->setUnitOfMeasure("Count", ""); - graph->setAxisScale(QwtAxis::YLeft, -1.0, 20.0); - graph->setNumSamples(dataGraphSamples); - graph->setAxisTitle(QwtAxis::YLeft, tr("Count")); - break; - } - changeGraphColorByChannelName(graph, value); - graph->reset(); - }); -} +// void HarmonicCalibration::changeGraphColorByChannelName(Sismograph* graph, const char* channelName) +// { +// int index = m_admtController->getChannelIndex(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), channelName); +// if(index > -1){ +// graph->setColor(StyleHelper::getColor( QString::fromStdString("CH" + std::to_string(index) ))); +// } +// } + +// void HarmonicCalibration::connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph) +// { +// QComboBox *combo = menuCombo->combo(); +// connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [this, combo, graph]() { +// int currentIndex = combo->currentIndex(); +// QVariant currentData = combo->currentData(); +// char *value = reinterpret_cast(currentData.value()); +// switch(currentIndex) +// { +// case ADMTController::Channel::ROTATION: +// dataGraphValue = &rotation; +// graph->setUnitOfMeasure("Degree", "°"); +// graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); +// graph->setNumSamples(dataGraphSamples); +// graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); +// break; +// case ADMTController::Channel::ANGLE: +// dataGraphValue = ∠ +// graph->setUnitOfMeasure("Degree", "°"); +// graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); +// graph->setNumSamples(dataGraphSamples); +// graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); +// break; +// case ADMTController::Channel::COUNT: +// dataGraphValue = &count; +// graph->setUnitOfMeasure("Count", ""); +// graph->setAxisScale(QwtAxis::YLeft, -1.0, 20.0); +// graph->setNumSamples(dataGraphSamples); +// graph->setAxisTitle(QwtAxis::YLeft, tr("Count")); +// break; +// } +// changeGraphColorByChannelName(graph, value); +// graph->reset(); +// }); +// } void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax) { diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp index d65a9b41ae..93b6ecbadd 100644 --- a/plugins/admt/src/widgets/registerblockwidget.cpp +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -14,7 +14,7 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui container->setMargin(0); container->setSpacing(0); MenuSectionWidget *menuSectionWidget = new MenuSectionWidget(this); - MenuCollapseSection *menuCollapseSection = new MenuCollapseSection(header, MenuCollapseSection::MHCW_NONE, menuSectionWidget); + MenuCollapseSection *menuCollapseSection = new MenuCollapseSection(header, MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, menuSectionWidget); menuCollapseSection->contentLayout()->setSpacing(10); menuSectionWidget->setFixedHeight(180); menuSectionWidget->contentLayout()->setSpacing(10); From 1077522337b72691990e7edbdcb19cdf938092d2 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 4 Nov 2024 12:12:56 +0800 Subject: [PATCH 060/112] admt: Hide MT Diagnostic indicator and register Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/harmoniccalibration.h | 3 +++ plugins/admt/src/harmoniccalibration.cpp | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 746f547d24..9c5c46d5f6 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -126,6 +126,8 @@ public Q_SLOTS: QCheckBox *autoCalibrateCheckBox; + QScrollArea *MTDiagnosticsScrollArea; + PlotWidget *angleErrorPlotWidget, *calibrationRawDataPlotWidget, *FFTAngleErrorPlotWidget, *correctedErrorPlotWidget, *postCalibrationRawDataPlotWidget, *FFTCorrectedErrorPlotWidget; PlotAxis *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis, @@ -223,6 +225,7 @@ public Q_SLOTS: void startAcquisition(); void getAcquisitionSamples(); void acquisitionUITask(); + void toggleMTDiagnostics(int mode); QTimer *acquisitionUITimer, *calibrationTimer, *utilityTimer; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index e3606b833f..ac55d219b2 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -496,6 +496,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool utilityTimer->start(utilityTimerRate); readSequence(); toggleFaultRegisterMode(generalRegisterMap.at("Sequence Type")); + toggleMTDiagnostics(generalRegisterMap.at("Sequence Type")); } else { utilityTimer->stop(); } }); @@ -1663,7 +1664,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() #pragma endregion #pragma region MT Diagnostics - QScrollArea *MTDiagnosticsScrollArea = new QScrollArea(centerUtilityWidget); + MTDiagnosticsScrollArea = new QScrollArea(centerUtilityWidget); QWidget *MTDiagnosticsWidget = new QWidget(MTDiagnosticsScrollArea); MTDiagnosticsScrollArea->setWidget(MTDiagnosticsWidget); MTDiagnosticsScrollArea->setWidgetResizable(true); @@ -1806,6 +1807,18 @@ void HarmonicCalibration::toggleFaultRegisterMode(int mode) } } +void HarmonicCalibration::toggleMTDiagnostics(int mode) +{ + switch(mode){ + case 0: + MTDiagnosticsScrollArea->hide(); + break; + case 1: + MTDiagnosticsScrollArea->show(); + break; + } +} + void HarmonicCalibration::toggleMotorControls(bool value) { motorMaxVelocitySpinBox->setEnabled(value); From f382e502b33826490b848b23479873da68f74b28 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 4 Nov 2024 13:38:28 +0800 Subject: [PATCH 061/112] admt: Hide registers on sequence mode Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 3 + plugins/admt/src/harmoniccalibration.cpp | 134 +++++++++++------- 2 files changed, 86 insertions(+), 51 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 9c5c46d5f6..5cea512aba 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -150,6 +150,8 @@ public Q_SLOTS: CustomSwitch *calibrationDisplayFormatSwitch, *DIGIOBUSYToggleSwitch, *DIGIOCNVToggleSwitch, *DIGIOSENTToggleSwitch, *DIGIOACALCToggleSwitch, *DIGIOFAULTToggleSwitch, *DIGIOBOOTLOADERToggleSwitch, *DIGIOALLToggleSwitch; + RegisterBlockWidget *cnvPageRegisterBlock, *digIORegisterBlock, *faultRegisterBlock, *generalRegisterBlock, *digIOEnRegisterBlock, *angleCkRegisterBlock, *eccDcdeRegisterBlock, *eccDisRegisterBlock, *absAngleRegisterBlock, *angleRegisterBlock, *angleSecRegisterBlock, *sineRegisterBlock, *cosineRegisterBlock, *secAnglIRegisterBlock, *secAnglQRegisterBlock, *radiusRegisterBlock, *diag1RegisterBlock, *diag2RegisterBlock, *tmp0RegisterBlock, *tmp1RegisterBlock, *cnvCntRegisterBlock, *uniqID0RegisterBlock, *uniqID1RegisterBlock, *uniqID2RegisterBlock, *uniqID3RegisterBlock, *h1MagRegisterBlock, *h1PhRegisterBlock, *h2MagRegisterBlock, *h2PhRegisterBlock, *h3MagRegisterBlock, *h3PhRegisterBlock, *h8MagRegisterBlock, *h8PhRegisterBlock; + void updateChannelValues(); void updateLineEditValues(); void updateGeneralSettingEnabled(bool value); @@ -226,6 +228,7 @@ public Q_SLOTS: void getAcquisitionSamples(); void acquisitionUITask(); void toggleMTDiagnostics(int mode); + void toggleSequenceModeRegisters(int mode); QTimer *acquisitionUITimer, *calibrationTimer, *utilityTimer; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index ac55d219b2..6c2d5ffdcb 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -497,8 +497,14 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool readSequence(); toggleFaultRegisterMode(generalRegisterMap.at("Sequence Type")); toggleMTDiagnostics(generalRegisterMap.at("Sequence Type")); - } + } else { utilityTimer->stop(); } + + if(index == 3) // Registers Tab + { + readSequence(); + toggleSequenceModeRegisters(generalRegisterMap.at("Sequence Type")); + } }); } @@ -1298,65 +1304,65 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerSensorDataGridLayout->setMargin(0); registerSensorDataGridLayout->setSpacing(8); - RegisterBlockWidget *cnvPageRegisterBlock = new RegisterBlockWidget("CNVPAGE", "Convert Start and Page Select", 0x01, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *digIORegisterBlock = new RegisterBlockWidget("DIGIO", "Digital Input Output", 0x04, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *faultRegisterBlock = new RegisterBlockWidget("FAULT", "Fault Register", 0x06, 0xFFFF, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *generalRegisterBlock = new RegisterBlockWidget("GENERAL", "General Device Configuration", 0x10, 0x1230, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *digIOEnRegisterBlock = new RegisterBlockWidget("DIGIOEN", "Enable Digital Input/Outputs", 0x12, 0x241B, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *angleCkRegisterBlock = new RegisterBlockWidget("ANGLECK", "Primary vs Secondary Angle Check", 0x13, 0x000F, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *eccDcdeRegisterBlock = new RegisterBlockWidget("ECCDCDE", "Error Correction Codes", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *eccDisRegisterBlock = new RegisterBlockWidget("ECCDIS", "Error Correction Code disable", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - - RegisterBlockWidget *absAngleRegisterBlock = new RegisterBlockWidget("ABSANGLE", "Absolute Angle", 0x03, 0xDB00, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *angleRegisterBlock = new RegisterBlockWidget("ANGLE", "Angle Register", 0x05, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *angleSecRegisterBlock = new RegisterBlockWidget("ANGLESEC", "Secondary Angle", 0x08, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *sineRegisterBlock = new RegisterBlockWidget("SINE", "Sine Measurement", 0x10, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *cosineRegisterBlock = new RegisterBlockWidget("COSINE", "Cosine Measurement", 0x11, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *secAnglIRegisterBlock = new RegisterBlockWidget("SECANGLI", "In-phase secondary angle measurement", 0x12, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *secAnglQRegisterBlock = new RegisterBlockWidget("SECANGLQ", "Quadrature phase secondary angle measurement", 0x13, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *radiusRegisterBlock = new RegisterBlockWidget("RADIUS", "Angle measurement radius", 0x18, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *diag1RegisterBlock = new RegisterBlockWidget("DIAG1", "State of the MT reference resistors and AFE fixed input voltage", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *diag2RegisterBlock = new RegisterBlockWidget("DIAG2", "Measurements of two diagnostics resistors of fixed value", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *tmp0RegisterBlock = new RegisterBlockWidget("TMP0", "Primary Temperature Sensor", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *tmp1RegisterBlock = new RegisterBlockWidget("TMP1", "Secondary Temperature Sensor", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *cnvCntRegisterBlock = new RegisterBlockWidget("CNVCNT", "Conversion Count", 0x14, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - - RegisterBlockWidget *uniqID0RegisterBlock = new RegisterBlockWidget("UNIQID0", "Unique ID Register 0", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *uniqID1RegisterBlock = new RegisterBlockWidget("UNIQID1", "Unique ID Register 1", 0x1F, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *uniqID2RegisterBlock = new RegisterBlockWidget("UNIQID2", "Unique ID Register 2", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - RegisterBlockWidget *uniqID3RegisterBlock = new RegisterBlockWidget("UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", 0x21, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - - RegisterBlockWidget *h1MagRegisterBlock = new RegisterBlockWidget("H1MAG", "1st Harmonic error magnitude", 0x15, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *h1PhRegisterBlock = new RegisterBlockWidget("H1PH", "1st Harmonic error phase", 0x16, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *h2MagRegisterBlock = new RegisterBlockWidget("H2MAG", "2nd Harmonic error magnitude", 0x17, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *h2PhRegisterBlock = new RegisterBlockWidget("H2PH", "2nd Harmonic error phase", 0x18, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *h3MagRegisterBlock = new RegisterBlockWidget("H3MAG", "3rd Harmonic error magnitude", 0x19, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *h3PhRegisterBlock = new RegisterBlockWidget("H3PH", "3rd Harmonic error phase", 0x1A, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *h8MagRegisterBlock = new RegisterBlockWidget("H8MAG", "8th Harmonic error magnitude", 0x1B, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - RegisterBlockWidget *h8PhRegisterBlock = new RegisterBlockWidget("H8PH", "8th Harmonic error phase", 0x1C, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + cnvPageRegisterBlock = new RegisterBlockWidget("CNVPAGE", "Convert Start and Page Select", 0x01, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + digIORegisterBlock = new RegisterBlockWidget("DIGIO", "Digital Input Output", 0x04, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + faultRegisterBlock = new RegisterBlockWidget("FAULT", "Fault Register", 0x06, 0xFFFF, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + generalRegisterBlock = new RegisterBlockWidget("GENERAL", "General Device Configuration", 0x10, 0x1230, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + digIOEnRegisterBlock = new RegisterBlockWidget("DIGIOEN", "Enable Digital Input/Outputs", 0x12, 0x241B, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + angleCkRegisterBlock = new RegisterBlockWidget("ANGLECK", "Primary vs Secondary Angle Check", 0x13, 0x000F, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + eccDcdeRegisterBlock = new RegisterBlockWidget("ECCDCDE", "Error Correction Codes", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + eccDisRegisterBlock = new RegisterBlockWidget("ECCDIS", "Error Correction Code disable", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + + absAngleRegisterBlock = new RegisterBlockWidget("ABSANGLE", "Absolute Angle", 0x03, 0xDB00, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + angleRegisterBlock = new RegisterBlockWidget("ANGLE", "Angle Register", 0x05, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + angleSecRegisterBlock = new RegisterBlockWidget("ANGLESEC", "Secondary Angle", 0x08, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + sineRegisterBlock = new RegisterBlockWidget("SINE", "Sine Measurement", 0x10, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + cosineRegisterBlock = new RegisterBlockWidget("COSINE", "Cosine Measurement", 0x11, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + secAnglIRegisterBlock = new RegisterBlockWidget("SECANGLI", "In-phase secondary angle measurement", 0x12, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + secAnglQRegisterBlock = new RegisterBlockWidget("SECANGLQ", "Quadrature phase secondary angle measurement", 0x13, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + radiusRegisterBlock = new RegisterBlockWidget("RADIUS", "Angle measurement radius", 0x18, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + diag1RegisterBlock = new RegisterBlockWidget("DIAG1", "State of the MT reference resistors and AFE fixed input voltage", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + diag2RegisterBlock = new RegisterBlockWidget("DIAG2", "Measurements of two diagnostics resistors of fixed value", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + tmp0RegisterBlock = new RegisterBlockWidget("TMP0", "Primary Temperature Sensor", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + tmp1RegisterBlock = new RegisterBlockWidget("TMP1", "Secondary Temperature Sensor", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + cnvCntRegisterBlock = new RegisterBlockWidget("CNVCNT", "Conversion Count", 0x14, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + + uniqID0RegisterBlock = new RegisterBlockWidget("UNIQID0", "Unique ID Register 0", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID1RegisterBlock = new RegisterBlockWidget("UNIQID1", "Unique ID Register 1", 0x1F, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID2RegisterBlock = new RegisterBlockWidget("UNIQID2", "Unique ID Register 2", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID3RegisterBlock = new RegisterBlockWidget("UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", 0x21, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + + h1MagRegisterBlock = new RegisterBlockWidget("H1MAG", "1st Harmonic error magnitude", 0x15, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h1PhRegisterBlock = new RegisterBlockWidget("H1PH", "1st Harmonic error phase", 0x16, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h2MagRegisterBlock = new RegisterBlockWidget("H2MAG", "2nd Harmonic error magnitude", 0x17, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h2PhRegisterBlock = new RegisterBlockWidget("H2PH", "2nd Harmonic error phase", 0x18, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h3MagRegisterBlock = new RegisterBlockWidget("H3MAG", "3rd Harmonic error magnitude", 0x19, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h3PhRegisterBlock = new RegisterBlockWidget("H3PH", "3rd Harmonic error phase", 0x1A, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h8MagRegisterBlock = new RegisterBlockWidget("H8MAG", "8th Harmonic error magnitude", 0x1B, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h8PhRegisterBlock = new RegisterBlockWidget("H8PH", "8th Harmonic error phase", 0x1C, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); registerConfigurationGridLayout->addWidget(cnvPageRegisterBlock, 0, 0); registerConfigurationGridLayout->addWidget(digIORegisterBlock, 0, 1); registerConfigurationGridLayout->addWidget(faultRegisterBlock, 0, 2); registerConfigurationGridLayout->addWidget(generalRegisterBlock, 0, 3); registerConfigurationGridLayout->addWidget(digIOEnRegisterBlock, 0, 4); - registerConfigurationGridLayout->addWidget(angleCkRegisterBlock, 1, 0); - registerConfigurationGridLayout->addWidget(eccDcdeRegisterBlock, 1, 1); - registerConfigurationGridLayout->addWidget(eccDisRegisterBlock, 1, 2); + registerConfigurationGridLayout->addWidget(eccDcdeRegisterBlock, 1, 0); + registerConfigurationGridLayout->addWidget(eccDisRegisterBlock, 1, 1); + registerConfigurationGridLayout->addWidget(angleCkRegisterBlock, 1, 2); registerSensorDataGridLayout->addWidget(absAngleRegisterBlock, 0, 0); registerSensorDataGridLayout->addWidget(angleRegisterBlock, 0, 1); - registerSensorDataGridLayout->addWidget(angleSecRegisterBlock, 0, 2); - registerSensorDataGridLayout->addWidget(sineRegisterBlock, 0, 3); - registerSensorDataGridLayout->addWidget(cosineRegisterBlock, 0, 4); - registerSensorDataGridLayout->addWidget(secAnglIRegisterBlock, 1, 0); - registerSensorDataGridLayout->addWidget(secAnglQRegisterBlock, 1, 1); - registerSensorDataGridLayout->addWidget(radiusRegisterBlock, 1, 2); - registerSensorDataGridLayout->addWidget(diag1RegisterBlock, 1, 3); - registerSensorDataGridLayout->addWidget(diag2RegisterBlock, 1, 4); - registerSensorDataGridLayout->addWidget(tmp0RegisterBlock, 2, 0); - registerSensorDataGridLayout->addWidget(tmp1RegisterBlock, 2, 1); - registerSensorDataGridLayout->addWidget(cnvCntRegisterBlock, 2, 2); + registerSensorDataGridLayout->addWidget(sineRegisterBlock, 0, 2); + registerSensorDataGridLayout->addWidget(cosineRegisterBlock, 0, 3); + registerSensorDataGridLayout->addWidget(cnvCntRegisterBlock, 0, 4); + registerSensorDataGridLayout->addWidget(tmp0RegisterBlock, 1, 0); + registerSensorDataGridLayout->addWidget(tmp1RegisterBlock, 1, 1); + registerSensorDataGridLayout->addWidget(diag1RegisterBlock, 1, 2); + registerSensorDataGridLayout->addWidget(diag2RegisterBlock, 1, 3); + registerSensorDataGridLayout->addWidget(radiusRegisterBlock, 1, 4); + registerSensorDataGridLayout->addWidget(angleSecRegisterBlock, 2, 0); + registerSensorDataGridLayout->addWidget(secAnglIRegisterBlock, 2, 1); + registerSensorDataGridLayout->addWidget(secAnglQRegisterBlock, 2, 2); registerDeviceIDGridLayout->addWidget(uniqID0RegisterBlock, 0, 0); registerDeviceIDGridLayout->addWidget(uniqID1RegisterBlock, 0, 1); @@ -1819,6 +1825,32 @@ void HarmonicCalibration::toggleMTDiagnostics(int mode) } } +void HarmonicCalibration::toggleSequenceModeRegisters(int mode) +{ + switch(mode){ + case 0: + angleSecRegisterBlock->hide(); + secAnglIRegisterBlock->hide(); + secAnglQRegisterBlock->hide(); + tmp1RegisterBlock->hide(); + angleCkRegisterBlock->hide(); + radiusRegisterBlock->hide(); + diag1RegisterBlock->hide(); + diag2RegisterBlock->hide(); + break; + case 1: + angleSecRegisterBlock->show(); + secAnglIRegisterBlock->show(); + secAnglQRegisterBlock->show(); + tmp1RegisterBlock->show(); + angleCkRegisterBlock->show(); + radiusRegisterBlock->show(); + diag1RegisterBlock->show(); + diag2RegisterBlock->show(); + break; + } +} + void HarmonicCalibration::toggleMotorControls(bool value) { motorMaxVelocitySpinBox->setEnabled(value); From bd8e165011167ffec11291cbd327930baeb5b3ad Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 5 Nov 2024 11:46:20 +0800 Subject: [PATCH 062/112] admt: Updated graph style Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 2 + plugins/admt/src/harmoniccalibration.cpp | 37 ++++++++++++------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 5cea512aba..b203bbf212 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -229,6 +229,8 @@ public Q_SLOTS: void acquisitionUITask(); void toggleMTDiagnostics(int mode); void toggleSequenceModeRegisters(int mode); + void readAllRegisters(); + void applyPlotWidgetStyle(PlotWidget *widget); QTimer *acquisitionUITimer, *calibrationTimer, *utilityTimer; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 6c2d5ffdcb..9c546c2231 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -578,16 +578,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationSamplesLayout->setSpacing(0); calibrationRawDataPlotWidget = new PlotWidget(); - calibrationRawDataPlotWidget->setContentsMargins(10, 20, 10, 10); - calibrationRawDataPlotWidget->xAxis()->setVisible(false); - calibrationRawDataPlotWidget->yAxis()->setVisible(false); + applyPlotWidgetStyle(calibrationRawDataPlotWidget); calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, scopyBluePen); + calibrationRawDataXPlotAxis->setMin(0); calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, scopyBluePen); calibrationRawDataYPlotAxis->setInterval(0, 400); calibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - calibrationRawDataPlotChannel->xAxis()->setMin(0); calibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); calibrationCosineDataPlotChannel = new PlotChannel("Cosine", cosinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); @@ -598,11 +596,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationSineDataPlotChannel->setEnabled(true); calibrationCosineDataPlotChannel->setEnabled(true); calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); - calibrationRawDataPlotWidget->replot(); - calibrationRawDataPlotWidget->setShowXAxisLabels(true); - calibrationRawDataPlotWidget->setShowYAxisLabels(true); - calibrationRawDataPlotWidget->showAxisLabels(); + calibrationRawDataPlotWidget->replot(); QWidget *calibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); QHBoxLayout *calibrationDataGraphChannelsLayout = new QHBoxLayout(calibrationDataGraphChannelsWidget); @@ -636,7 +631,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() postCalibrationSamplesLayout->setSpacing(0); postCalibrationRawDataPlotWidget = new PlotWidget(); - postCalibrationRawDataPlotWidget->setContentsMargins(10, 20, 10, 10); + applyPlotWidgetStyle(postCalibrationRawDataPlotWidget); postCalibrationRawDataPlotWidget->xAxis()->setVisible(false); postCalibrationRawDataPlotWidget->yAxis()->setVisible(false); @@ -703,7 +698,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() angleErrorLayout->setSpacing(0); angleErrorPlotWidget = new PlotWidget(); - angleErrorPlotWidget->setContentsMargins(10, 20, 10, 10); + applyPlotWidgetStyle(angleErrorPlotWidget); angleErrorPlotWidget->xAxis()->setVisible(false); angleErrorPlotWidget->yAxis()->setVisible(false); @@ -734,7 +729,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTAngleErrorLayout->setSpacing(0); FFTAngleErrorPlotWidget = new PlotWidget(); - FFTAngleErrorPlotWidget->setContentsMargins(10, 20, 10, 10); + applyPlotWidgetStyle(FFTAngleErrorPlotWidget); FFTAngleErrorPlotWidget->xAxis()->setVisible(false); FFTAngleErrorPlotWidget->yAxis()->setVisible(false); @@ -783,7 +778,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() correctedErrorLayout->setSpacing(0); correctedErrorPlotWidget = new PlotWidget(); - correctedErrorPlotWidget->setContentsMargins(10, 20, 10, 10); + applyPlotWidgetStyle(correctedErrorPlotWidget); correctedErrorPlotWidget->xAxis()->setVisible(false); correctedErrorPlotWidget->yAxis()->setVisible(false); @@ -814,7 +809,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTCorrectedErrorLayout->setSpacing(0); FFTCorrectedErrorPlotWidget = new PlotWidget(); - FFTCorrectedErrorPlotWidget->setContentsMargins(10, 20, 10, 10); + applyPlotWidgetStyle(FFTCorrectedErrorPlotWidget); FFTCorrectedErrorPlotWidget->xAxis()->setVisible(false); FFTCorrectedErrorPlotWidget->yAxis()->setVisible(false); @@ -1388,7 +1383,12 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() for(int c=0; c < registerHarmonicsGridLayout->columnCount(); ++c) registerHarmonicsGridLayout->setColumnStretch(c,1); for(int c=0; c < registerSensorDataGridLayout->columnCount(); ++c) registerSensorDataGridLayout->setColumnStretch(c,1); + QPushButton *readAllRegistersButton = new QPushButton("Read All Registers", registerWidget); + StyleHelper::BlueButton(readAllRegistersButton, "readAllRegistersButton"); + connect(readAllRegistersButton, &QPushButton::clicked, this, &HarmonicCalibration::readAllRegisters); + // registerLayout->addWidget(registerGridWidget); + registerLayout->addWidget(readAllRegistersButton); registerLayout->addWidget(registerConfigurationLabel); registerLayout->addWidget(registerConfigurationGridWidget); registerLayout->addWidget(registerSensorDataLabel); @@ -1791,6 +1791,11 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() return tool; } +void HarmonicCalibration::readAllRegisters() +{ + +} + void HarmonicCalibration::toggleFaultRegisterMode(int mode) { switch(mode){ @@ -3365,4 +3370,10 @@ void HarmonicCalibration::applyTabWidgetStyle(QTabWidget *widget, const QString& style.replace("&&ScopyBlue&&", StyleHelper::getColor(styleHelperColor)); style.replace("&&UIElementBackground&&", StyleHelper::getColor("UIElementBackground")); widget->tabBar()->setStyleSheet(style); +} + +void HarmonicCalibration::applyPlotWidgetStyle(PlotWidget *widget) +{ + widget->setContentsMargins(10, 10, 10, 6); + widget->plot()->canvas()->setStyleSheet("background-color: black;"); } \ No newline at end of file From 5718ea2b1483da6e983037e87285cdca98221db0 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 6 Nov 2024 09:08:41 +0800 Subject: [PATCH 063/112] admt: Add read all registers - Changed register block widget to include CNVPAGE Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 14 +- .../admt/include/admt/harmoniccalibration.h | 12 +- .../admt/widgets/registerblockwidget.h | 5 +- plugins/admt/src/admtcontroller.cpp | 11 +- plugins/admt/src/harmoniccalibration.cpp | 300 ++++++++++-------- .../admt/src/widgets/registerblockwidget.cpp | 10 +- 6 files changed, 205 insertions(+), 147 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index afe71319ae..68c5f84d15 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -155,25 +155,27 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject const char* MotorAttributes[MOTOR_ATTR_COUNT] = { "amax", "rotate_vmax", "dmax", "disable", "target_pos", "current_pos", "ramp_mode" }; - const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = { 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C }; const uint32_t ConfigurationRegisters[CONFIGURATION_REGISTER_COUNT] = { 0x01, 0x04, 0x06, 0x10, 0x12, 0x13, 0x1D, 0x23 }; const uint32_t ConfigurationPages[CONFIGURATION_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x02, 0x02, 0x02, 0x02, 0x02 }; - const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = { 0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14 }; - const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }; const uint32_t UniqueIdRegisters[UNIQID_REGISTER_COUNT] = { 0x1E, 0x1F, 0x20, 0x21 }; const uint32_t UniqueIdPages[UNIQID_REGISTER_COUNT] = { 0x02, 0x02, 0x02, 0x02 }; + const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = { 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C }; + const uint32_t HarmonicPages[HARMONIC_REGISTER_COUNT] = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }; + const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = { 0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14 }; + const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }; const char* getChannelId(Channel channel); const char* getDeviceId(Device device); const char* getDeviceAttribute(DeviceAttribute attribute); const char* getMotorAttribute(MotorAttribute attribute); - const uint32_t getHarmonicRegister(HarmonicRegister registerID); const uint32_t getConfigurationRegister(ConfigurationRegister registerID); const uint32_t getConfigurationPage(ConfigurationRegister registerID); - const uint32_t getSensorRegister(SensorRegister registerID); - const uint32_t getSensorPage(SensorRegister registerID); const uint32_t getUniqueIdRegister(UniqueIDRegister registerID); + const uint32_t getHarmonicRegister(HarmonicRegister registerID); + const uint32_t getHarmonicPage(HarmonicRegister registerID); const uint32_t getUniqueIdPage(UniqueIDRegister registerID); + const uint32_t getSensorRegister(SensorRegister registerID); + const uint32_t getSensorPage(SensorRegister registerID); void connectADMT(); void disconnectADMT(); diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index b203bbf212..5543732800 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -68,7 +70,7 @@ public Q_SLOTS: void clearCommandLog(); void canCalibrate(bool); void applySequence(); - void readSequence(); + bool readSequence(); Q_SIGNALS: void runningChanged(bool); void canCalibrateChanged(bool); @@ -85,7 +87,7 @@ public Q_SLOTS: afeDiag0, afeDiag1, afeDiag2; QPushButton *openLastMenuButton, *calibrationStartMotorButton, *applyCalibrationDataButton, *calibrateDataButton, *extractDataButton, - *clearCommandLogButton, *applySequenceButton; + *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; QButtonGroup *rightMenuButtonGroup; QLineEdit *graphUpdateIntervalLineEdit, *dataSampleSizeLineEdit, @@ -174,8 +176,8 @@ public Q_SLOTS: void importCalibrationData(); void calibrationLogWrite(QString message = ""); void commandLogWrite(QString message); - void readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value); - void writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); + int readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value); + int writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); void applyLineEditStyle(QLineEdit *widget); void applyComboBoxStyle(QComboBox *widget, const QString& styleHelperColor = "CH0"); void applyTextStyle(QWidget *widget, const QString& styleHelperColor = "CH0", bool isBold = false); @@ -201,7 +203,7 @@ public Q_SLOTS: void updateFaultRegister(); void updateMTDiagnostics(); void changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked = true); - bool changeCNVPage(uint32_t page, QString registerName); + bool changeCNVPage(uint32_t page); void toggleWidget(QPushButton *widget, bool value); void GMRReset(); void updateCountValue(); diff --git a/plugins/admt/include/admt/widgets/registerblockwidget.h b/plugins/admt/include/admt/widgets/registerblockwidget.h index f94b1e6e21..8e05d6c247 100644 --- a/plugins/admt/include/admt/widgets/registerblockwidget.h +++ b/plugins/admt/include/admt/widgets/registerblockwidget.h @@ -25,18 +25,19 @@ namespace scopy::admt { QPushButton *m_readButton, *m_writeButton; - RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t defaultValue, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent = nullptr); + RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t cnvPage, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent = nullptr); virtual ~RegisterBlockWidget(); QPushButton *readButton(); QPushButton *writeButton(); uint32_t getAddress(); + uint32_t getCnvPage(); uint32_t getValue(); void setValue(uint32_t value); RegisterBlockWidget::ACCESS_PERMISSION getAccessPermission(); public Q_SLOTS: void onValueChanged(int); private: - uint32_t m_address, m_value; + uint32_t m_address, m_value, m_cnvPage; RegisterBlockWidget::ACCESS_PERMISSION m_accessPermission; QSpinBox *m_spinBox; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 08779258ed..b535681dde 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -17,7 +17,6 @@ #include #include - static const size_t maxAttrSize = 512; using namespace scopy::admt; @@ -86,7 +85,15 @@ const uint32_t ADMTController::getHarmonicRegister(HarmonicRegister registerID) if(registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT){ return HarmonicRegisters[registerID]; } - return 0x0; + return UINT32_MAX; +} + +const uint32_t ADMTController::getHarmonicPage(HarmonicRegister registerID) +{ + if(registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT){ + return HarmonicPages[registerID]; + } + return UINT32_MAX; } const uint32_t ADMTController::getConfigurationRegister(ConfigurationRegister registerID) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 9c546c2231..5447e160e6 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -4,9 +4,6 @@ #include #include -#include -#include - static int acquisitionUITimerRate = 50; static int calibrationTimerRate = 1000; static int utilityTimerRate = 1000; @@ -1001,7 +998,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatSwitch); calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffLabel); calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffWidget); - // calibrationCoeffSectionWidget->contentLayout()->addWidget(applyCalibrationDataButton); #pragma endregion #pragma region Calibration Dataset Configuration @@ -1039,9 +1035,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDataSectionWidget->contentLayout()->setSpacing(8); calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); - // QPushButton *importDataButton = new QPushButton(calibrationDataCollapseSection); - // importDataButton->setText("Import from CSV"); - // StyleHelper::BlueButton(importDataButton, "importDataButton"); QPushButton *extractDataButton = new QPushButton(calibrationDataCollapseSection); extractDataButton->setText("Extract to CSV"); StyleHelper::BlueButton(extractDataButton, "extractDataButton"); @@ -1050,7 +1043,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() StyleHelper::BlueButton(clearCalibrateDataButton, "clearCalibrateDataButton"); calibrationDataCollapseSection->contentLayout()->setSpacing(8); - // calibrationDataCollapseSection->contentLayout()->addWidget(importDataButton); calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); calibrationDataCollapseSection->contentLayout()->addWidget(clearCalibrateDataButton); #pragma endregion @@ -1142,16 +1134,12 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrateDataButton->setEnabled(false); StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); - // autoCalibrateCheckBox = new QCheckBox("Auto Calibrate", motorControlSectionWidget); - // StyleHelper::BlueSquareCheckbox(autoCalibrateCheckBox, "autoCalibrateCheckBox"); - motorControlCollapseSection->contentLayout()->setSpacing(8); motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); motorControlCollapseSection->contentLayout()->addWidget(calibrationMotorCurrentPositionLabel); motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionSpinBox); motorControlCollapseSection->contentLayout()->addWidget(calibrationStartMotorButton); motorControlCollapseSection->contentLayout()->addWidget(calibrateDataButton); - // motorControlCollapseSection->contentLayout()->addWidget(autoCalibrateCheckBox); #pragma endregion #pragma region Logs Section Widget @@ -1195,17 +1183,12 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::postCalibrateData); connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); - // connect(importDataButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::clearRawDataList); connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); connectLineEditToNumberWrite(motorMaxDisplacementSpinBox->lineEdit(), dmax, ADMTController::MotorAttribute::DMAX); connectLineEditToNumberWrite(motorTargetPositionSpinBox->lineEdit(), target_pos, ADMTController::MotorAttribute::TARGET_POS); connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); - // connect(autoCalibrateCheckBox, &QCheckBox::toggled, [=](bool toggled){ - // autoCalibrate = toggled; - // StatusBarManager::pushMessage(QString("Auto Calibrate: ") + QString((toggled ? "True" : "False"))); - // }); connect(toggleAngleButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); @@ -1299,42 +1282,42 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerSensorDataGridLayout->setMargin(0); registerSensorDataGridLayout->setSpacing(8); - cnvPageRegisterBlock = new RegisterBlockWidget("CNVPAGE", "Convert Start and Page Select", 0x01, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - digIORegisterBlock = new RegisterBlockWidget("DIGIO", "Digital Input Output", 0x04, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - faultRegisterBlock = new RegisterBlockWidget("FAULT", "Fault Register", 0x06, 0xFFFF, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - generalRegisterBlock = new RegisterBlockWidget("GENERAL", "General Device Configuration", 0x10, 0x1230, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - digIOEnRegisterBlock = new RegisterBlockWidget("DIGIOEN", "Enable Digital Input/Outputs", 0x12, 0x241B, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - angleCkRegisterBlock = new RegisterBlockWidget("ANGLECK", "Primary vs Secondary Angle Check", 0x13, 0x000F, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - eccDcdeRegisterBlock = new RegisterBlockWidget("ECCDCDE", "Error Correction Codes", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - eccDisRegisterBlock = new RegisterBlockWidget("ECCDIS", "Error Correction Code disable", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - - absAngleRegisterBlock = new RegisterBlockWidget("ABSANGLE", "Absolute Angle", 0x03, 0xDB00, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - angleRegisterBlock = new RegisterBlockWidget("ANGLE", "Angle Register", 0x05, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - angleSecRegisterBlock = new RegisterBlockWidget("ANGLESEC", "Secondary Angle", 0x08, 0x8000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - sineRegisterBlock = new RegisterBlockWidget("SINE", "Sine Measurement", 0x10, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - cosineRegisterBlock = new RegisterBlockWidget("COSINE", "Cosine Measurement", 0x11, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - secAnglIRegisterBlock = new RegisterBlockWidget("SECANGLI", "In-phase secondary angle measurement", 0x12, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - secAnglQRegisterBlock = new RegisterBlockWidget("SECANGLQ", "Quadrature phase secondary angle measurement", 0x13, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - radiusRegisterBlock = new RegisterBlockWidget("RADIUS", "Angle measurement radius", 0x18, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - diag1RegisterBlock = new RegisterBlockWidget("DIAG1", "State of the MT reference resistors and AFE fixed input voltage", 0x1D, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - diag2RegisterBlock = new RegisterBlockWidget("DIAG2", "Measurements of two diagnostics resistors of fixed value", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - tmp0RegisterBlock = new RegisterBlockWidget("TMP0", "Primary Temperature Sensor", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - tmp1RegisterBlock = new RegisterBlockWidget("TMP1", "Secondary Temperature Sensor", 0x23, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - cnvCntRegisterBlock = new RegisterBlockWidget("CNVCNT", "Conversion Count", 0x14, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - - uniqID0RegisterBlock = new RegisterBlockWidget("UNIQID0", "Unique ID Register 0", 0x1E, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - uniqID1RegisterBlock = new RegisterBlockWidget("UNIQID1", "Unique ID Register 1", 0x1F, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - uniqID2RegisterBlock = new RegisterBlockWidget("UNIQID2", "Unique ID Register 2", 0x20, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - uniqID3RegisterBlock = new RegisterBlockWidget("UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", 0x21, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - - h1MagRegisterBlock = new RegisterBlockWidget("H1MAG", "1st Harmonic error magnitude", 0x15, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h1PhRegisterBlock = new RegisterBlockWidget("H1PH", "1st Harmonic error phase", 0x16, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h2MagRegisterBlock = new RegisterBlockWidget("H2MAG", "2nd Harmonic error magnitude", 0x17, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h2PhRegisterBlock = new RegisterBlockWidget("H2PH", "2nd Harmonic error phase", 0x18, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h3MagRegisterBlock = new RegisterBlockWidget("H3MAG", "3rd Harmonic error magnitude", 0x19, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h3PhRegisterBlock = new RegisterBlockWidget("H3PH", "3rd Harmonic error phase", 0x1A, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h8MagRegisterBlock = new RegisterBlockWidget("H8MAG", "8th Harmonic error magnitude", 0x1B, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h8PhRegisterBlock = new RegisterBlockWidget("H8PH", "8th Harmonic error phase", 0x1C, 0x0000, RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + cnvPageRegisterBlock = new RegisterBlockWidget("CNVPAGE", "Convert Start and Page Select", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::CNVPAGE), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + digIORegisterBlock = new RegisterBlockWidget("DIGIO", "Digital Input Output", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIO), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIO), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + faultRegisterBlock = new RegisterBlockWidget("FAULT", "Fault Register", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::FAULT), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + generalRegisterBlock = new RegisterBlockWidget("GENERAL", "General Device Configuration", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + digIOEnRegisterBlock = new RegisterBlockWidget("DIGIOEN", "Enable Digital Input/Outputs", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + angleCkRegisterBlock = new RegisterBlockWidget("ANGLECK", "Primary vs Secondary Angle Check", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ANGLECK), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ANGLECK), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + eccDcdeRegisterBlock = new RegisterBlockWidget("ECCDCDE", "Error Correction Codes", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ECCDCDE), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCDCDE), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + eccDisRegisterBlock = new RegisterBlockWidget("ECCDIS", "Error Correction Code disable", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ECCDIS), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCDIS), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + + absAngleRegisterBlock = new RegisterBlockWidget("ABSANGLE", "Absolute Angle", m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), m_admtController->getSensorPage(ADMTController::SensorRegister::ABSANGLE), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + angleRegisterBlock = new RegisterBlockWidget("ANGLE", "Angle Register", m_admtController->getSensorRegister(ADMTController::SensorRegister::ANGLEREG), m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLEREG), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + angleSecRegisterBlock = new RegisterBlockWidget("ANGLESEC", "Secondary Angle", m_admtController->getSensorRegister(ADMTController::SensorRegister::ANGLESEC), m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLESEC), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + sineRegisterBlock = new RegisterBlockWidget("SINE", "Sine Measurement", m_admtController->getSensorRegister(ADMTController::SensorRegister::SINE), m_admtController->getSensorPage(ADMTController::SensorRegister::SINE), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + cosineRegisterBlock = new RegisterBlockWidget("COSINE", "Cosine Measurement", m_admtController->getSensorRegister(ADMTController::SensorRegister::COSINE), m_admtController->getSensorPage(ADMTController::SensorRegister::COSINE), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + secAnglIRegisterBlock = new RegisterBlockWidget("SECANGLI", "In-phase secondary angle measurement", m_admtController->getSensorRegister(ADMTController::SensorRegister::SECANGLI), m_admtController->getSensorPage(ADMTController::SensorRegister::SECANGLI), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + secAnglQRegisterBlock = new RegisterBlockWidget("SECANGLQ", "Quadrature phase secondary angle measurement", m_admtController->getSensorRegister(ADMTController::SensorRegister::SECANGLQ), m_admtController->getSensorPage(ADMTController::SensorRegister::SECANGLQ), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + radiusRegisterBlock = new RegisterBlockWidget("RADIUS", "Angle measurement radius", m_admtController->getSensorRegister(ADMTController::SensorRegister::RADIUS), m_admtController->getSensorPage(ADMTController::SensorRegister::RADIUS), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + diag1RegisterBlock = new RegisterBlockWidget("DIAG1", "State of the MT reference resistors and AFE fixed input voltage", m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1), m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + diag2RegisterBlock = new RegisterBlockWidget("DIAG2", "Measurements of two diagnostics resistors of fixed value", m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG2), m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + tmp0RegisterBlock = new RegisterBlockWidget("TMP0", "Primary Temperature Sensor", m_admtController->getSensorRegister(ADMTController::SensorRegister::TMP0), m_admtController->getSensorPage(ADMTController::SensorRegister::TMP0), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + tmp1RegisterBlock = new RegisterBlockWidget("TMP1", "Secondary Temperature Sensor", m_admtController->getSensorRegister(ADMTController::SensorRegister::TMP1), m_admtController->getSensorPage(ADMTController::SensorRegister::TMP1), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + cnvCntRegisterBlock = new RegisterBlockWidget("CNVCNT", "Conversion Count", m_admtController->getSensorRegister(ADMTController::SensorRegister::CNVCNT), m_admtController->getSensorPage(ADMTController::SensorRegister::CNVCNT), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + + uniqID0RegisterBlock = new RegisterBlockWidget("UNIQID0", "Unique ID Register 0", m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID0), m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID0), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID1RegisterBlock = new RegisterBlockWidget("UNIQID1", "Unique ID Register 1", m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID1), m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID1), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID2RegisterBlock = new RegisterBlockWidget("UNIQID2", "Unique ID Register 2", m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID2), m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID2), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID3RegisterBlock = new RegisterBlockWidget("UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID3), m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + + h1MagRegisterBlock = new RegisterBlockWidget("H1MAG", "1st Harmonic error magnitude", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1MAG), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h1PhRegisterBlock = new RegisterBlockWidget("H1PH", "1st Harmonic error phase", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1PH), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h2MagRegisterBlock = new RegisterBlockWidget("H2MAG", "2nd Harmonic error magnitude", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H2MAG), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h2PhRegisterBlock = new RegisterBlockWidget("H2PH", "2nd Harmonic error phase", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H2PH), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h3MagRegisterBlock = new RegisterBlockWidget("H3MAG", "3rd Harmonic error magnitude", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H3MAG), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h3PhRegisterBlock = new RegisterBlockWidget("H3PH", "3rd Harmonic error phase", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H3PH), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h8MagRegisterBlock = new RegisterBlockWidget("H8MAG", "8th Harmonic error magnitude", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H8MAG), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h8PhRegisterBlock = new RegisterBlockWidget("H8PH", "8th Harmonic error phase", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H8PH), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); registerConfigurationGridLayout->addWidget(cnvPageRegisterBlock, 0, 0); registerConfigurationGridLayout->addWidget(digIORegisterBlock, 0, 1); @@ -1375,19 +1358,16 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerHarmonicsGridLayout->addWidget(h8MagRegisterBlock, 1, 1); registerHarmonicsGridLayout->addWidget(h8PhRegisterBlock, 1, 2); - - // for(int c=0; c < registerGridLayout->columnCount(); ++c) registerGridLayout->setColumnStretch(c,1); - // for(int r=0; r < registerGridLayout->rowCount(); ++r) registerGridLayout->setRowStretch(r,1); for(int c=0; c < registerConfigurationGridLayout->columnCount(); ++c) registerConfigurationGridLayout->setColumnStretch(c,1); for(int c=0; c < registerDeviceIDGridLayout->columnCount(); ++c) registerDeviceIDGridLayout->setColumnStretch(c,1); for(int c=0; c < registerHarmonicsGridLayout->columnCount(); ++c) registerHarmonicsGridLayout->setColumnStretch(c,1); for(int c=0; c < registerSensorDataGridLayout->columnCount(); ++c) registerSensorDataGridLayout->setColumnStretch(c,1); - QPushButton *readAllRegistersButton = new QPushButton("Read All Registers", registerWidget); + readAllRegistersButton = new QPushButton("Read All Registers", registerWidget); StyleHelper::BlueButton(readAllRegistersButton, "readAllRegistersButton"); + readAllRegistersButton->setFixedWidth(270); connect(readAllRegistersButton, &QPushButton::clicked, this, &HarmonicCalibration::readAllRegisters); - // registerLayout->addWidget(registerGridWidget); registerLayout->addWidget(readAllRegistersButton); registerLayout->addWidget(registerConfigurationLabel); registerLayout->addWidget(registerConfigurationGridWidget); @@ -1493,7 +1473,6 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() centerUtilityWidget->setLayout(centerUtilityLayout); centerUtilityLayout->setMargin(0); centerUtilityLayout->setSpacing(8); - // centerUtilityLayout->setAlignment(Qt::AlignTop); QScrollArea *DIGIOScrollArea = new QScrollArea(centerUtilityWidget); QWidget *DIGIOWidget = new QWidget(DIGIOScrollArea); @@ -1718,8 +1697,6 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() centerUtilityLayout->addWidget(DIGIOScrollArea); centerUtilityLayout->addWidget(MTDiagnosticsScrollArea); - // centerUtilityLayout->addWidget(MTDIAG1SectionWidget, 0, Qt::AlignTop); - // centerUtilityLayout->addWidget(MTDiagnosticsSectionWidget, 0, Qt::AlignTop); #pragma endregion @@ -1793,7 +1770,49 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() void HarmonicCalibration::readAllRegisters() { + readAllRegistersButton->setEnabled(false); + readAllRegistersButton->setText(QString("Reading Registers...")); + QTimer::singleShot(1000, this, [this](){ + readAllRegistersButton->setEnabled(true); + readAllRegistersButton->setText(QString("Read All Registers")); + }); + cnvPageRegisterBlock->readButton()->click(); + digIORegisterBlock->readButton()->click(); + faultRegisterBlock->readButton()->click(); + generalRegisterBlock->readButton()->click(); + digIOEnRegisterBlock->readButton()->click(); + eccDcdeRegisterBlock->readButton()->click(); + eccDisRegisterBlock->readButton()->click(); + absAngleRegisterBlock->readButton()->click(); + angleRegisterBlock->readButton()->click(); + sineRegisterBlock->readButton()->click(); + cosineRegisterBlock->readButton()->click(); + tmp0RegisterBlock->readButton()->click(); + cnvCntRegisterBlock->readButton()->click(); + uniqID0RegisterBlock->readButton()->click(); + uniqID1RegisterBlock->readButton()->click(); + uniqID2RegisterBlock->readButton()->click(); + uniqID3RegisterBlock->readButton()->click(); + h1MagRegisterBlock->readButton()->click(); + h1PhRegisterBlock->readButton()->click(); + h2MagRegisterBlock->readButton()->click(); + h2PhRegisterBlock->readButton()->click(); + h3MagRegisterBlock->readButton()->click(); + h3PhRegisterBlock->readButton()->click(); + h8MagRegisterBlock->readButton()->click(); + h8PhRegisterBlock->readButton()->click(); + + if(generalRegisterMap.at("Sequence Type") == 1){ + angleSecRegisterBlock->readButton()->click(); + secAnglIRegisterBlock->readButton()->click(); + secAnglQRegisterBlock->readButton()->click(); + tmp1RegisterBlock->readButton()->click(); + angleCkRegisterBlock->readButton()->click(); + radiusRegisterBlock->readButton()->click(); + diag1RegisterBlock->readButton()->click(); + diag2RegisterBlock->readButton()->click(); + } } void HarmonicCalibration::toggleFaultRegisterMode(int mode) @@ -1882,7 +1901,9 @@ void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) uint32_t *DIGIOENRegisterValue = new uint32_t; uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - if(changeCNVPage(DIGIOENPage, "DIGIOEN")) + bool success = false; + + if(changeCNVPage(DIGIOENPage)) { if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), @@ -1893,7 +1914,7 @@ void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); - changeCNVPage(DIGIOENPage, "DIGIOEN"); + changeCNVPage(DIGIOENPage); if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), @@ -1910,14 +1931,14 @@ void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) DIGIOACALCToggleSwitch->setChecked(DIGIOSettings["DIGIO3EN"]); DIGIOFAULTToggleSwitch->setChecked(DIGIOSettings["DIGIO4EN"]); DIGIOBOOTLOADERToggleSwitch->setChecked(DIGIOSettings["DIGIO5EN"]); - //StatusBarManager::pushMessage(QString::fromStdString(DIGIOENName) + " is " + QString(value ? "enabled" : "disabled")); + success = true; } - else{ StatusBarManager::pushMessage("Failed to read DIGIOEN Register"); } } - else{ StatusBarManager::pushMessage("Failed to write DIGIOEN Register"); } } } + if(!success) { StatusBarManager::pushMessage("Failed to toggle" + QString::fromStdString(DIGIOENName) + " " + QString(value ? "on" : "off")); } + toggleUtilityTask(true); } @@ -1927,6 +1948,8 @@ void HarmonicCalibration::toggleAllDIGIO(bool value) uint32_t *DIGIOENRegisterValue = new uint32_t; uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + bool success = false; + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), DIGIOENRegisterValue) != -1) @@ -1940,7 +1963,7 @@ void HarmonicCalibration::toggleAllDIGIO(bool value) DIGIOSettings["DIGIO0EN"] = value; uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); - changeCNVPage(DIGIOENPage, "DIGIOEN"); + changeCNVPage(DIGIOENPage); if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), static_cast(newRegisterValue)) != -1) @@ -1956,13 +1979,13 @@ void HarmonicCalibration::toggleAllDIGIO(bool value) DIGIOACALCToggleSwitch->setChecked(DIGIOSettings["DIGIO3EN"]); DIGIOFAULTToggleSwitch->setChecked(DIGIOSettings["DIGIO4EN"]); DIGIOBOOTLOADERToggleSwitch->setChecked(DIGIOSettings["DIGIO5EN"]); - StatusBarManager::pushMessage("GPIO Outputs are " + QString(value ? "enabled" : "disabled")); + success = true; } - else{ StatusBarManager::pushMessage("Failed to read DIGIOEN Register"); } - } - else{ StatusBarManager::pushMessage("Failed to write DIGIOEN Register"); } } + + if(!success) { StatusBarManager::pushMessage("Failed to toggle all GPIO outputs " + QString(value ? "on" : "off")); } + toggleUtilityTask(true); } @@ -1973,48 +1996,31 @@ void HarmonicCalibration::readDeviceProperties() uint32_t page = m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3); uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + bool success = false; + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, page) != -1){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ if(*cnvPageRegValue == page){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID3), uniqId3RegisterValue) != -1){ deviceRegisterMap = m_admtController->getUNIQID3RegisterMapping(static_cast(*uniqId3RegisterValue)); - if(deviceRegisterMap.at("Supply ID") == "5V") - { - is5V = true; - } - else if(deviceRegisterMap.at("Supply ID") == "3.3V") - { - is5V = false; - } - else - { - is5V = false; - } + if(deviceRegisterMap.at("Supply ID") == "5V") { is5V = true; } + else if(deviceRegisterMap.at("Supply ID") == "3.3V") { is5V = false; } + else { is5V = false; } deviceName = QString::fromStdString(deviceRegisterMap.at("Product ID")); - if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") - { - deviceType = QString::fromStdString("Industrial"); - } - else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") - { - deviceType = QString::fromStdString("Automotive"); - } - else{ - deviceType = QString::fromStdString(deviceRegisterMap.at("ASIL ID")); - } - } - else{ StatusBarManager::pushMessage("Failed to read UNIQID3 register"); } + if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { deviceType = QString::fromStdString("Industrial"); } + else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { deviceType = QString::fromStdString("Automotive"); } + else { deviceType = QString::fromStdString(deviceRegisterMap.at("ASIL ID")); } + success = true; + } } - else{ StatusBarManager::pushMessage("CNVPAGE for UNIQID3 is a different value, abort reading"); } } - else{ StatusBarManager::pushMessage("Failed to read CNVPAGE for UNIQID3"); } } - else{ StatusBarManager::pushMessage("Failed to write CNVPAGE for UNIQID3"); } + + if(!success) { StatusBarManager::pushMessage("Failed to read device properties"); } } void HarmonicCalibration::changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel) @@ -2103,7 +2109,7 @@ void HarmonicCalibration::acquisitionUITask() void HarmonicCalibration::applySequence(){ toggleWidget(applySequenceButton, false); applySequenceButton->setText("Writing..."); - QTimer::singleShot(2000, this, [this](){ + QTimer::singleShot(1000, this, [this](){ this->toggleWidget(applySequenceButton, true); applySequenceButton->setText("Apply"); }); @@ -2123,37 +2129,52 @@ void HarmonicCalibration::applySequence(){ uint32_t newGeneralRegValue = m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings); uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); - if(changeCNVPage(generalRegisterPage, "GENERAL")){ + bool success = false; + + if(changeCNVPage(generalRegisterPage)){ if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, newGeneralRegValue) != -1){ //StatusBarManager::pushMessage("WRITE GENERAL: 0b" + QString::number(static_cast(newGeneralRegValue), 2).rightJustified(16, '0')); - readSequence(); + if(readSequence()){ + if(settings.at("Convert Synchronization") == generalRegisterMap.at("Convert Synchronization") && + settings.at("Angle Filter") == generalRegisterMap.at("Angle Filter") && + settings.at("8th Harmonic") == generalRegisterMap.at("8th Harmonic") && + settings.at("Sequence Type") == generalRegisterMap.at("Sequence Type") && + settings.at("Conversion Type") == generalRegisterMap.at("Conversion Type")) + { + StatusBarManager::pushMessage("Sequence settings applied successfully"); + success = true; + } + } } - else{ StatusBarManager::pushMessage("Failed to write GENERAL Register"); } } + + if(!success){ StatusBarManager::pushMessage("Failed to apply sequence settings"); } } void HarmonicCalibration::toggleWidget(QPushButton *widget, bool value){ widget->setEnabled(value); } -void HarmonicCalibration::readSequence(){ +bool HarmonicCalibration::readSequence(){ uint32_t *generalRegValue = new uint32_t; uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); - if(changeCNVPage(generalRegisterPage, "GENERAL")){ + bool success = false; + + if(changeCNVPage(generalRegisterPage)){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ if(*generalRegValue != UINT32_MAX){ generalRegisterMap = m_admtController->getGeneralRegisterBitMapping(static_cast(*generalRegValue)); updateSequenceWidget(); - - //StatusBarManager::pushMessage("READ GENERAL: 0b" + QString::number(static_cast(*generalRegValue), 2).rightJustified(16, '0')); + success = true; } } - else{ StatusBarManager::pushMessage("Failed to read GENERAL Register"); } } + + return success; } void HarmonicCalibration::updateSequenceWidget(){ @@ -2167,7 +2188,7 @@ void HarmonicCalibration::updateSequenceWidget(){ eighthHarmonicMenuCombo->combo()->setCurrentIndex(eighthHarmonicMenuCombo->combo()->findData(generalRegisterMap.at("8th Harmonic"))); } -bool HarmonicCalibration::changeCNVPage(uint32_t page, QString registerName){ +bool HarmonicCalibration::changeCNVPage(uint32_t page){ uint32_t *cnvPageRegValue = new uint32_t; uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); @@ -2176,11 +2197,8 @@ bool HarmonicCalibration::changeCNVPage(uint32_t page, QString registerName){ if(*cnvPageRegValue == page){ return true; } - else{ StatusBarManager::pushMessage("CNVPAGE for " + registerName + " is a different value, abort reading"); } } - else{ StatusBarManager::pushMessage("Failed to read CNVPAGE for " + registerName); } } - else{ StatusBarManager::pushMessage("Failed to write CNVPAGE for " + registerName); } return false; } @@ -2196,7 +2214,7 @@ void HarmonicCalibration::utilityTask(){ void HarmonicCalibration::updateDigioMonitor(){ uint32_t *digioRegValue = new uint32_t; uint32_t digioEnPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - if(changeCNVPage(digioEnPage, "DIGIOEN")) + if(changeCNVPage(digioEnPage)) { uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN); @@ -2576,17 +2594,43 @@ void HarmonicCalibration::connectRegisterBlockToRegistry(RegisterBlockWidget* wi { uint32_t *readValue = new uint32_t; connect(widget->readButton(), &QPushButton::clicked, this, [=]{ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) - { widget->setValue(*readValue); } + bool ok = false, success = false; + + if(widget->getCnvPage() != UINT32_MAX) + { + ok = this->changeCNVPage(widget->getCnvPage()); + } + else { ok = true; } + + if(ok){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) + { widget->setValue(*readValue); } + } + else{ StatusBarManager::pushMessage("Failed to read registry"); } }); if(widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::READWRITE || widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::WRITE){ connect(widget->writeButton(), &QPushButton::clicked, this, [=]{ - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), widget->getValue()) == 0) - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) - { widget->setValue(*readValue); } + bool ok = false, success = false; + + if(widget->getCnvPage() != UINT32_MAX) + { + ok = this->changeCNVPage(widget->getCnvPage()); } + else { ok = true; } + + if(ok){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), widget->getValue()) == 0) + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) + { + widget->setValue(*readValue); + success = true; + } + } + } + + if(!success) { StatusBarManager::pushMessage("Failed to write to registry"); } }); } } @@ -2649,24 +2693,26 @@ void HarmonicCalibration::updateChannelValue(int channelIndex) } } -void HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value) +int HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value) { + int result = -1; if(!isDebug){ - int result = m_admtController->getDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), + result = m_admtController->getDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), m_admtController->getMotorAttribute(attribute), &value); - if(result != 0) { calibrationLogWrite(QString(m_admtController->getMotorAttribute(attribute)) + ": Read Error " + QString::number(result)); } } + return result; } -void HarmonicCalibration::writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value) +int HarmonicCalibration::writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value) { + int result = -1; if(!isDebug){ - int result = m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), + result = m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), m_admtController->getMotorAttribute(attribute), value); - if(result != 0) { calibrationLogWrite(QString(m_admtController->getMotorAttribute(attribute)) + ": Write Error " + QString::number(result)); } } + return result; } void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute) @@ -2883,7 +2929,7 @@ void HarmonicCalibration::flashHarmonicValues() *h8MagCurrent = new uint32_t, *h8PhaseCurrent = new uint32_t; - if(changeCNVPage(0x02, "Harmonic Registers")){ + if(changeCNVPage(0x02)){ m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp index 93b6ecbadd..f2b22f97a2 100644 --- a/plugins/admt/src/widgets/registerblockwidget.cpp +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -4,9 +4,10 @@ using namespace scopy; using namespace scopy::admt; -RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t defaultValue, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent) +RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t cnvPage, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent) : QWidget(parent) , m_address(address) + , m_cnvPage(cnvPage) , m_accessPermission(accessPermission) { QVBoxLayout *container = new QVBoxLayout(this); @@ -40,13 +41,10 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui descriptionLabel->setAlignment(Qt::AlignTop); descriptionLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); - // QLineEdit *lineEdit = new QLineEdit(menuSectionWidget); - // applyLineEditStyle(lineEdit); - m_spinBox = new PaddedSpinBox(menuSectionWidget); applySpinBoxStyle(m_spinBox); - m_value = defaultValue; + m_value = 0x00; m_spinBox->setValue(m_value); QWidget *buttonsWidget = new QWidget(menuSectionWidget); @@ -95,6 +93,8 @@ void RegisterBlockWidget::setValue(uint32_t value) uint32_t RegisterBlockWidget::getAddress() { return m_address; } +uint32_t RegisterBlockWidget::getCnvPage() { return m_cnvPage; } + RegisterBlockWidget::ACCESS_PERMISSION RegisterBlockWidget::getAccessPermission() { return m_accessPermission; } void RegisterBlockWidget::addReadButton(QWidget *parent) From 77d144a665642d5816012de532dd549127cb2f9c Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Tue, 12 Nov 2024 11:33:42 +0800 Subject: [PATCH 064/112] admt: Reverted changes to calibration samples graph Signed-off-by: dpineda2 Signed-off-by: JJuanill --- plugins/admt/src/harmoniccalibration.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 5447e160e6..92835a5820 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -580,7 +580,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, scopyBluePen); calibrationRawDataXPlotAxis->setMin(0); calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, scopyBluePen); - calibrationRawDataYPlotAxis->setInterval(0, 400); + calibrationRawDataYPlotAxis->setInterval(0, 400); calibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); calibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); @@ -594,6 +594,10 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationCosineDataPlotChannel->setEnabled(true); calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); + calibrationRawDataPlotWidget->setShowXAxisLabels(true); + calibrationRawDataPlotWidget->setShowYAxisLabels(true); + calibrationRawDataPlotWidget->showAxisLabels(); + calibrationRawDataPlotWidget->replot(); QWidget *calibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); From 747e20c023398a5ad2318abb665e5e145c37579f Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Wed, 13 Nov 2024 07:28:13 +0800 Subject: [PATCH 065/112] admt: Initial implement of style helper Signed-off-by: dpineda2 Signed-off-by: JJuanill --- plugins/admt/include/admt/admtstylehelper.h | 37 +++ .../admt/include/admt/harmoniccalibration.h | 5 +- plugins/admt/src/admtstylehelper.cpp | 149 +++++++++++ plugins/admt/src/harmoniccalibration.cpp | 232 ++++-------------- 4 files changed, 231 insertions(+), 192 deletions(-) create mode 100644 plugins/admt/include/admt/admtstylehelper.h create mode 100644 plugins/admt/src/admtstylehelper.cpp diff --git a/plugins/admt/include/admt/admtstylehelper.h b/plugins/admt/include/admt/admtstylehelper.h new file mode 100644 index 0000000000..e20c2f60e2 --- /dev/null +++ b/plugins/admt/include/admt/admtstylehelper.h @@ -0,0 +1,37 @@ +#ifndef ADMTSTYLEHELPER_H +#define ADMTSTYLEHELPER_H + +#include "scopy-admt_export.h" +#include "stylehelper.h" + +#include +#include +#include + +#include + +namespace scopy { +namespace admt{ +class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject +{ + Q_OBJECT +protected: + ADMTStyleHelper(QObject *parent = nullptr); + ~ADMTStyleHelper(); +public: + // singleton + ADMTStyleHelper(ADMTStyleHelper &other) = delete; + void operator=(const ADMTStyleHelper &) = delete; + static ADMTStyleHelper *GetInstance(); +public: + static void TopContainerButtonStyle(QPushButton *btn, QString objectName = ""); + static void PlotWidgetStyle(PlotWidget *widget, QString objectName = ""); + static void ComboBoxStyle(QComboBox *widget, QString objectName = ""); + static void LineEditStyle(QLineEdit *widget, QString objectName = ""); +private: + static ADMTStyleHelper *pinstance_; +}; +} // namespace admt +} // namespace scopy + +#endif // ADMTSTYLEHELPER_H \ No newline at end of file diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 5543732800..b11f74189a 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -130,7 +130,7 @@ public Q_SLOTS: QScrollArea *MTDiagnosticsScrollArea; - PlotWidget *angleErrorPlotWidget, *calibrationRawDataPlotWidget, *FFTAngleErrorPlotWidget, + PlotWidget *acquisitionGraphWidget, *angleErrorPlotWidget, *calibrationRawDataPlotWidget, *FFTAngleErrorPlotWidget, *correctedErrorPlotWidget, *postCalibrationRawDataPlotWidget, *FFTCorrectedErrorPlotWidget; PlotAxis *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis, *angleErrorXPlotAxis, *angleErrorYPlotAxis, *FFTAngleErrorXPlotAxis, *FFTAngleErrorYPlotAxis, @@ -178,8 +178,6 @@ public Q_SLOTS: void commandLogWrite(QString message); int readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value); int writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); - void applyLineEditStyle(QLineEdit *widget); - void applyComboBoxStyle(QComboBox *widget, const QString& styleHelperColor = "CH0"); void applyTextStyle(QWidget *widget, const QString& styleHelperColor = "CH0", bool isBold = false); void applyLabelStyle(QLabel *widget); void initializeMotor(); @@ -232,7 +230,6 @@ public Q_SLOTS: void toggleMTDiagnostics(int mode); void toggleSequenceModeRegisters(int mode); void readAllRegisters(); - void applyPlotWidgetStyle(PlotWidget *widget); QTimer *acquisitionUITimer, *calibrationTimer, *utilityTimer; diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp new file mode 100644 index 0000000000..f7aae2664b --- /dev/null +++ b/plugins/admt/src/admtstylehelper.cpp @@ -0,0 +1,149 @@ +#include "admtstylehelper.h" +#include "stylehelper.h" + +using namespace scopy::admt; + +ADMTStyleHelper *ADMTStyleHelper::pinstance_{nullptr}; + +ADMTStyleHelper:: ADMTStyleHelper(QObject *parent) {} + +ADMTStyleHelper *ADMTStyleHelper::GetInstance() +{ + if(pinstance_ == nullptr) { + pinstance_ = new ADMTStyleHelper(QApplication::instance()); // singleton has the app as parent + } + return pinstance_; +} + +ADMTStyleHelper::~ADMTStyleHelper() {} + +void ADMTStyleHelper::TopContainerButtonStyle(QPushButton *btn, QString objectName) +{ + if(!objectName.isEmpty()) + btn->setObjectName(objectName); + QString style = QString(R"css( + QPushButton { + width: 88px; + height: 48px; + border-radius: 2px; + padding-left: 20px; + padding-right: 20px; + color: white; + font-weight: 700; + font-size: 14px; + background-color: &&ScopyBlue&&; + } + + QPushButton:disabled { + background-color:#727273; /* design token - uiElement*/ + } + + QPushButton:checked { + background-color:#272730; /* design token - scopy blue*/ + } + QPushButton:pressed { + background-color:#272730; + } + })css"); + style.replace("&&ScopyBlue&&", StyleHelper::getColor("ScopyBlue")); + btn->setStyleSheet(style); +} + +void ADMTStyleHelper::PlotWidgetStyle(PlotWidget *widget, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + widget->setContentsMargins(10, 10, 10, 6); + widget->plot()->canvas()->setStyleSheet("background-color: black;"); +} + +void ADMTStyleHelper::ComboBoxStyle(QComboBox *widget, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + QString style = QString(R"css( + QWidget { + } + QComboBox { + text-align: right; + color: &&colorname&&; + border-radius: 4px; + height: 30px; + border-bottom: 0px solid none; + padding-left: 12px; + padding-right: 12px; + font-weight: normal; + font-size: 16px; + background-color: black; + } + QComboBox:disabled, QLineEdit:disabled { + background-color: #18181d; + color: #9c4600; + } + QComboBox QAbstractItemView { + border: none; + color: transparent; + outline: none; + background-color: black; + border-bottom: 0px solid transparent; + border-top: 0px solid transparent; + } + QComboBox QAbstractItemView::item { + text-align: right; + } + QComboBox::item:selected { + font-weight: bold; + font-size: 18px; + background-color: transparent; + } + QComboBox::drop-down { + border-image: none; + border: 0px; + width: 16px; + height: 16px; + margin-right: 12px; + } + QComboBox::down-arrow { + image: url(:/admt/chevron-down-s.svg); + } + QComboBox::indicator { + background-color: transparent; + selection-background-color: transparent; + color: transparent; + selection-color: transparent; + } + )css"); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + widget->setStyleSheet(style); + widget->setFixedHeight(30); +} + +void ADMTStyleHelper::LineEditStyle(QLineEdit *widget, QString objectName) +{ + QString style = QString(R"css( + QLineEdit { + font-family: Open Sans; + font-size: 16px; + font-weight: normal; + text-align: right; + color: &&colorname&&; + + background-color: black; + border-radius: 4px; + border: none; + } + + QLineEdit:disabled { + background-color: #18181d; + color: #9c4600; + } + )css"); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setContentsMargins(0, 0, 0, 0); + widget->setTextMargins(12, 4, 12, 4); + widget->setAlignment(Qt::AlignRight); +} + +#include "moc_admtstylehelper.cpp" \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 92835a5820..32bcbde776 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -3,6 +3,7 @@ #include #include +#include static int acquisitionUITimerRate = 50; static int calibrationTimerRate = 1000; @@ -83,11 +84,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool setLayout(lay); lay->setMargin(0); tabWidget = new QTabWidget(this); - tabWidget->setObjectName("HarmonicTabWidget"); - QString tabWidgetStyle = QString(R"css( - QTabWidget::tab-bar { left: 240px; } - )css"); - tabWidget->tabBar()->setStyleSheet(tabWidgetStyle); tabWidget->addTab(tool, "Acquisition"); openLastMenuButton = new OpenLastMenuBtn(dynamic_cast(tool->rightContainer()), true, this); @@ -100,37 +96,12 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool QPushButton *resetGMRButton = new QPushButton(this); resetGMRButton->setText("GMR Reset"); - QString topContainerButtonStyle = QString(R"css( - QPushButton { - width: 88px; - height: 48px; - border-radius: 2px; - padding-left: 20px; - padding-right: 20px; - color: white; - font-weight: 700; - font-size: 14px; - background-color: &&ScopyBlue&&; - } - - QPushButton:disabled { - background-color:#727273; /* design token - uiElement*/ - } - - QPushButton:checked { - background-color:#272730; /* design token - scopy blue*/ - } - QPushButton:pressed { - background-color:#272730; - } - })css"); - topContainerButtonStyle.replace("&&ScopyBlue&&", StyleHelper::getColor("ScopyBlue")); - resetGMRButton->setStyleSheet(topContainerButtonStyle); + ADMTStyleHelper::TopContainerButtonStyle(resetGMRButton); connect(resetGMRButton, &QPushButton::clicked, this, &HarmonicCalibration::GMRReset); rightMenuButtonGroup->addButton(settingsButton); - // Raw Data Widget + #pragma region Raw Data Widget QScrollArea *rawDataScroll = new QScrollArea(this); rawDataScroll->setWidgetResizable(true); QWidget *rawDataWidget = new QWidget(rawDataScroll); @@ -196,7 +167,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool auto calibrationMotorRampModeCombo = m_calibrationMotorRampModeMenuCombo->combo(); calibrationMotorRampModeCombo->addItem("Position", QVariant(ADMTController::MotorRampMode::POSITION)); calibrationMotorRampModeCombo->addItem("Ramp Mode 1", QVariant(ADMTController::MotorRampMode::RAMP_MODE_1)); - applyComboBoxStyle(calibrationMotorRampModeCombo); + ADMTStyleHelper::ComboBoxStyle(calibrationMotorRampModeCombo); motorConfigurationCollapseSection->contentLayout()->setSpacing(8); motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxVelocitySpinBox); @@ -231,44 +202,22 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool rawDataLayout->addWidget(motorConfigurationSectionWidget); rawDataLayout->addWidget(motorControlSectionWidget); rawDataLayout->addStretch(); + #pragma endregion + + #pragma region Acquisition Graph Section Widget + MenuSectionWidget *acquisitionGraphSectionWidget = new MenuSectionWidget(this); + MenuCollapseSection *acquisitionGraphCollapseSection = new MenuCollapseSection("Captured Data", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, acquisitionGraphSectionWidget); + acquisitionGraphSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + acquisitionGraphSectionWidget->contentLayout()->addWidget(acquisitionGraphCollapseSection); - QWidget *historicalGraphWidget = new QWidget(); - QVBoxLayout *historicalGraphLayout = new QVBoxLayout(this); - - QLabel *dataGraphLabel = new QLabel(historicalGraphWidget); - dataGraphLabel->setText("Phase"); - StyleHelper::MenuSmallLabel(dataGraphLabel, "dataGraphLabel"); - - // dataGraph = new Sismograph(this); - // changeGraphColorByChannelName(dataGraph, rotationChannelName); - // dataGraph->setPlotAxisXTitle("Degree (°)"); - // dataGraph->setUnitOfMeasure("Degree", "°"); - // dataGraph->setAutoscale(false); - // dataGraph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); - // dataGraph->setHistoryDuration(10.0); - // dataGraphValue = &rotation; - - QLabel *tempGraphLabel = new QLabel(historicalGraphWidget); - tempGraphLabel->setText("Temperature"); - StyleHelper::MenuSmallLabel(tempGraphLabel, "tempGraphLabel"); - - // tempGraph = new Sismograph(this); - // changeGraphColorByChannelName(tempGraph, temperatureChannelName); - // tempGraph->setPlotAxisXTitle("Celsius (°C)"); - // tempGraph->setUnitOfMeasure("Celsius", "°C"); - // tempGraph->setAutoscale(false); - // tempGraph->setAxisScale(QwtAxis::YLeft, 0.0, 100.0); - // tempGraph->setHistoryDuration(10.0); - // tempGraphValue = &temp; - - historicalGraphLayout->addWidget(dataGraphLabel); - // historicalGraphLayout->addWidget(dataGraph); - historicalGraphLayout->addWidget(tempGraphLabel); - // historicalGraphLayout->addWidget(tempGraph); - - historicalGraphWidget->setLayout(historicalGraphLayout); - - // General Setting + acquisitionGraphWidget = new PlotWidget(); + ADMTStyleHelper::PlotWidgetStyle(acquisitionGraphWidget); + acquisitionGraphWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + + acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphWidget); + #pragma endregion + + #pragma region General Setting QScrollArea *generalSettingScroll = new QScrollArea(this); generalSettingScroll->setWidgetResizable(true); QWidget *generalSettingWidget = new QWidget(generalSettingScroll); @@ -292,7 +241,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool graphUpdateIntervalLabel->setText("Graph Update Interval (ms)"); StyleHelper::MenuSmallLabel(graphUpdateIntervalLabel, "graphUpdateIntervalLabel"); graphUpdateIntervalLineEdit = new QLineEdit(generalSection); - applyLineEditStyle(graphUpdateIntervalLineEdit); + ADMTStyleHelper::LineEditStyle(graphUpdateIntervalLineEdit); graphUpdateIntervalLineEdit->setText(QString::number(acquisitionUITimerRate)); connectLineEditToNumber(graphUpdateIntervalLineEdit, acquisitionUITimerRate, 1, 5000); @@ -305,7 +254,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool dataSampleSizeLabel->setText("Data Sample Size"); StyleHelper::MenuSmallLabel(dataSampleSizeLabel, "dataSampleSizeLabel"); dataSampleSizeLineEdit = new QLineEdit(generalSection); - applyLineEditStyle(dataSampleSizeLineEdit); + ADMTStyleHelper::LineEditStyle(dataSampleSizeLineEdit); dataSampleSizeLineEdit->setText(QString::number(bufferSize)); connectLineEditToNumber(dataSampleSizeLineEdit, bufferSize, 1, 2048); @@ -325,31 +274,31 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool { sequenceTypeComboBox->addItem("Mode 2", QVariant(1)); } - applyComboBoxStyle(sequenceTypeComboBox); + ADMTStyleHelper::ComboBoxStyle(sequenceTypeComboBox); conversionTypeMenuCombo = new MenuCombo("Conversion Type", sequenceSection); QComboBox *conversionTypeComboBox = conversionTypeMenuCombo->combo(); conversionTypeComboBox->addItem("Continuous conversions", QVariant(0)); conversionTypeComboBox->addItem("One-shot conversion", QVariant(1)); - applyComboBoxStyle(conversionTypeComboBox); + ADMTStyleHelper::ComboBoxStyle(conversionTypeComboBox); convertSynchronizationMenuCombo = new MenuCombo("Convert Synchronization", sequenceSection); QComboBox *convertSynchronizationComboBox = convertSynchronizationMenuCombo->combo(); convertSynchronizationComboBox->addItem("Enabled", QVariant(1)); convertSynchronizationComboBox->addItem("Disabled", QVariant(0)); - applyComboBoxStyle(convertSynchronizationComboBox); + ADMTStyleHelper::ComboBoxStyle(convertSynchronizationComboBox); angleFilterMenuCombo = new MenuCombo("Angle Filter", sequenceSection); QComboBox *angleFilterComboBox = angleFilterMenuCombo->combo(); angleFilterComboBox->addItem("Enabled", QVariant(1)); angleFilterComboBox->addItem("Disabled", QVariant(0)); - applyComboBoxStyle(angleFilterComboBox); + ADMTStyleHelper::ComboBoxStyle(angleFilterComboBox); eighthHarmonicMenuCombo = new MenuCombo("8th Harmonic", sequenceSection); QComboBox *eighthHarmonicComboBox = eighthHarmonicMenuCombo->combo(); eighthHarmonicComboBox->addItem("User-Supplied Values", QVariant(1)); eighthHarmonicComboBox->addItem("ADI Factory Values", QVariant(0)); - applyComboBoxStyle(eighthHarmonicComboBox); + ADMTStyleHelper::ComboBoxStyle(eighthHarmonicComboBox); readSequence(); @@ -377,7 +326,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool dataGraphChannelCombo->addItem("Rotation", QVariant::fromValue(reinterpret_cast(const_cast(rotationChannelName)))); dataGraphChannelCombo->addItem("Angle", QVariant::fromValue(reinterpret_cast(const_cast(angleChannelName)))); dataGraphChannelCombo->addItem("Count", QVariant::fromValue(reinterpret_cast(const_cast(countChannelName)))); - applyComboBoxStyle(dataGraphChannelCombo); + ADMTStyleHelper::ComboBoxStyle(dataGraphChannelCombo); // connectMenuComboToGraphChannel(m_dataGraphChannelMenuCombo, dataGraph); @@ -388,7 +337,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool dataGraphSamplesLabel->setText("Samples"); StyleHelper::MenuSmallLabel(dataGraphSamplesLabel, "dataGraphSamplesLabel"); dataGraphSamplesLineEdit = new QLineEdit(generalSection); - applyLineEditStyle(dataGraphSamplesLineEdit); + ADMTStyleHelper::LineEditStyle(dataGraphSamplesLineEdit); dataGraphSamplesLineEdit->setText(QString::number(dataGraphSamples)); // connectLineEditToGraphSamples(dataGraphSamplesLineEdit, dataGraphSamples, dataGraph, 1, 5000); @@ -410,7 +359,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool tempGraphSamplesLabel->setText("Samples"); StyleHelper::MenuSmallLabel(tempGraphSamplesLabel, "tempGraphSamplesLabel"); tempGraphSamplesLineEdit = new QLineEdit(generalSection); - applyLineEditStyle(tempGraphSamplesLineEdit); + ADMTStyleHelper::LineEditStyle(tempGraphSamplesLineEdit); tempGraphSamplesLineEdit->setText(QString::number(tempGraphSamples)); tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLabel); tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLineEdit); @@ -426,16 +375,16 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool generalSettingLayout->addWidget(dataGraphWidget); generalSettingLayout->addWidget(tempGraphWidget); generalSettingLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + #pragma endregion tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); tool->topContainer()->setVisible(true); tool->leftContainer()->setVisible(true); tool->rightContainer()->setVisible(true); - tool->bottomContainer()->setVisible(true); + tool->bottomContainer()->setVisible(false); tool->setLeftContainerWidth(210); tool->setRightContainerWidth(300); tool->setTopContainerHeight(100); - tool->setBottomContainerHeight(90); tool->openBottomContainerHelper(false); tool->openTopContainerHelper(false); tool->addWidgetToTopContainerMenuControlHelper(openLastMenuButton, TTA_RIGHT); @@ -444,7 +393,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); tool->leftStack()->add("rawDataScroll", rawDataScroll); tool->rightStack()->add("generalSettingScroll", generalSettingScroll); - tool->addWidgetToCentralContainerHelper(historicalGraphWidget); + tool->addWidgetToCentralContainerHelper(acquisitionGraphSectionWidget); connect(runButton, &QPushButton::toggled, this, &HarmonicCalibration::setRunning); connect(this, &HarmonicCalibration::runningChanged, this, &HarmonicCalibration::run); @@ -575,7 +524,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationSamplesLayout->setSpacing(0); calibrationRawDataPlotWidget = new PlotWidget(); - applyPlotWidgetStyle(calibrationRawDataPlotWidget); + ADMTStyleHelper::PlotWidgetStyle(calibrationRawDataPlotWidget); calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, scopyBluePen); calibrationRawDataXPlotAxis->setMin(0); @@ -632,7 +581,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() postCalibrationSamplesLayout->setSpacing(0); postCalibrationRawDataPlotWidget = new PlotWidget(); - applyPlotWidgetStyle(postCalibrationRawDataPlotWidget); + ADMTStyleHelper::PlotWidgetStyle(postCalibrationRawDataPlotWidget); postCalibrationRawDataPlotWidget->xAxis()->setVisible(false); postCalibrationRawDataPlotWidget->yAxis()->setVisible(false); @@ -699,7 +648,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() angleErrorLayout->setSpacing(0); angleErrorPlotWidget = new PlotWidget(); - applyPlotWidgetStyle(angleErrorPlotWidget); + ADMTStyleHelper::PlotWidgetStyle(angleErrorPlotWidget); angleErrorPlotWidget->xAxis()->setVisible(false); angleErrorPlotWidget->yAxis()->setVisible(false); @@ -730,7 +679,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTAngleErrorLayout->setSpacing(0); FFTAngleErrorPlotWidget = new PlotWidget(); - applyPlotWidgetStyle(FFTAngleErrorPlotWidget); + ADMTStyleHelper::PlotWidgetStyle(FFTAngleErrorPlotWidget); FFTAngleErrorPlotWidget->xAxis()->setVisible(false); FFTAngleErrorPlotWidget->yAxis()->setVisible(false); @@ -779,7 +728,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() correctedErrorLayout->setSpacing(0); correctedErrorPlotWidget = new PlotWidget(); - applyPlotWidgetStyle(correctedErrorPlotWidget); + ADMTStyleHelper::PlotWidgetStyle(correctedErrorPlotWidget); correctedErrorPlotWidget->xAxis()->setVisible(false); correctedErrorPlotWidget->yAxis()->setVisible(false); @@ -810,7 +759,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTCorrectedErrorLayout->setSpacing(0); FFTCorrectedErrorPlotWidget = new PlotWidget(); - applyPlotWidgetStyle(FFTCorrectedErrorPlotWidget); + ADMTStyleHelper::PlotWidgetStyle(FFTCorrectedErrorPlotWidget); FFTCorrectedErrorPlotWidget->xAxis()->setVisible(false); FFTCorrectedErrorPlotWidget->yAxis()->setVisible(false); @@ -1013,14 +962,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", calibrationDatasetConfigCollapseSection); StyleHelper::MenuSmallLabel(calibrationCycleCountLabel); QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(calibrationDatasetConfigCollapseSection); - applyLineEditStyle(calibrationCycleCountLineEdit); + ADMTStyleHelper::LineEditStyle(calibrationCycleCountLineEdit); calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 1000); QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", calibrationDatasetConfigCollapseSection); StyleHelper::MenuSmallLabel(calibrationSamplesPerCycleLabel); QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationDatasetConfigCollapseSection); - applyLineEditStyle(calibrationSamplesPerCycleLineEdit); + ADMTStyleHelper::LineEditStyle(calibrationSamplesPerCycleLineEdit); calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); calibrationSamplesPerCycleLineEdit->setReadOnly(true); connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, 1, 5000); @@ -1067,7 +1016,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() auto calibrationMotorRampModeCombo = m_calibrationMotorRampModeMenuCombo->combo(); calibrationMotorRampModeCombo->addItem("Position", QVariant(ADMTController::MotorRampMode::POSITION)); calibrationMotorRampModeCombo->addItem("Ramp Mode 1", QVariant(ADMTController::MotorRampMode::RAMP_MODE_1)); - applyComboBoxStyle(calibrationMotorRampModeCombo); + ADMTStyleHelper::ComboBoxStyle(calibrationMotorRampModeCombo); motorConfigurationCollapseSection->contentLayout()->setSpacing(8); motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxVelocitySpinBox); @@ -1677,9 +1626,9 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() AFEDIAG0LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); AFEDIAG1LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); AFEDIAG2LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); - applyLineEditStyle(AFEDIAG0LineEdit); - applyLineEditStyle(AFEDIAG1LineEdit); - applyLineEditStyle(AFEDIAG2LineEdit); + ADMTStyleHelper::LineEditStyle(AFEDIAG0LineEdit); + ADMTStyleHelper::LineEditStyle(AFEDIAG1LineEdit); + ADMTStyleHelper::LineEditStyle(AFEDIAG2LineEdit); AFEDIAG0LineEdit->setReadOnly(true); AFEDIAG1LineEdit->setReadOnly(true); AFEDIAG2LineEdit->setReadOnly(true); @@ -3276,93 +3225,6 @@ void HarmonicCalibration::clearCalibrationSamples() calibrationRawDataPlotWidget->replot(); } -void HarmonicCalibration::applyLineEditStyle(QLineEdit *widget) -{ - QString style = QString(R"css( - QLineEdit { - font-family: Open Sans; - font-size: 16px; - font-weight: normal; - text-align: right; - color: &&colorname&&; - - background-color: black; - border-radius: 4px; - border: none; - } - - QLineEdit:disabled { - background-color: #18181d; - color: #9c4600; - } - )css"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setContentsMargins(0, 0, 0, 0); - widget->setTextMargins(12, 4, 12, 4); - widget->setAlignment(Qt::AlignRight); -} - -void HarmonicCalibration::applyComboBoxStyle(QComboBox *widget, const QString& styleHelperColor) -{ - QString style = QString(R"css( - QWidget { - } - QComboBox { - text-align: right; - color: &&colorname&&; - border-radius: 4px; - height: 30px; - border-bottom: 0px solid none; - padding-left: 12px; - padding-right: 12px; - font-weight: normal; - font-size: 16px; - background-color: black; - } - QComboBox:disabled, QLineEdit:disabled { - background-color: #18181d; - color: #9c4600; - } - QComboBox QAbstractItemView { - border: none; - color: transparent; - outline: none; - background-color: black; - border-bottom: 0px solid transparent; - border-top: 0px solid transparent; - } - QComboBox QAbstractItemView::item { - text-align: right; - } - QComboBox::item:selected { - font-weight: bold; - font-size: 18px; - background-color: transparent; - } - QComboBox::drop-down { - border-image: none; - border: 0px; - width: 16px; - height: 16px; - margin-right: 12px; - } - QComboBox::down-arrow { - image: url(:/admt/chevron-down-s.svg); - } - QComboBox::indicator { - background-color: transparent; - selection-background-color: transparent; - color: transparent; - selection-color: transparent; - } - )css"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor(styleHelperColor)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); -} - void HarmonicCalibration::applyTextStyle(QWidget *widget, const QString& styleHelperColor, bool isBold) { QString existingStyle = widget->styleSheet(); @@ -3420,10 +3282,4 @@ void HarmonicCalibration::applyTabWidgetStyle(QTabWidget *widget, const QString& style.replace("&&ScopyBlue&&", StyleHelper::getColor(styleHelperColor)); style.replace("&&UIElementBackground&&", StyleHelper::getColor("UIElementBackground")); widget->tabBar()->setStyleSheet(style); -} - -void HarmonicCalibration::applyPlotWidgetStyle(PlotWidget *widget) -{ - widget->setContentsMargins(10, 10, 10, 6); - widget->plot()->canvas()->setStyleSheet("background-color: black;"); } \ No newline at end of file From fcc372cbefd0c9cfd7d01d1821b4399f2089e0eb Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Wed, 13 Nov 2024 09:22:28 +0800 Subject: [PATCH 066/112] admt: Included import samples in calibration data - Initialized acquisition graph axes Signed-off-by: dpineda2 Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 6 +-- plugins/admt/src/harmoniccalibration.cpp | 39 ++++++++++++++----- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index b11f74189a..f815e6cf6d 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -130,13 +130,13 @@ public Q_SLOTS: QScrollArea *MTDiagnosticsScrollArea; - PlotWidget *acquisitionGraphWidget, *angleErrorPlotWidget, *calibrationRawDataPlotWidget, *FFTAngleErrorPlotWidget, + PlotWidget *acquisitionGraphPlotWidget, *angleErrorPlotWidget, *calibrationRawDataPlotWidget, *FFTAngleErrorPlotWidget, *correctedErrorPlotWidget, *postCalibrationRawDataPlotWidget, *FFTCorrectedErrorPlotWidget; - PlotAxis *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis, + PlotAxis *acquisitionXPlotAxis, *acquisitionYPlotAxis, *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis, *angleErrorXPlotAxis, *angleErrorYPlotAxis, *FFTAngleErrorXPlotAxis, *FFTAngleErrorYPlotAxis, *correctedErrorXPlotAxis, *correctedErrorYPlotAxis, *FFTCorrectedErrorXPlotAxis, *FFTCorrectedErrorYPlotAxis, *postCalibrationRawDataXPlotAxis, *postCalibrationRawDataYPlotAxis; - PlotChannel *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel, + PlotChannel *acquisitionAnglePlotChannel, *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel, *FFTAngleErrorMagnitudeChannel, *FFTAngleErrorPhaseChannel, *correctedErrorPlotChannel, *postCalibrationRawDataPlotChannel, *postCalibrationSineDataPlotChannel, *postCalibrationCosineDataPlotChannel, diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 32bcbde776..a6189a61a2 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -210,11 +210,28 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool acquisitionGraphSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); acquisitionGraphSectionWidget->contentLayout()->addWidget(acquisitionGraphCollapseSection); - acquisitionGraphWidget = new PlotWidget(); - ADMTStyleHelper::PlotWidgetStyle(acquisitionGraphWidget); - acquisitionGraphWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + acquisitionGraphPlotWidget = new PlotWidget(); + ADMTStyleHelper::PlotWidgetStyle(acquisitionGraphPlotWidget); + acquisitionGraphPlotWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphWidget); + acquisitionGraphPlotWidget->setShowXAxisLabels(true); + acquisitionGraphPlotWidget->setShowYAxisLabels(true); + acquisitionGraphPlotWidget->showAxisLabels(); + + acquisitionXPlotAxis = new PlotAxis(QwtAxis::XBottom, acquisitionGraphPlotWidget, scopyBluePen); + acquisitionXPlotAxis->setMin(0); + acquisitionYPlotAxis = new PlotAxis(QwtAxis::YLeft, acquisitionGraphPlotWidget, scopyBluePen); + acquisitionYPlotAxis->setInterval(0, 400); + + acquisitionAnglePlotChannel = new PlotChannel("Angle", scopyBluePen, acquisitionXPlotAxis, acquisitionYPlotAxis); + + acquisitionGraphPlotWidget->addPlotChannel(acquisitionAnglePlotChannel); + acquisitionAnglePlotChannel->setEnabled(true); + acquisitionGraphPlotWidget->selectChannel(acquisitionAnglePlotChannel); + + acquisitionGraphPlotWidget->replot(); + + acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphPlotWidget); #pragma endregion #pragma region General Setting @@ -988,14 +1005,15 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDataSectionWidget->contentLayout()->setSpacing(8); calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); - QPushButton *extractDataButton = new QPushButton(calibrationDataCollapseSection); - extractDataButton->setText("Extract to CSV"); - StyleHelper::BlueButton(extractDataButton, "extractDataButton"); - QPushButton *clearCalibrateDataButton = new QPushButton(calibrationDataCollapseSection); - clearCalibrateDataButton->setText("Clear All Data"); - StyleHelper::BlueButton(clearCalibrateDataButton, "clearCalibrateDataButton"); + QPushButton *importSamplesButton = new QPushButton("Import Samples", calibrationDataCollapseSection); + QPushButton *extractDataButton = new QPushButton("Save to CSV", calibrationDataCollapseSection); + QPushButton *clearCalibrateDataButton = new QPushButton("Clear All Data", calibrationDataCollapseSection); + StyleHelper::BlueButton(importSamplesButton); + StyleHelper::BlueButton(extractDataButton); + StyleHelper::BlueButton(clearCalibrateDataButton); calibrationDataCollapseSection->contentLayout()->setSpacing(8); + calibrationDataCollapseSection->contentLayout()->addWidget(importSamplesButton); calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); calibrationDataCollapseSection->contentLayout()->addWidget(clearCalibrateDataButton); #pragma endregion @@ -1136,6 +1154,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::postCalibrateData); connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); + connect(importSamplesButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::clearRawDataList); connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); From 4bd1a04899d2b337145d2c9231e5773787e785af Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Wed, 13 Nov 2024 14:22:38 +0800 Subject: [PATCH 067/112] admt: Initial implement of acquisition graph data Signed-off-by: dpineda2 Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 5 +- plugins/admt/src/harmoniccalibration.cpp | 117 ++++++------------ 2 files changed, 44 insertions(+), 78 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index f815e6cf6d..acf4b0f1a2 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -90,7 +90,7 @@ public Q_SLOTS: *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; QButtonGroup *rightMenuButtonGroup; - QLineEdit *graphUpdateIntervalLineEdit, *dataSampleSizeLineEdit, + QLineEdit *graphUpdateIntervalLineEdit, *displayLengthLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, @@ -230,6 +230,9 @@ public Q_SLOTS: void toggleMTDiagnostics(int mode); void toggleSequenceModeRegisters(int mode); void readAllRegisters(); + void prependAcquisitionData(double& data, QVector& list); + void plotAcquisition(QVector& list, PlotChannel* channel, PlotWidget* plot); + void resizeAquisitionData(QVector& list); QTimer *acquisitionUITimer, *calibrationTimer, *utilityTimer; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index a6189a61a2..8b44111e2e 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -41,15 +41,18 @@ static uint32_t h2PhaseDeviceRegister = 0x18; static uint32_t h3PhaseDeviceRegister = 0x1A; static uint32_t h8PhaseDeviceRegister = 0x1C; -static QVector graphDataList, graphPostDataList; +static int acquisitionDisplayLength = 200; +static QVector acquisitionAngleList(acquisitionDisplayLength), graphDataList, graphPostDataList; static const QColor scopyBlueColor = scopy::StyleHelper::getColor("ScopyBlue"); +static const QColor channel0Color = scopy::StyleHelper::getColor("CH0"); static const QColor sineColor = QColor("#85e94c"); static const QColor cosineColor = QColor("#91e6cf"); static const QColor faultLEDColor = QColor("#c81a28"); static const QColor statusLEDColor = QColor("#2e9e6f"); static const QPen scopyBluePen(scopyBlueColor); +static const QPen channel0Pen(channel0Color); static const QPen sinePen(sineColor); static const QPen cosinePen(cosineColor); @@ -218,12 +221,12 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool acquisitionGraphPlotWidget->setShowYAxisLabels(true); acquisitionGraphPlotWidget->showAxisLabels(); - acquisitionXPlotAxis = new PlotAxis(QwtAxis::XBottom, acquisitionGraphPlotWidget, scopyBluePen); - acquisitionXPlotAxis->setMin(0); - acquisitionYPlotAxis = new PlotAxis(QwtAxis::YLeft, acquisitionGraphPlotWidget, scopyBluePen); - acquisitionYPlotAxis->setInterval(0, 400); + acquisitionXPlotAxis = new PlotAxis(QwtAxis::XBottom, acquisitionGraphPlotWidget, channel0Pen); + acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); + acquisitionYPlotAxis = new PlotAxis(QwtAxis::YLeft, acquisitionGraphPlotWidget, channel0Pen); + acquisitionYPlotAxis->setInterval(0, 360); - acquisitionAnglePlotChannel = new PlotChannel("Angle", scopyBluePen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionAnglePlotChannel = new PlotChannel("Angle", channel0Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); acquisitionGraphPlotWidget->addPlotChannel(acquisitionAnglePlotChannel); acquisitionAnglePlotChannel->setEnabled(true); @@ -267,17 +270,16 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool generalSection->contentLayout()->addWidget(graphUpdateIntervalLineEdit); // Data Sample Size - QLabel *dataSampleSizeLabel = new QLabel(generalSection); - dataSampleSizeLabel->setText("Data Sample Size"); - StyleHelper::MenuSmallLabel(dataSampleSizeLabel, "dataSampleSizeLabel"); - dataSampleSizeLineEdit = new QLineEdit(generalSection); - ADMTStyleHelper::LineEditStyle(dataSampleSizeLineEdit); - dataSampleSizeLineEdit->setText(QString::number(bufferSize)); + QLabel *displayLengthLabel = new QLabel("Display Length", generalSection); + StyleHelper::MenuSmallLabel(displayLengthLabel); + displayLengthLineEdit = new QLineEdit(generalSection); + ADMTStyleHelper::LineEditStyle(displayLengthLineEdit); + displayLengthLineEdit->setText(QString::number(acquisitionDisplayLength)); - connectLineEditToNumber(dataSampleSizeLineEdit, bufferSize, 1, 2048); + connectLineEditToNumber(displayLengthLineEdit, acquisitionDisplayLength, 1, 2048); - generalSection->contentLayout()->addWidget(dataSampleSizeLabel); - generalSection->contentLayout()->addWidget(dataSampleSizeLineEdit); + generalSection->contentLayout()->addWidget(displayLengthLabel); + generalSection->contentLayout()->addWidget(displayLengthLineEdit); MenuSectionWidget *sequenceWidget = new MenuSectionWidget(generalSettingWidget); MenuCollapseSection *sequenceSection = new MenuCollapseSection("Sequence", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, sequenceWidget); @@ -330,67 +332,10 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool sequenceSection->contentLayout()->addWidget(eighthHarmonicMenuCombo); sequenceSection->contentLayout()->addWidget(applySequenceButton); - // Data Graph Setting Widget - MenuSectionWidget *dataGraphWidget = new MenuSectionWidget(generalSettingWidget); - dataGraphWidget->contentLayout()->setSpacing(8); - MenuCollapseSection *dataGraphSection = new MenuCollapseSection("Data Graph", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, dataGraphWidget); - dataGraphSection->header()->toggle(); - dataGraphSection->contentLayout()->setSpacing(8); - - // Graph Channel - m_dataGraphChannelMenuCombo = new MenuCombo("Channel", dataGraphSection); - auto dataGraphChannelCombo = m_dataGraphChannelMenuCombo->combo(); - dataGraphChannelCombo->addItem("Rotation", QVariant::fromValue(reinterpret_cast(const_cast(rotationChannelName)))); - dataGraphChannelCombo->addItem("Angle", QVariant::fromValue(reinterpret_cast(const_cast(angleChannelName)))); - dataGraphChannelCombo->addItem("Count", QVariant::fromValue(reinterpret_cast(const_cast(countChannelName)))); - ADMTStyleHelper::ComboBoxStyle(dataGraphChannelCombo); - - // connectMenuComboToGraphChannel(m_dataGraphChannelMenuCombo, dataGraph); - - dataGraphSection->contentLayout()->addWidget(m_dataGraphChannelMenuCombo); - - // Graph Samples - QLabel *dataGraphSamplesLabel = new QLabel(generalSection); - dataGraphSamplesLabel->setText("Samples"); - StyleHelper::MenuSmallLabel(dataGraphSamplesLabel, "dataGraphSamplesLabel"); - dataGraphSamplesLineEdit = new QLineEdit(generalSection); - ADMTStyleHelper::LineEditStyle(dataGraphSamplesLineEdit); - dataGraphSamplesLineEdit->setText(QString::number(dataGraphSamples)); - - // connectLineEditToGraphSamples(dataGraphSamplesLineEdit, dataGraphSamples, dataGraph, 1, 5000); - - dataGraphSection->contentLayout()->addWidget(dataGraphSamplesLabel); - dataGraphSection->contentLayout()->addWidget(dataGraphSamplesLineEdit); - - dataGraphWidget->contentLayout()->addWidget(dataGraphSection); - - // Temperature Graph - MenuSectionWidget *tempGraphWidget = new MenuSectionWidget(generalSettingWidget); - tempGraphWidget->contentLayout()->setSpacing(8); - MenuCollapseSection *tempGraphSection = new MenuCollapseSection("Temperature Graph", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, tempGraphWidget); - tempGraphSection->header()->toggle(); - tempGraphSection->contentLayout()->setSpacing(8); - - // Graph Samples - QLabel *tempGraphSamplesLabel = new QLabel(generalSection); - tempGraphSamplesLabel->setText("Samples"); - StyleHelper::MenuSmallLabel(tempGraphSamplesLabel, "tempGraphSamplesLabel"); - tempGraphSamplesLineEdit = new QLineEdit(generalSection); - ADMTStyleHelper::LineEditStyle(tempGraphSamplesLineEdit); - tempGraphSamplesLineEdit->setText(QString::number(tempGraphSamples)); - tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLabel); - tempGraphSection->contentLayout()->addWidget(tempGraphSamplesLineEdit); - - // connectLineEditToGraphSamples(tempGraphSamplesLineEdit, tempGraphSamples, tempGraph, 1, 5000); - - tempGraphWidget->contentLayout()->addWidget(tempGraphSection); - generalSettingLayout->addWidget(header); generalSettingLayout->addSpacerItem(new QSpacerItem(0, 3, QSizePolicy::Fixed, QSizePolicy::Fixed)); generalSettingLayout->addWidget(sequenceWidget); generalSettingLayout->addWidget(generalWidget); - generalSettingLayout->addWidget(dataGraphWidget); - generalSettingLayout->addWidget(tempGraphWidget); generalSettingLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); #pragma endregion @@ -476,6 +421,8 @@ HarmonicCalibration::~HarmonicCalibration() {} void HarmonicCalibration::startAcquisition() { isStartAcquisition = true; + acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); + resizeAquisitionData(acquisitionAngleList); QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples); } @@ -484,12 +431,27 @@ void HarmonicCalibration::getAcquisitionSamples() while(isStartAcquisition) { updateChannelValues(); - // dataGraph->plot(*dataGraphValue); - // tempGraph->plot(*tempGraphValue); + prependAcquisitionData(angle, acquisitionAngleList); readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); } } +void HarmonicCalibration::resizeAquisitionData(QVector& list) +{ + list.resize(acquisitionDisplayLength); +} + +void HarmonicCalibration::prependAcquisitionData(double& data, QVector& list) +{ + list.prepend(data); +} + +void HarmonicCalibration::plotAcquisition(QVector& list, PlotChannel* channel, PlotWidget* plot) +{ + channel->curve()->setSamples(list); + plot->replot(); +} + void HarmonicCalibration::initializeMotor() { rotate_vmax = 53687.0912; @@ -2074,6 +2036,7 @@ void HarmonicCalibration::canCalibrate(bool value) void HarmonicCalibration::acquisitionUITask() { + plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel, acquisitionGraphPlotWidget); updateLineEditValues(); updateLabelValue(acquisitionMotorCurrentPositionLabel, ADMTController::MotorAttribute::CURRENT_POS); } @@ -2352,9 +2315,9 @@ void HarmonicCalibration::updateLineEditValues(){ void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { graphUpdateIntervalLineEdit->setEnabled(value); - dataSampleSizeLineEdit->setEnabled(value); - dataGraphSamplesLineEdit->setEnabled(value); - tempGraphSamplesLineEdit->setEnabled(value); + displayLengthLineEdit->setEnabled(value); + // dataGraphSamplesLineEdit->setEnabled(value); + // tempGraphSamplesLineEdit->setEnabled(value); } MenuControlButton *HarmonicCalibration::createStatusLEDWidget(const QString title, QColor color, QWidget *parent) From d16c81dc357d82ea79845defcefb7ac961ea825d Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Fri, 15 Nov 2024 16:07:41 +0800 Subject: [PATCH 068/112] admt: Added state for MT Diagnostics - Updated import sample behavior - Changed calibration UI timer rate Signed-off-by: dpineda2 Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 7 +- plugins/admt/src/harmoniccalibration.cpp | 80 ++++++++++++------- 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index acf4b0f1a2..2b5a64c720 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -65,7 +65,7 @@ public Q_SLOTS: void stop(); void start(); void restart(); - void calibrationTask(); + void calibrationUITask(); void utilityTask(); void clearCommandLog(); void canCalibrate(bool); @@ -120,7 +120,7 @@ public Q_SLOTS: MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo, *m_calibrationMotorRampModeMenuCombo, *sequenceTypeMenuCombo, *conversionTypeMenuCombo, *cnvSourceMenuCombo, *convertSynchronizationMenuCombo, *angleFilterMenuCombo, *eighthHarmonicMenuCombo; - QTabWidget *tabWidget, *calibrationDataGraphTabWidget; + QTabWidget *tabWidget, *calibrationDataGraphTabWidget, *resultDataTabWidget; QListWidget *rawDataListWidget; @@ -233,8 +233,9 @@ public Q_SLOTS: void prependAcquisitionData(double& data, QVector& list); void plotAcquisition(QVector& list, PlotChannel* channel, PlotWidget* plot); void resizeAquisitionData(QVector& list); + void populateAngleErrorGraphs(); - QTimer *acquisitionUITimer, *calibrationTimer, *utilityTimer; + QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; int uuid = 0; const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 8b44111e2e..204ccbe26c 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -6,7 +6,7 @@ #include static int acquisitionUITimerRate = 50; -static int calibrationTimerRate = 1000; +static int calibrationUITimerRate = 50; static int utilityTimerRate = 1000; static int bufferSize = 1; @@ -19,12 +19,14 @@ static double *tempGraphValue; static int cycleCount = 11; static int samplesPerCycle = 256; static int totalSamplesCount = cycleCount * samplesPerCycle; +static int samplesCollected = 0; static bool isStartAcquisition = false; static bool isStartMotor = false; static bool isPostCalibration = false; static bool isCalculatedCoeff = false; static bool isAngleDisplayFormat = false; static bool resetToZero = true; +static bool hasMTDiagnostics = false; static double motorTimeUnit = 1.048576; // t = 2^24/16Mhz static int motorMicrostepPerRevolution = 51200; @@ -372,8 +374,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool // timer = new QTimer(this); // connect(timer, &QTimer::timeout, this, &HarmonicCalibration::timerTask); - calibrationTimer = new QTimer(this); - connect(calibrationTimer, &QTimer::timeout, this, &HarmonicCalibration::calibrationTask); + calibrationUITimer = new QTimer(this); + connect(calibrationUITimer, &QTimer::timeout, this, &HarmonicCalibration::calibrationUITask); utilityTimer = new QTimer(this); connect(utilityTimer, &QTimer::timeout, this, &HarmonicCalibration::utilityTask); @@ -392,11 +394,11 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 1) // Calibration Tab { - calibrationTimer->start(calibrationTimerRate); + calibrationUITimer->start(calibrationUITimerRate); } else { - calibrationTimer->stop(); + calibrationUITimer->stop(); } if(index == 2) // Utility Tab @@ -611,7 +613,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDataGraphTabWidget->addTab(postCalibrationSamplesWidget, "Post Calibration Samples"); MenuSectionWidget *resultDataSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); - QTabWidget *resultDataTabWidget = new QTabWidget(resultDataSectionWidget); + resultDataTabWidget = new QTabWidget(resultDataSectionWidget); applyTabWidgetStyle(resultDataTabWidget); resultDataSectionWidget->contentLayout()->setSpacing(8); resultDataSectionWidget->contentLayout()->addWidget(resultDataTabWidget); @@ -1776,9 +1778,11 @@ void HarmonicCalibration::toggleMTDiagnostics(int mode) switch(mode){ case 0: MTDiagnosticsScrollArea->hide(); + hasMTDiagnostics = false; break; case 1: MTDiagnosticsScrollArea->show(); + hasMTDiagnostics = true; break; } } @@ -2141,8 +2145,10 @@ bool HarmonicCalibration::changeCNVPage(uint32_t page){ void HarmonicCalibration::utilityTask(){ updateDigioMonitor(); updateFaultRegister(); - updateMTDiagRegister(); - updateMTDiagnostics(); + if(hasMTDiagnostics){ + updateMTDiagRegister(); + updateMTDiagnostics(); + } commandLogWrite(""); } @@ -2679,7 +2685,7 @@ void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorA } } -void HarmonicCalibration::calibrationTask() +void HarmonicCalibration::calibrationUITask() { if(!isDebug){ readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); @@ -2753,7 +2759,7 @@ void HarmonicCalibration::startMotor() if(isPostCalibration) { - if(graphPostDataList.size() == totalSamplesCount) + if(samplesCollected == totalSamplesCount) { computeSineCosineOfAngles(graphPostDataList); m_admtController->postcalibrate(vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, samplesPerCycle); @@ -2781,7 +2787,7 @@ void HarmonicCalibration::startMotor() } } else{ - if(graphDataList.size() == totalSamplesCount) + if(samplesCollected == totalSamplesCount) { computeSineCosineOfAngles(graphDataList); canCalibrate(true); @@ -2790,25 +2796,7 @@ void HarmonicCalibration::startMotor() flashHarmonicValues(); - QVector angleError = QVector(m_admtController->angleError.begin(), m_admtController->angleError.end()); - QVector FFTAngleErrorMagnitude = QVector(m_admtController->FFTAngleErrorMagnitude.begin(), m_admtController->FFTAngleErrorMagnitude.end()); - QVector FFTAngleErrorPhase = QVector(m_admtController->FFTAngleErrorPhase.begin(), m_admtController->FFTAngleErrorPhase.end()); - - angleErrorPlotChannel->curve()->setSamples(angleError); - auto angleErrorMinMax = std::minmax_element(angleError.begin(), angleError.end()); - angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, *angleErrorMinMax.second); - angleErrorXPlotAxis->setInterval(0, angleError.size()); - angleErrorPlotWidget->replot(); - - FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); - auto angleErrorMagnitudeMinMax = std::minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); - FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); - auto angleErrorPhaseMinMax = std::minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); - double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first ? *angleErrorMagnitudeMinMax.first : *angleErrorPhaseMinMax.first; - double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second ? *angleErrorMagnitudeMinMax.second : *angleErrorPhaseMinMax.second; - FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); - FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); - FFTAngleErrorPlotWidget->replot(); + populateAngleErrorGraphs(); } else{ resetToZero = true; @@ -2819,6 +2807,31 @@ void HarmonicCalibration::startMotor() watcher->setFuture(future); } +void HarmonicCalibration::populateAngleErrorGraphs() +{ + QVector angleError = QVector(m_admtController->angleError.begin(), m_admtController->angleError.end()); + QVector FFTAngleErrorMagnitude = QVector(m_admtController->FFTAngleErrorMagnitude.begin(), m_admtController->FFTAngleErrorMagnitude.end()); + QVector FFTAngleErrorPhase = QVector(m_admtController->FFTAngleErrorPhase.begin(), m_admtController->FFTAngleErrorPhase.end()); + + angleErrorPlotChannel->curve()->setSamples(angleError); + auto angleErrorMinMax = std::minmax_element(angleError.begin(), angleError.end()); + angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, *angleErrorMinMax.second); + angleErrorXPlotAxis->setInterval(0, angleError.size()); + angleErrorPlotWidget->replot(); + + FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); + auto angleErrorMagnitudeMinMax = std::minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); + FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); + auto angleErrorPhaseMinMax = std::minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); + double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first ? *angleErrorMagnitudeMinMax.first : *angleErrorPhaseMinMax.first; + double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second ? *angleErrorMagnitudeMinMax.second : *angleErrorPhaseMinMax.second; + FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); + FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); + FFTAngleErrorPlotWidget->replot(); + + resultDataTabWidget->setCurrentIndex(0); // Set tab to Angle Error +} + void HarmonicCalibration::canStartMotor(bool value) { calibrationStartMotorButton->setEnabled(value); @@ -3135,9 +3148,14 @@ void HarmonicCalibration::importCalibrationData() { calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); calibrationRawDataXPlotAxis->setInterval(0, graphDataList.size()); - computeSineCosineOfAngles(graphDataList); calibrationRawDataPlotWidget->replot(); + + computeSineCosineOfAngles(graphDataList); + canStartMotor(false); canCalibrate(true); + calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); + flashHarmonicValues(); + populateAngleErrorGraphs(); } } catch(FileManagerException &ex) { calibrationLogWrite(QString(ex.what())); From 93e9e29578ca42f0a3e7f37338b09d76d46633c5 Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Fri, 15 Nov 2024 16:19:52 +0800 Subject: [PATCH 069/112] admt: Removed resizing acquisition list Signed-off-by: dpineda2 Signed-off-by: JJuanill --- plugins/admt/include/admt/harmoniccalibration.h | 1 - plugins/admt/src/harmoniccalibration.cpp | 8 +------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 2b5a64c720..c9673e28b9 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -232,7 +232,6 @@ public Q_SLOTS: void readAllRegisters(); void prependAcquisitionData(double& data, QVector& list); void plotAcquisition(QVector& list, PlotChannel* channel, PlotWidget* plot); - void resizeAquisitionData(QVector& list); void populateAngleErrorGraphs(); QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 204ccbe26c..352822624d 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -44,7 +44,7 @@ static uint32_t h3PhaseDeviceRegister = 0x1A; static uint32_t h8PhaseDeviceRegister = 0x1C; static int acquisitionDisplayLength = 200; -static QVector acquisitionAngleList(acquisitionDisplayLength), graphDataList, graphPostDataList; +static QVector acquisitionAngleList, graphDataList, graphPostDataList; static const QColor scopyBlueColor = scopy::StyleHelper::getColor("ScopyBlue"); static const QColor channel0Color = scopy::StyleHelper::getColor("CH0"); @@ -424,7 +424,6 @@ void HarmonicCalibration::startAcquisition() { isStartAcquisition = true; acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); - resizeAquisitionData(acquisitionAngleList); QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples); } @@ -438,11 +437,6 @@ void HarmonicCalibration::getAcquisitionSamples() } } -void HarmonicCalibration::resizeAquisitionData(QVector& list) -{ - list.resize(acquisitionDisplayLength); -} - void HarmonicCalibration::prependAcquisitionData(double& data, QVector& list) { list.prepend(data); From 7d8d71633992655b95f49e3d7a3be3127664ba7a Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 25 Nov 2024 10:01:54 +0800 Subject: [PATCH 070/112] admt: Improved stability for applying sequence Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 21 ++++------ plugins/admt/src/harmoniccalibration.cpp | 52 +++++++++++++----------- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index b535681dde..ddff9934bd 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -172,16 +172,15 @@ int ADMTController::getChannelIndex(const char *deviceName, const char *channelN double ADMTController::getChannelValue(const char *deviceName, const char *channelName, int bufferSize) { double value; - char converted[bufferSize] = ""; int deviceCount = iio_context_get_devices_count(m_iioCtx); - //if(deviceCount < 1) return QString("No devices found"); + if(deviceCount < 1) return static_cast(UINT64_MAX); // return QString("No devices found"); iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); - //if(admtDevice == NULL) return QString("No ADMT4000 device"); + if(admtDevice == NULL) return static_cast(UINT64_MAX); // return QString("No ADMT4000 device"); int channelCount = iio_device_get_channels_count(admtDevice); - //if(channelCount < 1) return QString("No channels found."); + if(channelCount < 1) return static_cast(UINT64_MAX); // return QString("No channels found."); iio_channel *channel; std::string message = ""; @@ -197,9 +196,7 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann channel = NULL; } } - if(channel == NULL) { - //return QString::fromStdString(message); - } + if(channel == NULL) return static_cast(UINT64_MAX); // return QString("Channel not found."); iio_channel_enable(channel); double scale = 1.0; @@ -207,13 +204,13 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann const char *scaleAttrName = "scale"; const char *offsetAttrName = "offset"; const char *scaleAttr = iio_channel_find_attr(channel, scaleAttrName); - //if(scaleAttr == NULL) return QString("No scale attribute"); + if(scaleAttr == NULL) return static_cast(UINT64_MAX); // return QString("No scale attribute"); const char *offsetAttr = iio_channel_find_attr(channel, offsetAttrName); - //if(offsetAttr == NULL) return QString("No offset attribute"); + if(offsetAttr == NULL) return static_cast(UINT64_MAX); // return QString("No offset attribute"); double *scaleVal = new double(1); int scaleRet = iio_channel_attr_read_double(channel, scaleAttr, scaleVal); - //if(scaleRet != 0) return QString("Cannot read scale attribute"); + if(scaleRet != 0) return static_cast(UINT64_MAX); // return QString("Cannot read scale attribute"); scale = *scaleVal; char *offsetDst = new char[maxAttrSize]; @@ -221,7 +218,7 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann offsetAttrVal = std::atoi(offsetDst); iio_buffer *iioBuffer = iio_device_create_buffer(admtDevice, bufferSize, false); - //if(!iioBuffer) return QString("Cannot create buffer."); + if(iioBuffer == NULL) return static_cast(UINT64_MAX); // return QString("Cannot create buffer."); ssize_t numBytesRead; int8_t *pointerData, *pointerEnd; @@ -229,7 +226,7 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann ptrdiff_t pointerIncrement; numBytesRead = iio_buffer_refill(iioBuffer); - //if(numBytesRead < 1) return QString("Cannot refill buffer."); + if(numBytesRead < 0) return static_cast(UINT64_MAX); // return QString("Cannot refill buffer."); pointerIncrement = reinterpret_cast(iio_buffer_step(iioBuffer)); pointerEnd = static_cast(iio_buffer_end(iioBuffer)); diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 352822624d..518c4477ac 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -2056,32 +2056,31 @@ void HarmonicCalibration::applySequence(){ settings["Sequence Type"] = qvariant_cast(sequenceTypeMenuCombo->combo()->currentData()); // sequenceType; settings["Conversion Type"] = qvariant_cast(conversionTypeMenuCombo->combo()->currentData()); // conversionType; - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - generalRegisterAddress, generalRegValue); - - uint32_t newGeneralRegValue = m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings); - uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); - bool success = false; - if(changeCNVPage(generalRegisterPage)){ - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, newGeneralRegValue) != -1){ - //StatusBarManager::pushMessage("WRITE GENERAL: 0b" + QString::number(static_cast(newGeneralRegValue), 2).rightJustified(16, '0')); - - if(readSequence()){ - if(settings.at("Convert Synchronization") == generalRegisterMap.at("Convert Synchronization") && - settings.at("Angle Filter") == generalRegisterMap.at("Angle Filter") && - settings.at("8th Harmonic") == generalRegisterMap.at("8th Harmonic") && - settings.at("Sequence Type") == generalRegisterMap.at("Sequence Type") && - settings.at("Conversion Type") == generalRegisterMap.at("Conversion Type")) - { - StatusBarManager::pushMessage("Sequence settings applied successfully"); - success = true; + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ + + uint32_t newGeneralRegValue = m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings); + uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); + + if(changeCNVPage(generalRegisterPage)){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, newGeneralRegValue) != -1){ + if(readSequence()){ + if(settings.at("Convert Synchronization") == generalRegisterMap.at("Convert Synchronization") && + settings.at("Angle Filter") == generalRegisterMap.at("Angle Filter") && + settings.at("8th Harmonic") == generalRegisterMap.at("8th Harmonic") && + settings.at("Sequence Type") == generalRegisterMap.at("Sequence Type") && + settings.at("Conversion Type") == generalRegisterMap.at("Conversion Type")) + { + StatusBarManager::pushMessage("Sequence settings applied successfully"); + success = true; + } } } } } + if(!success){ StatusBarManager::pushMessage("Failed to apply sequence settings"); } } @@ -2298,18 +2297,25 @@ void HarmonicCalibration::updateChannelValues(){ void HarmonicCalibration::updateCountValue(){ uint32_t *absAngleRegValue = new uint32_t; + bool success = false; if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0x0000) != -1){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), absAngleRegValue) != -1){ count = m_admtController->getAbsAngleTurnCount(static_cast(*absAngleRegValue)); + success = true; } } + if(!success){ count = static_cast(UINT64_MAX); } } void HarmonicCalibration::updateLineEditValues(){ - rotationValueLabel->setText(QString::number(rotation) + "°"); - angleValueLabel->setText(QString::number(angle) + "°"); - countValueLabel->setText(QString::number(count)); - tempValueLabel->setText(QString::number(temp) + " °C"); + if(rotation == static_cast(UINT64_MAX)) { rotationValueLabel->setText("N/A"); } + else { rotationValueLabel->setText(QString::number(rotation) + "°"); } + if(angle == static_cast(UINT64_MAX)) { angleValueLabel->setText("N/A"); } + else { angleValueLabel->setText(QString::number(angle) + "°"); } + if(count == static_cast(UINT64_MAX)) { countValueLabel->setText("N/A"); } + else { countValueLabel->setText(QString::number(count)); } + if(temp == static_cast(UINT64_MAX)) { tempValueLabel->setText("N/A"); } + else { tempValueLabel->setText(QString::number(temp) + " °C"); } } void HarmonicCalibration::updateGeneralSettingEnabled(bool value) From a02a443647fa783457954ddf1f0ac4115a0c9acd Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 25 Nov 2024 10:24:12 +0800 Subject: [PATCH 071/112] admt: Write zeros to fault register before read Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/harmoniccalibration.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 518c4477ac..c43f8fdc16 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -2207,6 +2207,7 @@ void HarmonicCalibration::updateMTDiagRegister(){ void HarmonicCalibration::updateFaultRegister(){ uint32_t *faultRegValue = new uint32_t; uint32_t faultRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, 0); // Write all zeros to fault before read m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, faultRegValue); if(*faultRegValue != -1){ From 68fc00980b3c594357b91b7cd8dd8bf7b6de87cd Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 26 Nov 2024 10:26:11 +0800 Subject: [PATCH 072/112] admt: Added fine control for DIGIOEN register Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 2 + .../admt/include/admt/harmoniccalibration.h | 15 +- plugins/admt/src/admtcontroller.cpp | 156 +++++++- plugins/admt/src/harmoniccalibration.cpp | 376 ++++++++++++------ 4 files changed, 434 insertions(+), 115 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 68c5f84d15..a235c1625d 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -193,6 +193,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject map getFaultRegisterBitMapping(uint16_t registerValue); map getGeneralRegisterBitMapping(uint16_t registerValue); map getDIGIOENRegisterBitMapping(uint16_t registerValue); + map getDIGIORegisterBitMapping(uint16_t registerValue); map getDiag1RegisterBitMapping_Register(uint16_t registerValue); map getDiag1RegisterBitMapping_Afe(uint16_t registerValue, bool is5V); map getDiag2RegisterBitMapping(uint16_t registerValue); @@ -200,6 +201,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle); int getAbsAngleTurnCount(uint16_t registerValue); uint16_t setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings); + uint16_t setDIGIORegisterBitMapping(uint16_t currentRegisterValue, map settings); void unwrapAngles(vector& angles_rad); map getUNIQID3RegisterMapping(uint16_t registerValue); private: diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index c9673e28b9..92a26669cf 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -150,7 +150,14 @@ public Q_SLOTS: *AFEDIAGStatusLED, *NVMCRCFaultStatusLED, *ECCDoubleBitErrorStatusLED, *OscillatorDriftStatusLED, *CountSensorFalseStateStatusLED, *AngleCrossCheckStatusLED, *TurnCountSensorLevelsStatusLED, *MTDIAGStatusLED, *TurnCounterCrossCheckStatusLED, *RadiusCheckStatusLED, *SequencerWatchdogStatusLED; - CustomSwitch *calibrationDisplayFormatSwitch, *DIGIOBUSYToggleSwitch, *DIGIOCNVToggleSwitch, *DIGIOSENTToggleSwitch, *DIGIOACALCToggleSwitch, *DIGIOFAULTToggleSwitch, *DIGIOBOOTLOADERToggleSwitch, *DIGIOALLToggleSwitch; + CustomSwitch *calibrationDisplayFormatSwitch, + *DIGIO0ENToggleSwitch, *DIGIO0FNCToggleSwitch, + *DIGIO1ENToggleSwitch, *DIGIO1FNCToggleSwitch, + *DIGIO2ENToggleSwitch, *DIGIO2FNCToggleSwitch, + *DIGIO3ENToggleSwitch, *DIGIO3FNCToggleSwitch, + *DIGIO4ENToggleSwitch, *DIGIO4FNCToggleSwitch, + *DIGIO5ENToggleSwitch, *DIGIO5FNCToggleSwitch, + *DIGIOALLToggleSwitch; RegisterBlockWidget *cnvPageRegisterBlock, *digIORegisterBlock, *faultRegisterBlock, *generalRegisterBlock, *digIOEnRegisterBlock, *angleCkRegisterBlock, *eccDcdeRegisterBlock, *eccDisRegisterBlock, *absAngleRegisterBlock, *angleRegisterBlock, *angleSecRegisterBlock, *sineRegisterBlock, *cosineRegisterBlock, *secAnglIRegisterBlock, *secAnglQRegisterBlock, *radiusRegisterBlock, *diag1RegisterBlock, *diag2RegisterBlock, *tmp0RegisterBlock, *tmp1RegisterBlock, *cnvCntRegisterBlock, *uniqID0RegisterBlock, *uniqID1RegisterBlock, *uniqID2RegisterBlock, *uniqID3RegisterBlock, *h1MagRegisterBlock, *h1PhRegisterBlock, *h2MagRegisterBlock, *h2PhRegisterBlock, *h3MagRegisterBlock, *h3PhRegisterBlock, *h8MagRegisterBlock, *h8PhRegisterBlock; @@ -207,9 +214,9 @@ public Q_SLOTS: void updateCountValue(); void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel); void readDeviceProperties(); - void toggleAllDIGIO(bool value); + void toggleAllDIGIOEN(bool value); void toggleUtilityTask(bool run); - void toggleDIGIOEN(string DIGIOENName, bool value); + void toggleDIGIOEN(string DIGIOENName, bool& value); void getCalibrationSamples(); void startMotor(); void computeSineCosineOfAngles(QVector graphDataList); @@ -233,6 +240,8 @@ public Q_SLOTS: void prependAcquisitionData(double& data, QVector& list); void plotAcquisition(QVector& list, PlotChannel* channel, PlotWidget* plot); void populateAngleErrorGraphs(); + void resetDIGIO(); + bool updateDIGIOToggle(); QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index ddff9934bd..a4b31c77ad 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -945,6 +945,32 @@ map ADMTController::getDIGIOENRegisterBitMapping(uint16_t register return result; } +map ADMTController::getDIGIORegisterBitMapping(uint16_t registerValue) { + map result; + + // Bits 15:6: Reserved (skipped) + + // Bit 5: GPIO5 + result["GPIO5"] = ((registerValue >> 5) & 0x01) ? true : false; + + // Bit 4: GPIO4 + result["GPIO4"] = ((registerValue >> 4) & 0x01) ? true : false; + + // Bit 3: GPIO3 + result["GPIO3"] = ((registerValue >> 3) & 0x01) ? true : false; + + // Bit 2: GPIO2 + result["GPIO2"] = ((registerValue >> 2) & 0x01) ? true : false; + + // Bit 1: GPIO1 + result["GPIO1"] = ((registerValue >> 1) & 0x01) ? true : false; + + // Bit 0: GPIO0 + result["GPIO0"] = (registerValue & 0x01) ? true : false; + + return result; +} + map ADMTController::getDiag1RegisterBitMapping_Register(uint16_t registerValue) { map result; @@ -1140,7 +1166,135 @@ uint16_t ADMTController::setDIGIOENRegisterBitMapping(uint16_t currentRegisterVa registerValue &= ~(1 << 8); // Clear bit 8 (Disabled) } - // Bits 7:0: (preserve original value) + // Bits 7:6: (preserve original value) + + // Bit 5: Bootload + if (settings["BOOTLOAD"]) // "Enabled" + { + registerValue |= (1 << 5); // Set bit 5 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 5); // Clear bit 5 (Disabled) + } + + // Bit 4: Fault + if (settings["FAULT"]) // "Enabled" + { + registerValue |= (1 << 4); // Set bit 4 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 4); // Clear bit 4 (Disabled) + } + + // Bit 3: Acalc + if (settings["ACALC"]) // "Enabled" + { + registerValue |= (1 << 3); // Set bit 3 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 3); // Clear bit 3 (Disabled) + } + + // Bit 2: Sent + if (settings["SENT"]) // "Enabled" + { + registerValue |= (1 << 2); // Set bit 2 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 2); // Clear bit 2 (Disabled) + } + + // Bit 1: Cnv + if (settings["CNV"]) // "Enabled" + { + registerValue |= (1 << 1); // Set bit 1 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 1); // Clear bit 1 (Disabled) + } + + // Bit 0: Sent + if (settings["BUSY"]) // "Enabled" + { + registerValue |= (1 << 0); // Set bit 0 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 0); // Clear bit 0 (Disabled) + } + + return registerValue; +} + +uint16_t ADMTController::setDIGIORegisterBitMapping(uint16_t currentRegisterValue, map settings) { + uint16_t registerValue = currentRegisterValue; // Start with the current register value + + // Bits 15:6: (preserve original value) + + // Bit 5: GPIO5 + if (settings["GPIO5"]) // "Enabled" + { + registerValue |= (1 << 5); // Set bit 5 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 5); // Clear bit 5 (Disabled) + } + + // Bit 4: GPIO4 + if (settings["GPIO4"]) // "Enabled" + { + registerValue |= (1 << 4); // Set bit 4 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 4); // Clear bit 4 (Disabled) + } + + // Bit 3: GPIO3 + if (settings["GPIO3"]) // "Enabled" + { + registerValue |= (1 << 3); // Set bit 3 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 3); // Clear bit 3 (Disabled) + } + + // Bit 2: GPIO2 + if (settings["GPIO2"]) // "Enabled" + { + registerValue |= (1 << 2); // Set bit 2 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 2); // Clear bit 2 (Disabled) + } + + // Bit 1: GPIO1 + if (settings["GPIO1"]) // "Enabled" + { + registerValue |= (1 << 1); // Set bit 1 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 1); // Clear bit 1 (Disabled) + } + + // Bit 0: GPIO0 + if (settings["GPIO0"]) // "Enabled" + { + registerValue |= (1 << 0); // Set bit 0 to 1 (Enabled) + } + else // "Disabled" + { + registerValue &= ~(1 << 0); // Clear bit 0 (Disabled) + } return registerValue; } diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index c43f8fdc16..adf4df28ee 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -51,6 +51,7 @@ static const QColor channel0Color = scopy::StyleHelper::getColor("CH0"); static const QColor sineColor = QColor("#85e94c"); static const QColor cosineColor = QColor("#91e6cf"); static const QColor faultLEDColor = QColor("#c81a28"); +static const QColor gpioLEDColor = scopyBlueColor; static const QColor statusLEDColor = QColor("#2e9e6f"); static const QPen scopyBluePen(scopyBlueColor); @@ -391,6 +392,10 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool { readSequence(); } + else + { + stop(); + } if(index == 1) // Calibration Tab { @@ -407,6 +412,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool readSequence(); toggleFaultRegisterMode(generalRegisterMap.at("Sequence Type")); toggleMTDiagnostics(generalRegisterMap.at("Sequence Type")); + updateDIGIOToggle(); } else { utilityTimer->stop(); } @@ -1435,7 +1441,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() #pragma region DIGIO Control MenuSectionWidget *DIGIOControlSectionWidget = new MenuSectionWidget(DIGIOWidget); - MenuCollapseSection *DIGIOControlCollapseSection = new MenuCollapseSection("GPIO Control", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOControlSectionWidget); + MenuCollapseSection *DIGIOControlCollapseSection = new MenuCollapseSection("DIGIO Control", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOControlSectionWidget); DIGIOControlSectionWidget->contentLayout()->addWidget(DIGIOControlCollapseSection); QWidget *DIGIOControlGridWidget = new QWidget(DIGIOControlSectionWidget); @@ -1458,66 +1464,112 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() } )css"); - QLabel *DIGIOBUSYLabel = new QLabel("GPIO0", DIGIOControlGridWidget); - QLabel *DIGIOCNVLabel = new QLabel("GPIO1", DIGIOControlGridWidget); - QLabel *DIGIOSENTLabel = new QLabel("GPIO2", DIGIOControlGridWidget); - QLabel *DIGIOACALCLabel = new QLabel("GPIO3", DIGIOControlGridWidget); - QLabel *DIGIOFAULTLabel = new QLabel("GPIO4", DIGIOControlGridWidget); - QLabel *DIGIOBOOTLOADERLabel = new QLabel("GPIO5", DIGIOControlGridWidget); - QLabel *DIGIOALLLabel = new QLabel("GPIO Output", DIGIOControlGridWidget); - - DIGIOBUSYLabel->setStyleSheet(labelStyle); - DIGIOCNVLabel->setStyleSheet(labelStyle); - DIGIOSENTLabel->setStyleSheet(labelStyle); - DIGIOACALCLabel->setStyleSheet(labelStyle); - DIGIOFAULTLabel->setStyleSheet(labelStyle); - DIGIOBOOTLOADERLabel->setStyleSheet(labelStyle); + QLabel *DIGIO0Label = new QLabel("DIGIO0", DIGIOControlGridWidget); + QLabel *DIGIO1Label = new QLabel("DIGIO1", DIGIOControlGridWidget); + QLabel *DIGIO2Label = new QLabel("DIGIO2", DIGIOControlGridWidget); + QLabel *DIGIO3Label = new QLabel("DIGIO3", DIGIOControlGridWidget); + QLabel *DIGIO4Label = new QLabel("DIGIO4", DIGIOControlGridWidget); + QLabel *DIGIO5Label = new QLabel("DIGIO5", DIGIOControlGridWidget); + QLabel *DIGIOALLLabel = new QLabel("All DIGIO Output", DIGIOControlGridWidget); + + DIGIO0Label->setStyleSheet(labelStyle); + DIGIO1Label->setStyleSheet(labelStyle); + DIGIO2Label->setStyleSheet(labelStyle); + DIGIO3Label->setStyleSheet(labelStyle); + DIGIO4Label->setStyleSheet(labelStyle); + DIGIO5Label->setStyleSheet(labelStyle); DIGIOALLLabel->setStyleSheet(labelStyle); - DIGIOBUSYToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIOBUSYToggleSwitch, "On", "Off"); - connect(DIGIOBUSYToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + DIGIO0ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Enable", "Disable"); + connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO0EN", value); }); - DIGIOCNVToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIOCNVToggleSwitch, "On", "Off"); - connect(DIGIOCNVToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + DIGIO0FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO0FNCToggleSwitch, "GPIO0", "BUSY"); + connect(DIGIO0FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("BUSY", value); + }); + + DIGIO1ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO1ENToggleSwitch, "Enable", "Disable"); + connect(DIGIO1ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO1EN", value); }); - DIGIOSENTToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIOSENTToggleSwitch, "On", "Off"); - connect(DIGIOSENTToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + DIGIO1FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO1FNCToggleSwitch, "GPIO1", "CNV"); + connect(DIGIO1FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("CNV", value); + }); + + DIGIO2ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO2ENToggleSwitch, "Enable", "Disable"); + connect(DIGIO2ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO2EN", value); }); - DIGIOACALCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIOACALCToggleSwitch, "On", "Off"); - connect(DIGIOACALCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + DIGIO2FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO2FNCToggleSwitch, "GPIO2", "SENT"); + connect(DIGIO2FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("SENT", value); + }); + + DIGIO3ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO3ENToggleSwitch, "Enable", "Disable"); + connect(DIGIO3ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO3EN", value); }); - DIGIOFAULTToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIOFAULTToggleSwitch, "On", "Off"); - connect(DIGIOFAULTToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + DIGIO3FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO3FNCToggleSwitch, "GPIO3", "ACALC"); + connect(DIGIO3FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("ACALC", value); + }); + + DIGIO4ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO4ENToggleSwitch, "Enable", "Disable"); + connect(DIGIO4ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO4EN", value); }); - DIGIOBOOTLOADERToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIOBOOTLOADERToggleSwitch, "On", "Off"); - connect(DIGIOBOOTLOADERToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + DIGIO4FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO4FNCToggleSwitch, "GPIO4", "FAULT"); + connect(DIGIO4FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("FAULT", value); + }); + + DIGIO5ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO5ENToggleSwitch, "Enable", "Disable"); + connect(DIGIO5ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO5EN", value); }); + DIGIO5FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO5FNCToggleSwitch, "GPIO5", "BOOT"); + connect(DIGIO5FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ + toggleDIGIOEN("BOOTLOAD", value); + }); + DIGIOALLToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIOALLToggleSwitch, "On", "Off"); + changeCustomSwitchLabel(DIGIOALLToggleSwitch, "Enable", "Disable"); connect(DIGIOALLToggleSwitch, &CustomSwitch::toggled, [=](bool value){ - toggleAllDIGIO(value); + toggleAllDIGIOEN(value); + // toggleAllDIGIO(value); + }); + + QPushButton *DIGIOResetButton = new QPushButton("Reset DIGIO", DIGIOControlGridWidget); + DIGIOResetButton->setFixedWidth(100); + StyleHelper::BlueButton(DIGIOResetButton); + connect(DIGIOResetButton, &QPushButton::clicked, [=]{ + resetDIGIO(); + updateDIGIOToggle(); }); DIGIOControlGridLayout->addWidget(DIGIOALLLabel, 0, 0); DIGIOControlGridLayout->addWidget(DIGIOALLToggleSwitch, 0, 1); + DIGIOControlGridLayout->addWidget(DIGIOResetButton, 0, 2); DIGIOControlGridLayout->addItem(new QSpacerItem(0, 4, QSizePolicy::Fixed, QSizePolicy::Expanding), 1, 0, 1, 2); QFrame *line = new QFrame(); @@ -1531,21 +1583,26 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() )css"); line->setStyleSheet(lineStyle); DIGIOControlGridLayout->addWidget(line, 2, 0, 1, 2); - - DIGIOControlGridLayout->addItem(new QSpacerItem(0, 4, QSizePolicy::Fixed, QSizePolicy::Expanding), 3, 0, 1, 2); - - DIGIOControlGridLayout->addWidget(DIGIOBUSYLabel, 4, 0); - DIGIOControlGridLayout->addWidget(DIGIOBUSYToggleSwitch, 4, 1); - DIGIOControlGridLayout->addWidget(DIGIOCNVLabel, 5, 0); - DIGIOControlGridLayout->addWidget(DIGIOCNVToggleSwitch, 5, 1); - DIGIOControlGridLayout->addWidget(DIGIOSENTLabel, 6, 0); - DIGIOControlGridLayout->addWidget(DIGIOSENTToggleSwitch, 6, 1); - DIGIOControlGridLayout->addWidget(DIGIOACALCLabel, 7, 0); - DIGIOControlGridLayout->addWidget(DIGIOACALCToggleSwitch, 7, 1); - DIGIOControlGridLayout->addWidget(DIGIOFAULTLabel, 8, 0); - DIGIOControlGridLayout->addWidget(DIGIOFAULTToggleSwitch, 8, 1); - DIGIOControlGridLayout->addWidget(DIGIOBOOTLOADERLabel, 9, 0); - DIGIOControlGridLayout->addWidget(DIGIOBOOTLOADERToggleSwitch, 9, 1); + DIGIOControlGridLayout->addItem(new QSpacerItem(0, 4, QSizePolicy::Fixed, QSizePolicy::Expanding), 3, 0, 1, 3); + + DIGIOControlGridLayout->addWidget(DIGIO0Label, 4, 0); + DIGIOControlGridLayout->addWidget(DIGIO0ENToggleSwitch, 4, 1); + DIGIOControlGridLayout->addWidget(DIGIO0FNCToggleSwitch, 4, 2); + DIGIOControlGridLayout->addWidget(DIGIO1Label, 5, 0); + DIGIOControlGridLayout->addWidget(DIGIO1ENToggleSwitch, 5, 1); + DIGIOControlGridLayout->addWidget(DIGIO1FNCToggleSwitch, 5, 2); + DIGIOControlGridLayout->addWidget(DIGIO2Label, 6, 0); + DIGIOControlGridLayout->addWidget(DIGIO2ENToggleSwitch, 6, 1); + DIGIOControlGridLayout->addWidget(DIGIO2FNCToggleSwitch, 6, 2); + DIGIOControlGridLayout->addWidget(DIGIO3Label, 7, 0); + DIGIOControlGridLayout->addWidget(DIGIO3ENToggleSwitch, 7, 1); + DIGIOControlGridLayout->addWidget(DIGIO3FNCToggleSwitch, 7, 2); + DIGIOControlGridLayout->addWidget(DIGIO4Label, 8, 0); + DIGIOControlGridLayout->addWidget(DIGIO4ENToggleSwitch, 8, 1); + DIGIOControlGridLayout->addWidget(DIGIO4FNCToggleSwitch, 8, 2); + DIGIOControlGridLayout->addWidget(DIGIO5Label, 9, 0); + DIGIOControlGridLayout->addWidget(DIGIO5ENToggleSwitch, 9, 1); + DIGIOControlGridLayout->addWidget(DIGIO5FNCToggleSwitch, 9, 2); DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOControlGridWidget, 1); #pragma endregion @@ -1698,6 +1755,13 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() return tool; } +void HarmonicCalibration::resetDIGIO() +{ + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + 0x241b); +} + void HarmonicCalibration::readAllRegisters() { readAllRegistersButton->setEnabled(false); @@ -1826,7 +1890,7 @@ void HarmonicCalibration::toggleUtilityTask(bool run) } } -void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) +void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool& value) { toggleUtilityTask(false); @@ -1838,34 +1902,24 @@ void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) if(changeCNVPage(DIGIOENPage)) { if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) { map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); + DIGIOSettings[DIGIOENName] = value; uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); - changeCNVPage(DIGIOENPage); - - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - static_cast(newRegisterValue)) != -1) - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) + if(changeCNVPage(DIGIOENPage)){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + static_cast(newRegisterValue)) != -1) { - map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); - DIGIOBUSYToggleSwitch->setChecked(DIGIOSettings["DIGIO0EN"]); - DIGIOCNVToggleSwitch->setChecked(DIGIOSettings["DIGIO1EN"]); - DIGIOSENTToggleSwitch->setChecked(DIGIOSettings["DIGIO2EN"]); - DIGIOACALCToggleSwitch->setChecked(DIGIOSettings["DIGIO3EN"]); - DIGIOFAULTToggleSwitch->setChecked(DIGIOSettings["DIGIO4EN"]); - DIGIOBOOTLOADERToggleSwitch->setChecked(DIGIOSettings["DIGIO5EN"]); - success = true; + success = updateDIGIOToggle(); } } + } } @@ -1874,7 +1928,37 @@ void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) toggleUtilityTask(true); } -void HarmonicCalibration::toggleAllDIGIO(bool value) +bool HarmonicCalibration::updateDIGIOToggle() +{ + uint32_t *DIGIOENRegisterValue = new uint32_t; + uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + bool success = false; + + if(changeCNVPage(DIGIOENPage)){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) + { + map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); + DIGIO0ENToggleSwitch->setChecked(DIGIOSettings["DIGIO0EN"]); + DIGIO1ENToggleSwitch->setChecked(DIGIOSettings["DIGIO1EN"]); + DIGIO2ENToggleSwitch->setChecked(DIGIOSettings["DIGIO2EN"]); + DIGIO3ENToggleSwitch->setChecked(DIGIOSettings["DIGIO3EN"]); + DIGIO4ENToggleSwitch->setChecked(DIGIOSettings["DIGIO4EN"]); + DIGIO5ENToggleSwitch->setChecked(DIGIOSettings["DIGIO5EN"]); + DIGIO0FNCToggleSwitch->setChecked(DIGIOSettings["BUSY"]); + DIGIO1FNCToggleSwitch->setChecked(DIGIOSettings["CNV"]); + DIGIO2FNCToggleSwitch->setChecked(DIGIOSettings["SENT"]); + DIGIO3FNCToggleSwitch->setChecked(DIGIOSettings["ACALC"]); + DIGIO4FNCToggleSwitch->setChecked(DIGIOSettings["FAULT"]); + DIGIO5FNCToggleSwitch->setChecked(DIGIOSettings["BOOTLOAD"]); + success = true; + } + } + return success; +} + +void HarmonicCalibration::toggleAllDIGIOEN(bool value) { toggleUtilityTask(false); uint32_t *DIGIOENRegisterValue = new uint32_t; @@ -1882,36 +1966,28 @@ void HarmonicCalibration::toggleAllDIGIO(bool value) bool success = false; - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) + if(changeCNVPage(DIGIOENPage)) { - map DIGIOSettings; - DIGIOSettings["DIGIO5EN"] = value; - DIGIOSettings["DIGIO4EN"] = value; - DIGIOSettings["DIGIO3EN"] = value; - DIGIOSettings["DIGIO2EN"] = value; - DIGIOSettings["DIGIO1EN"] = value; - DIGIOSettings["DIGIO0EN"] = value; - uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); - - changeCNVPage(DIGIOENPage); - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - static_cast(newRegisterValue)) != -1) + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) - { - map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); - DIGIOBUSYToggleSwitch->setChecked(DIGIOSettings["DIGIO0EN"]); - DIGIOCNVToggleSwitch->setChecked(DIGIOSettings["DIGIO1EN"]); - DIGIOSENTToggleSwitch->setChecked(DIGIOSettings["DIGIO2EN"]); - DIGIOACALCToggleSwitch->setChecked(DIGIOSettings["DIGIO3EN"]); - DIGIOFAULTToggleSwitch->setChecked(DIGIOSettings["DIGIO4EN"]); - DIGIOBOOTLOADERToggleSwitch->setChecked(DIGIOSettings["DIGIO5EN"]); - success = true; + map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue));; + DIGIOSettings["DIGIO5EN"] = value; + DIGIOSettings["DIGIO4EN"] = value; + DIGIOSettings["DIGIO3EN"] = value; + DIGIOSettings["DIGIO2EN"] = value; + DIGIOSettings["DIGIO1EN"] = value; + DIGIOSettings["DIGIO0EN"] = value; + uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); + + if(changeCNVPage(DIGIOENPage)){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + static_cast(newRegisterValue)) != -1) + { + success = updateDIGIOToggle(); + } } } } @@ -2154,18 +2230,96 @@ void HarmonicCalibration::updateDigioMonitor(){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), digioRegisterAddress, digioRegValue) != -1){ std::map digioBitMapping = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*digioRegValue)); - if(digioBitMapping.at("DIGIO0EN")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor, digioBitMapping.at("BUSY")); } - else { changeStatusLEDColor(DIGIOBusyStatusLED, faultLEDColor); } - if(digioBitMapping.at("DIGIO1EN")){ changeStatusLEDColor(DIGIOCNVStatusLED, statusLEDColor, digioBitMapping.at("CNV")); } - else { changeStatusLEDColor(DIGIOCNVStatusLED, faultLEDColor); } - if(digioBitMapping.at("DIGIO2EN")){ changeStatusLEDColor(DIGIOSENTStatusLED, statusLEDColor, digioBitMapping.at("SENT")); } - else { changeStatusLEDColor(DIGIOSENTStatusLED, faultLEDColor); } - if(digioBitMapping.at("DIGIO3EN")){ changeStatusLEDColor(DIGIOACALCStatusLED, statusLEDColor, digioBitMapping.at("ACALC")); } - else { changeStatusLEDColor(DIGIOACALCStatusLED, faultLEDColor); } - if(digioBitMapping.at("DIGIO4EN")){ changeStatusLEDColor(DIGIOFaultStatusLED, statusLEDColor, digioBitMapping.at("FAULT")); } - else { changeStatusLEDColor(DIGIOFaultStatusLED, faultLEDColor); } - if(digioBitMapping.at("DIGIO5EN")){ changeStatusLEDColor(DIGIOBootloaderStatusLED, statusLEDColor, digioBitMapping.at("BOOTLOAD")); } - else { changeStatusLEDColor(DIGIOBootloaderStatusLED, faultLEDColor); } + if(digioBitMapping.at("DIGIO0EN")){ + if(!digioBitMapping.at("BUSY")){ + changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor); + DIGIOBusyStatusLED->setName("BUSY"); + } + else{ + changeStatusLEDColor(DIGIOBusyStatusLED, gpioLEDColor); + DIGIOBusyStatusLED->setName("GPIO0"); + } + } + else { + changeStatusLEDColor(DIGIOBusyStatusLED, faultLEDColor, false); + DIGIOBusyStatusLED->setName("DIGIO0"); + } + + if(digioBitMapping.at("DIGIO1EN")){ + if(!digioBitMapping.at("CNV")){ + changeStatusLEDColor(DIGIOCNVStatusLED, statusLEDColor); + DIGIOCNVStatusLED->setName("CNV"); + } + else{ + changeStatusLEDColor(DIGIOCNVStatusLED, gpioLEDColor); + DIGIOCNVStatusLED->setName("GPIO1"); + } + } + else { + changeStatusLEDColor(DIGIOCNVStatusLED, faultLEDColor, false); + DIGIOCNVStatusLED->setName("DIGIO1"); + } + + if(digioBitMapping.at("DIGIO2EN")){ + if(!digioBitMapping.at("SENT")){ + changeStatusLEDColor(DIGIOSENTStatusLED, statusLEDColor); + DIGIOSENTStatusLED->setName("SENT"); + } + else{ + changeStatusLEDColor(DIGIOSENTStatusLED, gpioLEDColor); + DIGIOSENTStatusLED->setName("GPIO2"); + } + } + else { + changeStatusLEDColor(DIGIOSENTStatusLED, faultLEDColor, false); + DIGIOSENTStatusLED->setName("DIGIO2"); + } + + if(digioBitMapping.at("DIGIO3EN")){ + if(!digioBitMapping.at("ACALC")){ + changeStatusLEDColor(DIGIOACALCStatusLED, statusLEDColor); + DIGIOACALCStatusLED->setName("ACALC"); + } + else{ + changeStatusLEDColor(DIGIOACALCStatusLED, gpioLEDColor); + DIGIOACALCStatusLED->setName("GPIO3"); + } + } + else { + changeStatusLEDColor(DIGIOACALCStatusLED, faultLEDColor, false); + DIGIOACALCStatusLED->setName("DIGIO3"); + } + + if(digioBitMapping.at("DIGIO4EN")){ + if(!digioBitMapping.at("FAULT")){ + changeStatusLEDColor(DIGIOFaultStatusLED, statusLEDColor); + DIGIOFaultStatusLED->setName("FAULT"); + } + else{ + changeStatusLEDColor(DIGIOFaultStatusLED, gpioLEDColor); + DIGIOFaultStatusLED->setName("GPIO4"); + } + } + else { + changeStatusLEDColor(DIGIOFaultStatusLED, faultLEDColor, false); + DIGIOFaultStatusLED->setName("DIGIO4"); + } + + if(digioBitMapping.at("DIGIO5EN")){ + if(!digioBitMapping.at("BOOTLOAD")){ + changeStatusLEDColor(DIGIOBootloaderStatusLED, statusLEDColor); + DIGIOBootloaderStatusLED->setName("BOOTLOAD"); + } + else{ + changeStatusLEDColor(DIGIOBootloaderStatusLED, gpioLEDColor); + DIGIOBootloaderStatusLED->setName("GPIO5"); + } + } + else { + changeStatusLEDColor(DIGIOBootloaderStatusLED, faultLEDColor, false); + DIGIOBootloaderStatusLED->setName("DIGIO5"); + } + commandLogWrite("DIGIOEN: 0b" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); } else{ commandLogWrite("Failed to read DIGIOEN Register"); } From 12247bf129e965072ca760df1a18f5ec0c65daed Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 27 Nov 2024 14:31:00 +0800 Subject: [PATCH 073/112] admt: Applied fixes for calibration Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 8 +- plugins/admt/src/harmoniccalibration.cpp | 236 +++++++----------- 2 files changed, 90 insertions(+), 154 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 92a26669cf..dfe4f1ce55 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -178,7 +178,6 @@ public Q_SLOTS: void updateLabelValue(QLabel* label, int channelIndex); void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); void updateChannelValue(int channelIndex); - void calibrateData(); void extractCalibrationData(); void importCalibrationData(); void calibrationLogWrite(QString message = ""); @@ -189,7 +188,7 @@ public Q_SLOTS: void applyLabelStyle(QLabel *widget); void initializeMotor(); void stepMotorAcquisition(double step = -408); - void clearRawDataList(); + void resetAllCalibrationState(); void connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax); void connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute); double convertRPStoVMAX(double rps); @@ -240,8 +239,13 @@ public Q_SLOTS: void prependAcquisitionData(double& data, QVector& list); void plotAcquisition(QVector& list, PlotChannel* channel, PlotWidget* plot); void populateAngleErrorGraphs(); + void populateCorrectedAngleErrorGraphs(); void resetDIGIO(); bool updateDIGIOToggle(); + void clearPostCalibrationSamples(); + void clearAngleErrorGraphs(); + void clearCorrectedAngleErrorGraphs(); + void clearCalibrationSineCosine(); QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index adf4df28ee..c5244834f4 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -6,7 +6,7 @@ #include static int acquisitionUITimerRate = 50; -static int calibrationUITimerRate = 50; +static int calibrationUITimerRate = 300; static int utilityTimerRate = 1000; static int bufferSize = 1; @@ -19,7 +19,6 @@ static double *tempGraphValue; static int cycleCount = 11; static int samplesPerCycle = 256; static int totalSamplesCount = cycleCount * samplesPerCycle; -static int samplesCollected = 0; static bool isStartAcquisition = false; static bool isStartMotor = false; static bool isPostCalibration = false; @@ -1032,6 +1031,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() isStartMotor = b; if(b){ isPostCalibration = false; + graphPostDataList.reserve(totalSamplesCount); + graphDataList.reserve(totalSamplesCount); startMotor(); } }); @@ -1119,7 +1120,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::postCalibrateData); connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); connect(importSamplesButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); - connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::clearRawDataList); + connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAllCalibrationState); connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); connectLineEditToNumberWrite(motorMaxDisplacementSpinBox->lineEdit(), dmax, ADMTController::MotorAttribute::DMAX); @@ -2560,39 +2561,6 @@ void HarmonicCalibration::connectLineEditToNumberWrite(QLineEdit* lineEdit, doub }); } -// void HarmonicCalibration::connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph, int min, int max) -// { -// connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, graph, min, max]() { -// bool ok; -// int value = lineEdit->text().toInt(&ok); -// if (ok && value >= min && value <= max) { -// variable = value; -// graph->setNumSamples(variable); -// } else { -// lineEdit->setText(QString::number(variable)); -// } -// }); -// } - -// void HarmonicCalibration::connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph) -// { -// QComboBox *combo = menuCombo->combo(); -// connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [combo, graph]() { -// int value = qvariant_cast(combo->currentData()); -// switch(value) -// { -// case Sismograph::LEFT_TO_RIGHT: -// graph->setPlotDirection(Sismograph::LEFT_TO_RIGHT); -// graph->reset(); -// break; -// case Sismograph::RIGHT_TO_LEFT: -// graph->setPlotDirection(Sismograph::RIGHT_TO_LEFT); -// graph->reset(); -// break; -// } -// }); -// } - void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, double& variable) { QComboBox *combo = menuCombo->combo(); @@ -2609,50 +2577,6 @@ void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, int& va }); } -// void HarmonicCalibration::changeGraphColorByChannelName(Sismograph* graph, const char* channelName) -// { -// int index = m_admtController->getChannelIndex(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), channelName); -// if(index > -1){ -// graph->setColor(StyleHelper::getColor( QString::fromStdString("CH" + std::to_string(index) ))); -// } -// } - -// void HarmonicCalibration::connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph) -// { -// QComboBox *combo = menuCombo->combo(); -// connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [this, combo, graph]() { -// int currentIndex = combo->currentIndex(); -// QVariant currentData = combo->currentData(); -// char *value = reinterpret_cast(currentData.value()); -// switch(currentIndex) -// { -// case ADMTController::Channel::ROTATION: -// dataGraphValue = &rotation; -// graph->setUnitOfMeasure("Degree", "°"); -// graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); -// graph->setNumSamples(dataGraphSamples); -// graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); -// break; -// case ADMTController::Channel::ANGLE: -// dataGraphValue = ∠ -// graph->setUnitOfMeasure("Degree", "°"); -// graph->setAxisScale(QwtAxis::YLeft, -30.0, 390.0); -// graph->setNumSamples(dataGraphSamples); -// graph->setAxisTitle(QwtAxis::YLeft, tr("Degree (°)")); -// break; -// case ADMTController::Channel::COUNT: -// dataGraphValue = &count; -// graph->setUnitOfMeasure("Count", ""); -// graph->setAxisScale(QwtAxis::YLeft, -1.0, 20.0); -// graph->setNumSamples(dataGraphSamples); -// graph->setAxisTitle(QwtAxis::YLeft, tr("Count")); -// break; -// } -// changeGraphColorByChannelName(graph, value); -// graph->reset(); -// }); -// } - void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax) { connect(lineEdit, &QLineEdit::editingFinished, [=, &vmax]() { @@ -2875,6 +2799,7 @@ void HarmonicCalibration::getCalibrationSamples() } } else{ + clearCalibrationSineCosine(); while(isStartMotor && graphDataList.size() < totalSamplesCount){ stepMotorAcquisition(); updateChannelValue(ADMTController::Channel::ANGLE); @@ -2899,7 +2824,16 @@ void HarmonicCalibration::startMotor() if(resetToZero && !isPostCalibration){ clearCalibrationSamples(); + clearPostCalibrationSamples(); + clearAngleErrorGraphs(); + clearCorrectedAngleErrorGraphs(); } + + if(isPostCalibration) + calibrationDataGraphTabWidget->setCurrentIndex(1); // Set tab to Post Calibration Samples + else + calibrationDataGraphTabWidget->setCurrentIndex(0); // Set tab to Calibration Samples + QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getCalibrationSamples); QFutureWatcher *watcher = new QFutureWatcher(this); @@ -2914,44 +2848,25 @@ void HarmonicCalibration::startMotor() if(isPostCalibration) { - if(samplesCollected == totalSamplesCount) + if(static_cast(graphPostDataList.size()) == totalSamplesCount) { computeSineCosineOfAngles(graphPostDataList); m_admtController->postcalibrate(vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, samplesPerCycle); + populateCorrectedAngleErrorGraphs(); isPostCalibration = false; isStartMotor = false; canStartMotor(true); - QVector correctedError(m_admtController->correctedError.begin(), m_admtController->correctedError.end()); - correctedErrorPlotChannel->curve()->setSamples(correctedError); - auto correctedErrorMagnitudeMinMax = std::minmax_element(correctedError.begin(), correctedError.end()); - correctedErrorYPlotAxis->setInterval(*correctedErrorMagnitudeMinMax.first, *correctedErrorMagnitudeMinMax.second); - correctedErrorXPlotAxis->setMax(correctedError.size()); - correctedErrorPlotWidget->replot(); - - QVector FFTCorrectedErrorMagnitude(m_admtController->FFTCorrectedErrorMagnitude.begin(), m_admtController->FFTCorrectedErrorMagnitude.end()); - QVector FFTCorrectedErrorPhase(m_admtController->FFTCorrectedErrorPhase.begin(), m_admtController->FFTCorrectedErrorPhase.end()); - FFTCorrectedErrorMagnitudeChannel->curve()->setSamples(FFTCorrectedErrorMagnitude); - FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); - auto FFTCorrectedErrorMagnitudeMinMax = std::minmax_element(FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); - auto FFTCorrectedErrorPhaseMinMax = std::minmax_element(FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); - double FFTCorrectedErrorPlotMin = *FFTCorrectedErrorMagnitudeMinMax.first < *FFTCorrectedErrorPhaseMinMax.first ? *FFTCorrectedErrorMagnitudeMinMax.first : *FFTCorrectedErrorPhaseMinMax.first; - double FFTCorrectedErrorPlotMax = *FFTCorrectedErrorMagnitudeMinMax.second > *FFTCorrectedErrorPhaseMinMax.second ? *FFTCorrectedErrorMagnitudeMinMax.second : *FFTCorrectedErrorPhaseMinMax.second; - FFTCorrectedErrorYPlotAxis->setInterval(FFTCorrectedErrorPlotMin, FFTCorrectedErrorPlotMax); - FFTCorrectedErrorXPlotAxis->setMax(FFTCorrectedErrorMagnitude.size()); - FFTCorrectedErrorPlotWidget->replot(); + resetToZero = true; } } else{ - if(samplesCollected == totalSamplesCount) + if(static_cast(graphDataList.size()) == totalSamplesCount) { computeSineCosineOfAngles(graphDataList); - canCalibrate(true); - calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); - flashHarmonicValues(); - populateAngleErrorGraphs(); + canCalibrate(true); } else{ resetToZero = true; @@ -2962,6 +2877,31 @@ void HarmonicCalibration::startMotor() watcher->setFuture(future); } +void HarmonicCalibration::populateCorrectedAngleErrorGraphs() +{ + QVector correctedError(m_admtController->correctedError.begin(), m_admtController->correctedError.end()); + QVector FFTCorrectedErrorMagnitude(m_admtController->FFTCorrectedErrorMagnitude.begin(), m_admtController->FFTCorrectedErrorMagnitude.end()); + QVector FFTCorrectedErrorPhase(m_admtController->FFTCorrectedErrorPhase.begin(), m_admtController->FFTCorrectedErrorPhase.end()); + + correctedErrorPlotChannel->curve()->setSamples(correctedError); + auto correctedErrorMagnitudeMinMax = std::minmax_element(correctedError.begin(), correctedError.end()); + correctedErrorYPlotAxis->setInterval(*correctedErrorMagnitudeMinMax.first, *correctedErrorMagnitudeMinMax.second); + correctedErrorXPlotAxis->setMax(correctedError.size()); + correctedErrorPlotWidget->replot(); + + FFTCorrectedErrorMagnitudeChannel->curve()->setSamples(FFTCorrectedErrorMagnitude); + FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); + auto FFTCorrectedErrorMagnitudeMinMax = std::minmax_element(FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); + auto FFTCorrectedErrorPhaseMinMax = std::minmax_element(FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); + double FFTCorrectedErrorPlotMin = *FFTCorrectedErrorMagnitudeMinMax.first < *FFTCorrectedErrorPhaseMinMax.first ? *FFTCorrectedErrorMagnitudeMinMax.first : *FFTCorrectedErrorPhaseMinMax.first; + double FFTCorrectedErrorPlotMax = *FFTCorrectedErrorMagnitudeMinMax.second > *FFTCorrectedErrorPhaseMinMax.second ? *FFTCorrectedErrorMagnitudeMinMax.second : *FFTCorrectedErrorPhaseMinMax.second; + FFTCorrectedErrorYPlotAxis->setInterval(FFTCorrectedErrorPlotMin, FFTCorrectedErrorPlotMax); + FFTCorrectedErrorXPlotAxis->setMax(FFTCorrectedErrorMagnitude.size()); + FFTCorrectedErrorPlotWidget->replot(); + + resultDataTabWidget->setCurrentIndex(2); // Set tab to Angle Error +} + void HarmonicCalibration::populateAngleErrorGraphs() { QVector angleError = QVector(m_admtController->angleError.begin(), m_admtController->angleError.end()); @@ -2992,35 +2932,6 @@ void HarmonicCalibration::canStartMotor(bool value) calibrationStartMotorButton->setEnabled(value); } -void HarmonicCalibration::calibrateData() -{ - calibrationLogWrite("==== Calibration Start ===="); - - calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); - - flashHarmonicValues(); - - QVector angleError = QVector(m_admtController->angleError.begin(), m_admtController->angleError.end()); - QVector FFTAngleErrorMagnitude = QVector(m_admtController->FFTAngleErrorMagnitude.begin(), m_admtController->FFTAngleErrorMagnitude.end()); - QVector FFTAngleErrorPhase = QVector(m_admtController->FFTAngleErrorPhase.begin(), m_admtController->FFTAngleErrorPhase.end()); - - angleErrorPlotChannel->curve()->setSamples(angleError); - auto angleErrorMinMax = std::minmax_element(angleError.begin(), angleError.end()); - angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, *angleErrorMinMax.second); - angleErrorXPlotAxis->setInterval(0, angleError.size()); - angleErrorPlotWidget->replot(); - - FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); - auto angleErrorMagnitudeMinMax = std::minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); - FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); - auto angleErrorPhaseMinMax = std::minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); - double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first ? *angleErrorMagnitudeMinMax.first : *angleErrorPhaseMinMax.first; - double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second ? *angleErrorMagnitudeMinMax.second : *angleErrorPhaseMinMax.second; - FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); - FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); - FFTAngleErrorPlotWidget->replot(); -} - void HarmonicCalibration::flashHarmonicValues() { uint32_t *h1MagCurrent = new uint32_t, @@ -3306,11 +3217,11 @@ void HarmonicCalibration::importCalibrationData() calibrationRawDataPlotWidget->replot(); computeSineCosineOfAngles(graphDataList); - canStartMotor(false); - canCalibrate(true); calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); flashHarmonicValues(); populateAngleErrorGraphs(); + canStartMotor(false); + canCalibrate(true); } } catch(FileManagerException &ex) { calibrationLogWrite(QString(ex.what())); @@ -3342,26 +3253,13 @@ void HarmonicCalibration::stepMotorAcquisition(double step) } } -void HarmonicCalibration::clearRawDataList() +void HarmonicCalibration::resetAllCalibrationState() { clearCalibrationSamples(); + clearPostCalibrationSamples(); - graphPostDataList.clear(); - postCalibrationRawDataPlotChannel->curve()->setData(nullptr); - postCalibrationSineDataPlotChannel->curve()->setData(nullptr); - postCalibrationCosineDataPlotChannel->curve()->setData(nullptr); - postCalibrationRawDataPlotWidget->replot(); - - angleErrorPlotChannel->curve()->setData(nullptr); - angleErrorPlotWidget->replot(); - FFTAngleErrorMagnitudeChannel->curve()->setData(nullptr); - FFTAngleErrorPhaseChannel->curve()->setData(nullptr); - FFTAngleErrorPlotWidget->replot(); - correctedErrorPlotChannel->curve()->setData(nullptr); - correctedErrorPlotWidget->replot(); - FFTCorrectedErrorMagnitudeChannel->curve()->setData(nullptr); - FFTCorrectedErrorPhaseChannel->curve()->setData(nullptr); - FFTCorrectedErrorPlotWidget->replot(); + clearAngleErrorGraphs(); + clearCorrectedAngleErrorGraphs(); canCalibrate(false); canStartMotor(true); @@ -3380,6 +3278,40 @@ void HarmonicCalibration::clearCalibrationSamples() calibrationRawDataPlotWidget->replot(); } +void HarmonicCalibration::clearCalibrationSineCosine() +{ + calibrationSineDataPlotChannel->curve()->setData(nullptr); + calibrationCosineDataPlotChannel->curve()->setData(nullptr); + calibrationRawDataPlotWidget->replot(); +} + +void HarmonicCalibration::clearPostCalibrationSamples() +{ + graphPostDataList.clear(); + postCalibrationRawDataPlotChannel->curve()->setData(nullptr); + postCalibrationSineDataPlotChannel->curve()->setData(nullptr); + postCalibrationCosineDataPlotChannel->curve()->setData(nullptr); + postCalibrationRawDataPlotWidget->replot(); +} + +void HarmonicCalibration::clearAngleErrorGraphs() +{ + angleErrorPlotChannel->curve()->setData(nullptr); + angleErrorPlotWidget->replot(); + FFTAngleErrorMagnitudeChannel->curve()->setData(nullptr); + FFTAngleErrorPhaseChannel->curve()->setData(nullptr); + FFTAngleErrorPlotWidget->replot(); +} + +void HarmonicCalibration::clearCorrectedAngleErrorGraphs() +{ + correctedErrorPlotChannel->curve()->setData(nullptr); + correctedErrorPlotWidget->replot(); + FFTCorrectedErrorMagnitudeChannel->curve()->setData(nullptr); + FFTCorrectedErrorPhaseChannel->curve()->setData(nullptr); + FFTCorrectedErrorPlotWidget->replot(); +} + void HarmonicCalibration::applyTextStyle(QWidget *widget, const QString& styleHelperColor, bool isBold) { QString existingStyle = widget->styleSheet(); From 65c67bcbd0181de49adbda1755613e59dc4e4600 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 2 Dec 2024 12:39:18 +0800 Subject: [PATCH 074/112] admt: Implemented multi-channel acquisition graph Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtstylehelper.h | 1 + .../admt/include/admt/harmoniccalibration.h | 32 ++++- plugins/admt/src/admtstylehelper.cpp | 25 ++++ plugins/admt/src/harmoniccalibration.cpp | 120 ++++++++++++++++-- 4 files changed, 162 insertions(+), 16 deletions(-) diff --git a/plugins/admt/include/admt/admtstylehelper.h b/plugins/admt/include/admt/admtstylehelper.h index e20c2f60e2..857c32c34f 100644 --- a/plugins/admt/include/admt/admtstylehelper.h +++ b/plugins/admt/include/admt/admtstylehelper.h @@ -28,6 +28,7 @@ class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject static void PlotWidgetStyle(PlotWidget *widget, QString objectName = ""); static void ComboBoxStyle(QComboBox *widget, QString objectName = ""); static void LineEditStyle(QLineEdit *widget, QString objectName = ""); + static void ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName = ""); private: static ADMTStyleHelper *pinstance_; }; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index dfe4f1ce55..34a050f920 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,26 @@ #include #include +enum AcquisitionDataKey +{ + RADIUS, + ANGLE, + TURNCOUNT, + ABSANGLE, + SINE, + COSINE, + SECANGLI, + SECANGLQ, + ANGLESEC, + DIAG1, + DIAG2, + TMP0, + TMP1, + CNVCNT, + SCRADIUS, + SPIFAULT +}; + namespace scopy{ namespace admt { @@ -136,7 +157,8 @@ public Q_SLOTS: *angleErrorXPlotAxis, *angleErrorYPlotAxis, *FFTAngleErrorXPlotAxis, *FFTAngleErrorYPlotAxis, *correctedErrorXPlotAxis, *correctedErrorYPlotAxis, *FFTCorrectedErrorXPlotAxis, *FFTCorrectedErrorYPlotAxis, *postCalibrationRawDataXPlotAxis, *postCalibrationRawDataYPlotAxis; - PlotChannel *acquisitionAnglePlotChannel, *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel, + PlotChannel *acquisitionAnglePlotChannel, *acquisitionABSAnglePlotChannel, *acquisitionTurnCountPlotChannel, *acquisitionTmp0PlotChannel, + *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel, *FFTAngleErrorMagnitudeChannel, *FFTAngleErrorPhaseChannel, *correctedErrorPlotChannel, *postCalibrationRawDataPlotChannel, *postCalibrationSineDataPlotChannel, *postCalibrationCosineDataPlotChannel, @@ -166,12 +188,8 @@ public Q_SLOTS: void updateGeneralSettingEnabled(bool value); void connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max); void connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit = ""); - // void connectLineEditToGraphSamples(QLineEdit* lineEdit, int& variable, Sismograph* graph, int min, int max); - // void connectMenuComboToGraphDirection(MenuCombo* menuCombo, Sismograph* graph); - // void connectMenuComboToGraphChannel(MenuCombo* menuCombo, Sismograph* graph); void connectMenuComboToNumber(MenuCombo* menuCombo, double& variable); void connectMenuComboToNumber(MenuCombo* menuCombo, int& variable); - // void changeGraphColorByChannelName(Sismograph* graph, const char* channelName); ToolTemplate* createCalibrationWidget(); ToolTemplate* createRegistersWidget(); ToolTemplate* createUtilityWidget(); @@ -237,7 +255,7 @@ public Q_SLOTS: void toggleSequenceModeRegisters(int mode); void readAllRegisters(); void prependAcquisitionData(double& data, QVector& list); - void plotAcquisition(QVector& list, PlotChannel* channel, PlotWidget* plot); + void plotAcquisition(QVector& list, PlotChannel* channel); void populateAngleErrorGraphs(); void populateCorrectedAngleErrorGraphs(); void resetDIGIO(); @@ -246,6 +264,8 @@ public Q_SLOTS: void clearAngleErrorGraphs(); void clearCorrectedAngleErrorGraphs(); void clearCalibrationSineCosine(); + void connectCheckBoxToAcquisitionGraph(QCheckBox* widget, PlotChannel* channel, AcquisitionDataKey key); + void prependNullAcquisitionData(QVector& list); QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp index f7aae2664b..b50e44f079 100644 --- a/plugins/admt/src/admtstylehelper.cpp +++ b/plugins/admt/src/admtstylehelper.cpp @@ -146,4 +146,29 @@ void ADMTStyleHelper::LineEditStyle(QLineEdit *widget, QString objectName) widget->setAlignment(Qt::AlignRight); } +void ADMTStyleHelper::ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName) +{ + if(!objectName.isEmpty()) + chk->setObjectName(objectName); + QString style = QString(R"css( + QCheckBox { + width:16px; + height:16px; + background-color: rgba(128,128,128,0); + color: rgba(255, 255, 255, 153); + } + QCheckBox::indicator { + width: 12px; + height: 12px; + border: 2px solid #FFFFFF; + border-radius: 4px; + } + QCheckBox::indicator:unchecked { background-color: &&UIElementBackground&&; } + QCheckBox::indicator:checked { background-color: &&colorname&&; } + )css"); + style.replace("&&colorname&&", color.name()); + style.replace("&&UIElementBackground&&", StyleHelper::getColor("UIElementBackground")); + chk->setStyleSheet(style); +} + #include "moc_admtstylehelper.cpp" \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index c5244834f4..2132592a9f 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -43,10 +43,10 @@ static uint32_t h3PhaseDeviceRegister = 0x1A; static uint32_t h8PhaseDeviceRegister = 0x1C; static int acquisitionDisplayLength = 200; -static QVector acquisitionAngleList, graphDataList, graphPostDataList; +static QVector acquisitionAngleList, acquisitionABSAngleList, acquisitionTurnCountList, acquisitionTmp0List, + graphDataList, graphPostDataList; static const QColor scopyBlueColor = scopy::StyleHelper::getColor("ScopyBlue"); -static const QColor channel0Color = scopy::StyleHelper::getColor("CH0"); static const QColor sineColor = QColor("#85e94c"); static const QColor cosineColor = QColor("#91e6cf"); static const QColor faultLEDColor = QColor("#c81a28"); @@ -54,7 +54,10 @@ static const QColor gpioLEDColor = scopyBlueColor; static const QColor statusLEDColor = QColor("#2e9e6f"); static const QPen scopyBluePen(scopyBlueColor); -static const QPen channel0Pen(channel0Color); +static const QPen channel0Pen(scopy::StyleHelper::getColor("CH0")); +static const QPen channel1Pen(scopy::StyleHelper::getColor("CH1")); +static const QPen channel2Pen(scopy::StyleHelper::getColor("CH2")); +static const QPen channel3Pen(scopy::StyleHelper::getColor("CH3")); static const QPen sinePen(sineColor); static const QPen cosinePen(cosineColor); @@ -67,6 +70,25 @@ static bool is5V = false; static double H1_MAG_ANGLE, H2_MAG_ANGLE, H3_MAG_ANGLE, H8_MAG_ANGLE, H1_PHASE_ANGLE, H2_PHASE_ANGLE, H3_PHASE_ANGLE, H8_PHASE_ANGLE; static uint32_t H1_MAG_HEX, H2_MAG_HEX, H3_MAG_HEX, H8_MAG_HEX, H1_PHASE_HEX, H2_PHASE_HEX, H3_PHASE_HEX, H8_PHASE_HEX; +static std::map acquisitionDataMap = { + {RADIUS, false}, + {ANGLE, false}, + {TURNCOUNT, false}, + {ABSANGLE, false}, + {SINE, false}, + {COSINE, false}, + {SECANGLI, false}, + {SECANGLQ, false}, + {ANGLESEC, false}, + {DIAG1, false}, + {DIAG2, false}, + {TMP0, false}, + {TMP1, false}, + {CNVCNT, false}, + {SCRADIUS, false}, + {SPIFAULT, false} +}; + using namespace scopy; using namespace scopy::admt; @@ -214,6 +236,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool MenuCollapseSection *acquisitionGraphCollapseSection = new MenuCollapseSection("Captured Data", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, acquisitionGraphSectionWidget); acquisitionGraphSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); acquisitionGraphSectionWidget->contentLayout()->addWidget(acquisitionGraphCollapseSection); + acquisitionGraphCollapseSection->contentLayout()->setSpacing(8); acquisitionGraphPlotWidget = new PlotWidget(); ADMTStyleHelper::PlotWidgetStyle(acquisitionGraphPlotWidget); @@ -229,14 +252,53 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool acquisitionYPlotAxis->setInterval(0, 360); acquisitionAnglePlotChannel = new PlotChannel("Angle", channel0Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionABSAnglePlotChannel = new PlotChannel("ABS Angle", channel1Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTurnCountPlotChannel = new PlotChannel("Turn Count", channel2Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTmp0PlotChannel = new PlotChannel("TMP 0", channel3Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); acquisitionGraphPlotWidget->addPlotChannel(acquisitionAnglePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionABSAnglePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionTurnCountPlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp0PlotChannel); acquisitionAnglePlotChannel->setEnabled(true); + acquisitionABSAnglePlotChannel->setEnabled(true); + acquisitionTurnCountPlotChannel->setEnabled(true); + acquisitionTmp0PlotChannel->setEnabled(true); acquisitionGraphPlotWidget->selectChannel(acquisitionAnglePlotChannel); acquisitionGraphPlotWidget->replot(); + #pragma region Channel Selection + QWidget *acquisitionGraphChannelWidget = new QWidget(acquisitionGraphSectionWidget); + QGridLayout *acquisitionGraphChannelGridLayout = new QGridLayout(acquisitionGraphChannelWidget); + // QHBoxLayout *acquisitionGraphChannelLayout = new QHBoxLayout(acquisitionGraphChannelWidget); + acquisitionGraphChannelGridLayout->setContentsMargins(16, 8, 8, 16); + acquisitionGraphChannelGridLayout->setSpacing(8); + + QCheckBox *angleCheckBox = new QCheckBox("Angle", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(angleCheckBox, channel0Pen.color()); + connectCheckBoxToAcquisitionGraph(angleCheckBox, acquisitionAnglePlotChannel, ANGLE); + + QCheckBox *absAngleCheckBox = new QCheckBox("ABS Angle", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(absAngleCheckBox, channel1Pen.color()); + connectCheckBoxToAcquisitionGraph(absAngleCheckBox, acquisitionABSAnglePlotChannel, ABSANGLE); + + QCheckBox *countCheckBox = new QCheckBox("Count", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(countCheckBox, channel2Pen.color()); + connectCheckBoxToAcquisitionGraph(countCheckBox, acquisitionTurnCountPlotChannel, TURNCOUNT); + + QCheckBox *temp0CheckBox = new QCheckBox("Temp 0", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(temp0CheckBox, channel3Pen.color()); + connectCheckBoxToAcquisitionGraph(temp0CheckBox, acquisitionTmp0PlotChannel, TMP0); + + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(countCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 0, 3); + #pragma endregion + acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphPlotWidget); + acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphChannelWidget); #pragma endregion #pragma region General Setting @@ -268,9 +330,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connectLineEditToNumber(graphUpdateIntervalLineEdit, acquisitionUITimerRate, 1, 5000); - generalSection->contentLayout()->addWidget(graphUpdateIntervalLabel); - generalSection->contentLayout()->addWidget(graphUpdateIntervalLineEdit); - // Data Sample Size QLabel *displayLengthLabel = new QLabel("Display Length", generalSection); StyleHelper::MenuSmallLabel(displayLengthLabel); @@ -280,6 +339,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connectLineEditToNumber(displayLengthLineEdit, acquisitionDisplayLength, 1, 2048); + generalSection->contentLayout()->addWidget(graphUpdateIntervalLabel); + generalSection->contentLayout()->addWidget(graphUpdateIntervalLineEdit); generalSection->contentLayout()->addWidget(displayLengthLabel); generalSection->contentLayout()->addWidget(displayLengthLineEdit); @@ -437,7 +498,19 @@ void HarmonicCalibration::getAcquisitionSamples() while(isStartAcquisition) { updateChannelValues(); - prependAcquisitionData(angle, acquisitionAngleList); + + if(acquisitionDataMap.at(ANGLE)) prependAcquisitionData(angle, acquisitionAngleList); + else if(acquisitionDataMap.at(ANGLE) == false && acquisitionAngleList.size() > 0) acquisitionAngleList.clear(); + + if(acquisitionDataMap.at(ABSANGLE)) prependAcquisitionData(rotation, acquisitionABSAngleList); + else if(acquisitionDataMap.at(ABSANGLE) == false && acquisitionABSAngleList.size() > 0) acquisitionABSAngleList.clear(); + + if(acquisitionDataMap.at(TURNCOUNT)) prependAcquisitionData(count, acquisitionTurnCountList); + else if(acquisitionDataMap.at(TURNCOUNT) == false && acquisitionTurnCountList.size() > 0) acquisitionTurnCountList.clear(); + + if(acquisitionDataMap.at(TMP0)) prependAcquisitionData(temp, acquisitionTmp0List); + else if(acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) acquisitionTmp0List.clear(); + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); } } @@ -447,10 +520,14 @@ void HarmonicCalibration::prependAcquisitionData(double& data, QVector& list.prepend(data); } -void HarmonicCalibration::plotAcquisition(QVector& list, PlotChannel* channel, PlotWidget* plot) +void HarmonicCalibration::prependNullAcquisitionData(QVector& list) +{ + list.prepend(qQNaN()); +} + +void HarmonicCalibration::plotAcquisition(QVector& list, PlotChannel* channel) { channel->curve()->setSamples(list); - plot->replot(); } void HarmonicCalibration::initializeMotor() @@ -2111,7 +2188,16 @@ void HarmonicCalibration::canCalibrate(bool value) void HarmonicCalibration::acquisitionUITask() { - plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel, acquisitionGraphPlotWidget); + if(acquisitionDataMap.at(ANGLE)) + plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel); + if(acquisitionDataMap.at(ABSANGLE)) + plotAcquisition(acquisitionABSAngleList, acquisitionABSAnglePlotChannel); + if(acquisitionDataMap.at(TURNCOUNT)) + plotAcquisition(acquisitionTurnCountList, acquisitionTurnCountPlotChannel); + if(acquisitionDataMap.at(TMP0)) + plotAcquisition(acquisitionTmp0List, acquisitionTmp0PlotChannel); + + acquisitionGraphPlotWidget->replot(); updateLineEditValues(); updateLabelValue(acquisitionMotorCurrentPositionLabel, ADMTController::MotorAttribute::CURRENT_POS); } @@ -2655,6 +2741,20 @@ void HarmonicCalibration::connectRegisterBlockToRegistry(RegisterBlockWidget* wi } } +void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox* widget, PlotChannel* channel, AcquisitionDataKey key) +{ + connect(widget, &QCheckBox::stateChanged, [=](int state){ + if(state == Qt::Checked){ + channel->setEnabled(true); + acquisitionDataMap[key] = true; + } + else{ + channel->setEnabled(false); + acquisitionDataMap[key] = false; + } + }); +} + double HarmonicCalibration::convertRPStoVMAX(double rps) { return (rps * motorMicrostepPerRevolution * motorTimeUnit); From dd1e049fa3c89b0b14093d3c9607558834e5dd87 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 5 Dec 2024 15:16:32 +0800 Subject: [PATCH 075/112] admt: Fixed crashing issue when calibrating - Adjusted graph behavior for acquisition tab - Adjusted layout for calibration Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtstylehelper.h | 3 + .../admt/include/admt/harmoniccalibration.h | 19 +- .../include/admt/widgets/horizontalspinbox.h | 1 + plugins/admt/src/admtstylehelper.cpp | 38 ++ plugins/admt/src/harmoniccalibration.cpp | 439 ++++++++++-------- .../admt/src/widgets/horizontalspinbox.cpp | 3 + 6 files changed, 297 insertions(+), 206 deletions(-) diff --git a/plugins/admt/include/admt/admtstylehelper.h b/plugins/admt/include/admt/admtstylehelper.h index 857c32c34f..d3f22ecc14 100644 --- a/plugins/admt/include/admt/admtstylehelper.h +++ b/plugins/admt/include/admt/admtstylehelper.h @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include @@ -29,6 +31,7 @@ class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject static void ComboBoxStyle(QComboBox *widget, QString objectName = ""); static void LineEditStyle(QLineEdit *widget, QString objectName = ""); static void ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName = ""); + static void StartButtonStyle(QPushButton *btn, QString objectName = ""); private: static ADMTStyleHelper *pinstance_; }; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 34a050f920..76ddb24528 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include @@ -107,21 +109,22 @@ public Q_SLOTS: double rotation, angle, count, temp = 0.0, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode, afeDiag0, afeDiag1, afeDiag2; - QPushButton *openLastMenuButton, *calibrationStartMotorButton, *applyCalibrationDataButton, *calibrateDataButton, *extractDataButton, + QPushButton *openLastMenuButton, *calibrationStartMotorButton, + *calibrateDataButton, *extractDataButton, *clearCalibrateDataButton, *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; QButtonGroup *rightMenuButtonGroup; QLineEdit *graphUpdateIntervalLineEdit, *displayLengthLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, + *acquisitionMotorCurrentPositionLineEdit, *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit, + *calibrationMotorCurrentPositionLineEdit, *AFEDIAG0LineEdit, *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; - QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, - *acquisitionMotorCurrentPositionLabel, - *calibrationMotorCurrentPositionLabel, + QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, *motorAmaxValueLabel, *motorRotateVmaxValueLabel, *motorDmaxValueLabel, *motorDisableValueLabel, *motorTargetPosValueLabel, *motorCurrentPosValueLabel, *motorRampModeValueLabel, @@ -205,7 +208,7 @@ public Q_SLOTS: void applyTextStyle(QWidget *widget, const QString& styleHelperColor = "CH0", bool isBold = false); void applyLabelStyle(QLabel *widget); void initializeMotor(); - void stepMotorAcquisition(double step = -408); + void moveMotorToPosition(double& position, bool validate = true); void resetAllCalibrationState(); void connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax); void connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute); @@ -266,6 +269,12 @@ public Q_SLOTS: void clearCalibrationSineCosine(); void connectCheckBoxToAcquisitionGraph(QCheckBox* widget, PlotChannel* channel, AcquisitionDataKey key); void prependNullAcquisitionData(QVector& list); + void startMotorContinuous(); + void stopMotor(); + void calculateHarmonicValues(); + void connectLineEditToDouble(QLineEdit* lineEdit, double& variable); + void updateLineEditValue(QLineEdit* lineEdit, double value); + void toggleTabSwitching(bool value); QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; diff --git a/plugins/admt/include/admt/widgets/horizontalspinbox.h b/plugins/admt/include/admt/widgets/horizontalspinbox.h index e28d3446a5..61c29a081d 100644 --- a/plugins/admt/include/admt/widgets/horizontalspinbox.h +++ b/plugins/admt/include/admt/widgets/horizontalspinbox.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace scopy::admt { class SCOPY_ADMT_EXPORT HorizontalSpinBox : public QWidget diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp index b50e44f079..6e3a7542fd 100644 --- a/plugins/admt/src/admtstylehelper.cpp +++ b/plugins/admt/src/admtstylehelper.cpp @@ -171,4 +171,42 @@ void ADMTStyleHelper::ColoredSquareCheckbox(QCheckBox *chk, QColor color, QStrin chk->setStyleSheet(style); } +void ADMTStyleHelper::StartButtonStyle(QPushButton *btn, QString objectName) +{ + if(!objectName.isEmpty()) + btn->setObjectName(objectName); + QString style = QString(R"css( + QPushButton { + border-radius: 2px; + padding-left: 20px; + padding-right: 20px; + color: white; + font-weight: 700; + font-size: 14px; + } + + QPushButton:!checked { + background-color: #27b34f; + } + + QPushButton:checked { + background-color: #F45000; + } + + QPushButton:disabled { + background-color: grey; + })css"); + btn->setCheckable(true); + btn->setChecked(false); + btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + btn->setFixedHeight(36); + btn->setStyleSheet(style); + QIcon playIcon; + playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/play.svg", "white", 1), QIcon::Normal, QIcon::Off); + playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/scopy-default/icons/play_stop.svg", "white", 1), + QIcon::Normal, QIcon::On); + btn->setIcon(playIcon); + btn->setIconSize(QSize(64, 64)); +} + #include "moc_admtstylehelper.cpp" \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 2132592a9f..a6161986e9 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -145,10 +145,10 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool angleWidget->contentLayout()->setSpacing(8); countWidget->contentLayout()->setSpacing(8); tempWidget->contentLayout()->setSpacing(8); - MenuCollapseSection *rotationSection = new MenuCollapseSection("AMR Angle", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, rotationWidget); - MenuCollapseSection *angleSection = new MenuCollapseSection("GMR Angle", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, angleWidget); + MenuCollapseSection *rotationSection = new MenuCollapseSection("ABS Angle", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, rotationWidget); + MenuCollapseSection *angleSection = new MenuCollapseSection("Angle", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, angleWidget); MenuCollapseSection *countSection = new MenuCollapseSection("Count", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, countWidget); - MenuCollapseSection *tempSection = new MenuCollapseSection("Sensor Temperature", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, tempWidget); + MenuCollapseSection *tempSection = new MenuCollapseSection("Temp 0", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, tempWidget); rotationSection->contentLayout()->setSpacing(8); angleSection->contentLayout()->setSpacing(8); countSection->contentLayout()->setSpacing(8); @@ -210,20 +210,21 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); StyleHelper::MenuSmallLabel(currentPositionLabel, "currentPositionLabel"); - acquisitionMotorCurrentPositionLabel = new QLabel("--.--", motorControlSectionWidget); - acquisitionMotorCurrentPositionLabel->setAlignment(Qt::AlignRight); - applyLabelStyle(acquisitionMotorCurrentPositionLabel); + acquisitionMotorCurrentPositionLineEdit = new QLineEdit("--.--", motorControlSectionWidget); + acquisitionMotorCurrentPositionLineEdit->setReadOnly(true); + ADMTStyleHelper::LineEditStyle(acquisitionMotorCurrentPositionLineEdit); + connectLineEditToDouble(acquisitionMotorCurrentPositionLineEdit, current_pos); motorTargetPositionSpinBox = new HorizontalSpinBox("Target Position", target_pos, "", motorControlSectionWidget); motorControlCollapseSection->contentLayout()->setSpacing(8); motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); - motorControlCollapseSection->contentLayout()->addWidget(acquisitionMotorCurrentPositionLabel); + motorControlCollapseSection->contentLayout()->addWidget(acquisitionMotorCurrentPositionLineEdit); motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionSpinBox); #pragma endregion - rawDataLayout->addWidget(rotationWidget); rawDataLayout->addWidget(angleWidget); + rawDataLayout->addWidget(rotationWidget); rawDataLayout->addWidget(countWidget); rawDataLayout->addWidget(tempWidget); rawDataLayout->addWidget(motorConfigurationSectionWidget); @@ -278,6 +279,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool QCheckBox *angleCheckBox = new QCheckBox("Angle", acquisitionGraphChannelWidget); ADMTStyleHelper::ColoredSquareCheckbox(angleCheckBox, channel0Pen.color()); connectCheckBoxToAcquisitionGraph(angleCheckBox, acquisitionAnglePlotChannel, ANGLE); + angleCheckBox->setChecked(true); QCheckBox *absAngleCheckBox = new QCheckBox("ABS Angle", acquisitionGraphChannelWidget); ADMTStyleHelper::ColoredSquareCheckbox(absAngleCheckBox, channel1Pen.color()); @@ -586,7 +588,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, scopyBluePen); calibrationRawDataXPlotAxis->setMin(0); calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, scopyBluePen); - calibrationRawDataYPlotAxis->setInterval(0, 400); + calibrationRawDataYPlotAxis->setInterval(0, 360); calibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); calibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); @@ -595,9 +597,9 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); calibrationRawDataPlotWidget->addPlotChannel(calibrationSineDataPlotChannel); calibrationRawDataPlotWidget->addPlotChannel(calibrationCosineDataPlotChannel); - calibrationRawDataPlotChannel->setEnabled(true); calibrationSineDataPlotChannel->setEnabled(true); calibrationCosineDataPlotChannel->setEnabled(true); + calibrationRawDataPlotChannel->setEnabled(true); calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); calibrationRawDataPlotWidget->setShowXAxisLabels(true); @@ -645,7 +647,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() postCalibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, postCalibrationRawDataPlotWidget, scopyBluePen); postCalibrationRawDataXPlotAxis->setMin(0); postCalibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, postCalibrationRawDataPlotWidget, scopyBluePen); - postCalibrationRawDataYPlotAxis->setInterval(0, 400); + postCalibrationRawDataYPlotAxis->setInterval(0, 360); postCalibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); postCalibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); @@ -655,9 +657,9 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationSineDataPlotChannel); postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationCosineDataPlotChannel); - postCalibrationRawDataPlotChannel->setEnabled(true); postCalibrationSineDataPlotChannel->setEnabled(true); postCalibrationCosineDataPlotChannel->setEnabled(true); + postCalibrationRawDataPlotChannel->setEnabled(true); postCalibrationRawDataPlotWidget->selectChannel(postCalibrationRawDataPlotChannel); postCalibrationRawDataPlotWidget->replot(); @@ -750,8 +752,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorMagnitudeChannel); FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorPhaseChannel); - FFTAngleErrorMagnitudeChannel->setEnabled(true); FFTAngleErrorPhaseChannel->setEnabled(true); + FFTAngleErrorMagnitudeChannel->setEnabled(true); FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); FFTAngleErrorPlotWidget->replot(); @@ -830,8 +832,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorMagnitudeChannel); FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorPhaseChannel); - FFTCorrectedErrorMagnitudeChannel->setEnabled(true); FFTCorrectedErrorPhaseChannel->setEnabled(true); + FFTCorrectedErrorMagnitudeChannel->setEnabled(true); FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); FFTCorrectedErrorPlotWidget->replot(); @@ -870,6 +872,51 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma endregion #pragma region Calibration Settings Widget + QWidget *calibrationSettingsGroupWidget = new QWidget(); + QVBoxLayout *calibrationSettingsGroupLayout = new QVBoxLayout(calibrationSettingsGroupWidget); + calibrationSettingsGroupWidget->setLayout(calibrationSettingsGroupLayout); + calibrationSettingsGroupLayout->setMargin(0); + calibrationSettingsGroupLayout->setSpacing(8); + + #pragma region Acquire Calibration Samples Button + calibrationStartMotorButton = new QPushButton(calibrationSettingsGroupWidget); + ADMTStyleHelper::StartButtonStyle(calibrationStartMotorButton); + calibrationStartMotorButton->setText(" Acquire Samples"); + + connect(calibrationStartMotorButton, &QPushButton::toggled, this, [=](bool toggled) { + calibrationStartMotorButton->setText(toggled ? " Stop Acquisition" : " Acquire Samples"); + totalSamplesCount = cycleCount * samplesPerCycle; + isStartMotor = toggled; + if(toggled){ + isPostCalibration = false; + graphPostDataList.reserve(totalSamplesCount); + graphDataList.reserve(totalSamplesCount); + startMotor(); + } + }); + #pragma endregion + + #pragma region Start Calibration Button + calibrateDataButton = new QPushButton(calibrationSettingsGroupWidget); + ADMTStyleHelper::StartButtonStyle(calibrateDataButton); + calibrateDataButton->setText(" Calibrate"); + calibrateDataButton->setEnabled(false); + + connect(calibrateDataButton, &QPushButton::toggled, this, [=](bool toggled) { + calibrateDataButton->setText(toggled ? " Stop Calibration" : " Calibrate"); + if(toggled) postCalibrateData(); + }); + #pragma endregion + + #pragma region Reset Calibration Button + clearCalibrateDataButton = new QPushButton("Reset Calibration", calibrationSettingsGroupWidget); + StyleHelper::BlueButton(clearCalibrateDataButton); + QIcon resetIcon; + resetIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/refresh.svg", "white", 1), QIcon::Normal, QIcon::Off); + clearCalibrateDataButton->setIcon(resetIcon); + clearCalibrateDataButton->setIconSize(QSize(26, 26)); + #pragma endregion + QScrollArea *calibrationSettingsScrollArea = new QScrollArea(); QWidget *calibrationSettingsWidget = new QWidget(calibrationSettingsScrollArea); QVBoxLayout *calibrationSettingsLayout = new QVBoxLayout(calibrationSettingsWidget); @@ -878,6 +925,11 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationSettingsWidget->setFixedWidth(260); calibrationSettingsWidget->setLayout(calibrationSettingsLayout); + calibrationSettingsGroupLayout->addWidget(calibrationStartMotorButton); + calibrationSettingsGroupLayout->addWidget(calibrateDataButton); + calibrationSettingsGroupLayout->addWidget(clearCalibrateDataButton); + calibrationSettingsGroupLayout->addWidget(calibrationSettingsScrollArea); + #pragma region Calibration Coefficient Section Widget MenuSectionWidget *calibrationCoeffSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); QLabel *calibrationDisplayFormatLabel = new QLabel(calibrationCoeffSectionWidget); @@ -925,8 +977,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() applyTextStyle(calibrationH1MagLabel, "CH0"); applyTextStyle(calibrationH1PhaseLabel, "CH1"); calibrationH1Label->setFixedWidth(24); - calibrationH1MagLabel->setContentsMargins(0, 0, 48, 0); - calibrationH1PhaseLabel->setFixedWidth(56); + calibrationH1MagLabel->setContentsMargins(0, 0, 32, 0); + calibrationH1PhaseLabel->setFixedWidth(72); h1RowLayout->addWidget(calibrationH1Label); h1RowLayout->addWidget(calibrationH1MagLabel, 0, Qt::AlignRight); @@ -947,8 +999,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() applyTextStyle(calibrationH2MagLabel, "CH0"); applyTextStyle(calibrationH2PhaseLabel, "CH1"); calibrationH2Label->setFixedWidth(24); - calibrationH2MagLabel->setContentsMargins(0, 0, 48, 0); - calibrationH2PhaseLabel->setFixedWidth(56); + calibrationH2MagLabel->setContentsMargins(0, 0, 32, 0); + calibrationH2PhaseLabel->setFixedWidth(72); h2RowLayout->addWidget(calibrationH2Label); h2RowLayout->addWidget(calibrationH2MagLabel, 0, Qt::AlignRight); @@ -969,8 +1021,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() applyTextStyle(calibrationH3MagLabel, "CH0"); applyTextStyle(calibrationH3PhaseLabel, "CH1"); calibrationH3Label->setFixedWidth(24); - calibrationH3MagLabel->setContentsMargins(0, 0, 48, 0); - calibrationH3PhaseLabel->setFixedWidth(56); + calibrationH3MagLabel->setContentsMargins(0, 0, 32, 0); + calibrationH3PhaseLabel->setFixedWidth(72); h3RowLayout->addWidget(calibrationH3Label); h3RowLayout->addWidget(calibrationH3MagLabel, 0, Qt::AlignRight); @@ -991,8 +1043,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() applyTextStyle(calibrationH8MagLabel, "CH0"); applyTextStyle(calibrationH8PhaseLabel, "CH1"); calibrationH8Label->setFixedWidth(24); - calibrationH8MagLabel->setContentsMargins(0, 0, 48, 0); - calibrationH8PhaseLabel->setFixedWidth(56); + calibrationH8MagLabel->setContentsMargins(0, 0, 32, 0); + calibrationH8PhaseLabel->setFixedWidth(72); h8RowLayout->addWidget(calibrationH8Label); h8RowLayout->addWidget(calibrationH8MagLabel, 0, Qt::AlignRight); @@ -1047,15 +1099,12 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QPushButton *importSamplesButton = new QPushButton("Import Samples", calibrationDataCollapseSection); QPushButton *extractDataButton = new QPushButton("Save to CSV", calibrationDataCollapseSection); - QPushButton *clearCalibrateDataButton = new QPushButton("Clear All Data", calibrationDataCollapseSection); StyleHelper::BlueButton(importSamplesButton); StyleHelper::BlueButton(extractDataButton); - StyleHelper::BlueButton(clearCalibrateDataButton); calibrationDataCollapseSection->contentLayout()->setSpacing(8); calibrationDataCollapseSection->contentLayout()->addWidget(importSamplesButton); calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); - calibrationDataCollapseSection->contentLayout()->addWidget(clearCalibrateDataButton); #pragma endregion #pragma region Motor Configuration Section Widget @@ -1090,69 +1139,17 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); StyleHelper::MenuSmallLabel(currentPositionLabel, "currentPositionLabel"); - calibrationMotorCurrentPositionLabel = new QLabel("--.--", motorControlSectionWidget); - calibrationMotorCurrentPositionLabel->setAlignment(Qt::AlignRight); - applyLabelStyle(calibrationMotorCurrentPositionLabel); + calibrationMotorCurrentPositionLineEdit = new QLineEdit("--.--", motorControlSectionWidget); + calibrationMotorCurrentPositionLineEdit->setReadOnly(true); + ADMTStyleHelper::LineEditStyle(calibrationMotorCurrentPositionLineEdit); + connectLineEditToDouble(calibrationMotorCurrentPositionLineEdit, current_pos); motorTargetPositionSpinBox = new HorizontalSpinBox("Target Position", target_pos, "", motorControlSectionWidget); - calibrationStartMotorButton = new QPushButton(motorControlSectionWidget); - calibrationStartMotorButton->setCheckable(true); - calibrationStartMotorButton->setChecked(false); - calibrationStartMotorButton->setText("Start Motor"); - calibrationStartMotorButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - calibrationStartMotorButton->setFixedHeight(36); - connect(calibrationStartMotorButton, &QPushButton::toggled, this, [=](bool b) { - calibrationStartMotorButton->setText(b ? " Stop Motor" : " Start Motor"); - totalSamplesCount = cycleCount * samplesPerCycle; - isStartMotor = b; - if(b){ - isPostCalibration = false; - graphPostDataList.reserve(totalSamplesCount); - graphDataList.reserve(totalSamplesCount); - startMotor(); - } - }); - QString calibrationStartMotorButtonStyle = QString(R"css( - QPushButton { - border-radius: 2px; - padding-left: 20px; - padding-right: 20px; - color: white; - font-weight: 700; - font-size: 14px; - } - - QPushButton:!checked { - background-color: #27b34f; - } - - QPushButton:checked { - background-color: #F45000; - } - - QPushButton:disabled { - background-color: grey; - })css"); - calibrationStartMotorButton->setStyleSheet(calibrationStartMotorButtonStyle); - QIcon playIcon; - playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/play.svg", "white", 1), QIcon::Normal, QIcon::Off); - playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/scopy-default/icons/play_stop.svg", "white", 1), - QIcon::Normal, QIcon::On); - calibrationStartMotorButton->setIcon(playIcon); - calibrationStartMotorButton->setIconSize(QSize(64, 64)); - - calibrateDataButton = new QPushButton(motorControlSectionWidget); - calibrateDataButton->setText("Calibrate"); - calibrateDataButton->setEnabled(false); - StyleHelper::BlueButton(calibrateDataButton, "calibrateDataButton"); - motorControlCollapseSection->contentLayout()->setSpacing(8); motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); - motorControlCollapseSection->contentLayout()->addWidget(calibrationMotorCurrentPositionLabel); + motorControlCollapseSection->contentLayout()->addWidget(calibrationMotorCurrentPositionLineEdit); motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionSpinBox); - motorControlCollapseSection->contentLayout()->addWidget(calibrationStartMotorButton); - motorControlCollapseSection->contentLayout()->addWidget(calibrateDataButton); #pragma endregion #pragma region Logs Section Widget @@ -1172,10 +1169,10 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationSettingsLayout->setMargin(0); calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); - calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); + calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); calibrationSettingsLayout->addWidget(motorControlSectionWidget); + calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); - calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); calibrationSettingsLayout->addWidget(logsSectionWidget); calibrationSettingsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); #pragma endregion @@ -1192,9 +1189,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() tool->openTopContainerHelper(false); tool->addWidgetToCentralContainerHelper(calibrationDataGraphWidget); - tool->rightStack()->add("calibrationSettingsScrollArea", calibrationSettingsScrollArea); + tool->rightStack()->add("calibrationSettingsGroupWidget", calibrationSettingsGroupWidget); - connect(calibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::postCalibrateData); connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); connect(importSamplesButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAllCalibrationState); @@ -2199,7 +2195,7 @@ void HarmonicCalibration::acquisitionUITask() acquisitionGraphPlotWidget->replot(); updateLineEditValues(); - updateLabelValue(acquisitionMotorCurrentPositionLabel, ADMTController::MotorAttribute::CURRENT_POS); + updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); } void HarmonicCalibration::applySequence(){ @@ -2560,6 +2556,11 @@ void HarmonicCalibration::updateLineEditValues(){ else { tempValueLabel->setText(QString::number(temp) + " °C"); } } +void HarmonicCalibration::updateLineEditValue(QLineEdit* lineEdit, double value){ + if(value == static_cast(UINT64_MAX)) { lineEdit->setText("N/A"); } + else { lineEdit->setText(QString::number(value)); } +} + void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { graphUpdateIntervalLineEdit->setEnabled(value); @@ -2607,6 +2608,8 @@ MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max) { + QIntValidator *validator = new QIntValidator(min, max, this); + lineEdit->setValidator(validator); connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, min, max]() { bool ok; int value = lineEdit->text().toInt(&ok); @@ -2618,6 +2621,22 @@ void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& vari }); } +void HarmonicCalibration::connectLineEditToDouble(QLineEdit* lineEdit, double& variable) +{ + // QDoubleValidator *validator = new QDoubleValidator(this); + // validator->setNotation(QDoubleValidator::StandardNotation); + // lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok){ + variable = value; + } else { + lineEdit->setText(QString::number(variable, 'f', 2)); + } + }); +} + void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit) { connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, unit]() { @@ -2634,6 +2653,9 @@ void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& v void HarmonicCalibration::connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute) { + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + lineEdit->setValidator(validator); connect(lineEdit, &QLineEdit::editingFinished, [=, &variable]() { bool ok; double value = lineEdit->text().toDouble(&ok); @@ -2860,7 +2882,6 @@ void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorA case ADMTController::MotorAttribute::RAMP_MODE: label->setText(QString::number(ramp_mode)); break; - } } @@ -2868,18 +2889,16 @@ void HarmonicCalibration::calibrationUITask() { if(!isDebug){ readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - updateLabelValue(calibrationMotorCurrentPositionLabel, ADMTController::MotorAttribute::CURRENT_POS); + updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); if(isStartMotor) { if(isPostCalibration){ postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); - postCalibrationRawDataPlotChannel->xAxis()->setMax(graphPostDataList.size()); postCalibrationRawDataPlotWidget->replot(); } else{ calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotChannel->xAxis()->setMax(graphDataList.size()); calibrationRawDataPlotWidget->replot(); } } @@ -2888,24 +2907,30 @@ void HarmonicCalibration::calibrationUITask() void HarmonicCalibration::getCalibrationSamples() { - if(resetToZero){ - resetCurrentPositionToZero(); - } + resetCurrentPositionToZero(); + if(isPostCalibration){ - while(isStartMotor && graphPostDataList.size() < totalSamplesCount){ - stepMotorAcquisition(); + int currentSamplesCount = graphPostDataList.size(); + while(isStartMotor && currentSamplesCount < totalSamplesCount){ + target_pos = current_pos + -408; + moveMotorToPosition(target_pos, true); updateChannelValue(ADMTController::Channel::ANGLE); graphPostDataList.append(angle); + currentSamplesCount++; } } else{ - clearCalibrationSineCosine(); - while(isStartMotor && graphDataList.size() < totalSamplesCount){ - stepMotorAcquisition(); + int currentSamplesCount = graphDataList.size(); + while(isStartMotor && currentSamplesCount < totalSamplesCount){ + target_pos = current_pos + -408; + moveMotorToPosition(target_pos, true); updateChannelValue(ADMTController::Channel::ANGLE); graphDataList.append(angle); + currentSamplesCount++; } } + + stopMotor(); } void HarmonicCalibration::resetCurrentPositionToZero() @@ -2920,6 +2945,7 @@ void HarmonicCalibration::resetCurrentPositionToZero() void HarmonicCalibration::startMotor() { + toggleTabSwitching(false); toggleMotorControls(false); if(resetToZero && !isPostCalibration){ @@ -2929,15 +2955,22 @@ void HarmonicCalibration::startMotor() clearCorrectedAngleErrorGraphs(); } + if(isPostCalibration) + postCalibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); + else + calibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); + if(isPostCalibration) calibrationDataGraphTabWidget->setCurrentIndex(1); // Set tab to Post Calibration Samples else calibrationDataGraphTabWidget->setCurrentIndex(0); // Set tab to Calibration Samples + clearCalibrateDataButton->setEnabled(false); QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getCalibrationSamples); QFutureWatcher *watcher = new QFutureWatcher(this); connect(watcher, &QFutureWatcher::finished, this, [=]() { + toggleTabSwitching(true); toggleMotorControls(true); calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); @@ -2945,6 +2978,7 @@ void HarmonicCalibration::startMotor() calibrationRawDataPlotWidget->replot(); isStartMotor = false; calibrationStartMotorButton->setChecked(false); + clearCalibrateDataButton->setEnabled(true); if(isPostCalibration) { @@ -2955,8 +2989,8 @@ void HarmonicCalibration::startMotor() populateCorrectedAngleErrorGraphs(); isPostCalibration = false; isStartMotor = false; - canStartMotor(true); resetToZero = true; + canCalibrate(false); } } else{ @@ -2964,8 +2998,9 @@ void HarmonicCalibration::startMotor() { computeSineCosineOfAngles(graphDataList); calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); - flashHarmonicValues(); populateAngleErrorGraphs(); + calculateHarmonicValues(); + canStartMotor(false); canCalibrate(true); } else{ @@ -2977,6 +3012,13 @@ void HarmonicCalibration::startMotor() watcher->setFuture(future); } +void HarmonicCalibration::toggleTabSwitching(bool value) +{ + tabWidget->setTabEnabled(0, value); + tabWidget->setTabEnabled(2, value); + tabWidget->setTabEnabled(3, value); +} + void HarmonicCalibration::populateCorrectedAngleErrorGraphs() { QVector correctedError(m_admtController->correctedError.begin(), m_admtController->correctedError.end()); @@ -2989,8 +3031,8 @@ void HarmonicCalibration::populateCorrectedAngleErrorGraphs() correctedErrorXPlotAxis->setMax(correctedError.size()); correctedErrorPlotWidget->replot(); - FFTCorrectedErrorMagnitudeChannel->curve()->setSamples(FFTCorrectedErrorMagnitude); FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); + FFTCorrectedErrorMagnitudeChannel->curve()->setSamples(FFTCorrectedErrorMagnitude); auto FFTCorrectedErrorMagnitudeMinMax = std::minmax_element(FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); auto FFTCorrectedErrorPhaseMinMax = std::minmax_element(FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); double FFTCorrectedErrorPlotMin = *FFTCorrectedErrorMagnitudeMinMax.first < *FFTCorrectedErrorPhaseMinMax.first ? *FFTCorrectedErrorMagnitudeMinMax.first : *FFTCorrectedErrorPhaseMinMax.first; @@ -3014,9 +3056,9 @@ void HarmonicCalibration::populateAngleErrorGraphs() angleErrorXPlotAxis->setInterval(0, angleError.size()); angleErrorPlotWidget->replot(); + FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); auto angleErrorMagnitudeMinMax = std::minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); - FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); auto angleErrorPhaseMinMax = std::minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first ? *angleErrorMagnitudeMinMax.first : *angleErrorPhaseMinMax.first; double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second ? *angleErrorMagnitudeMinMax.second : *angleErrorPhaseMinMax.second; @@ -3034,54 +3076,7 @@ void HarmonicCalibration::canStartMotor(bool value) void HarmonicCalibration::flashHarmonicValues() { - uint32_t *h1MagCurrent = new uint32_t, - *h1PhaseCurrent = new uint32_t, - *h2MagCurrent = new uint32_t, - *h2PhaseCurrent = new uint32_t, - *h3MagCurrent = new uint32_t, - *h3PhaseCurrent = new uint32_t, - *h8MagCurrent = new uint32_t, - *h8PhaseCurrent = new uint32_t; - if(changeCNVPage(0x02)){ - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); - - calibrationLogWrite(); - calibrationLogWrite("H1 Mag Current: " + QString::number(*h1MagCurrent)); - calibrationLogWrite("H1 Phase Current: " + QString::number(*h1PhaseCurrent)); - calibrationLogWrite("H2 Mag Current: " + QString::number(*h2MagCurrent)); - calibrationLogWrite("H2 Phase Current: " + QString::number(*h2PhaseCurrent)); - calibrationLogWrite("H3 Mag Current: " + QString::number(*h3MagCurrent)); - calibrationLogWrite("H3 Phase Current: " + QString::number(*h3PhaseCurrent)); - calibrationLogWrite("H8 Mag Current: " + QString::number(*h8MagCurrent)); - calibrationLogWrite("H8 Phase Current: " + QString::number(*h8PhaseCurrent)); - - H1_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_1), static_cast(*h1MagCurrent), "h1")); - H1_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_1), static_cast(*h1PhaseCurrent))); - H2_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_2), static_cast(*h2MagCurrent), "h2")); - H2_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_2), static_cast(*h2PhaseCurrent))); - H3_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_3), static_cast(*h3MagCurrent), "h3")); - H3_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_3), static_cast(*h3PhaseCurrent))); - H8_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_8), static_cast(*h8MagCurrent), "h8")); - H8_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_8), static_cast(*h8PhaseCurrent))); - - calibrationLogWrite(); - calibrationLogWrite("H1 Mag Scaled: " + QString::number(H1_MAG_HEX)); - calibrationLogWrite("H1 Phase Scaled: " + QString::number(H1_PHASE_HEX)); - calibrationLogWrite("H2 Mag Scaled: " + QString::number(H2_MAG_HEX)); - calibrationLogWrite("H2 Phase Scaled: " + QString::number(H2_PHASE_HEX)); - calibrationLogWrite("H3 Mag Scaled: " + QString::number(H3_MAG_HEX)); - calibrationLogWrite("H3 Phase Scaled: " + QString::number(H3_PHASE_HEX)); - calibrationLogWrite("H8 Mag Scaled: " + QString::number(H8_MAG_HEX)); - calibrationLogWrite("H8 Phase Scaled: " + QString::number(H8_PHASE_HEX)); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), 0x01, 0x02); m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), @@ -3109,58 +3104,87 @@ void HarmonicCalibration::flashHarmonicValues() m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), H8_PHASE_HEX); + isCalculatedCoeff = true; + displayCalculatedCoeff(); + } + else{ + calibrationLogWrite("Unabled to flash Harmonic Registers!"); + } +} + +void HarmonicCalibration::calculateHarmonicValues() +{ + uint32_t *h1MagCurrent = new uint32_t, + *h1PhaseCurrent = new uint32_t, + *h2MagCurrent = new uint32_t, + *h2PhaseCurrent = new uint32_t, + *h3MagCurrent = new uint32_t, + *h3PhaseCurrent = new uint32_t, + *h8MagCurrent = new uint32_t, + *h8PhaseCurrent = new uint32_t; + + if(changeCNVPage(0x02)) + { + // Read and store current harmonic values m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); - calibrationLogWrite(); - calibrationLogWrite("H1 Mag After Flash: " + QString::number(*h1MagCurrent)); - calibrationLogWrite("H1 Phase After Flash: " + QString::number(*h1PhaseCurrent)); - calibrationLogWrite("H2 Mag After Flash: " + QString::number(*h2MagCurrent)); - calibrationLogWrite("H2 Phase After Flash: " + QString::number(*h2PhaseCurrent)); - calibrationLogWrite("H3 Mag After Flash: " + QString::number(*h3MagCurrent)); - calibrationLogWrite("H3 Phase After Flash: " + QString::number(*h3PhaseCurrent)); - calibrationLogWrite("H8 Mag After Flash: " + QString::number(*h8MagCurrent)); - calibrationLogWrite("H8 Phase After Flash: " + QString::number(*h8PhaseCurrent)); - - H1_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h1MagCurrent), "h1mag"); - H1_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h1PhaseCurrent), "h1phase"); - H2_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h2MagCurrent), "h2mag"); - H2_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h2PhaseCurrent), "h2phase"); - H3_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h3MagCurrent), "h3mag"); - H3_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h3PhaseCurrent), "h3phase"); - H8_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h8MagCurrent), "h8mag"); - H8_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(*h8PhaseCurrent), "h8phase"); + // Calculate harmonic coefficients (Hex) + H1_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_1), static_cast(*h1MagCurrent), "h1")); + H2_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_2), static_cast(*h2MagCurrent), "h2")); + H3_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_3), static_cast(*h3MagCurrent), "h3")); + H8_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_8), static_cast(*h8MagCurrent), "h8")); + H1_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_1), static_cast(*h1PhaseCurrent))); + H2_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_2), static_cast(*h2PhaseCurrent))); + H3_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_3), static_cast(*h3PhaseCurrent))); + H8_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_8), static_cast(*h8PhaseCurrent))); calibrationLogWrite(); - calibrationLogWrite("H1 Mag Converted: " + QString::number(H1_MAG_ANGLE)); - calibrationLogWrite("H1 Phase Converted: " + QString::number(H1_PHASE_ANGLE)); - calibrationLogWrite("H2 Mag Converted: " + QString::number(H2_MAG_ANGLE)); - calibrationLogWrite("H2 Phase Converted: " + QString::number(H2_PHASE_ANGLE)); - calibrationLogWrite("H3 Mag Converted: " + QString::number(H3_MAG_ANGLE)); - calibrationLogWrite("H3 Phase Converted: " + QString::number(H3_PHASE_ANGLE)); - calibrationLogWrite("H8 Mag Converted: " + QString::number(H8_MAG_ANGLE)); - calibrationLogWrite("H8 Phase Converted: " + QString::number(H8_PHASE_ANGLE)); + calibrationLogWrite(QString("Calculated H1 Mag (Hex): 0x%1").arg(QString::number(H1_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H1 Phase (Hex): 0x%1").arg(QString::number(H1_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H2 Mag (Hex): 0x%1").arg(QString::number(H2_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H2 Phase (Hex): 0x%1").arg(QString::number(H2_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H3 Mag (Hex): 0x%1").arg(QString::number(H3_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H3 Phase (Hex): 0x%1").arg(QString::number(H3_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H8 Mag (Hex): 0x%1").arg(QString::number(H8_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H8 Phase (Hex): 0x%1").arg(QString::number(H8_PHASE_HEX, 16).rightJustified(4, '0'))); + + // Get actual harmonic values from hex + H1_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H1_MAG_HEX), "h1mag"); + H1_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H1_PHASE_HEX), "h1phase"); + H2_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H2_MAG_HEX), "h2mag"); + H2_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H2_PHASE_HEX), "h2phase"); + H3_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H3_MAG_HEX), "h3mag"); + H3_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H3_PHASE_HEX), "h3phase"); + H8_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H8_MAG_HEX), "h8mag"); + H8_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H8_PHASE_HEX), "h8phase"); + calibrationLogWrite(); + calibrationLogWrite(QString("Calculated H1 Mag (Angle): 0x%1").arg(QString::number(H1_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H1 Phase (Angle): 0x%1").arg(QString::number(H1_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H2 Mag (Angle): 0x%1").arg(QString::number(H2_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H2 Phase (Angle): 0x%1").arg(QString::number(H2_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H3 Mag (Angle): 0x%1").arg(QString::number(H3_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H3 Phase (Angle): 0x%1").arg(QString::number(H3_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H8 Mag (Angle): 0x%1").arg(QString::number(H8_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H8 Phase (Angle): 0x%1").arg(QString::number(H8_PHASE_ANGLE))); + + if(isAngleDisplayFormat) updateCalculatedCoeffAngle(); + else updateCalculatedCoeffHex(); isCalculatedCoeff = true; - - displayCalculatedCoeff(); - } - else{ - calibrationLogWrite("Unabled to flash Harmonic Registers!"); } } void HarmonicCalibration::postCalibrateData() { calibrationLogWrite("==== Post Calibration Start ====\n"); - canCalibrate(false); - canStartMotor(false); + flashHarmonicValues(); calibrationDataGraphTabWidget->setCurrentIndex(1); isPostCalibration = true; isStartMotor = true; @@ -3170,14 +3194,14 @@ void HarmonicCalibration::postCalibrateData() void HarmonicCalibration::updateCalculatedCoeffAngle() { - calibrationH1MagLabel->setText(QString::number(H1_MAG_ANGLE) + "°"); - calibrationH2MagLabel->setText(QString::number(H2_MAG_ANGLE) + "°"); - calibrationH3MagLabel->setText(QString::number(H3_MAG_ANGLE) + "°"); - calibrationH8MagLabel->setText(QString::number(H8_MAG_ANGLE) + "°"); - calibrationH1PhaseLabel->setText("Φ " + QString::number(H1_PHASE_ANGLE)); - calibrationH2PhaseLabel->setText("Φ " + QString::number(H2_PHASE_ANGLE)); - calibrationH3PhaseLabel->setText("Φ " + QString::number(H3_PHASE_ANGLE)); - calibrationH8PhaseLabel->setText("Φ " + QString::number(H8_PHASE_ANGLE)); + calibrationH1MagLabel->setText(QString::number(H1_MAG_ANGLE, 'f', 2) + "°"); + calibrationH2MagLabel->setText(QString::number(H2_MAG_ANGLE, 'f', 2) + "°"); + calibrationH3MagLabel->setText(QString::number(H3_MAG_ANGLE, 'f', 2) + "°"); + calibrationH8MagLabel->setText(QString::number(H8_MAG_ANGLE, 'f', 2) + "°"); + calibrationH1PhaseLabel->setText("Φ " + QString::number(H1_PHASE_ANGLE, 'f', 2)); + calibrationH2PhaseLabel->setText("Φ " + QString::number(H2_PHASE_ANGLE, 'f', 2)); + calibrationH3PhaseLabel->setText("Φ " + QString::number(H3_PHASE_ANGLE, 'f', 2)); + calibrationH8PhaseLabel->setText("Φ " + QString::number(H8_PHASE_ANGLE, 'f', 2)); } void HarmonicCalibration::resetCalculatedCoeffAngle() @@ -3318,7 +3342,6 @@ void HarmonicCalibration::importCalibrationData() computeSineCosineOfAngles(graphDataList); calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); - flashHarmonicValues(); populateAngleErrorGraphs(); canStartMotor(false); canCalibrate(true); @@ -3343,26 +3366,40 @@ void HarmonicCalibration::computeSineCosineOfAngles(QVector graphDataLis } } -void HarmonicCalibration::stepMotorAcquisition(double step) +void HarmonicCalibration::moveMotorToPosition(double& position, bool validate) { - target_pos = current_pos + step; - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - while(target_pos != current_pos) { + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, position); + if(validate){ readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + while(target_pos != current_pos) { + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + } } } +void HarmonicCalibration::startMotorContinuous() +{ + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); +} + +void HarmonicCalibration::stopMotor() +{ + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); +} + void HarmonicCalibration::resetAllCalibrationState() { clearCalibrationSamples(); clearPostCalibrationSamples(); + calibrationDataGraphTabWidget->setCurrentIndex(0); clearAngleErrorGraphs(); clearCorrectedAngleErrorGraphs(); + resultDataTabWidget->setCurrentIndex(0); - canCalibrate(false); canStartMotor(true); + canCalibrate(false); + calibrateDataButton->setChecked(false); isPostCalibration = false; isCalculatedCoeff = false; resetToZero = true; diff --git a/plugins/admt/src/widgets/horizontalspinbox.cpp b/plugins/admt/src/widgets/horizontalspinbox.cpp index feb1f6a1e8..aecbf29c0b 100644 --- a/plugins/admt/src/widgets/horizontalspinbox.cpp +++ b/plugins/admt/src/widgets/horizontalspinbox.cpp @@ -26,6 +26,9 @@ HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, QStrin controlLayout->setSpacing(2); m_lineEdit = new QLineEdit(controlWidget); + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + m_lineEdit->setValidator(validator); applyLineEditStyle(m_lineEdit); if(QString::compare(m_unit, "") != 0) { From 15329dec0e08f6aef203a644d7f4d2ad0f2b9b69 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 8 Jan 2025 07:54:46 +0800 Subject: [PATCH 076/112] admt: Implemented mapping and graph for acquisition graph variables - Added guards for controller methods - Added color map to ADMTStyleHelper Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 7 + plugins/admt/include/admt/admtstylehelper.h | 5 + .../admt/include/admt/harmoniccalibration.h | 11 +- plugins/admt/src/admtcontroller.cpp | 145 ++++++++++++++ plugins/admt/src/admtstylehelper.cpp | 23 +++ plugins/admt/src/harmoniccalibration.cpp | 178 +++++++++++++++--- 6 files changed, 341 insertions(+), 28 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index a235c1625d..16705b3ede 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -204,6 +204,13 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject uint16_t setDIGIORegisterBitMapping(uint16_t currentRegisterValue, map settings); void unwrapAngles(vector& angles_rad); map getUNIQID3RegisterMapping(uint16_t registerValue); + map getSineRegisterBitMapping(uint16_t registerValue); + map getCosineRegisterBitMapping(uint16_t registerValue); + map getRadiusRegisterBitMapping(uint16_t registerValue); + map getAngleSecRegisterBitMapping(uint16_t registerValue); + map getSecAnglQRegisterBitMapping(uint16_t registerValue); + map getSecAnglIRegisterBitMapping(uint16_t registerValue); + map getTmp1RegisterBitMapping(uint16_t registerValue, bool is5V); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/include/admt/admtstylehelper.h b/plugins/admt/include/admt/admtstylehelper.h index d3f22ecc14..b7898605f6 100644 --- a/plugins/admt/include/admt/admtstylehelper.h +++ b/plugins/admt/include/admt/admtstylehelper.h @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include @@ -26,6 +28,8 @@ class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject void operator=(const ADMTStyleHelper &) = delete; static ADMTStyleHelper *GetInstance(); public: + static void initColorMap(); + static QString getColor(QString id); static void TopContainerButtonStyle(QPushButton *btn, QString objectName = ""); static void PlotWidgetStyle(PlotWidget *widget, QString objectName = ""); static void ComboBoxStyle(QComboBox *widget, QString objectName = ""); @@ -33,6 +37,7 @@ class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject static void ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName = ""); static void StartButtonStyle(QPushButton *btn, QString objectName = ""); private: + QMap colorMap; static ADMTStyleHelper *pinstance_; }; } // namespace admt diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 76ddb24528..922b43d39c 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -161,6 +161,8 @@ public Q_SLOTS: *correctedErrorXPlotAxis, *correctedErrorYPlotAxis, *FFTCorrectedErrorXPlotAxis, *FFTCorrectedErrorYPlotAxis, *postCalibrationRawDataXPlotAxis, *postCalibrationRawDataYPlotAxis; PlotChannel *acquisitionAnglePlotChannel, *acquisitionABSAnglePlotChannel, *acquisitionTurnCountPlotChannel, *acquisitionTmp0PlotChannel, + *acquisitionTmp1PlotChannel, *acquisitionSinePlotChannel, *acquisitionCosinePlotChannel, *acquisitionRadiusPlotChannel, + *acquisitionSecAnglQPlotChannel, *acquisitionSecAnglIPlotChannel, *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel, *FFTAngleErrorMagnitudeChannel, *FFTAngleErrorPhaseChannel, *correctedErrorPlotChannel, @@ -186,7 +188,7 @@ public Q_SLOTS: RegisterBlockWidget *cnvPageRegisterBlock, *digIORegisterBlock, *faultRegisterBlock, *generalRegisterBlock, *digIOEnRegisterBlock, *angleCkRegisterBlock, *eccDcdeRegisterBlock, *eccDisRegisterBlock, *absAngleRegisterBlock, *angleRegisterBlock, *angleSecRegisterBlock, *sineRegisterBlock, *cosineRegisterBlock, *secAnglIRegisterBlock, *secAnglQRegisterBlock, *radiusRegisterBlock, *diag1RegisterBlock, *diag2RegisterBlock, *tmp0RegisterBlock, *tmp1RegisterBlock, *cnvCntRegisterBlock, *uniqID0RegisterBlock, *uniqID1RegisterBlock, *uniqID2RegisterBlock, *uniqID3RegisterBlock, *h1MagRegisterBlock, *h1PhRegisterBlock, *h2MagRegisterBlock, *h2PhRegisterBlock, *h3MagRegisterBlock, *h3PhRegisterBlock, *h8MagRegisterBlock, *h8PhRegisterBlock; - void updateChannelValues(); + bool updateChannelValues(); void updateLineEditValues(); void updateGeneralSettingEnabled(bool value); void connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max); @@ -198,7 +200,7 @@ public Q_SLOTS: ToolTemplate* createUtilityWidget(); void updateLabelValue(QLabel* label, int channelIndex); void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); - void updateChannelValue(int channelIndex); + bool updateChannelValue(int channelIndex); void extractCalibrationData(); void importCalibrationData(); void calibrationLogWrite(QString message = ""); @@ -208,7 +210,7 @@ public Q_SLOTS: void applyTextStyle(QWidget *widget, const QString& styleHelperColor = "CH0", bool isBold = false); void applyLabelStyle(QLabel *widget); void initializeMotor(); - void moveMotorToPosition(double& position, bool validate = true); + bool moveMotorToPosition(double& position, bool validate = true); void resetAllCalibrationState(); void connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax); void connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute); @@ -257,7 +259,7 @@ public Q_SLOTS: void toggleMTDiagnostics(int mode); void toggleSequenceModeRegisters(int mode); void readAllRegisters(); - void prependAcquisitionData(double& data, QVector& list); + void prependAcquisitionData(const double& data, QVector& list); void plotAcquisition(QVector& list, PlotChannel* channel); void populateAngleErrorGraphs(); void populateCorrectedAngleErrorGraphs(); @@ -275,6 +277,7 @@ public Q_SLOTS: void connectLineEditToDouble(QLineEdit* lineEdit, double& variable); void updateLineEditValue(QLineEdit* lineEdit, double value); void toggleTabSwitching(bool value); + double getAcquisitionParameterValue(const AcquisitionDataKey &key); QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index a4b31c77ad..da5d191838 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -171,6 +171,7 @@ int ADMTController::getChannelIndex(const char *deviceName, const char *channelN double ADMTController::getChannelValue(const char *deviceName, const char *channelName, int bufferSize) { + if(!m_iioCtx){ return static_cast(UINT64_MAX); } // return QString("No context available."); double value; int deviceCount = iio_context_get_devices_count(m_iioCtx); @@ -280,6 +281,7 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann * @return On error, -1 is returned. */ int ADMTController::getDeviceAttributeValue(const char *deviceName, const char *attributeName, double *returnValue) { + if(!m_iioCtx) { return -1; } int result = -1; int deviceCount = iio_context_get_devices_count(m_iioCtx); if(deviceCount == 0) { return result; } @@ -301,6 +303,7 @@ int ADMTController::getDeviceAttributeValue(const char *deviceName, const char * * @return On error, -1 is returned. */ int ADMTController::setDeviceAttributeValue(const char *deviceName, const char *attributeName, double writeValue) { + if(!m_iioCtx) { return -1; } int result = -1; int deviceCount = iio_context_get_devices_count(m_iioCtx); if(deviceCount == 0) { return result; } @@ -315,6 +318,7 @@ int ADMTController::setDeviceAttributeValue(const char *deviceName, const char * int ADMTController::writeDeviceRegistry(const char *deviceName, uint32_t address, uint32_t value) { + if(!m_iioCtx) { return -1; } int result = -1; int deviceCount = iio_context_get_devices_count(m_iioCtx); if(deviceCount == 0) { return result; } @@ -327,6 +331,8 @@ int ADMTController::writeDeviceRegistry(const char *deviceName, uint32_t address int ADMTController::readDeviceRegistry(const char *deviceName, uint32_t address, uint32_t *returnValue) { + if(!m_iioCtx) { return -1; } + if(address == UINT32_MAX) { return -1; } int result = -1; int deviceCount = iio_context_get_devices_count(m_iioCtx); if(deviceCount == 0) { return result; } @@ -1369,5 +1375,144 @@ map ADMTController::getUNIQID3RegisterMapping(uint16_t registerV break; } + return result; +} + +map ADMTController::getSineRegisterBitMapping(uint16_t registerValue) { + map result; + + // Bit 0 - Extract the status + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + + // Bit 1 - Reserved (ignore) + + // Bits 15:2 - Extract the sine value + int16_t sineValueRaw = (registerValue >> 2); // Shift right by 2 to discard Bits [1:0] + + // Check if the value is negative (2's complement format) + if (sineValueRaw & 0x2000) { + sineValueRaw |= 0xC000; + } + + // Convert the raw uncorrected sine value to a double + result["SINE"] = static_cast(sineValueRaw); + + return result; +} + +map ADMTController::getCosineRegisterBitMapping(uint16_t registerValue) { + map result; + + // Bit 0 - Extract the status + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + + // Bit 1 - Reserved (ignore) + + // Bits 15:2 - Extract the cosine value + int16_t cosineValueRaw = (registerValue >> 2); // Shift right by 2 to discard Bits [1:0] + + // Check if the value is negative (2's complement format) + if (cosineValueRaw & 0x2000) { + cosineValueRaw |= 0xC000; + } + + // Convert the raw uncorrected cosine value to a double + result["COSINE"] = static_cast(cosineValueRaw); + + return result; +} + +map ADMTController::getRadiusRegisterBitMapping(uint16_t registerValue) { + map result; + + // Bit 0 - Extract the STATUS + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + + // Bits 15:1 - Extract the RADIUS value + uint16_t radiusRaw = (registerValue >> 1); // Shift right by 1 to discard Bit 0 + + // Apply the resolution to convert the raw value + constexpr double resolution = 0.000924; // mV/V + result["RADIUS"] = static_cast(radiusRaw) * resolution; + + return result; +} + +map ADMTController::getAngleSecRegisterBitMapping(uint16_t registerValue) { + map result; + + // Bit 0 - Extract the STATUS + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + + // Bits 15:4 - Extract the ANGLESEC value + uint16_t angleSecRaw = (registerValue >> 4); // Right-shift by 4 to discard Bits [3:0] + + // Calculate the actual angle using the given resolution (360° / 4096) + constexpr double resolution = 360.0 / 4096.0; // 0.087890625 degrees per LSB + result["ANGLESEC"] = angleSecRaw * resolution; + + return result; +} + +map ADMTController::getSecAnglQRegisterBitMapping(uint16_t registerValue) { + map result; + + // Bit 0 - Extract the STATUS + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + + // Bits 15:2 - Extract the SECANGLQ raw value + int16_t secAnglQRaw = static_cast((registerValue & 0xFFFC) >> 2); // Mask Bits [1:0] and shift right by 2 + + // Convert the 2's complement raw value to the actual signed value + if (secAnglQRaw & 0x2000) { // Check the sign bit (Bit 13) + secAnglQRaw |= 0xC000; // Sign extend to preserve the 16-bit signed value + } + + // Store the SECANGLQ raw uncorrected value + result["SECANGLQ"] = static_cast(secAnglQRaw); + + return result; +} + +map ADMTController::getSecAnglIRegisterBitMapping(uint16_t registerValue) { + map result; + + // Bit 0 - Extract the STATUS bit + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + + // Bits 15:2 - Extract the SECANGLI raw value + int16_t secAnglIRaw = static_cast((registerValue & 0xFFFC) >> 2); // Mask Bits [1:0] and shift right by 2 + + // Convert the 2's complement raw value to the actual signed value + if (secAnglIRaw & 0x2000) { // Check the sign bit (Bit 13) + secAnglIRaw |= 0xC000; // Sign extend to preserve the 16-bit signed value + } + + // Store the SECANGLI raw value (optional, for debugging or diagnostic purposes) + result["SECANGLI"] = static_cast(secAnglIRaw); + + return result; +} + +map ADMTController::getTmp1RegisterBitMapping(uint16_t registerValue, bool is5V) { + map result; + + // Bits 15:4 - Extract the TMP1 raw value + uint16_t tmp1Raw = (registerValue & 0xFFF0) >> 4; + + // Store the raw TMP1 value (for diagnostics) + result["TMP1Raw"] = static_cast(tmp1Raw); + + // Calculate TMP1 temperature in degrees Celsius based on VDD + double tmp1DegC = 0.0; + if (is5V == true) { + tmp1DegC = (tmp1Raw - 1238.0) / 13.45; + } else { + tmp1DegC = (tmp1Raw - 1208.0) / 13.61; + } + + // Store the calculated temperature in degrees Celsius + result["TMP1"] = tmp1DegC; + return result; } \ No newline at end of file diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp index 6e3a7542fd..bfc64036d3 100644 --- a/plugins/admt/src/admtstylehelper.cpp +++ b/plugins/admt/src/admtstylehelper.cpp @@ -17,6 +17,29 @@ ADMTStyleHelper *ADMTStyleHelper::GetInstance() ADMTStyleHelper::~ADMTStyleHelper() {} +void ADMTStyleHelper::initColorMap() +{ + auto sh = ADMTStyleHelper::GetInstance(); + sh->colorMap.insert("CH0", "#FF7200"); + sh->colorMap.insert("CH1", "#9013FE"); + sh->colorMap.insert("CH2", "#27B34F"); + sh->colorMap.insert("CH3", "#F8E71C"); + sh->colorMap.insert("CH4", "#4A64FF"); + sh->colorMap.insert("CH5", "#02BCD4"); + sh->colorMap.insert("CH6", "#F44336"); + sh->colorMap.insert("CH7", "#F5A623"); + sh->colorMap.insert("CH8", "#1981AE"); + sh->colorMap.insert("CH9", "#6FCEA6"); + sh->colorMap.insert("CH10", "#F7A1DA"); + sh->colorMap.insert("CH11", "#E3F5FC"); +} + +QString ADMTStyleHelper::getColor(QString id) +{ + auto sh = ADMTStyleHelper::GetInstance(); + return sh->colorMap[id]; +} + void ADMTStyleHelper::TopContainerButtonStyle(QPushButton *btn, QString objectName) { if(!objectName.isEmpty()) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index a6161986e9..d562851abb 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -44,7 +44,8 @@ static uint32_t h8PhaseDeviceRegister = 0x1C; static int acquisitionDisplayLength = 200; static QVector acquisitionAngleList, acquisitionABSAngleList, acquisitionTurnCountList, acquisitionTmp0List, - graphDataList, graphPostDataList; + acquisitionTmp1List, acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, + graphDataList, graphPostDataList; static const QColor scopyBlueColor = scopy::StyleHelper::getColor("ScopyBlue"); static const QColor sineColor = QColor("#85e94c"); @@ -58,6 +59,10 @@ static const QPen channel0Pen(scopy::StyleHelper::getColor("CH0")); static const QPen channel1Pen(scopy::StyleHelper::getColor("CH1")); static const QPen channel2Pen(scopy::StyleHelper::getColor("CH2")); static const QPen channel3Pen(scopy::StyleHelper::getColor("CH3")); +static const QPen channel4Pen(scopy::StyleHelper::getColor("CH4")); +static const QPen channel5Pen(scopy::StyleHelper::getColor("CH5")); +static const QPen channel6Pen(scopy::StyleHelper::getColor("CH6")); +static const QPen channel7Pen(scopy::StyleHelper::getColor("CH7")); static const QPen sinePen(sineColor); static const QPen cosinePen(cosineColor); @@ -70,6 +75,9 @@ static bool is5V = false; static double H1_MAG_ANGLE, H2_MAG_ANGLE, H3_MAG_ANGLE, H8_MAG_ANGLE, H1_PHASE_ANGLE, H2_PHASE_ANGLE, H3_PHASE_ANGLE, H8_PHASE_ANGLE; static uint32_t H1_MAG_HEX, H2_MAG_HEX, H3_MAG_HEX, H8_MAG_HEX, H1_PHASE_HEX, H2_PHASE_HEX, H3_PHASE_HEX, H8_PHASE_HEX; +static int acquisitionGraphYMin = 0; +static int acquisitionGraphYMax = 360; + static std::map acquisitionDataMap = { {RADIUS, false}, {ANGLE, false}, @@ -97,7 +105,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool , isDebug(isDebug) , m_admtController(m_admtController) { + ADMTStyleHelper::GetInstance()->initColorMap(); readDeviceProperties(); + readSequence(); initializeMotor(); rotationChannelName = m_admtController->getChannelId(ADMTController::Channel::ROTATION); @@ -256,15 +266,33 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool acquisitionABSAnglePlotChannel = new PlotChannel("ABS Angle", channel1Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); acquisitionTurnCountPlotChannel = new PlotChannel("Turn Count", channel2Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); acquisitionTmp0PlotChannel = new PlotChannel("TMP 0", channel3Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTmp1PlotChannel = new PlotChannel("TMP 1", channel4Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionSinePlotChannel = new PlotChannel("Sine", sinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionCosinePlotChannel = new PlotChannel("Cosine", cosinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionRadiusPlotChannel = new PlotChannel("Radius", channel5Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionSecAnglQPlotChannel = new PlotChannel("SECANGLQ", channel6Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionSecAnglIPlotChannel = new PlotChannel("SECANGLI", channel7Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); acquisitionGraphPlotWidget->addPlotChannel(acquisitionAnglePlotChannel); acquisitionGraphPlotWidget->addPlotChannel(acquisitionABSAnglePlotChannel); acquisitionGraphPlotWidget->addPlotChannel(acquisitionTurnCountPlotChannel); acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp0PlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp1PlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionSinePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionCosinePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionRadiusPlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglQPlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglIPlotChannel); acquisitionAnglePlotChannel->setEnabled(true); acquisitionABSAnglePlotChannel->setEnabled(true); acquisitionTurnCountPlotChannel->setEnabled(true); acquisitionTmp0PlotChannel->setEnabled(true); + acquisitionTmp1PlotChannel->setEnabled(true); + acquisitionSinePlotChannel->setEnabled(true); + acquisitionCosinePlotChannel->setEnabled(true); + acquisitionRadiusPlotChannel->setEnabled(true); + acquisitionSecAnglQPlotChannel->setEnabled(true); + acquisitionSecAnglIPlotChannel->setEnabled(true); acquisitionGraphPlotWidget->selectChannel(acquisitionAnglePlotChannel); acquisitionGraphPlotWidget->replot(); @@ -285,18 +313,45 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool ADMTStyleHelper::ColoredSquareCheckbox(absAngleCheckBox, channel1Pen.color()); connectCheckBoxToAcquisitionGraph(absAngleCheckBox, acquisitionABSAnglePlotChannel, ABSANGLE); - QCheckBox *countCheckBox = new QCheckBox("Count", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(countCheckBox, channel2Pen.color()); - connectCheckBoxToAcquisitionGraph(countCheckBox, acquisitionTurnCountPlotChannel, TURNCOUNT); + // QCheckBox *countCheckBox = new QCheckBox("Count", acquisitionGraphChannelWidget); + // ADMTStyleHelper::ColoredSquareCheckbox(countCheckBox, channel2Pen.color()); + // connectCheckBoxToAcquisitionGraph(countCheckBox, acquisitionTurnCountPlotChannel, TURNCOUNT); QCheckBox *temp0CheckBox = new QCheckBox("Temp 0", acquisitionGraphChannelWidget); ADMTStyleHelper::ColoredSquareCheckbox(temp0CheckBox, channel3Pen.color()); connectCheckBoxToAcquisitionGraph(temp0CheckBox, acquisitionTmp0PlotChannel, TMP0); - acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); - acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 0, 1); - acquisitionGraphChannelGridLayout->addWidget(countCheckBox, 0, 2); - acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 0, 3); + QCheckBox *sineCheckBox = new QCheckBox("Sine", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(sineCheckBox, sineColor); + connectCheckBoxToAcquisitionGraph(sineCheckBox, acquisitionSinePlotChannel, SINE); + + QCheckBox *cosineCheckBox = new QCheckBox("Cosine", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(cosineCheckBox, cosineColor); + connectCheckBoxToAcquisitionGraph(cosineCheckBox, acquisitionCosinePlotChannel, COSINE); + + QCheckBox *radiusCheckBox = new QCheckBox("Radius", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(radiusCheckBox, channel5Pen.color()); + connectCheckBoxToAcquisitionGraph(radiusCheckBox, acquisitionRadiusPlotChannel, RADIUS); + + if(generalRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 + { + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); + } + else if(generalRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 + { + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); + } + // acquisitionGraphChannelGridLayout->addWidget(countCheckBox, 0, 2); #pragma endregion acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphPlotWidget); @@ -384,7 +439,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool eighthHarmonicComboBox->addItem("ADI Factory Values", QVariant(0)); ADMTStyleHelper::ComboBoxStyle(eighthHarmonicComboBox); - readSequence(); + updateSequenceWidget(); applySequenceButton = new QPushButton("Apply", sequenceSection); StyleHelper::BlueButton(applySequenceButton, "applySequenceButton"); @@ -499,7 +554,7 @@ void HarmonicCalibration::getAcquisitionSamples() { while(isStartAcquisition) { - updateChannelValues(); + if(!updateChannelValues()) { break; } if(acquisitionDataMap.at(ANGLE)) prependAcquisitionData(angle, acquisitionAngleList); else if(acquisitionDataMap.at(ANGLE) == false && acquisitionAngleList.size() > 0) acquisitionAngleList.clear(); @@ -513,11 +568,58 @@ void HarmonicCalibration::getAcquisitionSamples() if(acquisitionDataMap.at(TMP0)) prependAcquisitionData(temp, acquisitionTmp0List); else if(acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) acquisitionTmp0List.clear(); + if(acquisitionDataMap.at(SINE)) prependAcquisitionData(getAcquisitionParameterValue(SINE), acquisitionSineList); + else if(acquisitionDataMap.at(SINE) == false && acquisitionSineList.size() > 0) acquisitionSineList.clear(); + + if(acquisitionDataMap.at(COSINE)) prependAcquisitionData(getAcquisitionParameterValue(COSINE), acquisitionCosineList); + else if(acquisitionDataMap.at(COSINE) == false && acquisitionCosineList.size() > 0) acquisitionCosineList.clear(); + + if(acquisitionDataMap.at(RADIUS)) prependAcquisitionData(getAcquisitionParameterValue(RADIUS), acquisitionRadiusList); + else if(acquisitionDataMap.at(RADIUS) == false && acquisitionRadiusList.size() > 0) acquisitionRadiusList.clear(); + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); } } -void HarmonicCalibration::prependAcquisitionData(double& data, QVector& list) +double HarmonicCalibration::getAcquisitionParameterValue(const AcquisitionDataKey &key) +{ + uint32_t *readValue = new uint32_t; + switch(key) + { + case SINE: + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(ADMTController::SensorRegister::SINE), + readValue) == -1) return qQNaN(); + map sineRegisterMap = m_admtController->getSineRegisterBitMapping(static_cast(*readValue)); + return sineRegisterMap.at("SINE"); + break; + } + case COSINE: + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(ADMTController::SensorRegister::COSINE), + readValue) == -1) return qQNaN(); + map cosineRegisterMap = m_admtController->getCosineRegisterBitMapping(static_cast(*readValue)); + return cosineRegisterMap.at("COSINE"); + break; + } + case RADIUS: + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(ADMTController::SensorRegister::RADIUS), + readValue) == -1) return qQNaN(); + map radiusRegisterMap = m_admtController->getRadiusRegisterBitMapping(static_cast(*readValue)); + return radiusRegisterMap.at("RADIUS"); + break; + } + default: + return qQNaN(); + break; + } +} + +void HarmonicCalibration::prependAcquisitionData(const double& data, QVector& list) { list.prepend(data); } @@ -530,6 +632,9 @@ void HarmonicCalibration::prependNullAcquisitionData(QVector& list) void HarmonicCalibration::plotAcquisition(QVector& list, PlotChannel* channel) { channel->curve()->setSamples(list); + auto result = std::minmax_element(list.begin(), list.end()); + if(*result.first < acquisitionGraphYMin) acquisitionGraphYMin = *result.first; + if(*result.second > acquisitionGraphYMax) acquisitionGraphYMax = *result.second; } void HarmonicCalibration::initializeMotor() @@ -2192,7 +2297,14 @@ void HarmonicCalibration::acquisitionUITask() plotAcquisition(acquisitionTurnCountList, acquisitionTurnCountPlotChannel); if(acquisitionDataMap.at(TMP0)) plotAcquisition(acquisitionTmp0List, acquisitionTmp0PlotChannel); - + if(acquisitionDataMap.at(SINE)) + plotAcquisition(acquisitionSineList, acquisitionSinePlotChannel); + if(acquisitionDataMap.at(COSINE)) + plotAcquisition(acquisitionCosineList, acquisitionCosinePlotChannel); + if(acquisitionDataMap.at(RADIUS)) + plotAcquisition(acquisitionRadiusList, acquisitionRadiusPlotChannel); + + acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); acquisitionGraphPlotWidget->replot(); updateLineEditValues(); updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); @@ -2258,8 +2370,6 @@ bool HarmonicCalibration::readSequence(){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ if(*generalRegValue != UINT32_MAX){ generalRegisterMap = m_admtController->getGeneralRegisterBitMapping(static_cast(*generalRegValue)); - - updateSequenceWidget(); success = true; } } @@ -2526,11 +2636,17 @@ void HarmonicCalibration::clearCommandLog(){ commandLogPlainTextEdit->clear(); } -void HarmonicCalibration::updateChannelValues(){ +bool HarmonicCalibration::updateChannelValues(){ + bool success = false; rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, bufferSize); + if(rotation == static_cast(UINT64_MAX)) { return false; } angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, bufferSize); + if(angle == static_cast(UINT64_MAX)) { return false; } updateCountValue(); + if(count == static_cast(UINT64_MAX)) { return false; } temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, bufferSize); + if(temp == static_cast(UINT64_MAX)) { return false; } + return success = true; } void HarmonicCalibration::updateCountValue(){ @@ -2816,23 +2932,29 @@ void HarmonicCalibration::updateLabelValue(QLabel* label, int channelIndex) } } -void HarmonicCalibration::updateChannelValue(int channelIndex) +bool HarmonicCalibration::updateChannelValue(int channelIndex) { + bool success = false; switch(channelIndex) { case ADMTController::Channel::ROTATION: rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, 1); + if(rotation == static_cast(UINT64_MAX)) { success = false; } break; case ADMTController::Channel::ANGLE: angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, 1); + if(angle == static_cast(UINT64_MAX)) { success = false; } break; case ADMTController::Channel::COUNT: count = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, 1); + if(count == static_cast(UINT64_MAX)) { success = false; } break; case ADMTController::Channel::TEMPERATURE: temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, 1); + if(temp == static_cast(UINT64_MAX)) { success = false; } break; } + return success; } int HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value) @@ -2923,8 +3045,8 @@ void HarmonicCalibration::getCalibrationSamples() int currentSamplesCount = graphDataList.size(); while(isStartMotor && currentSamplesCount < totalSamplesCount){ target_pos = current_pos + -408; - moveMotorToPosition(target_pos, true); - updateChannelValue(ADMTController::Channel::ANGLE); + if(moveMotorToPosition(target_pos, true) == false) { m_admtController->disconnectADMT(); } + if(updateChannelValue(ADMTController::Channel::ANGLE)) { break; } graphDataList.append(angle); currentSamplesCount++; } @@ -3366,15 +3488,23 @@ void HarmonicCalibration::computeSineCosineOfAngles(QVector graphDataLis } } -void HarmonicCalibration::moveMotorToPosition(double& position, bool validate) +bool HarmonicCalibration::moveMotorToPosition(double& position, bool validate) { - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, position); - if(validate){ - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - while(target_pos != current_pos) { - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + bool success = false; + bool canRead = true; + if(writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, position) == 0){ + if(validate){ + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) + { + while(target_pos != current_pos && canRead) { + canRead = readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0 ? true : false; + } + if(canRead) success = true; + } } } + + return success; } void HarmonicCalibration::startMotorContinuous() From 156447f05f9b69c76712001a14176a587fb32d5d Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 8 Jan 2025 17:03:36 +0800 Subject: [PATCH 077/112] admt: Implemented multi-thread operations to acquisition tab - Set static value updates to 300ms - Variable graph update interval - Set acquisition to 16ms - Added layout for fault register widget Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 7 +- plugins/admt/src/harmoniccalibration.cpp | 136 ++++++++++++------ 2 files changed, 95 insertions(+), 48 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 922b43d39c..a5204d295b 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -254,8 +255,9 @@ public Q_SLOTS: void updateSequenceWidget(); void toggleFaultRegisterMode(int mode); void startAcquisition(); - void getAcquisitionSamples(); - void acquisitionUITask(); + void getAcquisitionSamples(int sampleRate); + void acquisitionUITask(int sampleRate); + void acquisitionPlotTask(int sampleRate); void toggleMTDiagnostics(int mode); void toggleSequenceModeRegisters(int mode); void readAllRegisters(); @@ -278,6 +280,7 @@ public Q_SLOTS: void updateLineEditValue(QLineEdit* lineEdit, double value); void toggleTabSwitching(bool value); double getAcquisitionParameterValue(const AcquisitionDataKey &key); + void resetYAxisScale(); QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index d562851abb..e24e0afb6e 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -8,6 +8,7 @@ static int acquisitionUITimerRate = 50; static int calibrationUITimerRate = 300; static int utilityTimerRate = 1000; +static int acquisitionSampleRate = 16; // In ms static int bufferSize = 1; static int dataGraphSamples = 100; @@ -396,10 +397,15 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connectLineEditToNumber(displayLengthLineEdit, acquisitionDisplayLength, 1, 2048); + QPushButton *resetYAxisButton = new QPushButton("Reset Y-Axis Scale", generalSection); + StyleHelper::BlueButton(resetYAxisButton, "resetYAxisButton"); + connect(resetYAxisButton, &QPushButton::clicked, this, &HarmonicCalibration::resetYAxisScale); + generalSection->contentLayout()->addWidget(graphUpdateIntervalLabel); generalSection->contentLayout()->addWidget(graphUpdateIntervalLineEdit); generalSection->contentLayout()->addWidget(displayLengthLabel); generalSection->contentLayout()->addWidget(displayLengthLineEdit); + generalSection->contentLayout()->addWidget(resetYAxisButton); MenuSectionWidget *sequenceWidget = new MenuSectionWidget(generalSettingWidget); MenuCollapseSection *sequenceSection = new MenuCollapseSection("Sequence", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, sequenceWidget); @@ -452,6 +458,26 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool sequenceSection->contentLayout()->addWidget(eighthHarmonicMenuCombo); sequenceSection->contentLayout()->addWidget(applySequenceButton); + #pragma region Device Status Widget + MenuSectionWidget *acquisitionDeviceStatusWidget = new MenuSectionWidget(generalSettingWidget); + acquisitionDeviceStatusWidget->contentLayout()->setSpacing(8); + MenuCollapseSection *acquisitionDeviceStatusSection = new MenuCollapseSection("Device Status", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); + acquisitionDeviceStatusSection->contentLayout()->setSpacing(8); + acquisitionDeviceStatusWidget->contentLayout()->addWidget(acquisitionDeviceStatusSection); + + MenuControlButton *acquisitionFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", statusLEDColor, acquisitionDeviceStatusSection); + acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionFaultRegisterLEDWidget); + + if(deviceType == "Automotive" && generalRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 + { + MenuControlButton *acquisitionSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", statusLEDColor, acquisitionDeviceStatusSection); + MenuControlButton *acquisitionSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", statusLEDColor, acquisitionDeviceStatusSection); + acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPICRCLEDWidget); + acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPIFlagLEDWidget); + } + #pragma endregion + + generalSettingLayout->addWidget(acquisitionDeviceStatusWidget); generalSettingLayout->addWidget(header); generalSettingLayout->addSpacerItem(new QSpacerItem(0, 3, QSizePolicy::Fixed, QSizePolicy::Fixed)); generalSettingLayout->addWidget(sequenceWidget); @@ -486,12 +512,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connectLineEditToNumberWrite(motorTargetPositionSpinBox->lineEdit(), target_pos, ADMTController::MotorAttribute::TARGET_POS); connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); - acquisitionUITimer = new QTimer(this); - connect(acquisitionUITimer, &QTimer::timeout, this, &HarmonicCalibration::acquisitionUITask); - - // timer = new QTimer(this); - // connect(timer, &QTimer::timeout, this, &HarmonicCalibration::timerTask); - calibrationUITimer = new QTimer(this); connect(calibrationUITimer, &QTimer::timeout, this, &HarmonicCalibration::calibrationUITask); @@ -543,41 +563,47 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool HarmonicCalibration::~HarmonicCalibration() {} +void HarmonicCalibration::resetYAxisScale() +{ + acquisitionGraphYMin = 0; + acquisitionGraphYMax = 360; + acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); + acquisitionGraphPlotWidget->replot(); +} + void HarmonicCalibration::startAcquisition() { isStartAcquisition = true; acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); - QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples); + + QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples, acquisitionSampleRate); + QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, acquisitionUITimerRate); + QtConcurrent::run(this, &HarmonicCalibration::acquisitionUITask, 200); } -void HarmonicCalibration::getAcquisitionSamples() +void HarmonicCalibration::getAcquisitionSamples(int sampleRate) { while(isStartAcquisition) { if(!updateChannelValues()) { break; } + if(acquisitionDataMap.at(ANGLE) == false && acquisitionAngleList.size() > 0) acquisitionAngleList.clear(); + if(acquisitionDataMap.at(ABSANGLE) == false && acquisitionABSAngleList.size() > 0) acquisitionABSAngleList.clear(); + if(acquisitionDataMap.at(TURNCOUNT) == false && acquisitionTurnCountList.size() > 0) acquisitionTurnCountList.clear(); + if(acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) acquisitionTmp0List.clear(); + if(acquisitionDataMap.at(SINE) == false && acquisitionSineList.size() > 0) acquisitionSineList.clear(); + if(acquisitionDataMap.at(COSINE) == false && acquisitionCosineList.size() > 0) acquisitionCosineList.clear(); + if(acquisitionDataMap.at(RADIUS) == false && acquisitionRadiusList.size() > 0) acquisitionRadiusList.clear(); + if(acquisitionDataMap.at(ANGLE)) prependAcquisitionData(angle, acquisitionAngleList); - else if(acquisitionDataMap.at(ANGLE) == false && acquisitionAngleList.size() > 0) acquisitionAngleList.clear(); - if(acquisitionDataMap.at(ABSANGLE)) prependAcquisitionData(rotation, acquisitionABSAngleList); - else if(acquisitionDataMap.at(ABSANGLE) == false && acquisitionABSAngleList.size() > 0) acquisitionABSAngleList.clear(); - if(acquisitionDataMap.at(TURNCOUNT)) prependAcquisitionData(count, acquisitionTurnCountList); - else if(acquisitionDataMap.at(TURNCOUNT) == false && acquisitionTurnCountList.size() > 0) acquisitionTurnCountList.clear(); - if(acquisitionDataMap.at(TMP0)) prependAcquisitionData(temp, acquisitionTmp0List); - else if(acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) acquisitionTmp0List.clear(); - if(acquisitionDataMap.at(SINE)) prependAcquisitionData(getAcquisitionParameterValue(SINE), acquisitionSineList); - else if(acquisitionDataMap.at(SINE) == false && acquisitionSineList.size() > 0) acquisitionSineList.clear(); - if(acquisitionDataMap.at(COSINE)) prependAcquisitionData(getAcquisitionParameterValue(COSINE), acquisitionCosineList); - else if(acquisitionDataMap.at(COSINE) == false && acquisitionCosineList.size() > 0) acquisitionCosineList.clear(); - if(acquisitionDataMap.at(RADIUS)) prependAcquisitionData(getAcquisitionParameterValue(RADIUS), acquisitionRadiusList); - else if(acquisitionDataMap.at(RADIUS) == false && acquisitionRadiusList.size() > 0) acquisitionRadiusList.clear(); - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + QThread::msleep(sampleRate); } } @@ -622,6 +648,10 @@ double HarmonicCalibration::getAcquisitionParameterValue(const AcquisitionDataKe void HarmonicCalibration::prependAcquisitionData(const double& data, QVector& list) { list.prepend(data); + if(list.size() >= acquisitionDisplayLength){ + list.resize(acquisitionDisplayLength); + list.squeeze(); + } } void HarmonicCalibration::prependNullAcquisitionData(QVector& list) @@ -2271,11 +2301,11 @@ void HarmonicCalibration::run(bool b) if(!b) { isStartAcquisition = false; - acquisitionUITimer->stop(); + // acquisitionUITimer->stop(); runButton->setChecked(false); } else{ - acquisitionUITimer->start(acquisitionUITimerRate); + // acquisitionUITimer->start(acquisitionUITimerRate); startAcquisition(); } @@ -2287,27 +2317,41 @@ void HarmonicCalibration::canCalibrate(bool value) calibrateDataButton->setEnabled(value); } -void HarmonicCalibration::acquisitionUITask() +void HarmonicCalibration::acquisitionPlotTask(int sampleRate) +{ + while(isStartAcquisition){ + if(acquisitionDataMap.at(ANGLE)) + plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel); + if(acquisitionDataMap.at(ABSANGLE)) + plotAcquisition(acquisitionABSAngleList, acquisitionABSAnglePlotChannel); + if(acquisitionDataMap.at(TURNCOUNT)) + plotAcquisition(acquisitionTurnCountList, acquisitionTurnCountPlotChannel); + if(acquisitionDataMap.at(TMP0)) + plotAcquisition(acquisitionTmp0List, acquisitionTmp0PlotChannel); + if(acquisitionDataMap.at(SINE)) + plotAcquisition(acquisitionSineList, acquisitionSinePlotChannel); + if(acquisitionDataMap.at(COSINE)) + plotAcquisition(acquisitionCosineList, acquisitionCosinePlotChannel); + if(acquisitionDataMap.at(RADIUS)) + plotAcquisition(acquisitionRadiusList, acquisitionRadiusPlotChannel); + + acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); + acquisitionGraphPlotWidget->replot(); + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::acquisitionUITask(int sampleRate) { - if(acquisitionDataMap.at(ANGLE)) - plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel); - if(acquisitionDataMap.at(ABSANGLE)) - plotAcquisition(acquisitionABSAngleList, acquisitionABSAnglePlotChannel); - if(acquisitionDataMap.at(TURNCOUNT)) - plotAcquisition(acquisitionTurnCountList, acquisitionTurnCountPlotChannel); - if(acquisitionDataMap.at(TMP0)) - plotAcquisition(acquisitionTmp0List, acquisitionTmp0PlotChannel); - if(acquisitionDataMap.at(SINE)) - plotAcquisition(acquisitionSineList, acquisitionSinePlotChannel); - if(acquisitionDataMap.at(COSINE)) - plotAcquisition(acquisitionCosineList, acquisitionCosinePlotChannel); - if(acquisitionDataMap.at(RADIUS)) - plotAcquisition(acquisitionRadiusList, acquisitionRadiusPlotChannel); + while(isStartAcquisition) + { + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); - acquisitionGraphPlotWidget->replot(); - updateLineEditValues(); - updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); + updateLineEditValues(); + updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); + QThread::msleep(sampleRate); + } } void HarmonicCalibration::applySequence(){ @@ -2808,11 +2852,11 @@ void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit* lineEdit, do double rps = lineEdit->text().toDouble(&ok); if (ok) { vmax = convertRPStoVMAX(rps); - StatusBarManager::pushMessage("Converted VMAX: " + QString::number(vmax)); + // StatusBarManager::pushMessage("Converted VMAX: " + QString::number(vmax)); writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, vmax); writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); amax = convertAccelTimetoAMAX(motorAccelTimeSpinBox->lineEdit()->text().toDouble()); - StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); + // StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); } else { lineEdit->setText(QString::number(convertVMAXtoRPS(vmax))); @@ -2827,7 +2871,7 @@ void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit* lineEdit, d double accelTime = lineEdit->text().toDouble(&ok); if (ok) { amax = convertAccelTimetoAMAX(accelTime); - StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); + // StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); } else { lineEdit->setText(QString::number(convertAMAXtoAccelTime(amax))); } From 99a122aba9f107ae609d5c56cd6a2327a5d57a79 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 10 Jan 2025 14:59:26 +0800 Subject: [PATCH 078/112] admt: Implemented device status fault monitoring - Added disconnect method for separate threads Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 2 + .../admt/include/admt/harmoniccalibration.h | 16 +- plugins/admt/src/admtcontroller.cpp | 36 ++- plugins/admt/src/admtplugin.cpp | 5 +- plugins/admt/src/harmoniccalibration.cpp | 232 +++++++++++++----- 5 files changed, 229 insertions(+), 62 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 16705b3ede..52d6f1d632 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -211,6 +211,8 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject map getSecAnglQRegisterBitMapping(uint16_t registerValue); map getSecAnglIRegisterBitMapping(uint16_t registerValue); map getTmp1RegisterBitMapping(uint16_t registerValue, bool is5V); + bool checkRegisterFault(uint16_t registerValue, bool isMode1); + private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index a5204d295b..671dd1af78 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -84,12 +84,12 @@ class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget ~HarmonicCalibration(); bool running() const; void setRunning(bool newRunning); + void requestDisconnect(); public Q_SLOTS: void run(bool); void stop(); void start(); void restart(); - void calibrationUITask(); void utilityTask(); void clearCommandLog(); void canCalibrate(bool); @@ -172,7 +172,7 @@ public Q_SLOTS: HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, *motorMaxDisplacementSpinBox, *motorTargetPositionSpinBox; - MenuControlButton *DIGIOBusyStatusLED ,*DIGIOCNVStatusLED ,*DIGIOSENTStatusLED ,*DIGIOACALCStatusLED ,*DIGIOFaultStatusLED ,*DIGIOBootloaderStatusLED, + MenuControlButton *acquisitionFaultRegisterLEDWidget, *calibrationFaultRegisterLEDWidget, *DIGIOBusyStatusLED ,*DIGIOCNVStatusLED ,*DIGIOSENTStatusLED ,*DIGIOACALCStatusLED ,*DIGIOFaultStatusLED ,*DIGIOBootloaderStatusLED, *R0StatusLED, *R1StatusLED, *R2StatusLED, *R3StatusLED, *R4StatusLED, *R5StatusLED, *R6StatusLED, *R7StatusLED, *VDDUnderVoltageStatusLED, *VDDOverVoltageStatusLED, *VDRIVEUnderVoltageStatusLED, *VDRIVEOverVoltageStatusLED, *AFEDIAGStatusLED, *NVMCRCFaultStatusLED, *ECCDoubleBitErrorStatusLED, *OscillatorDriftStatusLED, *CountSensorFalseStateStatusLED, @@ -189,6 +189,9 @@ public Q_SLOTS: RegisterBlockWidget *cnvPageRegisterBlock, *digIORegisterBlock, *faultRegisterBlock, *generalRegisterBlock, *digIOEnRegisterBlock, *angleCkRegisterBlock, *eccDcdeRegisterBlock, *eccDisRegisterBlock, *absAngleRegisterBlock, *angleRegisterBlock, *angleSecRegisterBlock, *sineRegisterBlock, *cosineRegisterBlock, *secAnglIRegisterBlock, *secAnglQRegisterBlock, *radiusRegisterBlock, *diag1RegisterBlock, *diag2RegisterBlock, *tmp0RegisterBlock, *tmp1RegisterBlock, *cnvCntRegisterBlock, *uniqID0RegisterBlock, *uniqID1RegisterBlock, *uniqID2RegisterBlock, *uniqID3RegisterBlock, *h1MagRegisterBlock, *h1PhRegisterBlock, *h2MagRegisterBlock, *h2PhRegisterBlock, *h3MagRegisterBlock, *h3PhRegisterBlock, *h8MagRegisterBlock, *h8PhRegisterBlock; + QFuture m_deviceStatusThread, m_acquisitionDataThread, m_acquisitionGraphThread; + QFutureWatcher m_deviceStatusWatcher, m_acquisitionDataWatcher, m_acquisitionGraphWatcher; + bool updateChannelValues(); void updateLineEditValues(); void updateGeneralSettingEnabled(bool value); @@ -245,7 +248,7 @@ public Q_SLOTS: void computeSineCosineOfAngles(QVector graphDataList); void postCalibrateData(); void canStartMotor(bool value); - void resetCurrentPositionToZero(); + bool resetCurrentPositionToZero(); void flashHarmonicValues(); void updateCalculatedCoeffHex(); void resetCalculatedCoeffHex(); @@ -256,7 +259,7 @@ public Q_SLOTS: void toggleFaultRegisterMode(int mode); void startAcquisition(); void getAcquisitionSamples(int sampleRate); - void acquisitionUITask(int sampleRate); + void acquisitionUITask(); void acquisitionPlotTask(int sampleRate); void toggleMTDiagnostics(int mode); void toggleSequenceModeRegisters(int mode); @@ -281,6 +284,11 @@ public Q_SLOTS: void toggleTabSwitching(bool value); double getAcquisitionParameterValue(const AcquisitionDataKey &key); void resetYAxisScale(); + void getDeviceFaultStatus(int sampleRate); + void startAcquisitionDeviceStatusMonitor(); + void startCalibrationDeviceStatusMonitor(); + void updateFaultStatusLEDColor(MenuControlButton *widget, bool value); + void calibrationUITask(); QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index da5d191838..4ee4240054 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -41,11 +41,10 @@ void ADMTController::disconnectADMT() if(!m_conn || !m_iioCtx){ return; } - + ConnectionProvider::close(uri); m_conn = nullptr; m_iioCtx = nullptr; - } const char* ADMTController::getChannelId(Channel channel) @@ -1515,4 +1514,37 @@ map ADMTController::getTmp1RegisterBitMapping(uint16_t registerV result["TMP1"] = tmp1DegC; return result; +} + +bool ADMTController::checkRegisterFault(uint16_t registerValue, bool isMode1) { + // Mode-specific checks + if (isMode1) { + return ((registerValue >> 14) & 0x01) || // AMR Radius Check + ((registerValue >> 13) & 0x01) || // Turn Counter Cross Check + ((registerValue >> 9) & 0x01) || // Count Sensor False State + ((registerValue >> 7) & 0x01) || // ECC Double Bit Error + ((registerValue >> 5) & 0x01) || // NVM CRC Fault + ((registerValue >> 3) & 0x01) || // VDRIVE Over Voltage + ((registerValue >> 2) & 0x01) || // VDRIVE Under Voltage + ((registerValue >> 1) & 0x01) || // VDD Over Voltage + ((registerValue >> 0) & 0x01); // VDD Under Voltage + } else { + // Check all bits if not in Mode 1 + return ((registerValue >> 15) & 0x01) || // Sequencer Watchdog + ((registerValue >> 14) & 0x01) || // AMR Radius Check + ((registerValue >> 13) & 0x01) || // Turn Counter Cross Check + ((registerValue >> 12) & 0x01) || // MT Diagnostic + ((registerValue >> 11) & 0x01) || // Turn Count Sensor Levels + ((registerValue >> 10) & 0x01) || // Angle Cross Check + ((registerValue >> 9) & 0x01) || // Count Sensor False State + ((registerValue >> 8) & 0x01) || // Oscillator Drift + ((registerValue >> 7) & 0x01) || // ECC Double Bit Error + ((registerValue >> 6) & 0x01) || // Reserved + ((registerValue >> 5) & 0x01) || // NVM CRC Fault + ((registerValue >> 4) & 0x01) || // AFE Diagnostic + ((registerValue >> 3) & 0x01) || // VDRIVE Over Voltage + ((registerValue >> 2) & 0x01) || // VDRIVE Under Voltage + ((registerValue >> 1) & 0x01) || // VDD Over Voltage + ((registerValue >> 0) & 0x01); // VDD Under Voltage + } } \ No newline at end of file diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index f2c36c4e7a..49e1fb57de 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -94,7 +94,7 @@ bool ADMTPlugin::onConnect() return false; m_ctx = conn->context(); m_toolList[0]->setEnabled(true); - m_toolList[0]->setRunBtnVisible(true); + m_toolList[0]->setRunBtnVisible(false); //auto recipe = createRecipe(m_ctx); @@ -110,6 +110,9 @@ bool ADMTPlugin::onDisconnect() { // This method is called when the disconnect button is pressed // It must remove all connections that were established on the connection + + dynamic_cast(harmonicCalibration)->requestDisconnect(); + for(auto &tool : m_toolList) { tool->setEnabled(false); tool->setRunning(false); diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index e24e0afb6e..449fc06783 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -5,10 +5,13 @@ #include #include -static int acquisitionUITimerRate = 50; -static int calibrationUITimerRate = 300; +static int acquisitionUITimerRate = 500; +static int calibrationUITimerRate = 500; static int utilityTimerRate = 1000; -static int acquisitionSampleRate = 16; // In ms + +static int deviceStatusMonitorRate = 500; // In ms +static int acquisitionSampleRate = 20; // In ms +static int acquisitionGraphSampleRate = 100; // In ms static int bufferSize = 1; static int dataGraphSamples = 100; @@ -20,7 +23,6 @@ static double *tempGraphValue; static int cycleCount = 11; static int samplesPerCycle = 256; static int totalSamplesCount = cycleCount * samplesPerCycle; -static bool isStartAcquisition = false; static bool isStartMotor = false; static bool isPostCalibration = false; static bool isCalculatedCoeff = false; @@ -78,6 +80,11 @@ static uint32_t H1_MAG_HEX, H2_MAG_HEX, H3_MAG_HEX, H8_MAG_HEX, H1_PHASE_HEX, H2 static int acquisitionGraphYMin = 0; static int acquisitionGraphYMax = 360; +static bool deviceStatusFault = false; +static bool isStartAcquisition = false; +static bool isDeviceStatusMonitor = false; + +static int readMotorDebounce = 50; // In ms static std::map acquisitionDataMap = { {RADIUS, false}, @@ -384,9 +391,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool StyleHelper::MenuSmallLabel(graphUpdateIntervalLabel, "graphUpdateIntervalLabel"); graphUpdateIntervalLineEdit = new QLineEdit(generalSection); ADMTStyleHelper::LineEditStyle(graphUpdateIntervalLineEdit); - graphUpdateIntervalLineEdit->setText(QString::number(acquisitionUITimerRate)); + graphUpdateIntervalLineEdit->setText(QString::number(acquisitionGraphSampleRate)); - connectLineEditToNumber(graphUpdateIntervalLineEdit, acquisitionUITimerRate, 1, 5000); + connectLineEditToNumber(graphUpdateIntervalLineEdit, acquisitionGraphSampleRate, 1, 5000); // Data Sample Size QLabel *displayLengthLabel = new QLabel("Display Length", generalSection); @@ -465,7 +472,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool acquisitionDeviceStatusSection->contentLayout()->setSpacing(8); acquisitionDeviceStatusWidget->contentLayout()->addWidget(acquisitionDeviceStatusSection); - MenuControlButton *acquisitionFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", statusLEDColor, acquisitionDeviceStatusSection); + acquisitionFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", statusLEDColor, acquisitionDeviceStatusSection); acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionFaultRegisterLEDWidget); if(deviceType == "Automotive" && generalRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 @@ -512,6 +519,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connectLineEditToNumberWrite(motorTargetPositionSpinBox->lineEdit(), target_pos, ADMTController::MotorAttribute::TARGET_POS); connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); + acquisitionUITimer = new QTimer(this); + connect(acquisitionUITimer, &QTimer::timeout, this, &HarmonicCalibration::acquisitionUITask); + calibrationUITimer = new QTimer(this); connect(calibrationUITimer, &QTimer::timeout, this, &HarmonicCalibration::calibrationUITask); @@ -525,18 +535,31 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connect(tabWidget, &QTabWidget::currentChanged, [=](int index){ tabWidget->setCurrentIndex(index); + if(index == 0 || index == 1) + { + if(isDeviceStatusMonitor) isDeviceStatusMonitor = false; + + if(index == 0) startAcquisitionDeviceStatusMonitor(); + else startCalibrationDeviceStatusMonitor(); + } + else{ + isDeviceStatusMonitor = false; + } + if(index == 0) // Acquisition Tab { + acquisitionUITimer->start(acquisitionUITimerRate); readSequence(); } else { + acquisitionUITimer->stop(); stop(); } if(index == 1) // Calibration Tab { - calibrationUITimer->start(calibrationUITimerRate); + calibrationUITimer->start(calibrationUITimerRate); } else { @@ -559,10 +582,27 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool toggleSequenceModeRegisters(generalRegisterMap.at("Sequence Type")); } }); + + acquisitionUITimer->start(acquisitionUITimerRate); + startAcquisitionDeviceStatusMonitor(); } HarmonicCalibration::~HarmonicCalibration() {} +void HarmonicCalibration::startAcquisitionDeviceStatusMonitor() +{ + isDeviceStatusMonitor = true; + m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); + m_deviceStatusWatcher.setFuture(m_deviceStatusThread); +} + +void HarmonicCalibration::startCalibrationDeviceStatusMonitor() +{ + isDeviceStatusMonitor = true; + m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); + m_deviceStatusWatcher.setFuture(m_deviceStatusThread); +} + void HarmonicCalibration::resetYAxisScale() { acquisitionGraphYMin = 0; @@ -576,9 +616,10 @@ void HarmonicCalibration::startAcquisition() isStartAcquisition = true; acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); - QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples, acquisitionSampleRate); - QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, acquisitionUITimerRate); - QtConcurrent::run(this, &HarmonicCalibration::acquisitionUITask, 200); + m_acquisitionDataThread = QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples, acquisitionSampleRate); + m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); + m_acquisitionGraphThread = QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, acquisitionGraphSampleRate); + m_acquisitionGraphWatcher.setFuture(m_acquisitionGraphThread); } void HarmonicCalibration::getAcquisitionSamples(int sampleRate) @@ -645,6 +686,33 @@ double HarmonicCalibration::getAcquisitionParameterValue(const AcquisitionDataKe } } +void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) +{ + while(isDeviceStatusMonitor) + { + uint32_t *readValue = new uint32_t; + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), 0) == 0) + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), readValue) == 0) + { + deviceStatusFault = m_admtController->checkRegisterFault(static_cast(*readValue), generalRegisterMap.at("Sequence Type") == 0 ? true : false); + } + else + { + deviceStatusFault = true; + } + } + else + { + deviceStatusFault = true; + } + + QThread::msleep(sampleRate); + } +} + void HarmonicCalibration::prependAcquisitionData(const double& data, QVector& list) { list.prepend(data); @@ -1013,6 +1081,25 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationSettingsGroupLayout->setMargin(0); calibrationSettingsGroupLayout->setSpacing(8); + #pragma region Device Status Widget + MenuSectionWidget *calibrationDeviceStatusWidget = new MenuSectionWidget(calibrationSettingsGroupWidget); + calibrationDeviceStatusWidget->contentLayout()->setSpacing(8); + MenuCollapseSection *calibrationDeviceStatusSection = new MenuCollapseSection("Device Status", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationSettingsGroupWidget); + calibrationDeviceStatusSection->contentLayout()->setSpacing(8); + calibrationDeviceStatusWidget->contentLayout()->addWidget(calibrationDeviceStatusSection); + + calibrationFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", statusLEDColor, calibrationDeviceStatusSection); + calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationFaultRegisterLEDWidget); + + if(deviceType == "Automotive" && generalRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 + { + MenuControlButton *calibrationSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", statusLEDColor, calibrationDeviceStatusSection); + MenuControlButton *calibrationSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", statusLEDColor, calibrationDeviceStatusSection); + calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPICRCLEDWidget); + calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPIFlagLEDWidget); + } + #pragma endregion + #pragma region Acquire Calibration Samples Button calibrationStartMotorButton = new QPushButton(calibrationSettingsGroupWidget); ADMTStyleHelper::StartButtonStyle(calibrationStartMotorButton); @@ -1060,6 +1147,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationSettingsWidget->setFixedWidth(260); calibrationSettingsWidget->setLayout(calibrationSettingsLayout); + calibrationSettingsGroupLayout->addWidget(calibrationDeviceStatusWidget); calibrationSettingsGroupLayout->addWidget(calibrationStartMotorButton); calibrationSettingsGroupLayout->addWidget(calibrateDataButton); calibrationSettingsGroupLayout->addWidget(clearCalibrateDataButton); @@ -2301,11 +2389,9 @@ void HarmonicCalibration::run(bool b) if(!b) { isStartAcquisition = false; - // acquisitionUITimer->stop(); runButton->setChecked(false); } else{ - // acquisitionUITimer->start(acquisitionUITimerRate); startAcquisition(); } @@ -2342,18 +2428,24 @@ void HarmonicCalibration::acquisitionPlotTask(int sampleRate) } } -void HarmonicCalibration::acquisitionUITask(int sampleRate) +void HarmonicCalibration::acquisitionUITask() { - while(isStartAcquisition) + updateFaultStatusLEDColor(acquisitionFaultRegisterLEDWidget, deviceStatusFault); + + if(isStartAcquisition) { readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - updateLineEditValues(); updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); - QThread::msleep(sampleRate); } } +void HarmonicCalibration::updateFaultStatusLEDColor(MenuControlButton *widget, bool value) +{ + if(value) changeStatusLEDColor(widget, faultLEDColor); + else changeStatusLEDColor(widget, statusLEDColor); +} + void HarmonicCalibration::applySequence(){ toggleWidget(applySequenceButton, false); applySequenceButton->setText("Writing..."); @@ -3053,60 +3145,76 @@ void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorA void HarmonicCalibration::calibrationUITask() { - if(!isDebug){ - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); + updateFaultStatusLEDColor(calibrationFaultRegisterLEDWidget, deviceStatusFault); - if(isStartMotor) - { - if(isPostCalibration){ - postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); - postCalibrationRawDataPlotWidget->replot(); - } - else{ - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotWidget->replot(); - } + if(isStartMotor) + { + if(isPostCalibration){ + postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); + postCalibrationRawDataPlotWidget->replot(); + } + else{ + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotWidget->replot(); } } } void HarmonicCalibration::getCalibrationSamples() { - resetCurrentPositionToZero(); - - if(isPostCalibration){ - int currentSamplesCount = graphPostDataList.size(); - while(isStartMotor && currentSamplesCount < totalSamplesCount){ - target_pos = current_pos + -408; - moveMotorToPosition(target_pos, true); - updateChannelValue(ADMTController::Channel::ANGLE); - graphPostDataList.append(angle); - currentSamplesCount++; + if(resetCurrentPositionToZero()){ + if(isPostCalibration){ + int currentSamplesCount = graphPostDataList.size(); + while(isStartMotor && currentSamplesCount < totalSamplesCount){ + target_pos = current_pos + -408; + moveMotorToPosition(target_pos, true); + updateChannelValue(ADMTController::Channel::ANGLE); + graphPostDataList.append(angle); + currentSamplesCount++; + } } - } - else{ - int currentSamplesCount = graphDataList.size(); - while(isStartMotor && currentSamplesCount < totalSamplesCount){ - target_pos = current_pos + -408; - if(moveMotorToPosition(target_pos, true) == false) { m_admtController->disconnectADMT(); } - if(updateChannelValue(ADMTController::Channel::ANGLE)) { break; } - graphDataList.append(angle); - currentSamplesCount++; + else{ + int currentSamplesCount = graphDataList.size(); + while(isStartMotor && currentSamplesCount < totalSamplesCount){ + target_pos = current_pos + -408; + if(moveMotorToPosition(target_pos, true) == false) { m_admtController->disconnectADMT(); } + if(updateChannelValue(ADMTController::Channel::ANGLE)) { break; } + graphDataList.append(angle); + currentSamplesCount++; + } } } stopMotor(); } -void HarmonicCalibration::resetCurrentPositionToZero() +bool HarmonicCalibration::resetCurrentPositionToZero() { - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - while(current_pos != 0){ - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + bool success = false; + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) + { + if(current_pos != 0 && + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0) == 0 && + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) + { + while(current_pos != 0){ + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) != 0) break; + QThread::msleep(readMotorDebounce); + } + if(current_pos == 0) + { + resetToZero = false; + success = true; + } + } + else{ + success = true; + } } - resetToZero = false; + + return success; } void HarmonicCalibration::startMotor() @@ -3680,4 +3788,18 @@ void HarmonicCalibration::applyTabWidgetStyle(QTabWidget *widget, const QString& style.replace("&&ScopyBlue&&", StyleHelper::getColor(styleHelperColor)); style.replace("&&UIElementBackground&&", StyleHelper::getColor("UIElementBackground")); widget->tabBar()->setStyleSheet(style); +} + +void HarmonicCalibration::requestDisconnect() +{ + isStartAcquisition = false; + isDeviceStatusMonitor = false; + + m_deviceStatusThread.cancel(); + m_acquisitionDataThread.cancel(); + m_acquisitionGraphThread.cancel(); + + m_deviceStatusWatcher.waitForFinished(); + m_acquisitionDataWatcher.waitForFinished(); + m_acquisitionGraphWatcher.waitForFinished(); } \ No newline at end of file From 64af56afc87834731ae0683e9f6c2c11f7977b55 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 15 Jan 2025 12:30:13 +0800 Subject: [PATCH 079/112] admt: Code cleanup Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtstylehelper.h | 7 + .../admt/include/admt/harmoniccalibration.h | 202 +- plugins/admt/src/admtstylehelper.cpp | 136 + plugins/admt/src/harmoniccalibration.cpp | 3594 ++++++++--------- 4 files changed, 2016 insertions(+), 1923 deletions(-) diff --git a/plugins/admt/include/admt/admtstylehelper.h b/plugins/admt/include/admt/admtstylehelper.h index b7898605f6..60406c31ea 100644 --- a/plugins/admt/include/admt/admtstylehelper.h +++ b/plugins/admt/include/admt/admtstylehelper.h @@ -36,6 +36,13 @@ class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject static void LineEditStyle(QLineEdit *widget, QString objectName = ""); static void ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName = ""); static void StartButtonStyle(QPushButton *btn, QString objectName = ""); + static void TabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor = "ScopyBlue", QString objectName = ""); + static void TextStyle(QWidget *widget, const QString& styleHelperColor, bool isBold = false, QString objectName = ""); + static void MenuSmallLabel(QLabel *label, QString objectName = ""); + static void LineStyle(QFrame *line, QString objectName = ""); + static void UIBackgroundStyle(QWidget *widget, QString objectName = ""); + static void GraphChannelStyle(QWidget *widget, QLayout *layout, QString objectName = ""); + static void CalculatedCoeffWidgetRowStyle(QWidget *widget, QHBoxLayout *layout, QLabel *hLabel, QLabel *hMagLabel, QLabel *hPhaseLabel, QString objectName = ""); private: QMap colorMap; static ADMTStyleHelper *pinstance_; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 671dd1af78..59caee6ed3 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -90,11 +90,6 @@ public Q_SLOTS: void stop(); void start(); void restart(); - void utilityTask(); - void clearCommandLog(); - void canCalibrate(bool); - void applySequence(); - bool readSequence(); Q_SIGNALS: void runningChanged(bool); void canCalibrateChanged(bool); @@ -107,6 +102,8 @@ public Q_SLOTS: InfoBtn *infoButton; RunBtn *runButton; + const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; + double rotation, angle, count, temp = 0.0, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode, afeDiag0, afeDiag1, afeDiag2; @@ -192,119 +189,134 @@ public Q_SLOTS: QFuture m_deviceStatusThread, m_acquisitionDataThread, m_acquisitionGraphThread; QFutureWatcher m_deviceStatusWatcher, m_acquisitionDataWatcher, m_acquisitionGraphWatcher; - bool updateChannelValues(); - void updateLineEditValues(); - void updateGeneralSettingEnabled(bool value); - void connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max); - void connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit = ""); - void connectMenuComboToNumber(MenuCombo* menuCombo, double& variable); - void connectMenuComboToNumber(MenuCombo* menuCombo, int& variable); + QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; + + + ToolTemplate* createAcquisitionWidget(); ToolTemplate* createCalibrationWidget(); ToolTemplate* createRegistersWidget(); ToolTemplate* createUtilityWidget(); - void updateLabelValue(QLabel* label, int channelIndex); - void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); - bool updateChannelValue(int channelIndex); - void extractCalibrationData(); - void importCalibrationData(); - void calibrationLogWrite(QString message = ""); - void commandLogWrite(QString message); - int readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value); - int writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); - void applyTextStyle(QWidget *widget, const QString& styleHelperColor = "CH0", bool isBold = false); - void applyLabelStyle(QLabel *widget); - void initializeMotor(); - bool moveMotorToPosition(double& position, bool validate = true); - void resetAllCalibrationState(); - void connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax); - void connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute); - double convertRPStoVMAX(double rps); - double convertVMAXtoRPS(double vmax); - void connectLineEditToAMAXConversion(QLineEdit* lineEdit, double& amax); - void connectRegisterBlockToRegistry(RegisterBlockWidget* widget); - double convertAccelTimetoAMAX(double accelTime); - double convertAMAXtoAccelTime(double amax); - void updateCalculatedCoeffAngle(); - void resetCalculatedCoeffAngle(); - void applyTabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor = "ScopyBlue"); - MenuControlButton *createStatusLEDWidget(const QString title, QColor color, QWidget *parent = nullptr); - MenuControlButton *createChannelToggleWidget(const QString title, QColor color, QWidget *parent = nullptr); - void updateDigioMonitor(); - void updateMTDiagRegister(); - void updateFaultRegister(); - void updateMTDiagnostics(); - void changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked = true); + + void readDeviceProperties(); + bool readSequence(); + void applySequence(); bool changeCNVPage(uint32_t page); - void toggleWidget(QPushButton *widget, bool value); - void GMRReset(); + void initializeMotor(); + void getDeviceFaultStatus(int sampleRate); + + #pragma region Acquisition Methods + bool updateChannelValues(); void updateCountValue(); - void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel); - void readDeviceProperties(); - void toggleAllDIGIOEN(bool value); - void toggleUtilityTask(bool run); - void toggleDIGIOEN(string DIGIOENName, bool& value); + void updateLineEditValues(); + void startAcquisition(); + void startAcquisitionDeviceStatusMonitor(); + void getAcquisitionSamples(int sampleRate); + double getAcquisitionParameterValue(const AcquisitionDataKey &key); + void plotAcquisition(QVector& list, PlotChannel* channel); + void prependAcquisitionData(const double& data, QVector& list); + void resetAcquisitionYAxisScale(); + void acquisitionPlotTask(int sampleRate); + void acquisitionUITask(); + void updateSequenceWidget(); + void updateGeneralSettingEnabled(bool value); + void connectCheckBoxToAcquisitionGraph(QCheckBox* widget, PlotChannel* channel, AcquisitionDataKey key); + void GMRReset(); + #pragma endregion + + #pragma region Calibration Methods + void startCalibrationDeviceStatusMonitor(); + void calibrationUITask(); void getCalibrationSamples(); void startMotor(); - void computeSineCosineOfAngles(QVector graphDataList); + void startMotorContinuous(); void postCalibrateData(); - void canStartMotor(bool value); - bool resetCurrentPositionToZero(); + void resetAllCalibrationState(); + void computeSineCosineOfAngles(QVector graphDataList); + void populateAngleErrorGraphs(); + void populateCorrectedAngleErrorGraphs(); void flashHarmonicValues(); + void calculateHarmonicValues(); + void updateCalculatedCoeffAngle(); void updateCalculatedCoeffHex(); + void resetCalculatedCoeffAngle(); void resetCalculatedCoeffHex(); void displayCalculatedCoeff(); + void calibrationLogWrite(QString message = ""); + void importCalibrationData(); + void extractCalibrationData(); + void toggleTabSwitching(bool value); + void canStartMotor(bool value); + void canCalibrate(bool); void toggleMotorControls(bool value); void clearCalibrationSamples(); - void updateSequenceWidget(); - void toggleFaultRegisterMode(int mode); - void startAcquisition(); - void getAcquisitionSamples(int sampleRate); - void acquisitionUITask(); - void acquisitionPlotTask(int sampleRate); - void toggleMTDiagnostics(int mode); - void toggleSequenceModeRegisters(int mode); - void readAllRegisters(); - void prependAcquisitionData(const double& data, QVector& list); - void plotAcquisition(QVector& list, PlotChannel* channel); - void populateAngleErrorGraphs(); - void populateCorrectedAngleErrorGraphs(); - void resetDIGIO(); - bool updateDIGIOToggle(); + void clearCalibrationSineCosine(); void clearPostCalibrationSamples(); void clearAngleErrorGraphs(); void clearCorrectedAngleErrorGraphs(); - void clearCalibrationSineCosine(); - void connectCheckBoxToAcquisitionGraph(QCheckBox* widget, PlotChannel* channel, AcquisitionDataKey key); - void prependNullAcquisitionData(QVector& list); - void startMotorContinuous(); - void stopMotor(); - void calculateHarmonicValues(); - void connectLineEditToDouble(QLineEdit* lineEdit, double& variable); - void updateLineEditValue(QLineEdit* lineEdit, double value); - void toggleTabSwitching(bool value); - double getAcquisitionParameterValue(const AcquisitionDataKey &key); - void resetYAxisScale(); - void getDeviceFaultStatus(int sampleRate); - void startAcquisitionDeviceStatusMonitor(); - void startCalibrationDeviceStatusMonitor(); - void updateFaultStatusLEDColor(MenuControlButton *widget, bool value); - void calibrationUITask(); + #pragma endregion - QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; + #pragma region Motor Methods + bool moveMotorToPosition(double& position, bool validate = true); + bool resetCurrentPositionToZero(); + void stopMotor(); + int readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value); + int writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); + #pragma endregion - int uuid = 0; - const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; -}; + #pragma region Utility Methods + void utilityTask(); + void toggleUtilityTask(bool run); + void updateDigioMonitor(); + bool updateDIGIOToggle(); + void updateMTDiagnostics(); + void updateMTDiagRegister(); + void updateFaultRegister(); + void toggleDIGIOEN(string DIGIOENName, bool& value); + void toggleAllDIGIOEN(bool value); + void toggleMTDiagnostics(int mode); + void toggleFaultRegisterMode(int mode); + void resetDIGIO(); + void commandLogWrite(QString message); + void clearCommandLog(); + #pragma endregion -enum TABS -{ - ACQUISITION = 0, - UTILITIES = 1, - CALIBRATION = 2, -}; + #pragma region Register Methods + void readAllRegisters(); + void toggleRegisters(int mode); + #pragma endregion + #pragma region UI Helper Methods + void updateLabelValue(QLabel* label, int channelIndex); + void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); + bool updateChannelValue(int channelIndex); + void updateLineEditValue(QLineEdit* lineEdit, double value); + void toggleWidget(QPushButton *widget, bool value); + void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel); + void changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked = true); + void updateFaultStatusLEDColor(MenuControlButton *widget, bool value); + MenuControlButton *createStatusLEDWidget(const QString title, QColor color, QWidget *parent = nullptr); + MenuControlButton *createChannelToggleWidget(const QString title, QColor color, QWidget *parent = nullptr); + #pragma endregion + #pragma region Connect Methods + void connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max); + void connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit = ""); + void connectLineEditToDouble(QLineEdit* lineEdit, double& variable); + void connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute); + void connectMenuComboToNumber(MenuCombo* menuCombo, double& variable); + void connectMenuComboToNumber(MenuCombo* menuCombo, int& variable); + void connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax); + void connectLineEditToAMAXConversion(QLineEdit* lineEdit, double& amax); + void connectRegisterBlockToRegistry(RegisterBlockWidget* widget); + #pragma endregion + #pragma region Convert Methods + double convertRPStoVMAX(double rps); + double convertVMAXtoRPS(double vmax); + double convertAccelTimetoAMAX(double accelTime); + double convertAMAXtoAccelTime(double amax); + #pragma endregion +}; } // namespace admt } // namespace scopy #endif // HARMONICCALIBRATION_H diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp index bfc64036d3..982547efbd 100644 --- a/plugins/admt/src/admtstylehelper.cpp +++ b/plugins/admt/src/admtstylehelper.cpp @@ -232,4 +232,140 @@ void ADMTStyleHelper::StartButtonStyle(QPushButton *btn, QString objectName) btn->setIconSize(QSize(64, 64)); } +void ADMTStyleHelper::TabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + QString style = QString(R"css( + QTabWidget::tab-bar { + left: 5px; /* move to the right by 5px */ + } + QTabBar::tab { + min-width: 100px; + min-height: 32px; + padding-bottom: 5px; + padding-left: 16px; + padding-right: 16px; + background-color: &&UIElementBackground&&; + font: normal; + } + QTabBar::tab:selected { + color: white; + border-bottom: 2px solid &&ScopyBlue&&; + margin-top: 0px; + } + )css"); + style.replace("&&ScopyBlue&&", StyleHelper::getColor(styleHelperColor)); + style.replace("&&UIElementBackground&&", StyleHelper::getColor("UIElementBackground")); + widget->tabBar()->setStyleSheet(style); +} + +void ADMTStyleHelper::TextStyle(QWidget *widget, const QString& styleHelperColor, bool isBold, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + QString existingStyle = widget->styleSheet(); + QString style = QString(R"css( + font-family: Open Sans; + font-size: 16px; + font-weight: &&fontweight&&; + text-align: right; + color: &&colorname&&; + )css"); + style = style.replace(QString("&&colorname&&"), StyleHelper::getColor(styleHelperColor)); + QString fontWeight = QString("normal"); + if(isBold){ + fontWeight = QString("bold"); + } + style = style.replace(QString("&&fontweight&&"), fontWeight); + widget->setStyleSheet(existingStyle + style); +} + +void ADMTStyleHelper::MenuSmallLabel(QLabel *label, QString objectName) +{ + if(!objectName.isEmpty()) + label->setObjectName(objectName); + label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + QString style = QString(R"css( + QLabel { + color: white; + background-color: rgba(255,255,255,0); + font-weight: 500; + font-family: Open Sans; + font-size: 12px; + font-style: normal; + } + QLabel:disabled { + color: grey; + } + )css"); + label->setStyleSheet(style); +} + +void ADMTStyleHelper::LineStyle(QFrame *line, QString objectName) +{ + if(!objectName.isEmpty()) + line->setObjectName(objectName); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Plain); + line->setFixedHeight(1); + QString lineStyle = QString(R"css( + QFrame { + border: 1px solid #808085; + } + )css"); + line->setStyleSheet(lineStyle); +} + +void ADMTStyleHelper::UIBackgroundStyle(QWidget *widget, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + QString style = QString(R"css( + background-color: &&colorname&&; + )css"); + style.replace(QString("&&colorname&&"), StyleHelper::getColor("UIElementBackground")); + widget->setStyleSheet(style); +} + +void ADMTStyleHelper::GraphChannelStyle(QWidget *widget, QLayout *layout, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + widget->setLayout(layout); + ADMTStyleHelper::UIBackgroundStyle(widget); + layout->setContentsMargins(20, 13, 20, 5); + layout->setSpacing(20); +} + +void ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(QWidget *widget, QHBoxLayout *layout, QLabel *hLabel, QLabel *hMagLabel, QLabel *hPhaseLabel, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + + widget->setLayout(layout); + QString style = QString(R"css( + background-color: &&colorname&&; + border-radius: 4px; + )css"); + style.replace(QString("&&colorname&&"), StyleHelper::getColor("ScopyBackground")); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + layout->setContentsMargins(12, 4, 12, 4); + + ADMTStyleHelper::TextStyle(hLabel, "LabelText", true); + ADMTStyleHelper::TextStyle(hMagLabel, "CH0"); + ADMTStyleHelper::TextStyle(hPhaseLabel, "CH1"); + + hLabel->setFixedWidth(24); + hMagLabel->setContentsMargins(0, 0, 32, 0); + hPhaseLabel->setFixedWidth(72); + + layout->addWidget(hLabel); + layout->addWidget(hMagLabel, 0, Qt::AlignRight); + layout->addWidget(hPhaseLabel); +} + #include "moc_admtstylehelper.cpp" \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 449fc06783..01d72e7a17 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -125,18 +125,80 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QHBoxLayout *lay = new QHBoxLayout(this); - tool = new ToolTemplate(this); + tabWidget = new QTabWidget(this); + setLayout(lay); lay->setMargin(0); - tabWidget = new QTabWidget(this); - tabWidget->addTab(tool, "Acquisition"); + lay->insertWidget(1, tabWidget); + tabWidget->addTab(createAcquisitionWidget(), "Acquisition"); + tabWidget->addTab(createCalibrationWidget(), "Calibration"); + tabWidget->addTab(createUtilityWidget(), "Utility"); + tabWidget->addTab(createRegistersWidget(), "Registers"); + + connect(tabWidget, &QTabWidget::currentChanged, [=](int index){ + tabWidget->setCurrentIndex(index); + + if(index == 0 || index == 1) + { + if(isDeviceStatusMonitor) isDeviceStatusMonitor = false; + + if(index == 0) startAcquisitionDeviceStatusMonitor(); + else startCalibrationDeviceStatusMonitor(); + } + else{ + isDeviceStatusMonitor = false; + } + + if(index == 0) // Acquisition Tab + { + acquisitionUITimer->start(acquisitionUITimerRate); + readSequence(); + } + else + { + acquisitionUITimer->stop(); + stop(); + } - openLastMenuButton = new OpenLastMenuBtn(dynamic_cast(tool->rightContainer()), true, this); + if(index == 1) // Calibration Tab + { + calibrationUITimer->start(calibrationUITimerRate); + } + else + { + calibrationUITimer->stop(); + } + + if(index == 2) // Utility Tab + { + utilityTimer->start(utilityTimerRate); + readSequence(); + toggleFaultRegisterMode(generalRegisterMap.at("Sequence Type")); + toggleMTDiagnostics(generalRegisterMap.at("Sequence Type")); + updateDIGIOToggle(); + } + else { utilityTimer->stop(); } + + if(index == 3) // Registers Tab + { + readSequence(); + toggleRegisters(generalRegisterMap.at("Sequence Type")); + } + }); + + acquisitionUITimer->start(acquisitionUITimerRate); + startAcquisitionDeviceStatusMonitor(); +} + +HarmonicCalibration::~HarmonicCalibration() {} + +ToolTemplate* HarmonicCalibration::createAcquisitionWidget() +{ + tool = new ToolTemplate(this); + openLastMenuButton = new OpenLastMenuBtn(dynamic_cast(tool->rightContainer()), true, this); rightMenuButtonGroup = dynamic_cast(openLastMenuButton)->getButtonGroup(); settingsButton = new GearBtn(this); - lay->insertWidget(1, tabWidget); - runButton = new RunBtn(this); QPushButton *resetGMRButton = new QPushButton(this); @@ -406,7 +468,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool QPushButton *resetYAxisButton = new QPushButton("Reset Y-Axis Scale", generalSection); StyleHelper::BlueButton(resetYAxisButton, "resetYAxisButton"); - connect(resetYAxisButton, &QPushButton::clicked, this, &HarmonicCalibration::resetYAxisScale); + connect(resetYAxisButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAcquisitionYAxisScale); generalSection->contentLayout()->addWidget(graphUpdateIntervalLabel); generalSection->contentLayout()->addWidget(graphUpdateIntervalLineEdit); @@ -528,337 +590,103 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool utilityTimer = new QTimer(this); connect(utilityTimer, &QTimer::timeout, this, &HarmonicCalibration::utilityTask); - tabWidget->addTab(createCalibrationWidget(), "Calibration"); - tabWidget->addTab(createUtilityWidget(), "Utility"); - tabWidget->addTab(createRegistersWidget(), "Registers"); + return tool; +} - connect(tabWidget, &QTabWidget::currentChanged, [=](int index){ - tabWidget->setCurrentIndex(index); +ToolTemplate* HarmonicCalibration::createCalibrationWidget() +{ + ToolTemplate *tool = new ToolTemplate(this); - if(index == 0 || index == 1) - { - if(isDeviceStatusMonitor) isDeviceStatusMonitor = false; + #pragma region Calibration Data Graph Widget + QWidget *calibrationDataGraphWidget = new QWidget(); + QGridLayout *calibrationDataGraphLayout = new QGridLayout(calibrationDataGraphWidget); + calibrationDataGraphWidget->setLayout(calibrationDataGraphLayout); + calibrationDataGraphLayout->setMargin(0); + calibrationDataGraphLayout->setSpacing(5); - if(index == 0) startAcquisitionDeviceStatusMonitor(); - else startCalibrationDeviceStatusMonitor(); - } - else{ - isDeviceStatusMonitor = false; - } + MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); + calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); + ADMTStyleHelper::TabWidgetStyle(calibrationDataGraphTabWidget); + calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); + calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); - if(index == 0) // Acquisition Tab - { - acquisitionUITimer->start(acquisitionUITimerRate); - readSequence(); - } - else - { - acquisitionUITimer->stop(); - stop(); - } + #pragma region Calibration Samples + QWidget *calibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); + QVBoxLayout *calibrationSamplesLayout = new QVBoxLayout(calibrationSamplesWidget); + calibrationSamplesWidget->setLayout(calibrationSamplesLayout); + calibrationSamplesLayout->setMargin(0); + calibrationSamplesLayout->setSpacing(0); - if(index == 1) // Calibration Tab - { - calibrationUITimer->start(calibrationUITimerRate); - } - else - { - calibrationUITimer->stop(); - } + calibrationRawDataPlotWidget = new PlotWidget(); + ADMTStyleHelper::PlotWidgetStyle(calibrationRawDataPlotWidget); - if(index == 2) // Utility Tab - { - utilityTimer->start(utilityTimerRate); - readSequence(); - toggleFaultRegisterMode(generalRegisterMap.at("Sequence Type")); - toggleMTDiagnostics(generalRegisterMap.at("Sequence Type")); - updateDIGIOToggle(); - } - else { utilityTimer->stop(); } + calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, scopyBluePen); + calibrationRawDataXPlotAxis->setMin(0); + calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, scopyBluePen); + calibrationRawDataYPlotAxis->setInterval(0, 360); - if(index == 3) // Registers Tab - { - readSequence(); - toggleSequenceModeRegisters(generalRegisterMap.at("Sequence Type")); - } - }); + calibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + calibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + calibrationCosineDataPlotChannel = new PlotChannel("Cosine", cosinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - acquisitionUITimer->start(acquisitionUITimerRate); - startAcquisitionDeviceStatusMonitor(); -} + calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); + calibrationRawDataPlotWidget->addPlotChannel(calibrationSineDataPlotChannel); + calibrationRawDataPlotWidget->addPlotChannel(calibrationCosineDataPlotChannel); + calibrationSineDataPlotChannel->setEnabled(true); + calibrationCosineDataPlotChannel->setEnabled(true); + calibrationRawDataPlotChannel->setEnabled(true); + calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); -HarmonicCalibration::~HarmonicCalibration() {} + calibrationRawDataPlotWidget->setShowXAxisLabels(true); + calibrationRawDataPlotWidget->setShowYAxisLabels(true); + calibrationRawDataPlotWidget->showAxisLabels(); -void HarmonicCalibration::startAcquisitionDeviceStatusMonitor() -{ - isDeviceStatusMonitor = true; - m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); - m_deviceStatusWatcher.setFuture(m_deviceStatusThread); -} + calibrationRawDataPlotWidget->replot(); -void HarmonicCalibration::startCalibrationDeviceStatusMonitor() -{ - isDeviceStatusMonitor = true; - m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); - m_deviceStatusWatcher.setFuture(m_deviceStatusThread); -} + QWidget *calibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); + ADMTStyleHelper::UIBackgroundStyle(calibrationDataGraphChannelsWidget); + QHBoxLayout *calibrationDataGraphChannelsLayout = new QHBoxLayout(calibrationDataGraphChannelsWidget); + calibrationDataGraphChannelsWidget->setLayout(calibrationDataGraphChannelsLayout); + calibrationDataGraphChannelsLayout->setContentsMargins(20, 13, 20, 5); + calibrationDataGraphChannelsLayout->setSpacing(20); + + MenuControlButton *toggleAngleButton = createChannelToggleWidget("Angle", scopyBlueColor, calibrationDataGraphChannelsWidget); + MenuControlButton *toggleSineButton = createChannelToggleWidget("Sine", sineColor, calibrationDataGraphChannelsWidget); + MenuControlButton *toggleCosineButton = createChannelToggleWidget("Cosine", cosineColor, calibrationDataGraphChannelsWidget); -void HarmonicCalibration::resetYAxisScale() -{ - acquisitionGraphYMin = 0; - acquisitionGraphYMax = 360; - acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); - acquisitionGraphPlotWidget->replot(); -} + calibrationDataGraphChannelsLayout->addWidget(toggleAngleButton); + calibrationDataGraphChannelsLayout->addWidget(toggleSineButton); + calibrationDataGraphChannelsLayout->addWidget(toggleCosineButton); + calibrationDataGraphChannelsLayout->addStretch(); -void HarmonicCalibration::startAcquisition() -{ - isStartAcquisition = true; - acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); + calibrationSamplesLayout->addWidget(calibrationRawDataPlotWidget); + calibrationSamplesLayout->addWidget(calibrationDataGraphChannelsWidget); + #pragma endregion - m_acquisitionDataThread = QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples, acquisitionSampleRate); - m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); - m_acquisitionGraphThread = QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, acquisitionGraphSampleRate); - m_acquisitionGraphWatcher.setFuture(m_acquisitionGraphThread); -} + #pragma region Post Calibration Samples + QWidget *postCalibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); + QVBoxLayout *postCalibrationSamplesLayout = new QVBoxLayout(postCalibrationSamplesWidget); + postCalibrationSamplesWidget->setLayout(postCalibrationSamplesLayout); + postCalibrationSamplesLayout->setMargin(0); + postCalibrationSamplesLayout->setSpacing(0); -void HarmonicCalibration::getAcquisitionSamples(int sampleRate) -{ - while(isStartAcquisition) - { - if(!updateChannelValues()) { break; } + postCalibrationRawDataPlotWidget = new PlotWidget(); + ADMTStyleHelper::PlotWidgetStyle(postCalibrationRawDataPlotWidget); + postCalibrationRawDataPlotWidget->xAxis()->setVisible(false); + postCalibrationRawDataPlotWidget->yAxis()->setVisible(false); - if(acquisitionDataMap.at(ANGLE) == false && acquisitionAngleList.size() > 0) acquisitionAngleList.clear(); - if(acquisitionDataMap.at(ABSANGLE) == false && acquisitionABSAngleList.size() > 0) acquisitionABSAngleList.clear(); - if(acquisitionDataMap.at(TURNCOUNT) == false && acquisitionTurnCountList.size() > 0) acquisitionTurnCountList.clear(); - if(acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) acquisitionTmp0List.clear(); - if(acquisitionDataMap.at(SINE) == false && acquisitionSineList.size() > 0) acquisitionSineList.clear(); - if(acquisitionDataMap.at(COSINE) == false && acquisitionCosineList.size() > 0) acquisitionCosineList.clear(); - if(acquisitionDataMap.at(RADIUS) == false && acquisitionRadiusList.size() > 0) acquisitionRadiusList.clear(); + postCalibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, postCalibrationRawDataPlotWidget, scopyBluePen); + postCalibrationRawDataXPlotAxis->setMin(0); + postCalibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, postCalibrationRawDataPlotWidget, scopyBluePen); + postCalibrationRawDataYPlotAxis->setInterval(0, 360); - if(acquisitionDataMap.at(ANGLE)) prependAcquisitionData(angle, acquisitionAngleList); - if(acquisitionDataMap.at(ABSANGLE)) prependAcquisitionData(rotation, acquisitionABSAngleList); - if(acquisitionDataMap.at(TURNCOUNT)) prependAcquisitionData(count, acquisitionTurnCountList); - if(acquisitionDataMap.at(TMP0)) prependAcquisitionData(temp, acquisitionTmp0List); - if(acquisitionDataMap.at(SINE)) prependAcquisitionData(getAcquisitionParameterValue(SINE), acquisitionSineList); - if(acquisitionDataMap.at(COSINE)) prependAcquisitionData(getAcquisitionParameterValue(COSINE), acquisitionCosineList); - if(acquisitionDataMap.at(RADIUS)) prependAcquisitionData(getAcquisitionParameterValue(RADIUS), acquisitionRadiusList); + postCalibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); + postCalibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); + postCalibrationCosineDataPlotChannel = new PlotChannel("Cosine", cosinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); - QThread::msleep(sampleRate); - } -} - -double HarmonicCalibration::getAcquisitionParameterValue(const AcquisitionDataKey &key) -{ - uint32_t *readValue = new uint32_t; - switch(key) - { - case SINE: - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(ADMTController::SensorRegister::SINE), - readValue) == -1) return qQNaN(); - map sineRegisterMap = m_admtController->getSineRegisterBitMapping(static_cast(*readValue)); - return sineRegisterMap.at("SINE"); - break; - } - case COSINE: - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(ADMTController::SensorRegister::COSINE), - readValue) == -1) return qQNaN(); - map cosineRegisterMap = m_admtController->getCosineRegisterBitMapping(static_cast(*readValue)); - return cosineRegisterMap.at("COSINE"); - break; - } - case RADIUS: - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(ADMTController::SensorRegister::RADIUS), - readValue) == -1) return qQNaN(); - map radiusRegisterMap = m_admtController->getRadiusRegisterBitMapping(static_cast(*readValue)); - return radiusRegisterMap.at("RADIUS"); - break; - } - default: - return qQNaN(); - break; - } -} - -void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) -{ - while(isDeviceStatusMonitor) - { - uint32_t *readValue = new uint32_t; - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), 0) == 0) - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), readValue) == 0) - { - deviceStatusFault = m_admtController->checkRegisterFault(static_cast(*readValue), generalRegisterMap.at("Sequence Type") == 0 ? true : false); - } - else - { - deviceStatusFault = true; - } - } - else - { - deviceStatusFault = true; - } - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::prependAcquisitionData(const double& data, QVector& list) -{ - list.prepend(data); - if(list.size() >= acquisitionDisplayLength){ - list.resize(acquisitionDisplayLength); - list.squeeze(); - } -} - -void HarmonicCalibration::prependNullAcquisitionData(QVector& list) -{ - list.prepend(qQNaN()); -} - -void HarmonicCalibration::plotAcquisition(QVector& list, PlotChannel* channel) -{ - channel->curve()->setSamples(list); - auto result = std::minmax_element(list.begin(), list.end()); - if(*result.first < acquisitionGraphYMin) acquisitionGraphYMin = *result.first; - if(*result.second > acquisitionGraphYMax) acquisitionGraphYMax = *result.second; -} - -void HarmonicCalibration::initializeMotor() -{ - rotate_vmax = 53687.0912; - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - - amax = 439.8046511104; - writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - - dmax = 3000; - writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - - ramp_mode = 0; - writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - - target_pos = 0; - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - - current_pos = 0; - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); -} - -ToolTemplate* HarmonicCalibration::createCalibrationWidget() -{ - ToolTemplate *tool = new ToolTemplate(this); - - #pragma region Calibration Data Graph Widget - QWidget *calibrationDataGraphWidget = new QWidget(); - QGridLayout *calibrationDataGraphLayout = new QGridLayout(calibrationDataGraphWidget); - calibrationDataGraphWidget->setLayout(calibrationDataGraphLayout); - calibrationDataGraphLayout->setMargin(0); - calibrationDataGraphLayout->setSpacing(5); - - MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); - calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); - applyTabWidgetStyle(calibrationDataGraphTabWidget); - calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); - calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); - - #pragma region Calibration Samples - QWidget *calibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); - QVBoxLayout *calibrationSamplesLayout = new QVBoxLayout(calibrationSamplesWidget); - calibrationSamplesWidget->setLayout(calibrationSamplesLayout); - calibrationSamplesLayout->setMargin(0); - calibrationSamplesLayout->setSpacing(0); - - calibrationRawDataPlotWidget = new PlotWidget(); - ADMTStyleHelper::PlotWidgetStyle(calibrationRawDataPlotWidget); - - calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, scopyBluePen); - calibrationRawDataXPlotAxis->setMin(0); - calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, scopyBluePen); - calibrationRawDataYPlotAxis->setInterval(0, 360); - - calibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - calibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - calibrationCosineDataPlotChannel = new PlotChannel("Cosine", cosinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - - calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); - calibrationRawDataPlotWidget->addPlotChannel(calibrationSineDataPlotChannel); - calibrationRawDataPlotWidget->addPlotChannel(calibrationCosineDataPlotChannel); - calibrationSineDataPlotChannel->setEnabled(true); - calibrationCosineDataPlotChannel->setEnabled(true); - calibrationRawDataPlotChannel->setEnabled(true); - calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); - - calibrationRawDataPlotWidget->setShowXAxisLabels(true); - calibrationRawDataPlotWidget->setShowYAxisLabels(true); - calibrationRawDataPlotWidget->showAxisLabels(); - - calibrationRawDataPlotWidget->replot(); - - QWidget *calibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); - QHBoxLayout *calibrationDataGraphChannelsLayout = new QHBoxLayout(calibrationDataGraphChannelsWidget); - calibrationDataGraphChannelsWidget->setLayout(calibrationDataGraphChannelsLayout); - QString calibrationDataGraphChannelsStyle = QString(R"css( - background-color: &&colorname&&; - )css"); - calibrationDataGraphChannelsStyle.replace(QString("&&colorname&&"), StyleHelper::getColor("UIElementBackground")); - calibrationDataGraphChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); - calibrationDataGraphChannelsLayout->setContentsMargins(20, 13, 20, 5); - calibrationDataGraphChannelsLayout->setSpacing(20); - - MenuControlButton *toggleAngleButton = createChannelToggleWidget("Angle", scopyBlueColor, calibrationDataGraphChannelsWidget); - MenuControlButton *toggleSineButton = createChannelToggleWidget("Sine", sineColor, calibrationDataGraphChannelsWidget); - MenuControlButton *toggleCosineButton = createChannelToggleWidget("Cosine", cosineColor, calibrationDataGraphChannelsWidget); - - calibrationDataGraphChannelsLayout->addWidget(toggleAngleButton); - calibrationDataGraphChannelsLayout->addWidget(toggleSineButton); - calibrationDataGraphChannelsLayout->addWidget(toggleCosineButton); - calibrationDataGraphChannelsLayout->addStretch(); - - calibrationSamplesLayout->addWidget(calibrationRawDataPlotWidget); - calibrationSamplesLayout->addWidget(calibrationDataGraphChannelsWidget); - #pragma endregion - - #pragma region Post Calibration Samples - QWidget *postCalibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); - QVBoxLayout *postCalibrationSamplesLayout = new QVBoxLayout(postCalibrationSamplesWidget); - postCalibrationSamplesWidget->setLayout(postCalibrationSamplesLayout); - postCalibrationSamplesLayout->setMargin(0); - postCalibrationSamplesLayout->setSpacing(0); - - postCalibrationRawDataPlotWidget = new PlotWidget(); - ADMTStyleHelper::PlotWidgetStyle(postCalibrationRawDataPlotWidget); - postCalibrationRawDataPlotWidget->xAxis()->setVisible(false); - postCalibrationRawDataPlotWidget->yAxis()->setVisible(false); - - postCalibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, postCalibrationRawDataPlotWidget, scopyBluePen); - postCalibrationRawDataXPlotAxis->setMin(0); - postCalibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, postCalibrationRawDataPlotWidget, scopyBluePen); - postCalibrationRawDataYPlotAxis->setInterval(0, 360); - - postCalibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); - postCalibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); - postCalibrationCosineDataPlotChannel = new PlotChannel("Cosine", cosinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); - - postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationRawDataPlotChannel); - postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationSineDataPlotChannel); - postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationCosineDataPlotChannel); + postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationRawDataPlotChannel); + postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationSineDataPlotChannel); + postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationCosineDataPlotChannel); postCalibrationSineDataPlotChannel->setEnabled(true); postCalibrationCosineDataPlotChannel->setEnabled(true); @@ -872,10 +700,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QWidget *postCalibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); QHBoxLayout *postCalibrationDataGraphChannelsLayout = new QHBoxLayout(postCalibrationDataGraphChannelsWidget); - postCalibrationDataGraphChannelsWidget->setLayout(postCalibrationDataGraphChannelsLayout); - postCalibrationDataGraphChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); - postCalibrationDataGraphChannelsLayout->setContentsMargins(20, 13, 20, 5); - postCalibrationDataGraphChannelsLayout->setSpacing(20); + ADMTStyleHelper::GraphChannelStyle(postCalibrationDataGraphChannelsWidget, postCalibrationDataGraphChannelsLayout); MenuControlButton *togglePostAngleButton = createChannelToggleWidget("Angle", scopyBlueColor, postCalibrationDataGraphChannelsWidget); MenuControlButton *togglePostSineButton = createChannelToggleWidget("Sine", sineColor, postCalibrationDataGraphChannelsWidget); @@ -895,7 +720,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() MenuSectionWidget *resultDataSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); resultDataTabWidget = new QTabWidget(resultDataSectionWidget); - applyTabWidgetStyle(resultDataTabWidget); + ADMTStyleHelper::TabWidgetStyle(resultDataTabWidget); resultDataSectionWidget->contentLayout()->setSpacing(8); resultDataSectionWidget->contentLayout()->addWidget(resultDataTabWidget); @@ -966,10 +791,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QWidget *FFTAngleErrorChannelsWidget = new QWidget(); QHBoxLayout *FFTAngleErrorChannelsLayout = new QHBoxLayout(FFTAngleErrorChannelsWidget); - FFTAngleErrorChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); - FFTAngleErrorChannelsWidget->setLayout(FFTAngleErrorChannelsLayout); - FFTAngleErrorChannelsLayout->setContentsMargins(20, 13, 20, 5); - FFTAngleErrorChannelsLayout->setSpacing(20); + ADMTStyleHelper::GraphChannelStyle(FFTAngleErrorChannelsWidget, FFTAngleErrorChannelsLayout); MenuControlButton *toggleFFTAngleErrorMagnitudeButton = createChannelToggleWidget("Magnitude", QColor(StyleHelper::getColor("CH0")), FFTAngleErrorChannelsWidget); MenuControlButton *toggleFFTAngleErrorPhaseButton = createChannelToggleWidget("Phase", QColor(StyleHelper::getColor("CH1")), FFTAngleErrorChannelsWidget); @@ -1046,9 +868,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QWidget *FFTCorrectedErrorChannelsWidget = new QWidget(); QHBoxLayout *FFTCorrectedErrorChannelsLayout = new QHBoxLayout(FFTCorrectedErrorChannelsWidget); - FFTCorrectedErrorChannelsWidget->setStyleSheet(calibrationDataGraphChannelsStyle); - FFTCorrectedErrorChannelsLayout->setContentsMargins(20, 13, 20, 5); - FFTCorrectedErrorChannelsLayout->setSpacing(20); + ADMTStyleHelper::GraphChannelStyle(FFTCorrectedErrorChannelsWidget, FFTCorrectedErrorChannelsLayout); MenuControlButton *toggleFFTCorrectedErrorMagnitudeButton = createChannelToggleWidget("Magnitude", QColor(StyleHelper::getColor("CH0")), FFTCorrectedErrorChannelsWidget); MenuControlButton *toggleFFTCorrectedErrorPhaseButton = createChannelToggleWidget("Phase", QColor(StyleHelper::getColor("CH1")), FFTCorrectedErrorChannelsWidget); @@ -1167,111 +987,41 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDisplayFormatSwitch->setOnText("Angle"); calibrationDisplayFormatSwitch->setProperty("bigBtn", true); - // Calculated Coefficients Widget QWidget *calibrationCalculatedCoeffWidget = new QWidget(calibrationCoeffSectionWidget); QGridLayout *calibrationCalculatedCoeffLayout = new QGridLayout(calibrationCalculatedCoeffWidget); + calibrationCalculatedCoeffWidget->setLayout(calibrationCalculatedCoeffLayout); calibrationCalculatedCoeffLayout->setMargin(0); calibrationCalculatedCoeffLayout->setVerticalSpacing(4); - QString calibrationCalculatedCoeffStyle = QString(R"css( - background-color: &&colorname&&; - )css"); - calibrationCalculatedCoeffStyle.replace(QString("&&colorname&&"), StyleHelper::getColor("UIElementBackground")); - calibrationCalculatedCoeffWidget->setStyleSheet(calibrationCalculatedCoeffStyle); - - QString rowContainerStyle = QString(R"css( - background-color: &&colorname&&; - border-radius: 4px; - )css"); - rowContainerStyle.replace(QString("&&colorname&&"), StyleHelper::getColor("ScopyBackground")); - - // H1 + ADMTStyleHelper::UIBackgroundStyle(calibrationCalculatedCoeffWidget); + QWidget *h1RowContainer = new QWidget(calibrationCalculatedCoeffWidget); QHBoxLayout *h1RowLayout = new QHBoxLayout(h1RowContainer); - h1RowContainer->setLayout(h1RowLayout); - h1RowContainer->setStyleSheet(rowContainerStyle); - h1RowContainer->setFixedHeight(30); - h1RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - h1RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH1Label = new QLabel("H1", calibrationCalculatedCoeffWidget); calibrationH1MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); calibrationH1PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - applyTextStyle(calibrationH1Label, "LabelText", true); - applyTextStyle(calibrationH1MagLabel, "CH0"); - applyTextStyle(calibrationH1PhaseLabel, "CH1"); - calibrationH1Label->setFixedWidth(24); - calibrationH1MagLabel->setContentsMargins(0, 0, 32, 0); - calibrationH1PhaseLabel->setFixedWidth(72); - - h1RowLayout->addWidget(calibrationH1Label); - h1RowLayout->addWidget(calibrationH1MagLabel, 0, Qt::AlignRight); - h1RowLayout->addWidget(calibrationH1PhaseLabel); - - // H2 + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h1RowContainer, h1RowLayout, calibrationH1Label, calibrationH1MagLabel, calibrationH1PhaseLabel); + QWidget *h2RowContainer = new QWidget(calibrationCalculatedCoeffWidget); QHBoxLayout *h2RowLayout = new QHBoxLayout(h2RowContainer); - h2RowContainer->setLayout(h2RowLayout); - h2RowContainer->setStyleSheet(rowContainerStyle); - h2RowContainer->setFixedHeight(30); - h2RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - h2RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH2Label = new QLabel("H2", calibrationCalculatedCoeffWidget); calibrationH2MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); calibrationH2PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - applyTextStyle(calibrationH2Label, "LabelText", true); - applyTextStyle(calibrationH2MagLabel, "CH0"); - applyTextStyle(calibrationH2PhaseLabel, "CH1"); - calibrationH2Label->setFixedWidth(24); - calibrationH2MagLabel->setContentsMargins(0, 0, 32, 0); - calibrationH2PhaseLabel->setFixedWidth(72); - - h2RowLayout->addWidget(calibrationH2Label); - h2RowLayout->addWidget(calibrationH2MagLabel, 0, Qt::AlignRight); - h2RowLayout->addWidget(calibrationH2PhaseLabel); - - // H3 + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h2RowContainer, h2RowLayout, calibrationH2Label, calibrationH2MagLabel, calibrationH2PhaseLabel); + QWidget *h3RowContainer = new QWidget(calibrationCalculatedCoeffWidget); QHBoxLayout *h3RowLayout = new QHBoxLayout(h3RowContainer); - h3RowContainer->setLayout(h3RowLayout); - h3RowContainer->setStyleSheet(rowContainerStyle); - h3RowContainer->setFixedHeight(30); - h3RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - h3RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH3Label = new QLabel("H3", calibrationCalculatedCoeffWidget); calibrationH3MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); calibrationH3PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - applyTextStyle(calibrationH3Label, "LabelText", true); - applyTextStyle(calibrationH3MagLabel, "CH0"); - applyTextStyle(calibrationH3PhaseLabel, "CH1"); - calibrationH3Label->setFixedWidth(24); - calibrationH3MagLabel->setContentsMargins(0, 0, 32, 0); - calibrationH3PhaseLabel->setFixedWidth(72); - - h3RowLayout->addWidget(calibrationH3Label); - h3RowLayout->addWidget(calibrationH3MagLabel, 0, Qt::AlignRight); - h3RowLayout->addWidget(calibrationH3PhaseLabel); - - // H8 + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h3RowContainer, h3RowLayout, calibrationH3Label, calibrationH3MagLabel, calibrationH3PhaseLabel); + QWidget *h8RowContainer = new QWidget(calibrationCalculatedCoeffWidget); QHBoxLayout *h8RowLayout = new QHBoxLayout(h8RowContainer); - h8RowContainer->setLayout(h8RowLayout); - h8RowContainer->setStyleSheet(rowContainerStyle); - h8RowContainer->setFixedHeight(30); - h8RowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - h8RowLayout->setContentsMargins(12, 4, 12, 4); QLabel *calibrationH8Label = new QLabel("H8", calibrationCalculatedCoeffWidget); calibrationH8MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); calibrationH8PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - applyTextStyle(calibrationH8Label, "LabelText", true); - applyTextStyle(calibrationH8MagLabel, "CH0"); - applyTextStyle(calibrationH8PhaseLabel, "CH1"); - calibrationH8Label->setFixedWidth(24); - calibrationH8MagLabel->setContentsMargins(0, 0, 32, 0); - calibrationH8PhaseLabel->setFixedWidth(72); - - h8RowLayout->addWidget(calibrationH8Label); - h8RowLayout->addWidget(calibrationH8MagLabel, 0, Qt::AlignRight); - h8RowLayout->addWidget(calibrationH8PhaseLabel); + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h8RowContainer, h8RowLayout, calibrationH8Label, calibrationH8MagLabel, calibrationH8PhaseLabel); calibrationCalculatedCoeffLayout->addWidget(h1RowContainer, 0, 0); calibrationCalculatedCoeffLayout->addWidget(h2RowContainer, 1, 0); @@ -1747,20 +1497,6 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() DIGIOControlGridLayout->setMargin(0); DIGIOControlGridLayout->setSpacing(8); - QString labelStyle = QString(R"css( - QLabel { - color: white; - background-color: rgba(255,255,255,0); - font-weight: 500; - font-family: Open Sans; - font-size: 12px; - font-style: normal; - } - QLabel:disabled { - color: grey; - } - )css"); - QLabel *DIGIO0Label = new QLabel("DIGIO0", DIGIOControlGridWidget); QLabel *DIGIO1Label = new QLabel("DIGIO1", DIGIOControlGridWidget); QLabel *DIGIO2Label = new QLabel("DIGIO2", DIGIOControlGridWidget); @@ -1769,13 +1505,13 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() QLabel *DIGIO5Label = new QLabel("DIGIO5", DIGIOControlGridWidget); QLabel *DIGIOALLLabel = new QLabel("All DIGIO Output", DIGIOControlGridWidget); - DIGIO0Label->setStyleSheet(labelStyle); - DIGIO1Label->setStyleSheet(labelStyle); - DIGIO2Label->setStyleSheet(labelStyle); - DIGIO3Label->setStyleSheet(labelStyle); - DIGIO4Label->setStyleSheet(labelStyle); - DIGIO5Label->setStyleSheet(labelStyle); - DIGIOALLLabel->setStyleSheet(labelStyle); + ADMTStyleHelper::MenuSmallLabel(DIGIO0Label); + ADMTStyleHelper::MenuSmallLabel(DIGIO1Label); + ADMTStyleHelper::MenuSmallLabel(DIGIO2Label); + ADMTStyleHelper::MenuSmallLabel(DIGIO3Label); + ADMTStyleHelper::MenuSmallLabel(DIGIO4Label); + ADMTStyleHelper::MenuSmallLabel(DIGIO5Label); + ADMTStyleHelper::MenuSmallLabel(DIGIOALLLabel); DIGIO0ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Enable", "Disable"); @@ -1870,15 +1606,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() DIGIOControlGridLayout->addItem(new QSpacerItem(0, 4, QSizePolicy::Fixed, QSizePolicy::Expanding), 1, 0, 1, 2); QFrame *line = new QFrame(); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Plain); - line->setFixedHeight(1); - QString lineStyle = QString(R"css( - QFrame { - border: 1px solid #808085; - } - )css"); - line->setStyleSheet(lineStyle); + ADMTStyleHelper::LineStyle(line); DIGIOControlGridLayout->addWidget(line, 2, 0, 1, 2); DIGIOControlGridLayout->addItem(new QSpacerItem(0, 4, QSizePolicy::Fixed, QSizePolicy::Expanding), 3, 0, 1, 3); @@ -2052,355 +1780,328 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() return tool; } -void HarmonicCalibration::resetDIGIO() +void HarmonicCalibration::readDeviceProperties() { - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - 0x241b); -} + uint32_t *uniqId3RegisterValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t page = m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3); + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); -void HarmonicCalibration::readAllRegisters() -{ - readAllRegistersButton->setEnabled(false); - readAllRegistersButton->setText(QString("Reading Registers...")); - QTimer::singleShot(1000, this, [this](){ - readAllRegistersButton->setEnabled(true); - readAllRegistersButton->setText(QString("Read All Registers")); - }); + bool success = false; - cnvPageRegisterBlock->readButton()->click(); - digIORegisterBlock->readButton()->click(); - faultRegisterBlock->readButton()->click(); - generalRegisterBlock->readButton()->click(); - digIOEnRegisterBlock->readButton()->click(); - eccDcdeRegisterBlock->readButton()->click(); - eccDisRegisterBlock->readButton()->click(); - absAngleRegisterBlock->readButton()->click(); - angleRegisterBlock->readButton()->click(); - sineRegisterBlock->readButton()->click(); - cosineRegisterBlock->readButton()->click(); - tmp0RegisterBlock->readButton()->click(); - cnvCntRegisterBlock->readButton()->click(); - uniqID0RegisterBlock->readButton()->click(); - uniqID1RegisterBlock->readButton()->click(); - uniqID2RegisterBlock->readButton()->click(); - uniqID3RegisterBlock->readButton()->click(); - h1MagRegisterBlock->readButton()->click(); - h1PhRegisterBlock->readButton()->click(); - h2MagRegisterBlock->readButton()->click(); - h2PhRegisterBlock->readButton()->click(); - h3MagRegisterBlock->readButton()->click(); - h3PhRegisterBlock->readButton()->click(); - h8MagRegisterBlock->readButton()->click(); - h8PhRegisterBlock->readButton()->click(); + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, page) != -1){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ + if(*cnvPageRegValue == page){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID3), uniqId3RegisterValue) != -1){ + deviceRegisterMap = m_admtController->getUNIQID3RegisterMapping(static_cast(*uniqId3RegisterValue)); - if(generalRegisterMap.at("Sequence Type") == 1){ - angleSecRegisterBlock->readButton()->click(); - secAnglIRegisterBlock->readButton()->click(); - secAnglQRegisterBlock->readButton()->click(); - tmp1RegisterBlock->readButton()->click(); - angleCkRegisterBlock->readButton()->click(); - radiusRegisterBlock->readButton()->click(); - diag1RegisterBlock->readButton()->click(); - diag2RegisterBlock->readButton()->click(); - } -} - -void HarmonicCalibration::toggleFaultRegisterMode(int mode) -{ - switch(mode){ - case 0: - AFEDIAGStatusLED->hide(); - OscillatorDriftStatusLED->hide(); - AngleCrossCheckStatusLED->hide(); - TurnCountSensorLevelsStatusLED->hide(); - MTDIAGStatusLED->hide(); - SequencerWatchdogStatusLED->hide(); - break; - case 1: - AFEDIAGStatusLED->show(); - OscillatorDriftStatusLED->show(); - AngleCrossCheckStatusLED->show(); - TurnCountSensorLevelsStatusLED->show(); - MTDIAGStatusLED->show(); - SequencerWatchdogStatusLED->show(); - break; - } -} + if(deviceRegisterMap.at("Supply ID") == "5V") { is5V = true; } + else if(deviceRegisterMap.at("Supply ID") == "3.3V") { is5V = false; } + else { is5V = false; } -void HarmonicCalibration::toggleMTDiagnostics(int mode) -{ - switch(mode){ - case 0: - MTDiagnosticsScrollArea->hide(); - hasMTDiagnostics = false; - break; - case 1: - MTDiagnosticsScrollArea->show(); - hasMTDiagnostics = true; - break; - } -} + deviceName = QString::fromStdString(deviceRegisterMap.at("Product ID")); + + if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { deviceType = QString::fromStdString("Industrial"); } + else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { deviceType = QString::fromStdString("Automotive"); } + else { deviceType = QString::fromStdString(deviceRegisterMap.at("ASIL ID")); } -void HarmonicCalibration::toggleSequenceModeRegisters(int mode) -{ - switch(mode){ - case 0: - angleSecRegisterBlock->hide(); - secAnglIRegisterBlock->hide(); - secAnglQRegisterBlock->hide(); - tmp1RegisterBlock->hide(); - angleCkRegisterBlock->hide(); - radiusRegisterBlock->hide(); - diag1RegisterBlock->hide(); - diag2RegisterBlock->hide(); - break; - case 1: - angleSecRegisterBlock->show(); - secAnglIRegisterBlock->show(); - secAnglQRegisterBlock->show(); - tmp1RegisterBlock->show(); - angleCkRegisterBlock->show(); - radiusRegisterBlock->show(); - diag1RegisterBlock->show(); - diag2RegisterBlock->show(); - break; + success = true; + } + } + } } -} - -void HarmonicCalibration::toggleMotorControls(bool value) -{ - motorMaxVelocitySpinBox->setEnabled(value); - motorAccelTimeSpinBox->setEnabled(value); - motorMaxDisplacementSpinBox->setEnabled(value); - m_calibrationMotorRampModeMenuCombo->setEnabled(value); - motorTargetPositionSpinBox->setEnabled(value); -} -void HarmonicCalibration::toggleUtilityTask(bool run) -{ - if(run){ - utilityTimer->start(utilityTimerRate); - } - else{ - utilityTimer->stop(); - } + if(!success) { StatusBarManager::pushMessage("Failed to read device properties"); } } -void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool& value) -{ - toggleUtilityTask(false); - - uint32_t *DIGIOENRegisterValue = new uint32_t; - uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); +bool HarmonicCalibration::readSequence(){ + uint32_t *generalRegValue = new uint32_t; + uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); + uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); bool success = false; - if(changeCNVPage(DIGIOENPage)) - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) - { - map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); - - DIGIOSettings[DIGIOENName] = value; - - uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); - - if(changeCNVPage(DIGIOENPage)){ - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - static_cast(newRegisterValue)) != -1) - { - success = updateDIGIOToggle(); - } + if(changeCNVPage(generalRegisterPage)){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ + if(*generalRegValue != UINT32_MAX){ + generalRegisterMap = m_admtController->getGeneralRegisterBitMapping(static_cast(*generalRegValue)); + success = true; } - } } - if(!success) { StatusBarManager::pushMessage("Failed to toggle" + QString::fromStdString(DIGIOENName) + " " + QString(value ? "on" : "off")); } - - toggleUtilityTask(true); -} - -bool HarmonicCalibration::updateDIGIOToggle() -{ - uint32_t *DIGIOENRegisterValue = new uint32_t; - uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - bool success = false; - - if(changeCNVPage(DIGIOENPage)){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) - { - map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); - DIGIO0ENToggleSwitch->setChecked(DIGIOSettings["DIGIO0EN"]); - DIGIO1ENToggleSwitch->setChecked(DIGIOSettings["DIGIO1EN"]); - DIGIO2ENToggleSwitch->setChecked(DIGIOSettings["DIGIO2EN"]); - DIGIO3ENToggleSwitch->setChecked(DIGIOSettings["DIGIO3EN"]); - DIGIO4ENToggleSwitch->setChecked(DIGIOSettings["DIGIO4EN"]); - DIGIO5ENToggleSwitch->setChecked(DIGIOSettings["DIGIO5EN"]); - DIGIO0FNCToggleSwitch->setChecked(DIGIOSettings["BUSY"]); - DIGIO1FNCToggleSwitch->setChecked(DIGIOSettings["CNV"]); - DIGIO2FNCToggleSwitch->setChecked(DIGIOSettings["SENT"]); - DIGIO3FNCToggleSwitch->setChecked(DIGIOSettings["ACALC"]); - DIGIO4FNCToggleSwitch->setChecked(DIGIOSettings["FAULT"]); - DIGIO5FNCToggleSwitch->setChecked(DIGIOSettings["BOOTLOAD"]); - success = true; - } - } return success; } -void HarmonicCalibration::toggleAllDIGIOEN(bool value) -{ - toggleUtilityTask(false); - uint32_t *DIGIOENRegisterValue = new uint32_t; - uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); +void HarmonicCalibration::applySequence(){ + toggleWidget(applySequenceButton, false); + applySequenceButton->setText("Writing..."); + QTimer::singleShot(1000, this, [this](){ + this->toggleWidget(applySequenceButton, true); + applySequenceButton->setText("Apply"); + }); + uint32_t *generalRegValue = new uint32_t; + uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); + std::map settings; + + settings["Convert Synchronization"] = qvariant_cast(convertSynchronizationMenuCombo->combo()->currentData()); // convertSync; + settings["Angle Filter"] = qvariant_cast(angleFilterMenuCombo->combo()->currentData()); // angleFilter; + settings["8th Harmonic"] = qvariant_cast(eighthHarmonicMenuCombo->combo()->currentData()); // eighthHarmonic; + settings["Sequence Type"] = qvariant_cast(sequenceTypeMenuCombo->combo()->currentData()); // sequenceType; + settings["Conversion Type"] = qvariant_cast(conversionTypeMenuCombo->combo()->currentData()); // conversionType; bool success = false; - if(changeCNVPage(DIGIOENPage)) - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) - { - map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue));; - DIGIOSettings["DIGIO5EN"] = value; - DIGIOSettings["DIGIO4EN"] = value; - DIGIOSettings["DIGIO3EN"] = value; - DIGIOSettings["DIGIO2EN"] = value; - DIGIOSettings["DIGIO1EN"] = value; - DIGIOSettings["DIGIO0EN"] = value; - uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ - if(changeCNVPage(DIGIOENPage)){ - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - static_cast(newRegisterValue)) != -1) - { - success = updateDIGIOToggle(); + uint32_t newGeneralRegValue = m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings); + uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); + + if(changeCNVPage(generalRegisterPage)){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, newGeneralRegValue) != -1){ + if(readSequence()){ + if(settings.at("Convert Synchronization") == generalRegisterMap.at("Convert Synchronization") && + settings.at("Angle Filter") == generalRegisterMap.at("Angle Filter") && + settings.at("8th Harmonic") == generalRegisterMap.at("8th Harmonic") && + settings.at("Sequence Type") == generalRegisterMap.at("Sequence Type") && + settings.at("Conversion Type") == generalRegisterMap.at("Conversion Type")) + { + StatusBarManager::pushMessage("Sequence settings applied successfully"); + success = true; + } } } } } - if(!success) { StatusBarManager::pushMessage("Failed to toggle all GPIO outputs " + QString(value ? "on" : "off")); } - toggleUtilityTask(true); + if(!success){ StatusBarManager::pushMessage("Failed to apply sequence settings"); } } -void HarmonicCalibration::readDeviceProperties() -{ - uint32_t *uniqId3RegisterValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t page = m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3); - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); - - bool success = false; +bool HarmonicCalibration::changeCNVPage(uint32_t page){ + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, page) != -1){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, page) != -1){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ if(*cnvPageRegValue == page){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID3), uniqId3RegisterValue) != -1){ - deviceRegisterMap = m_admtController->getUNIQID3RegisterMapping(static_cast(*uniqId3RegisterValue)); - - if(deviceRegisterMap.at("Supply ID") == "5V") { is5V = true; } - else if(deviceRegisterMap.at("Supply ID") == "3.3V") { is5V = false; } - else { is5V = false; } - - deviceName = QString::fromStdString(deviceRegisterMap.at("Product ID")); - - if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { deviceType = QString::fromStdString("Industrial"); } - else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { deviceType = QString::fromStdString("Automotive"); } - else { deviceType = QString::fromStdString(deviceRegisterMap.at("ASIL ID")); } - - success = true; - } + return true; } } } - if(!success) { StatusBarManager::pushMessage("Failed to read device properties"); } + return false; } -void HarmonicCalibration::changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel) +void HarmonicCalibration::initializeMotor() { - customSwitch->setOnText(onLabel); - customSwitch->setOffText(offLabel); -} - -void HarmonicCalibration::GMRReset() -{ - // Set Motor Angle to 315 degrees + rotate_vmax = 53687.0912; + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + + amax = 439.8046511104; + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + + dmax = 3000; + writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); + + ramp_mode = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + target_pos = 0; - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - // Write 1 to ADMT IIO Attribute coil_rs - m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getDeviceAttribute(ADMTController::DeviceAttribute::SDP_COIL_RS), 1); + current_pos = 0; + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); +} - // Write 0xc000 to CNVPAGE - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0xc000) != -1) +void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) +{ + while(isDeviceStatusMonitor) { - // Write 0x0000 to CNVPAGE - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0x0000) != -1) + uint32_t *readValue = new uint32_t; + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), 0) == 0) { - // Read ABSANGLE - - StatusBarManager::pushMessage("GMR Reset Done"); + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), readValue) == 0) + { + deviceStatusFault = m_admtController->checkRegisterFault(static_cast(*readValue), generalRegisterMap.at("Sequence Type") == 0 ? true : false); + } + else + { + deviceStatusFault = true; + } } - else { StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); } + else + { + deviceStatusFault = true; + } + + QThread::msleep(sampleRate); } - else { StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); } } -void HarmonicCalibration::restart() +void HarmonicCalibration::requestDisconnect() { - if(m_running) { - run(false); - run(true); + isStartAcquisition = false; + isDeviceStatusMonitor = false; + + m_deviceStatusThread.cancel(); + m_acquisitionDataThread.cancel(); + m_acquisitionGraphThread.cancel(); + + m_deviceStatusWatcher.waitForFinished(); + m_acquisitionDataWatcher.waitForFinished(); + m_acquisitionGraphWatcher.waitForFinished(); +} + +#pragma region Acquisition Methods +bool HarmonicCalibration::updateChannelValues(){ + bool success = false; + rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, bufferSize); + if(rotation == static_cast(UINT64_MAX)) { return false; } + angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, bufferSize); + if(angle == static_cast(UINT64_MAX)) { return false; } + updateCountValue(); + if(count == static_cast(UINT64_MAX)) { return false; } + temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, bufferSize); + if(temp == static_cast(UINT64_MAX)) { return false; } + return success = true; +} + +void HarmonicCalibration::updateCountValue(){ + uint32_t *absAngleRegValue = new uint32_t; + bool success = false; + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0x0000) != -1){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), absAngleRegValue) != -1){ + count = m_admtController->getAbsAngleTurnCount(static_cast(*absAngleRegValue)); + success = true; + } } + if(!success){ count = static_cast(UINT64_MAX); } } -bool HarmonicCalibration::running() const { return m_running; } +void HarmonicCalibration::updateLineEditValues(){ + if(rotation == static_cast(UINT64_MAX)) { rotationValueLabel->setText("N/A"); } + else { rotationValueLabel->setText(QString::number(rotation) + "°"); } + if(angle == static_cast(UINT64_MAX)) { angleValueLabel->setText("N/A"); } + else { angleValueLabel->setText(QString::number(angle) + "°"); } + if(count == static_cast(UINT64_MAX)) { countValueLabel->setText("N/A"); } + else { countValueLabel->setText(QString::number(count)); } + if(temp == static_cast(UINT64_MAX)) { tempValueLabel->setText("N/A"); } + else { tempValueLabel->setText(QString::number(temp) + " °C"); } +} -void HarmonicCalibration::setRunning(bool newRunning) +void HarmonicCalibration::startAcquisition() { - if(m_running == newRunning) - return; - m_running = newRunning; - Q_EMIT runningChanged(newRunning); -} + isStartAcquisition = true; + acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); -void HarmonicCalibration::start() { run(true); } + m_acquisitionDataThread = QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples, acquisitionSampleRate); + m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); + m_acquisitionGraphThread = QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, acquisitionGraphSampleRate); + m_acquisitionGraphWatcher.setFuture(m_acquisitionGraphThread); +} -void HarmonicCalibration::stop() { run(false); } +void HarmonicCalibration::startAcquisitionDeviceStatusMonitor() +{ + isDeviceStatusMonitor = true; + m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); + m_deviceStatusWatcher.setFuture(m_deviceStatusThread); +} -void HarmonicCalibration::run(bool b) +void HarmonicCalibration::getAcquisitionSamples(int sampleRate) { - qInfo() << b; - QElapsedTimer tim; - tim.start(); + while(isStartAcquisition) + { + if(!updateChannelValues()) { break; } - if(!b) { - isStartAcquisition = false; - runButton->setChecked(false); + if(acquisitionDataMap.at(ANGLE) == false && acquisitionAngleList.size() > 0) acquisitionAngleList.clear(); + if(acquisitionDataMap.at(ABSANGLE) == false && acquisitionABSAngleList.size() > 0) acquisitionABSAngleList.clear(); + if(acquisitionDataMap.at(TURNCOUNT) == false && acquisitionTurnCountList.size() > 0) acquisitionTurnCountList.clear(); + if(acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) acquisitionTmp0List.clear(); + if(acquisitionDataMap.at(SINE) == false && acquisitionSineList.size() > 0) acquisitionSineList.clear(); + if(acquisitionDataMap.at(COSINE) == false && acquisitionCosineList.size() > 0) acquisitionCosineList.clear(); + if(acquisitionDataMap.at(RADIUS) == false && acquisitionRadiusList.size() > 0) acquisitionRadiusList.clear(); + + if(acquisitionDataMap.at(ANGLE)) prependAcquisitionData(angle, acquisitionAngleList); + if(acquisitionDataMap.at(ABSANGLE)) prependAcquisitionData(rotation, acquisitionABSAngleList); + if(acquisitionDataMap.at(TURNCOUNT)) prependAcquisitionData(count, acquisitionTurnCountList); + if(acquisitionDataMap.at(TMP0)) prependAcquisitionData(temp, acquisitionTmp0List); + if(acquisitionDataMap.at(SINE)) prependAcquisitionData(getAcquisitionParameterValue(SINE), acquisitionSineList); + if(acquisitionDataMap.at(COSINE)) prependAcquisitionData(getAcquisitionParameterValue(COSINE), acquisitionCosineList); + if(acquisitionDataMap.at(RADIUS)) prependAcquisitionData(getAcquisitionParameterValue(RADIUS), acquisitionRadiusList); + + QThread::msleep(sampleRate); } - else{ - startAcquisition(); +} + +double HarmonicCalibration::getAcquisitionParameterValue(const AcquisitionDataKey &key) +{ + uint32_t *readValue = new uint32_t; + switch(key) + { + case SINE: + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(ADMTController::SensorRegister::SINE), + readValue) == -1) return qQNaN(); + map sineRegisterMap = m_admtController->getSineRegisterBitMapping(static_cast(*readValue)); + return sineRegisterMap.at("SINE"); + break; + } + case COSINE: + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(ADMTController::SensorRegister::COSINE), + readValue) == -1) return qQNaN(); + map cosineRegisterMap = m_admtController->getCosineRegisterBitMapping(static_cast(*readValue)); + return cosineRegisterMap.at("COSINE"); + break; + } + case RADIUS: + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(ADMTController::SensorRegister::RADIUS), + readValue) == -1) return qQNaN(); + map radiusRegisterMap = m_admtController->getRadiusRegisterBitMapping(static_cast(*readValue)); + return radiusRegisterMap.at("RADIUS"); + break; + } + default: + return qQNaN(); + break; } +} - updateGeneralSettingEnabled(!b); +void HarmonicCalibration::plotAcquisition(QVector& list, PlotChannel* channel) +{ + channel->curve()->setSamples(list); + auto result = std::minmax_element(list.begin(), list.end()); + if(*result.first < acquisitionGraphYMin) acquisitionGraphYMin = *result.first; + if(*result.second > acquisitionGraphYMax) acquisitionGraphYMax = *result.second; } -void HarmonicCalibration::canCalibrate(bool value) +void HarmonicCalibration::prependAcquisitionData(const double& data, QVector& list) { - calibrateDataButton->setEnabled(value); + list.prepend(data); + if(list.size() >= acquisitionDisplayLength){ + list.resize(acquisitionDisplayLength); + list.squeeze(); + } +} + +void HarmonicCalibration::resetAcquisitionYAxisScale() +{ + acquisitionGraphYMin = 0; + acquisitionGraphYMax = 360; + acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); + acquisitionGraphPlotWidget->replot(); } void HarmonicCalibration::acquisitionPlotTask(int sampleRate) @@ -2440,679 +2141,1226 @@ void HarmonicCalibration::acquisitionUITask() } } -void HarmonicCalibration::updateFaultStatusLEDColor(MenuControlButton *widget, bool value) +void HarmonicCalibration::updateSequenceWidget(){ + if(generalRegisterMap.at("Sequence Type") == -1){ sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); } + else{ sequenceTypeMenuCombo->combo()->setCurrentIndex(sequenceTypeMenuCombo->combo()->findData(generalRegisterMap.at("Sequence Type"))); } + conversionTypeMenuCombo->combo()->setCurrentIndex(conversionTypeMenuCombo->combo()->findData(generalRegisterMap.at("Conversion Type"))); + // cnvSourceMenuCombo->combo()->setCurrentValue(generalRegisterMap.at("Sequence Type")); + if(generalRegisterMap.at("Convert Synchronization") == -1){ convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); } + else{ convertSynchronizationMenuCombo->combo()->setCurrentIndex(convertSynchronizationMenuCombo->combo()->findData(generalRegisterMap.at("Convert Synchronization"))); } + angleFilterMenuCombo->combo()->setCurrentIndex(angleFilterMenuCombo->combo()->findData(generalRegisterMap.at("Angle Filter"))); + eighthHarmonicMenuCombo->combo()->setCurrentIndex(eighthHarmonicMenuCombo->combo()->findData(generalRegisterMap.at("8th Harmonic"))); +} + +void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { - if(value) changeStatusLEDColor(widget, faultLEDColor); - else changeStatusLEDColor(widget, statusLEDColor); + graphUpdateIntervalLineEdit->setEnabled(value); + displayLengthLineEdit->setEnabled(value); + // dataGraphSamplesLineEdit->setEnabled(value); + // tempGraphSamplesLineEdit->setEnabled(value); } -void HarmonicCalibration::applySequence(){ - toggleWidget(applySequenceButton, false); - applySequenceButton->setText("Writing..."); - QTimer::singleShot(1000, this, [this](){ - this->toggleWidget(applySequenceButton, true); - applySequenceButton->setText("Apply"); +void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox* widget, PlotChannel* channel, AcquisitionDataKey key) +{ + connect(widget, &QCheckBox::stateChanged, [=](int state){ + if(state == Qt::Checked){ + channel->setEnabled(true); + acquisitionDataMap[key] = true; + } + else{ + channel->setEnabled(false); + acquisitionDataMap[key] = false; + } }); - uint32_t *generalRegValue = new uint32_t; - uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); - std::map settings; - - settings["Convert Synchronization"] = qvariant_cast(convertSynchronizationMenuCombo->combo()->currentData()); // convertSync; - settings["Angle Filter"] = qvariant_cast(angleFilterMenuCombo->combo()->currentData()); // angleFilter; - settings["8th Harmonic"] = qvariant_cast(eighthHarmonicMenuCombo->combo()->currentData()); // eighthHarmonic; - settings["Sequence Type"] = qvariant_cast(sequenceTypeMenuCombo->combo()->currentData()); // sequenceType; - settings["Conversion Type"] = qvariant_cast(conversionTypeMenuCombo->combo()->currentData()); // conversionType; +} - bool success = false; +void HarmonicCalibration::GMRReset() +{ + // Set Motor Angle to 315 degrees + target_pos = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ + // Write 1 to ADMT IIO Attribute coil_rs + m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getDeviceAttribute(ADMTController::DeviceAttribute::SDP_COIL_RS), 1); - uint32_t newGeneralRegValue = m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings); - uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); + // Write 0xc000 to CNVPAGE + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0xc000) != -1) + { + // Write 0x0000 to CNVPAGE + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0x0000) != -1) + { + // Read ABSANGLE - if(changeCNVPage(generalRegisterPage)){ - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, newGeneralRegValue) != -1){ - if(readSequence()){ - if(settings.at("Convert Synchronization") == generalRegisterMap.at("Convert Synchronization") && - settings.at("Angle Filter") == generalRegisterMap.at("Angle Filter") && - settings.at("8th Harmonic") == generalRegisterMap.at("8th Harmonic") && - settings.at("Sequence Type") == generalRegisterMap.at("Sequence Type") && - settings.at("Conversion Type") == generalRegisterMap.at("Conversion Type")) - { - StatusBarManager::pushMessage("Sequence settings applied successfully"); - success = true; - } - } - } + StatusBarManager::pushMessage("GMR Reset Done"); } + else { StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); } } + else { StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); } +} - - if(!success){ StatusBarManager::pushMessage("Failed to apply sequence settings"); } +void HarmonicCalibration::restart() +{ + if(m_running) { + run(false); + run(true); + } } -void HarmonicCalibration::toggleWidget(QPushButton *widget, bool value){ - widget->setEnabled(value); +bool HarmonicCalibration::running() const { return m_running; } + +void HarmonicCalibration::setRunning(bool newRunning) +{ + if(m_running == newRunning) + return; + m_running = newRunning; + Q_EMIT runningChanged(newRunning); } -bool HarmonicCalibration::readSequence(){ - uint32_t *generalRegValue = new uint32_t; - uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); - uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); +void HarmonicCalibration::start() { run(true); } - bool success = false; +void HarmonicCalibration::stop() { run(false); } - if(changeCNVPage(generalRegisterPage)){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ - if(*generalRegValue != UINT32_MAX){ - generalRegisterMap = m_admtController->getGeneralRegisterBitMapping(static_cast(*generalRegValue)); - success = true; - } - } +void HarmonicCalibration::run(bool b) +{ + qInfo() << b; + QElapsedTimer tim; + tim.start(); + + if(!b) { + isStartAcquisition = false; + runButton->setChecked(false); + } + else{ + startAcquisition(); } - return success; + updateGeneralSettingEnabled(!b); } +#pragma endregion -void HarmonicCalibration::updateSequenceWidget(){ - if(generalRegisterMap.at("Sequence Type") == -1){ sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); } - else{ sequenceTypeMenuCombo->combo()->setCurrentIndex(sequenceTypeMenuCombo->combo()->findData(generalRegisterMap.at("Sequence Type"))); } - conversionTypeMenuCombo->combo()->setCurrentIndex(conversionTypeMenuCombo->combo()->findData(generalRegisterMap.at("Conversion Type"))); - // cnvSourceMenuCombo->combo()->setCurrentValue(generalRegisterMap.at("Sequence Type")); - if(generalRegisterMap.at("Convert Synchronization") == -1){ convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); } - else{ convertSynchronizationMenuCombo->combo()->setCurrentIndex(convertSynchronizationMenuCombo->combo()->findData(generalRegisterMap.at("Convert Synchronization"))); } - angleFilterMenuCombo->combo()->setCurrentIndex(angleFilterMenuCombo->combo()->findData(generalRegisterMap.at("Angle Filter"))); - eighthHarmonicMenuCombo->combo()->setCurrentIndex(eighthHarmonicMenuCombo->combo()->findData(generalRegisterMap.at("8th Harmonic"))); +#pragma region Calibration Methods +void HarmonicCalibration::startCalibrationDeviceStatusMonitor() +{ + isDeviceStatusMonitor = true; + m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); + m_deviceStatusWatcher.setFuture(m_deviceStatusThread); } -bool HarmonicCalibration::changeCNVPage(uint32_t page){ - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); +void HarmonicCalibration::calibrationUITask() +{ + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); + updateFaultStatusLEDColor(calibrationFaultRegisterLEDWidget, deviceStatusFault); - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, page) != -1){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ - if(*cnvPageRegValue == page){ - return true; - } + if(isStartMotor) + { + if(isPostCalibration){ + postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); + postCalibrationRawDataPlotWidget->replot(); + } + else{ + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotWidget->replot(); } } - - return false; } -void HarmonicCalibration::utilityTask(){ - updateDigioMonitor(); - updateFaultRegister(); - if(hasMTDiagnostics){ - updateMTDiagRegister(); - updateMTDiagnostics(); +void HarmonicCalibration::getCalibrationSamples() +{ + if(resetCurrentPositionToZero()){ + if(isPostCalibration){ + int currentSamplesCount = graphPostDataList.size(); + while(isStartMotor && currentSamplesCount < totalSamplesCount){ + target_pos = current_pos + -408; + moveMotorToPosition(target_pos, true); + updateChannelValue(ADMTController::Channel::ANGLE); + graphPostDataList.append(angle); + currentSamplesCount++; + } + } + else{ + int currentSamplesCount = graphDataList.size(); + while(isStartMotor && currentSamplesCount < totalSamplesCount){ + target_pos = current_pos + -408; + if(moveMotorToPosition(target_pos, true) == false) { m_admtController->disconnectADMT(); } + if(updateChannelValue(ADMTController::Channel::ANGLE)) { break; } + graphDataList.append(angle); + currentSamplesCount++; + } + } } - commandLogWrite(""); + + stopMotor(); } -void HarmonicCalibration::updateDigioMonitor(){ - uint32_t *digioRegValue = new uint32_t; - uint32_t digioEnPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - if(changeCNVPage(digioEnPage)) - { - uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN); +void HarmonicCalibration::startMotor() +{ + toggleTabSwitching(false); + toggleMotorControls(false); - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), digioRegisterAddress, digioRegValue) != -1){ - std::map digioBitMapping = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*digioRegValue)); - if(digioBitMapping.at("DIGIO0EN")){ - if(!digioBitMapping.at("BUSY")){ - changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor); - DIGIOBusyStatusLED->setName("BUSY"); - } - else{ - changeStatusLEDColor(DIGIOBusyStatusLED, gpioLEDColor); - DIGIOBusyStatusLED->setName("GPIO0"); - } - } - else { - changeStatusLEDColor(DIGIOBusyStatusLED, faultLEDColor, false); - DIGIOBusyStatusLED->setName("DIGIO0"); - } + if(resetToZero && !isPostCalibration){ + clearCalibrationSamples(); + clearPostCalibrationSamples(); + clearAngleErrorGraphs(); + clearCorrectedAngleErrorGraphs(); + } - if(digioBitMapping.at("DIGIO1EN")){ - if(!digioBitMapping.at("CNV")){ - changeStatusLEDColor(DIGIOCNVStatusLED, statusLEDColor); - DIGIOCNVStatusLED->setName("CNV"); - } - else{ - changeStatusLEDColor(DIGIOCNVStatusLED, gpioLEDColor); - DIGIOCNVStatusLED->setName("GPIO1"); - } - } - else { - changeStatusLEDColor(DIGIOCNVStatusLED, faultLEDColor, false); - DIGIOCNVStatusLED->setName("DIGIO1"); - } + if(isPostCalibration) + postCalibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); + else + calibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); - if(digioBitMapping.at("DIGIO2EN")){ - if(!digioBitMapping.at("SENT")){ - changeStatusLEDColor(DIGIOSENTStatusLED, statusLEDColor); - DIGIOSENTStatusLED->setName("SENT"); - } - else{ - changeStatusLEDColor(DIGIOSENTStatusLED, gpioLEDColor); - DIGIOSENTStatusLED->setName("GPIO2"); - } - } - else { - changeStatusLEDColor(DIGIOSENTStatusLED, faultLEDColor, false); - DIGIOSENTStatusLED->setName("DIGIO2"); - } + if(isPostCalibration) + calibrationDataGraphTabWidget->setCurrentIndex(1); // Set tab to Post Calibration Samples + else + calibrationDataGraphTabWidget->setCurrentIndex(0); // Set tab to Calibration Samples - if(digioBitMapping.at("DIGIO3EN")){ - if(!digioBitMapping.at("ACALC")){ - changeStatusLEDColor(DIGIOACALCStatusLED, statusLEDColor); - DIGIOACALCStatusLED->setName("ACALC"); - } - else{ - changeStatusLEDColor(DIGIOACALCStatusLED, gpioLEDColor); - DIGIOACALCStatusLED->setName("GPIO3"); - } - } - else { - changeStatusLEDColor(DIGIOACALCStatusLED, faultLEDColor, false); - DIGIOACALCStatusLED->setName("DIGIO3"); - } + clearCalibrateDataButton->setEnabled(false); + QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getCalibrationSamples); + QFutureWatcher *watcher = new QFutureWatcher(this); - if(digioBitMapping.at("DIGIO4EN")){ - if(!digioBitMapping.at("FAULT")){ - changeStatusLEDColor(DIGIOFaultStatusLED, statusLEDColor); - DIGIOFaultStatusLED->setName("FAULT"); - } - else{ - changeStatusLEDColor(DIGIOFaultStatusLED, gpioLEDColor); - DIGIOFaultStatusLED->setName("GPIO4"); - } - } - else { - changeStatusLEDColor(DIGIOFaultStatusLED, faultLEDColor, false); - DIGIOFaultStatusLED->setName("DIGIO4"); - } + connect(watcher, &QFutureWatcher::finished, this, [=]() { + toggleTabSwitching(true); + toggleMotorControls(true); - if(digioBitMapping.at("DIGIO5EN")){ - if(!digioBitMapping.at("BOOTLOAD")){ - changeStatusLEDColor(DIGIOBootloaderStatusLED, statusLEDColor); - DIGIOBootloaderStatusLED->setName("BOOTLOAD"); - } - else{ - changeStatusLEDColor(DIGIOBootloaderStatusLED, gpioLEDColor); - DIGIOBootloaderStatusLED->setName("GPIO5"); - } + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotChannel->xAxis()->setMax(graphDataList.size()); + calibrationRawDataPlotWidget->replot(); + isStartMotor = false; + calibrationStartMotorButton->setChecked(false); + clearCalibrateDataButton->setEnabled(true); + + if(isPostCalibration) + { + if(static_cast(graphPostDataList.size()) == totalSamplesCount) + { + computeSineCosineOfAngles(graphPostDataList); + m_admtController->postcalibrate(vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, samplesPerCycle); + populateCorrectedAngleErrorGraphs(); + isPostCalibration = false; + isStartMotor = false; + resetToZero = true; + canCalibrate(false); } - else { - changeStatusLEDColor(DIGIOBootloaderStatusLED, faultLEDColor, false); - DIGIOBootloaderStatusLED->setName("DIGIO5"); + } + else{ + if(static_cast(graphDataList.size()) == totalSamplesCount) + { + computeSineCosineOfAngles(graphDataList); + calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); + populateAngleErrorGraphs(); + calculateHarmonicValues(); + canStartMotor(false); + canCalibrate(true); + } + else{ + resetToZero = true; } - - commandLogWrite("DIGIOEN: 0b" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); } - else{ commandLogWrite("Failed to read DIGIOEN Register"); } - } - + }); + connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater())); + watcher->setFuture(future); } -void HarmonicCalibration::updateMTDiagRegister(){ - uint32_t *mtDiag1RegValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1); - uint32_t mtDiag1PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); +void HarmonicCalibration::startMotorContinuous() +{ + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); +} - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag1PageValue) != -1){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ - if(*cnvPageRegValue == mtDiag1PageValue){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1){ - std::map mtDiag1BitMapping = m_admtController->getDiag1RegisterBitMapping_Register(static_cast(*mtDiag1RegValue)); - changeStatusLEDColor(R0StatusLED, statusLEDColor, mtDiag1BitMapping.at("R0")); - changeStatusLEDColor(R1StatusLED, statusLEDColor, mtDiag1BitMapping.at("R1")); - changeStatusLEDColor(R2StatusLED, statusLEDColor, mtDiag1BitMapping.at("R2")); - changeStatusLEDColor(R3StatusLED, statusLEDColor, mtDiag1BitMapping.at("R3")); - changeStatusLEDColor(R4StatusLED, statusLEDColor, mtDiag1BitMapping.at("R4")); - changeStatusLEDColor(R5StatusLED, statusLEDColor, mtDiag1BitMapping.at("R5")); - changeStatusLEDColor(R6StatusLED, statusLEDColor, mtDiag1BitMapping.at("R6")); - changeStatusLEDColor(R7StatusLED, statusLEDColor, mtDiag1BitMapping.at("R7")); - commandLogWrite("DIAG1: 0b" + QString::number(static_cast(*mtDiag1RegValue), 2).rightJustified(16, '0')); - } - else{ commandLogWrite("Failed to read MT Diagnostic 1 Register"); } - } - else{ commandLogWrite("CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); } - } - else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 1"); } - } - else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 1"); } +void HarmonicCalibration::postCalibrateData() +{ + calibrationLogWrite("==== Post Calibration Start ====\n"); + flashHarmonicValues(); + calibrationDataGraphTabWidget->setCurrentIndex(1); + isPostCalibration = true; + isStartMotor = true; + resetToZero = true; + startMotor(); } -void HarmonicCalibration::updateFaultRegister(){ - uint32_t *faultRegValue = new uint32_t; - uint32_t faultRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, 0); // Write all zeros to fault before read - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, faultRegValue); +void HarmonicCalibration::resetAllCalibrationState() +{ + clearCalibrationSamples(); + clearPostCalibrationSamples(); + calibrationDataGraphTabWidget->setCurrentIndex(0); - if(*faultRegValue != -1){ - std::map faultBitMapping = m_admtController->getFaultRegisterBitMapping(static_cast(*faultRegValue)); - changeStatusLEDColor(VDDUnderVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDD Under Voltage")); - changeStatusLEDColor(VDDOverVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDD Over Voltage")); - changeStatusLEDColor(VDRIVEUnderVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDRIVE Under Voltage")); - changeStatusLEDColor(VDRIVEOverVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDRIVE Over Voltage")); - changeStatusLEDColor(AFEDIAGStatusLED, faultLEDColor, faultBitMapping.at("AFE Diagnostic")); - changeStatusLEDColor(NVMCRCFaultStatusLED, faultLEDColor, faultBitMapping.at("NVM CRC Fault")); - changeStatusLEDColor(ECCDoubleBitErrorStatusLED, faultLEDColor, faultBitMapping.at("ECC Double Bit Error")); - changeStatusLEDColor(OscillatorDriftStatusLED, faultLEDColor, faultBitMapping.at("Oscillator Drift")); - changeStatusLEDColor(CountSensorFalseStateStatusLED, faultLEDColor, faultBitMapping.at("Count Sensor False State")); - changeStatusLEDColor(AngleCrossCheckStatusLED, faultLEDColor, faultBitMapping.at("Angle Cross Check")); - changeStatusLEDColor(TurnCountSensorLevelsStatusLED, faultLEDColor, faultBitMapping.at("Turn Count Sensor Levels")); - changeStatusLEDColor(MTDIAGStatusLED, faultLEDColor, faultBitMapping.at("MT Diagnostic")); - changeStatusLEDColor(TurnCounterCrossCheckStatusLED, faultLEDColor, faultBitMapping.at("Turn Counter Cross Check")); - changeStatusLEDColor(RadiusCheckStatusLED, faultLEDColor, faultBitMapping.at("AMR Radius Check")); - changeStatusLEDColor(SequencerWatchdogStatusLED, faultLEDColor, faultBitMapping.at("Sequencer Watchdog")); + clearAngleErrorGraphs(); + clearCorrectedAngleErrorGraphs(); + resultDataTabWidget->setCurrentIndex(0); - commandLogWrite("FAULT: 0b" + QString::number(static_cast(*faultRegValue), 2).rightJustified(16, '0')); - } - else{ commandLogWrite("Failed to read FAULT Register"); } + canStartMotor(true); + canCalibrate(false); + calibrateDataButton->setChecked(false); + isPostCalibration = false; + isCalculatedCoeff = false; + resetToZero = true; + displayCalculatedCoeff(); } -void HarmonicCalibration::updateMTDiagnostics(){ - uint32_t *mtDiag1RegValue = new uint32_t; - uint32_t *mtDiag2RegValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; +void HarmonicCalibration::computeSineCosineOfAngles(QVector graphDataList) +{ + m_admtController->computeSineCosineOfAngles(vector(graphDataList.begin(), graphDataList.end())); + if(isPostCalibration){ + postCalibrationSineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_sine_scaled.data(), m_admtController->calibration_samples_sine_scaled.size()); + postCalibrationCosineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_cosine_scaled.data(), m_admtController->calibration_samples_cosine_scaled.size()); + postCalibrationRawDataPlotWidget->replot(); + } + else{ + calibrationSineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_sine_scaled.data(), m_admtController->calibration_samples_sine_scaled.size()); + calibrationCosineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_cosine_scaled.data(), m_admtController->calibration_samples_cosine_scaled.size()); + calibrationRawDataPlotWidget->replot(); + } +} - uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1); - uint32_t mtDiag2RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG2); +void HarmonicCalibration::populateAngleErrorGraphs() +{ + QVector angleError = QVector(m_admtController->angleError.begin(), m_admtController->angleError.end()); + QVector FFTAngleErrorMagnitude = QVector(m_admtController->FFTAngleErrorMagnitude.begin(), m_admtController->FFTAngleErrorMagnitude.end()); + QVector FFTAngleErrorPhase = QVector(m_admtController->FFTAngleErrorPhase.begin(), m_admtController->FFTAngleErrorPhase.end()); - uint32_t mtDiag1PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); - uint32_t mtDiag2PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2); + angleErrorPlotChannel->curve()->setSamples(angleError); + auto angleErrorMinMax = std::minmax_element(angleError.begin(), angleError.end()); + angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, *angleErrorMinMax.second); + angleErrorXPlotAxis->setInterval(0, angleError.size()); + angleErrorPlotWidget->replot(); + + FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); + FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); + auto angleErrorMagnitudeMinMax = std::minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); + auto angleErrorPhaseMinMax = std::minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); + double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first ? *angleErrorMagnitudeMinMax.first : *angleErrorPhaseMinMax.first; + double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second ? *angleErrorMagnitudeMinMax.second : *angleErrorPhaseMinMax.second; + FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); + FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); + FFTAngleErrorPlotWidget->replot(); - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + resultDataTabWidget->setCurrentIndex(0); // Set tab to Angle Error +} - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag1PageValue) != -1){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ - if(*cnvPageRegValue == mtDiag1PageValue){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1){ - std::map mtDiag1BitMapping = m_admtController->getDiag1RegisterBitMapping_Afe(static_cast(*mtDiag1RegValue), is5V); +void HarmonicCalibration::populateCorrectedAngleErrorGraphs() +{ + QVector correctedError(m_admtController->correctedError.begin(), m_admtController->correctedError.end()); + QVector FFTCorrectedErrorMagnitude(m_admtController->FFTCorrectedErrorMagnitude.begin(), m_admtController->FFTCorrectedErrorMagnitude.end()); + QVector FFTCorrectedErrorPhase(m_admtController->FFTCorrectedErrorPhase.begin(), m_admtController->FFTCorrectedErrorPhase.end()); - afeDiag2 = mtDiag1BitMapping.at("AFE Diagnostic 2"); - AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); - } - else{ commandLogWrite("Failed to read MT Diagnostic 1 Register"); } - } - else{ commandLogWrite("CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); } - } - else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 1"); } - } - else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 1"); } + correctedErrorPlotChannel->curve()->setSamples(correctedError); + auto correctedErrorMagnitudeMinMax = std::minmax_element(correctedError.begin(), correctedError.end()); + correctedErrorYPlotAxis->setInterval(*correctedErrorMagnitudeMinMax.first, *correctedErrorMagnitudeMinMax.second); + correctedErrorXPlotAxis->setMax(correctedError.size()); + correctedErrorPlotWidget->replot(); - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag2PageValue) != -1){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ - if(*cnvPageRegValue == mtDiag2PageValue){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag2RegisterAddress, mtDiag2RegValue) != -1){ - std::map mtDiag2BitMapping = m_admtController->getDiag2RegisterBitMapping(static_cast(*mtDiag2RegValue)); - - afeDiag0 = mtDiag2BitMapping.at("AFE Diagnostic 0 (-57%)"); - afeDiag1 = mtDiag2BitMapping.at("AFE Diagnostic 1 (+57%)"); - AFEDIAG0LineEdit->setText(QString::number(afeDiag0) + " V"); - AFEDIAG1LineEdit->setText(QString::number(afeDiag1) + " V"); + FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); + FFTCorrectedErrorMagnitudeChannel->curve()->setSamples(FFTCorrectedErrorMagnitude); + auto FFTCorrectedErrorMagnitudeMinMax = std::minmax_element(FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); + auto FFTCorrectedErrorPhaseMinMax = std::minmax_element(FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); + double FFTCorrectedErrorPlotMin = *FFTCorrectedErrorMagnitudeMinMax.first < *FFTCorrectedErrorPhaseMinMax.first ? *FFTCorrectedErrorMagnitudeMinMax.first : *FFTCorrectedErrorPhaseMinMax.first; + double FFTCorrectedErrorPlotMax = *FFTCorrectedErrorMagnitudeMinMax.second > *FFTCorrectedErrorPhaseMinMax.second ? *FFTCorrectedErrorMagnitudeMinMax.second : *FFTCorrectedErrorPhaseMinMax.second; + FFTCorrectedErrorYPlotAxis->setInterval(FFTCorrectedErrorPlotMin, FFTCorrectedErrorPlotMax); + FFTCorrectedErrorXPlotAxis->setMax(FFTCorrectedErrorMagnitude.size()); + FFTCorrectedErrorPlotWidget->replot(); - commandLogWrite("DIAG2: 0b" + QString::number(static_cast(*mtDiag2RegValue), 2).rightJustified(16, '0')); - } - else{ commandLogWrite("Failed to read MT Diagnostic 2 Register"); } - } - else{ commandLogWrite("CNVPAGE for MT Diagnostic 2 is a different value, abort reading"); } - } - else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 2"); } - } - else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 2"); } + resultDataTabWidget->setCurrentIndex(2); // Set tab to Angle Error } -void HarmonicCalibration::clearCommandLog(){ - commandLogPlainTextEdit->clear(); -} +void HarmonicCalibration::flashHarmonicValues() +{ + if(changeCNVPage(0x02)){ + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), 0x01, 0x02); -bool HarmonicCalibration::updateChannelValues(){ - bool success = false; - rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, bufferSize); - if(rotation == static_cast(UINT64_MAX)) { return false; } - angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, bufferSize); - if(angle == static_cast(UINT64_MAX)) { return false; } - updateCountValue(); - if(count == static_cast(UINT64_MAX)) { return false; } - temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, bufferSize); - if(temp == static_cast(UINT64_MAX)) { return false; } - return success = true; -} + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), + H1_MAG_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), + H1_PHASE_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), + H2_MAG_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), + H2_PHASE_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), + H3_MAG_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), + H3_PHASE_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), + H8_MAG_HEX); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), + H8_PHASE_HEX); -void HarmonicCalibration::updateCountValue(){ - uint32_t *absAngleRegValue = new uint32_t; - bool success = false; - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0x0000) != -1){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), absAngleRegValue) != -1){ - count = m_admtController->getAbsAngleTurnCount(static_cast(*absAngleRegValue)); - success = true; - } + isCalculatedCoeff = true; + displayCalculatedCoeff(); + } + else{ + calibrationLogWrite("Unabled to flash Harmonic Registers!"); } - if(!success){ count = static_cast(UINT64_MAX); } } -void HarmonicCalibration::updateLineEditValues(){ - if(rotation == static_cast(UINT64_MAX)) { rotationValueLabel->setText("N/A"); } - else { rotationValueLabel->setText(QString::number(rotation) + "°"); } - if(angle == static_cast(UINT64_MAX)) { angleValueLabel->setText("N/A"); } - else { angleValueLabel->setText(QString::number(angle) + "°"); } - if(count == static_cast(UINT64_MAX)) { countValueLabel->setText("N/A"); } - else { countValueLabel->setText(QString::number(count)); } - if(temp == static_cast(UINT64_MAX)) { tempValueLabel->setText("N/A"); } - else { tempValueLabel->setText(QString::number(temp) + " °C"); } -} +void HarmonicCalibration::calculateHarmonicValues() +{ + uint32_t *h1MagCurrent = new uint32_t, + *h1PhaseCurrent = new uint32_t, + *h2MagCurrent = new uint32_t, + *h2PhaseCurrent = new uint32_t, + *h3MagCurrent = new uint32_t, + *h3PhaseCurrent = new uint32_t, + *h8MagCurrent = new uint32_t, + *h8PhaseCurrent = new uint32_t; + + if(changeCNVPage(0x02)) + { + // Read and store current harmonic values + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); -void HarmonicCalibration::updateLineEditValue(QLineEdit* lineEdit, double value){ - if(value == static_cast(UINT64_MAX)) { lineEdit->setText("N/A"); } - else { lineEdit->setText(QString::number(value)); } -} + // Calculate harmonic coefficients (Hex) + H1_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_1), static_cast(*h1MagCurrent), "h1")); + H2_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_2), static_cast(*h2MagCurrent), "h2")); + H3_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_3), static_cast(*h3MagCurrent), "h3")); + H8_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_8), static_cast(*h8MagCurrent), "h8")); + H1_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_1), static_cast(*h1PhaseCurrent))); + H2_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_2), static_cast(*h2PhaseCurrent))); + H3_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_3), static_cast(*h3PhaseCurrent))); + H8_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_8), static_cast(*h8PhaseCurrent))); -void HarmonicCalibration::updateGeneralSettingEnabled(bool value) -{ - graphUpdateIntervalLineEdit->setEnabled(value); - displayLengthLineEdit->setEnabled(value); - // dataGraphSamplesLineEdit->setEnabled(value); - // tempGraphSamplesLineEdit->setEnabled(value); + calibrationLogWrite(); + calibrationLogWrite(QString("Calculated H1 Mag (Hex): 0x%1").arg(QString::number(H1_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H1 Phase (Hex): 0x%1").arg(QString::number(H1_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H2 Mag (Hex): 0x%1").arg(QString::number(H2_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H2 Phase (Hex): 0x%1").arg(QString::number(H2_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H3 Mag (Hex): 0x%1").arg(QString::number(H3_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H3 Phase (Hex): 0x%1").arg(QString::number(H3_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H8 Mag (Hex): 0x%1").arg(QString::number(H8_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H8 Phase (Hex): 0x%1").arg(QString::number(H8_PHASE_HEX, 16).rightJustified(4, '0'))); + + // Get actual harmonic values from hex + H1_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H1_MAG_HEX), "h1mag"); + H1_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H1_PHASE_HEX), "h1phase"); + H2_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H2_MAG_HEX), "h2mag"); + H2_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H2_PHASE_HEX), "h2phase"); + H3_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H3_MAG_HEX), "h3mag"); + H3_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H3_PHASE_HEX), "h3phase"); + H8_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H8_MAG_HEX), "h8mag"); + H8_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H8_PHASE_HEX), "h8phase"); + + calibrationLogWrite(); + calibrationLogWrite(QString("Calculated H1 Mag (Angle): 0x%1").arg(QString::number(H1_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H1 Phase (Angle): 0x%1").arg(QString::number(H1_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H2 Mag (Angle): 0x%1").arg(QString::number(H2_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H2 Phase (Angle): 0x%1").arg(QString::number(H2_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H3 Mag (Angle): 0x%1").arg(QString::number(H3_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H3 Phase (Angle): 0x%1").arg(QString::number(H3_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H8 Mag (Angle): 0x%1").arg(QString::number(H8_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H8 Phase (Angle): 0x%1").arg(QString::number(H8_PHASE_ANGLE))); + + if(isAngleDisplayFormat) updateCalculatedCoeffAngle(); + else updateCalculatedCoeffHex(); + isCalculatedCoeff = true; + } } -MenuControlButton *HarmonicCalibration::createStatusLEDWidget(const QString title, QColor color, QWidget *parent) +void HarmonicCalibration::updateCalculatedCoeffAngle() { - MenuControlButton *menuControlButton = new MenuControlButton(parent); - menuControlButton->setName(title); - menuControlButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); - menuControlButton->setOpenMenuChecksThis(true); - menuControlButton->setDoubleClickToOpenMenu(true); - menuControlButton->setColor(color); - menuControlButton->button()->setVisible(false); - menuControlButton->setCheckable(true); - menuControlButton->checkBox()->setChecked(false); - menuControlButton->setEnabled(false); - menuControlButton->layout()->setMargin(8); - return menuControlButton; + calibrationH1MagLabel->setText(QString::number(H1_MAG_ANGLE, 'f', 2) + "°"); + calibrationH2MagLabel->setText(QString::number(H2_MAG_ANGLE, 'f', 2) + "°"); + calibrationH3MagLabel->setText(QString::number(H3_MAG_ANGLE, 'f', 2) + "°"); + calibrationH8MagLabel->setText(QString::number(H8_MAG_ANGLE, 'f', 2) + "°"); + calibrationH1PhaseLabel->setText("Φ " + QString::number(H1_PHASE_ANGLE, 'f', 2)); + calibrationH2PhaseLabel->setText("Φ " + QString::number(H2_PHASE_ANGLE, 'f', 2)); + calibrationH3PhaseLabel->setText("Φ " + QString::number(H3_PHASE_ANGLE, 'f', 2)); + calibrationH8PhaseLabel->setText("Φ " + QString::number(H8_PHASE_ANGLE, 'f', 2)); } -void HarmonicCalibration::changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked) +void HarmonicCalibration::updateCalculatedCoeffHex() { - menuControlButton->setColor(color); - menuControlButton->checkBox()->setChecked(checked); + calibrationH1MagLabel->setText(QString("0x%1").arg(H1_MAG_HEX, 4, 16, QChar('0'))); + calibrationH2MagLabel->setText(QString("0x%1").arg(H2_MAG_HEX, 4, 16, QChar('0'))); + calibrationH3MagLabel->setText(QString("0x%1").arg(H3_MAG_HEX, 4, 16, QChar('0'))); + calibrationH8MagLabel->setText(QString("0x%1").arg(H8_MAG_HEX, 4, 16, QChar('0'))); + calibrationH1PhaseLabel->setText(QString("0x%1").arg(H1_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH2PhaseLabel->setText(QString("0x%1").arg(H2_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH3PhaseLabel->setText(QString("0x%1").arg(H3_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH8PhaseLabel->setText(QString("0x%1").arg(H8_PHASE_HEX, 4, 16, QChar('0'))); } -MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString title, QColor color, QWidget *parent) +void HarmonicCalibration::resetCalculatedCoeffAngle() { - MenuControlButton *menuControlButton = new MenuControlButton(parent); - menuControlButton->setName(title); - menuControlButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); - menuControlButton->setOpenMenuChecksThis(true); - menuControlButton->setDoubleClickToOpenMenu(true); - menuControlButton->setColor(color); - menuControlButton->button()->setVisible(false); - menuControlButton->setCheckable(false); - menuControlButton->checkBox()->setChecked(true); - menuControlButton->layout()->setMargin(0); - return menuControlButton; + calibrationH1MagLabel->setText("--.--°"); + calibrationH2MagLabel->setText("--.--°"); + calibrationH3MagLabel->setText("--.--°"); + calibrationH8MagLabel->setText("--.--°"); + calibrationH1PhaseLabel->setText("Φ --.--"); + calibrationH2PhaseLabel->setText("Φ --.--"); + calibrationH3PhaseLabel->setText("Φ --.--"); + calibrationH8PhaseLabel->setText("Φ --.--"); } -void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max) +void HarmonicCalibration::resetCalculatedCoeffHex() { - QIntValidator *validator = new QIntValidator(min, max, this); - lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, min, max]() { - bool ok; - int value = lineEdit->text().toInt(&ok); - if (ok && value >= min && value <= max) { - variable = value; - } else { - lineEdit->setText(QString::number(variable)); - } - }); + calibrationH1MagLabel->setText("0x----"); + calibrationH2MagLabel->setText("0x----"); + calibrationH3MagLabel->setText("0x----"); + calibrationH8MagLabel->setText("0x----"); + calibrationH1PhaseLabel->setText("0x----"); + calibrationH2PhaseLabel->setText("0x----"); + calibrationH3PhaseLabel->setText("0x----"); + calibrationH8PhaseLabel->setText("0x----"); } -void HarmonicCalibration::connectLineEditToDouble(QLineEdit* lineEdit, double& variable) +void HarmonicCalibration::displayCalculatedCoeff() { - // QDoubleValidator *validator = new QDoubleValidator(this); - // validator->setNotation(QDoubleValidator::StandardNotation); - // lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { - bool ok; - double value = lineEdit->text().toDouble(&ok); - if (ok){ - variable = value; - } else { - lineEdit->setText(QString::number(variable, 'f', 2)); - } - }); + if(isAngleDisplayFormat){ + if(isCalculatedCoeff){ + updateCalculatedCoeffAngle(); + } + else{ + resetCalculatedCoeffAngle(); + } + } + else{ + if(isCalculatedCoeff){ + updateCalculatedCoeffHex(); + } + else{ + resetCalculatedCoeffHex(); + } + } } -void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit) +void HarmonicCalibration::calibrationLogWrite(QString message) { - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, unit]() { - bool ok; - double value = lineEdit->text().replace(unit, "").trimmed().toDouble(&ok); - if (ok) { - variable = value; - - } else { - lineEdit->setText(QString::number(variable) + " " + unit); - } - }); + logsPlainTextEdit->appendPlainText(message); } -void HarmonicCalibration::connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute) +void HarmonicCalibration::importCalibrationData() { - QDoubleValidator *validator = new QDoubleValidator(this); - validator->setNotation(QDoubleValidator::StandardNotation); - lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, [=, &variable]() { - bool ok; - double value = lineEdit->text().toDouble(&ok); - if (ok) { - variable = value; - writeMotorAttributeValue(attribute, variable); - - } else { - lineEdit->setText(QString::number(variable)); - } - }); + QString fileName = QFileDialog::getOpenFileName( + this, tr("Import"), "", + tr("Comma-separated values files (*.csv);;" + "Tab-delimited values files (*.txt)"), + nullptr, QFileDialog::Options()); + + FileManager fm("HarmonicCalibration"); + + try { + fm.open(fileName, FileManager::IMPORT); + + graphDataList = fm.read(0); + if(graphDataList.size() > 0) + { + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataXPlotAxis->setInterval(0, graphDataList.size()); + calibrationRawDataPlotWidget->replot(); + + computeSineCosineOfAngles(graphDataList); + calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); + populateAngleErrorGraphs(); + canStartMotor(false); + canCalibrate(true); + } + } catch(FileManagerException &ex) { + calibrationLogWrite(QString(ex.what())); + } } -void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, double& variable) +void HarmonicCalibration::extractCalibrationData() { - QComboBox *combo = menuCombo->combo(); - connect(combo, QOverload::of(&QComboBox::currentIndexChanged), [=, &variable]() { - variable = qvariant_cast(combo->currentData()); - }); + QStringList filter; + filter += QString(tr("Comma-separated values files (*.csv)")); + filter += QString(tr("Tab-delimited values files (*.txt)")); + filter += QString(tr("All Files(*)")); + + QString selectedFilter = filter[0]; + + QString fileName = QFileDialog::getSaveFileName(this, tr("Export"), "", filter.join(";;"), &selectedFilter, QFileDialog::Options()); + + if(fileName.split(".").size() <= 1) { + // file name w/o extension. Let's append it + QString ext = selectedFilter.split(".")[1].split(")")[0]; + fileName += "." + ext; + } + + if(!fileName.isEmpty()) { + bool withScopyHeader = false; + FileManager fm("HarmonicCalibration"); + fm.open(fileName, FileManager::EXPORT); + + QVector preCalibrationAngleErrorsFFTMagnitude(m_admtController->angle_errors_fft_pre.begin(), m_admtController->angle_errors_fft_pre.end()); + QVector preCalibrationAngleErrorsFFTPhase(m_admtController->angle_errors_fft_phase_pre.begin(), m_admtController->angle_errors_fft_phase_pre.end()); + + QVector h1Mag = { H1_MAG_ANGLE }; + QVector h2Mag = { H2_MAG_ANGLE }; + QVector h3Mag = { H3_MAG_ANGLE }; + QVector h8Mag = { H8_MAG_ANGLE }; + QVector h1Phase = { H1_PHASE_ANGLE }; + QVector h2Phase = { H2_PHASE_ANGLE }; + QVector h3Phase = { H3_PHASE_ANGLE }; + QVector h8Phase = { H8_PHASE_ANGLE }; + + fm.save(graphDataList, "Raw Data"); + fm.save(preCalibrationAngleErrorsFFTMagnitude, "Pre-Calibration Angle Errors FFT Magnitude"); + fm.save(preCalibrationAngleErrorsFFTPhase, "Pre-Calibration Angle Errors FFT Phase"); + fm.save(h1Mag, "H1 Mag"); + fm.save(h2Mag, "H2 Mag"); + fm.save(h3Mag, "H3 Mag"); + fm.save(h8Mag, "H8 Mag"); + fm.save(h1Phase, "H1 Phase"); + fm.save(h2Phase, "H2 Phase"); + fm.save(h3Phase, "H3 Phase"); + fm.save(h8Phase, "H8 Phase"); + + fm.performWrite(withScopyHeader); + } } -void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, int& variable) +void HarmonicCalibration::toggleTabSwitching(bool value) { - QComboBox *combo = menuCombo->combo(); - connect(combo, QOverload::of(&QComboBox::currentIndexChanged), [=, &variable]() { - variable = qvariant_cast(combo->currentData()); - }); + tabWidget->setTabEnabled(0, value); + tabWidget->setTabEnabled(2, value); + tabWidget->setTabEnabled(3, value); } -void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax) +void HarmonicCalibration::canStartMotor(bool value) { - connect(lineEdit, &QLineEdit::editingFinished, [=, &vmax]() { - bool ok; - double rps = lineEdit->text().toDouble(&ok); - if (ok) { - vmax = convertRPStoVMAX(rps); - // StatusBarManager::pushMessage("Converted VMAX: " + QString::number(vmax)); - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - amax = convertAccelTimetoAMAX(motorAccelTimeSpinBox->lineEdit()->text().toDouble()); - // StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); - writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - } else { - lineEdit->setText(QString::number(convertVMAXtoRPS(vmax))); - } - }); + calibrationStartMotorButton->setEnabled(value); } -void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit* lineEdit, double& amax) +void HarmonicCalibration::canCalibrate(bool value) { - connect(lineEdit, &QLineEdit::editingFinished, [=, &amax]() { - bool ok; - double accelTime = lineEdit->text().toDouble(&ok); - if (ok) { - amax = convertAccelTimetoAMAX(accelTime); - // StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); - } else { - lineEdit->setText(QString::number(convertAMAXtoAccelTime(amax))); - } - }); + calibrateDataButton->setEnabled(value); } -void HarmonicCalibration::connectRegisterBlockToRegistry(RegisterBlockWidget* widget) +void HarmonicCalibration::toggleMotorControls(bool value) { - uint32_t *readValue = new uint32_t; - connect(widget->readButton(), &QPushButton::clicked, this, [=]{ - bool ok = false, success = false; + motorMaxVelocitySpinBox->setEnabled(value); + motorAccelTimeSpinBox->setEnabled(value); + motorMaxDisplacementSpinBox->setEnabled(value); + m_calibrationMotorRampModeMenuCombo->setEnabled(value); + motorTargetPositionSpinBox->setEnabled(value); +} - if(widget->getCnvPage() != UINT32_MAX) +void HarmonicCalibration::clearCalibrationSamples() +{ + graphDataList.clear(); + calibrationRawDataPlotChannel->curve()->setData(nullptr); + calibrationSineDataPlotChannel->curve()->setData(nullptr); + calibrationCosineDataPlotChannel->curve()->setData(nullptr); + calibrationRawDataPlotWidget->replot(); +} + +void HarmonicCalibration::clearCalibrationSineCosine() +{ + calibrationSineDataPlotChannel->curve()->setData(nullptr); + calibrationCosineDataPlotChannel->curve()->setData(nullptr); + calibrationRawDataPlotWidget->replot(); +} + +void HarmonicCalibration::clearPostCalibrationSamples() +{ + graphPostDataList.clear(); + postCalibrationRawDataPlotChannel->curve()->setData(nullptr); + postCalibrationSineDataPlotChannel->curve()->setData(nullptr); + postCalibrationCosineDataPlotChannel->curve()->setData(nullptr); + postCalibrationRawDataPlotWidget->replot(); +} + +void HarmonicCalibration::clearAngleErrorGraphs() +{ + angleErrorPlotChannel->curve()->setData(nullptr); + angleErrorPlotWidget->replot(); + FFTAngleErrorMagnitudeChannel->curve()->setData(nullptr); + FFTAngleErrorPhaseChannel->curve()->setData(nullptr); + FFTAngleErrorPlotWidget->replot(); +} + +void HarmonicCalibration::clearCorrectedAngleErrorGraphs() +{ + correctedErrorPlotChannel->curve()->setData(nullptr); + correctedErrorPlotWidget->replot(); + FFTCorrectedErrorMagnitudeChannel->curve()->setData(nullptr); + FFTCorrectedErrorPhaseChannel->curve()->setData(nullptr); + FFTCorrectedErrorPlotWidget->replot(); +} +#pragma endregion + +#pragma region Motor Methods +bool HarmonicCalibration::moveMotorToPosition(double& position, bool validate) +{ + bool success = false; + bool canRead = true; + if(writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, position) == 0){ + if(validate){ + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) + { + while(target_pos != current_pos && canRead) { + canRead = readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0 ? true : false; + } + if(canRead) success = true; + } + } + } + + return success; +} + +bool HarmonicCalibration::resetCurrentPositionToZero() +{ + bool success = false; + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) + { + if(current_pos != 0 && + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0) == 0 && + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) { - ok = this->changeCNVPage(widget->getCnvPage()); + while(current_pos != 0){ + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) != 0) break; + QThread::msleep(readMotorDebounce); + } + if(current_pos == 0) + { + resetToZero = false; + success = true; + } } - else { ok = true; } + else{ + success = true; + } + } + + return success; +} + +void HarmonicCalibration::stopMotor() +{ + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); +} + +int HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value) +{ + int result = -1; + if(!isDebug){ + result = m_admtController->getDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), + m_admtController->getMotorAttribute(attribute), + &value); + } + return result; +} + +int HarmonicCalibration::writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value) +{ + int result = -1; + if(!isDebug){ + result = m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), + m_admtController->getMotorAttribute(attribute), + value); + } + return result; +} +#pragma endregion + +#pragma region Utility Methods +void HarmonicCalibration::utilityTask(){ + updateDigioMonitor(); + updateFaultRegister(); + if(hasMTDiagnostics){ + updateMTDiagRegister(); + updateMTDiagnostics(); + } + commandLogWrite(""); +} + +void HarmonicCalibration::toggleUtilityTask(bool run) +{ + if(run){ + utilityTimer->start(utilityTimerRate); + } + else{ + utilityTimer->stop(); + } +} + +void HarmonicCalibration::updateDigioMonitor(){ + uint32_t *digioRegValue = new uint32_t; + uint32_t digioEnPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + if(changeCNVPage(digioEnPage)) + { + uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN); + + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), digioRegisterAddress, digioRegValue) != -1){ + std::map digioBitMapping = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*digioRegValue)); + if(digioBitMapping.at("DIGIO0EN")){ + if(!digioBitMapping.at("BUSY")){ + changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor); + DIGIOBusyStatusLED->setName("BUSY"); + } + else{ + changeStatusLEDColor(DIGIOBusyStatusLED, gpioLEDColor); + DIGIOBusyStatusLED->setName("GPIO0"); + } + } + else { + changeStatusLEDColor(DIGIOBusyStatusLED, faultLEDColor, false); + DIGIOBusyStatusLED->setName("DIGIO0"); + } + + if(digioBitMapping.at("DIGIO1EN")){ + if(!digioBitMapping.at("CNV")){ + changeStatusLEDColor(DIGIOCNVStatusLED, statusLEDColor); + DIGIOCNVStatusLED->setName("CNV"); + } + else{ + changeStatusLEDColor(DIGIOCNVStatusLED, gpioLEDColor); + DIGIOCNVStatusLED->setName("GPIO1"); + } + } + else { + changeStatusLEDColor(DIGIOCNVStatusLED, faultLEDColor, false); + DIGIOCNVStatusLED->setName("DIGIO1"); + } + + if(digioBitMapping.at("DIGIO2EN")){ + if(!digioBitMapping.at("SENT")){ + changeStatusLEDColor(DIGIOSENTStatusLED, statusLEDColor); + DIGIOSENTStatusLED->setName("SENT"); + } + else{ + changeStatusLEDColor(DIGIOSENTStatusLED, gpioLEDColor); + DIGIOSENTStatusLED->setName("GPIO2"); + } + } + else { + changeStatusLEDColor(DIGIOSENTStatusLED, faultLEDColor, false); + DIGIOSENTStatusLED->setName("DIGIO2"); + } + + if(digioBitMapping.at("DIGIO3EN")){ + if(!digioBitMapping.at("ACALC")){ + changeStatusLEDColor(DIGIOACALCStatusLED, statusLEDColor); + DIGIOACALCStatusLED->setName("ACALC"); + } + else{ + changeStatusLEDColor(DIGIOACALCStatusLED, gpioLEDColor); + DIGIOACALCStatusLED->setName("GPIO3"); + } + } + else { + changeStatusLEDColor(DIGIOACALCStatusLED, faultLEDColor, false); + DIGIOACALCStatusLED->setName("DIGIO3"); + } + + if(digioBitMapping.at("DIGIO4EN")){ + if(!digioBitMapping.at("FAULT")){ + changeStatusLEDColor(DIGIOFaultStatusLED, statusLEDColor); + DIGIOFaultStatusLED->setName("FAULT"); + } + else{ + changeStatusLEDColor(DIGIOFaultStatusLED, gpioLEDColor); + DIGIOFaultStatusLED->setName("GPIO4"); + } + } + else { + changeStatusLEDColor(DIGIOFaultStatusLED, faultLEDColor, false); + DIGIOFaultStatusLED->setName("DIGIO4"); + } + + if(digioBitMapping.at("DIGIO5EN")){ + if(!digioBitMapping.at("BOOTLOAD")){ + changeStatusLEDColor(DIGIOBootloaderStatusLED, statusLEDColor); + DIGIOBootloaderStatusLED->setName("BOOTLOAD"); + } + else{ + changeStatusLEDColor(DIGIOBootloaderStatusLED, gpioLEDColor); + DIGIOBootloaderStatusLED->setName("GPIO5"); + } + } + else { + changeStatusLEDColor(DIGIOBootloaderStatusLED, faultLEDColor, false); + DIGIOBootloaderStatusLED->setName("DIGIO5"); + } + + commandLogWrite("DIGIOEN: 0b" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); + } + else{ commandLogWrite("Failed to read DIGIOEN Register"); } + } + +} + +bool HarmonicCalibration::updateDIGIOToggle() +{ + uint32_t *DIGIOENRegisterValue = new uint32_t; + uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + bool success = false; + + if(changeCNVPage(DIGIOENPage)){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) + { + map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); + DIGIO0ENToggleSwitch->setChecked(DIGIOSettings["DIGIO0EN"]); + DIGIO1ENToggleSwitch->setChecked(DIGIOSettings["DIGIO1EN"]); + DIGIO2ENToggleSwitch->setChecked(DIGIOSettings["DIGIO2EN"]); + DIGIO3ENToggleSwitch->setChecked(DIGIOSettings["DIGIO3EN"]); + DIGIO4ENToggleSwitch->setChecked(DIGIOSettings["DIGIO4EN"]); + DIGIO5ENToggleSwitch->setChecked(DIGIOSettings["DIGIO5EN"]); + DIGIO0FNCToggleSwitch->setChecked(DIGIOSettings["BUSY"]); + DIGIO1FNCToggleSwitch->setChecked(DIGIOSettings["CNV"]); + DIGIO2FNCToggleSwitch->setChecked(DIGIOSettings["SENT"]); + DIGIO3FNCToggleSwitch->setChecked(DIGIOSettings["ACALC"]); + DIGIO4FNCToggleSwitch->setChecked(DIGIOSettings["FAULT"]); + DIGIO5FNCToggleSwitch->setChecked(DIGIOSettings["BOOTLOAD"]); + success = true; + } + } + return success; +} + +void HarmonicCalibration::updateMTDiagnostics(){ + uint32_t *mtDiag1RegValue = new uint32_t; + uint32_t *mtDiag2RegValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + + uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1); + uint32_t mtDiag2RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG2); + + uint32_t mtDiag1PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); + uint32_t mtDiag2PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2); + + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag1PageValue) != -1){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ + if(*cnvPageRegValue == mtDiag1PageValue){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1){ + std::map mtDiag1BitMapping = m_admtController->getDiag1RegisterBitMapping_Afe(static_cast(*mtDiag1RegValue), is5V); + + afeDiag2 = mtDiag1BitMapping.at("AFE Diagnostic 2"); + AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); + } + else{ commandLogWrite("Failed to read MT Diagnostic 1 Register"); } + } + else{ commandLogWrite("CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); } + } + else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 1"); } + } + else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 1"); } + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag2PageValue) != -1){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ + if(*cnvPageRegValue == mtDiag2PageValue){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag2RegisterAddress, mtDiag2RegValue) != -1){ + std::map mtDiag2BitMapping = m_admtController->getDiag2RegisterBitMapping(static_cast(*mtDiag2RegValue)); + + afeDiag0 = mtDiag2BitMapping.at("AFE Diagnostic 0 (-57%)"); + afeDiag1 = mtDiag2BitMapping.at("AFE Diagnostic 1 (+57%)"); + AFEDIAG0LineEdit->setText(QString::number(afeDiag0) + " V"); + AFEDIAG1LineEdit->setText(QString::number(afeDiag1) + " V"); + + commandLogWrite("DIAG2: 0b" + QString::number(static_cast(*mtDiag2RegValue), 2).rightJustified(16, '0')); + } + else{ commandLogWrite("Failed to read MT Diagnostic 2 Register"); } + } + else{ commandLogWrite("CNVPAGE for MT Diagnostic 2 is a different value, abort reading"); } + } + else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 2"); } + } + else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 2"); } +} + +void HarmonicCalibration::updateMTDiagRegister(){ + uint32_t *mtDiag1RegValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1); + uint32_t mtDiag1PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag1PageValue) != -1){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ + if(*cnvPageRegValue == mtDiag1PageValue){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1){ + std::map mtDiag1BitMapping = m_admtController->getDiag1RegisterBitMapping_Register(static_cast(*mtDiag1RegValue)); + changeStatusLEDColor(R0StatusLED, statusLEDColor, mtDiag1BitMapping.at("R0")); + changeStatusLEDColor(R1StatusLED, statusLEDColor, mtDiag1BitMapping.at("R1")); + changeStatusLEDColor(R2StatusLED, statusLEDColor, mtDiag1BitMapping.at("R2")); + changeStatusLEDColor(R3StatusLED, statusLEDColor, mtDiag1BitMapping.at("R3")); + changeStatusLEDColor(R4StatusLED, statusLEDColor, mtDiag1BitMapping.at("R4")); + changeStatusLEDColor(R5StatusLED, statusLEDColor, mtDiag1BitMapping.at("R5")); + changeStatusLEDColor(R6StatusLED, statusLEDColor, mtDiag1BitMapping.at("R6")); + changeStatusLEDColor(R7StatusLED, statusLEDColor, mtDiag1BitMapping.at("R7")); + commandLogWrite("DIAG1: 0b" + QString::number(static_cast(*mtDiag1RegValue), 2).rightJustified(16, '0')); + } + else{ commandLogWrite("Failed to read MT Diagnostic 1 Register"); } + } + else{ commandLogWrite("CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); } + } + else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 1"); } + } + else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 1"); } +} + +void HarmonicCalibration::updateFaultRegister(){ + uint32_t *faultRegValue = new uint32_t; + uint32_t faultRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, 0); // Write all zeros to fault before read + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, faultRegValue); + + if(*faultRegValue != -1){ + std::map faultBitMapping = m_admtController->getFaultRegisterBitMapping(static_cast(*faultRegValue)); + changeStatusLEDColor(VDDUnderVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDD Under Voltage")); + changeStatusLEDColor(VDDOverVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDD Over Voltage")); + changeStatusLEDColor(VDRIVEUnderVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDRIVE Under Voltage")); + changeStatusLEDColor(VDRIVEOverVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDRIVE Over Voltage")); + changeStatusLEDColor(AFEDIAGStatusLED, faultLEDColor, faultBitMapping.at("AFE Diagnostic")); + changeStatusLEDColor(NVMCRCFaultStatusLED, faultLEDColor, faultBitMapping.at("NVM CRC Fault")); + changeStatusLEDColor(ECCDoubleBitErrorStatusLED, faultLEDColor, faultBitMapping.at("ECC Double Bit Error")); + changeStatusLEDColor(OscillatorDriftStatusLED, faultLEDColor, faultBitMapping.at("Oscillator Drift")); + changeStatusLEDColor(CountSensorFalseStateStatusLED, faultLEDColor, faultBitMapping.at("Count Sensor False State")); + changeStatusLEDColor(AngleCrossCheckStatusLED, faultLEDColor, faultBitMapping.at("Angle Cross Check")); + changeStatusLEDColor(TurnCountSensorLevelsStatusLED, faultLEDColor, faultBitMapping.at("Turn Count Sensor Levels")); + changeStatusLEDColor(MTDIAGStatusLED, faultLEDColor, faultBitMapping.at("MT Diagnostic")); + changeStatusLEDColor(TurnCounterCrossCheckStatusLED, faultLEDColor, faultBitMapping.at("Turn Counter Cross Check")); + changeStatusLEDColor(RadiusCheckStatusLED, faultLEDColor, faultBitMapping.at("AMR Radius Check")); + changeStatusLEDColor(SequencerWatchdogStatusLED, faultLEDColor, faultBitMapping.at("Sequencer Watchdog")); + + commandLogWrite("FAULT: 0b" + QString::number(static_cast(*faultRegValue), 2).rightJustified(16, '0')); + } + else{ commandLogWrite("Failed to read FAULT Register"); } +} + +void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool& value) +{ + toggleUtilityTask(false); + + uint32_t *DIGIOENRegisterValue = new uint32_t; + uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + + bool success = false; + + if(changeCNVPage(DIGIOENPage)) + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) + { + map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); + + DIGIOSettings[DIGIOENName] = value; + + uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); + + if(changeCNVPage(DIGIOENPage)){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + static_cast(newRegisterValue)) != -1) + { + success = updateDIGIOToggle(); + } + } + + } + } + + if(!success) { StatusBarManager::pushMessage("Failed to toggle" + QString::fromStdString(DIGIOENName) + " " + QString(value ? "on" : "off")); } + + toggleUtilityTask(true); +} - if(ok){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) - { widget->setValue(*readValue); } - } - else{ StatusBarManager::pushMessage("Failed to read registry"); } - }); - if(widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::READWRITE || - widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::WRITE){ - connect(widget->writeButton(), &QPushButton::clicked, this, [=]{ - bool ok = false, success = false; +void HarmonicCalibration::toggleAllDIGIOEN(bool value) +{ + toggleUtilityTask(false); + uint32_t *DIGIOENRegisterValue = new uint32_t; + uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - if(widget->getCnvPage() != UINT32_MAX) - { - ok = this->changeCNVPage(widget->getCnvPage()); - } - else { ok = true; } + bool success = false; - if(ok){ - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), widget->getValue()) == 0) - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) - { - widget->setValue(*readValue); - success = true; - } + if(changeCNVPage(DIGIOENPage)) + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) + { + map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue));; + DIGIOSettings["DIGIO5EN"] = value; + DIGIOSettings["DIGIO4EN"] = value; + DIGIOSettings["DIGIO3EN"] = value; + DIGIOSettings["DIGIO2EN"] = value; + DIGIOSettings["DIGIO1EN"] = value; + DIGIOSettings["DIGIO0EN"] = value; + uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); + + if(changeCNVPage(DIGIOENPage)){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + static_cast(newRegisterValue)) != -1) + { + success = updateDIGIOToggle(); } } - - if(!success) { StatusBarManager::pushMessage("Failed to write to registry"); } - }); + } } + + if(!success) { StatusBarManager::pushMessage("Failed to toggle all GPIO outputs " + QString(value ? "on" : "off")); } + + toggleUtilityTask(true); } -void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox* widget, PlotChannel* channel, AcquisitionDataKey key) +void HarmonicCalibration::toggleMTDiagnostics(int mode) { - connect(widget, &QCheckBox::stateChanged, [=](int state){ - if(state == Qt::Checked){ - channel->setEnabled(true); - acquisitionDataMap[key] = true; - } - else{ - channel->setEnabled(false); - acquisitionDataMap[key] = false; - } - }); + switch(mode){ + case 0: + MTDiagnosticsScrollArea->hide(); + hasMTDiagnostics = false; + break; + case 1: + MTDiagnosticsScrollArea->show(); + hasMTDiagnostics = true; + break; + } } -double HarmonicCalibration::convertRPStoVMAX(double rps) -{ - return (rps * motorMicrostepPerRevolution * motorTimeUnit); +void HarmonicCalibration::toggleFaultRegisterMode(int mode) +{ + switch(mode){ + case 0: + AFEDIAGStatusLED->hide(); + OscillatorDriftStatusLED->hide(); + AngleCrossCheckStatusLED->hide(); + TurnCountSensorLevelsStatusLED->hide(); + MTDIAGStatusLED->hide(); + SequencerWatchdogStatusLED->hide(); + break; + case 1: + AFEDIAGStatusLED->show(); + OscillatorDriftStatusLED->show(); + AngleCrossCheckStatusLED->show(); + TurnCountSensorLevelsStatusLED->show(); + MTDIAGStatusLED->show(); + SequencerWatchdogStatusLED->show(); + break; + } } -double HarmonicCalibration::convertVMAXtoRPS(double vmax) +void HarmonicCalibration::resetDIGIO() { - return (vmax / motorMicrostepPerRevolution / motorTimeUnit); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + 0x241b); } -double HarmonicCalibration::convertAccelTimetoAMAX(double accelTime) +void HarmonicCalibration::commandLogWrite(QString message) { - return (rotate_vmax * 131072 / accelTime / motorfCLK); + commandLogPlainTextEdit->appendPlainText(message); } -double HarmonicCalibration::convertAMAXtoAccelTime(double amax) +void HarmonicCalibration::clearCommandLog(){ + commandLogPlainTextEdit->clear(); +} +#pragma endregion + +#pragma region Register Methods +void HarmonicCalibration::readAllRegisters() { - return ((rotate_vmax * 131072) / (amax * motorfCLK)); + readAllRegistersButton->setEnabled(false); + readAllRegistersButton->setText(QString("Reading Registers...")); + QTimer::singleShot(1000, this, [this](){ + readAllRegistersButton->setEnabled(true); + readAllRegistersButton->setText(QString("Read All Registers")); + }); + + cnvPageRegisterBlock->readButton()->click(); + digIORegisterBlock->readButton()->click(); + faultRegisterBlock->readButton()->click(); + generalRegisterBlock->readButton()->click(); + digIOEnRegisterBlock->readButton()->click(); + eccDcdeRegisterBlock->readButton()->click(); + eccDisRegisterBlock->readButton()->click(); + absAngleRegisterBlock->readButton()->click(); + angleRegisterBlock->readButton()->click(); + sineRegisterBlock->readButton()->click(); + cosineRegisterBlock->readButton()->click(); + tmp0RegisterBlock->readButton()->click(); + cnvCntRegisterBlock->readButton()->click(); + uniqID0RegisterBlock->readButton()->click(); + uniqID1RegisterBlock->readButton()->click(); + uniqID2RegisterBlock->readButton()->click(); + uniqID3RegisterBlock->readButton()->click(); + h1MagRegisterBlock->readButton()->click(); + h1PhRegisterBlock->readButton()->click(); + h2MagRegisterBlock->readButton()->click(); + h2PhRegisterBlock->readButton()->click(); + h3MagRegisterBlock->readButton()->click(); + h3PhRegisterBlock->readButton()->click(); + h8MagRegisterBlock->readButton()->click(); + h8PhRegisterBlock->readButton()->click(); + + if(generalRegisterMap.at("Sequence Type") == 1){ + angleSecRegisterBlock->readButton()->click(); + secAnglIRegisterBlock->readButton()->click(); + secAnglQRegisterBlock->readButton()->click(); + tmp1RegisterBlock->readButton()->click(); + angleCkRegisterBlock->readButton()->click(); + radiusRegisterBlock->readButton()->click(); + diag1RegisterBlock->readButton()->click(); + diag2RegisterBlock->readButton()->click(); + } } -void HarmonicCalibration::updateLabelValue(QLabel* label, int channelIndex) +void HarmonicCalibration::toggleRegisters(int mode) { - switch(channelIndex) - { - case ADMTController::Channel::ROTATION: - label->setText(QString("%1").arg(rotation, 0, 'f', 2) + "°"); - break; - case ADMTController::Channel::ANGLE: - label->setText(QString("%1").arg(angle, 0, 'f', 2) + "°"); - break; - case ADMTController::Channel::COUNT: - label->setText(QString::number(count)); + switch(mode){ + case 0: + angleSecRegisterBlock->hide(); + secAnglIRegisterBlock->hide(); + secAnglQRegisterBlock->hide(); + tmp1RegisterBlock->hide(); + angleCkRegisterBlock->hide(); + radiusRegisterBlock->hide(); + diag1RegisterBlock->hide(); + diag2RegisterBlock->hide(); break; - case ADMTController::Channel::TEMPERATURE: - label->setText(QString("%1").arg(temp, 0, 'f', 2) + "°C"); + case 1: + angleSecRegisterBlock->show(); + secAnglIRegisterBlock->show(); + secAnglQRegisterBlock->show(); + tmp1RegisterBlock->show(); + angleCkRegisterBlock->show(); + radiusRegisterBlock->show(); + diag1RegisterBlock->show(); + diag2RegisterBlock->show(); break; } } +#pragma endregion -bool HarmonicCalibration::updateChannelValue(int channelIndex) +#pragma region UI Helper Methods +void HarmonicCalibration::updateLabelValue(QLabel* label, int channelIndex) { - bool success = false; switch(channelIndex) { case ADMTController::Channel::ROTATION: - rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, 1); - if(rotation == static_cast(UINT64_MAX)) { success = false; } + label->setText(QString("%1").arg(rotation, 0, 'f', 2) + "°"); break; case ADMTController::Channel::ANGLE: - angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, 1); - if(angle == static_cast(UINT64_MAX)) { success = false; } + label->setText(QString("%1").arg(angle, 0, 'f', 2) + "°"); break; case ADMTController::Channel::COUNT: - count = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, 1); - if(count == static_cast(UINT64_MAX)) { success = false; } + label->setText(QString::number(count)); break; case ADMTController::Channel::TEMPERATURE: - temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, 1); - if(temp == static_cast(UINT64_MAX)) { success = false; } + label->setText(QString("%1").arg(temp, 0, 'f', 2) + "°C"); break; } - return success; -} - -int HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value) -{ - int result = -1; - if(!isDebug){ - result = m_admtController->getDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), - m_admtController->getMotorAttribute(attribute), - &value); - } - return result; -} - -int HarmonicCalibration::writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value) -{ - int result = -1; - if(!isDebug){ - result = m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), - m_admtController->getMotorAttribute(attribute), - value); - } - return result; } void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute) @@ -3134,672 +3382,362 @@ void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorA case ADMTController::MotorAttribute::TARGET_POS: label->setText(QString::number(target_pos)); break; - case ADMTController::MotorAttribute::CURRENT_POS: - label->setText(QString::number(current_pos)); + case ADMTController::MotorAttribute::CURRENT_POS: + label->setText(QString::number(current_pos)); + break; + case ADMTController::MotorAttribute::RAMP_MODE: + label->setText(QString::number(ramp_mode)); + break; + } +} + +bool HarmonicCalibration::updateChannelValue(int channelIndex) +{ + bool success = false; + switch(channelIndex) + { + case ADMTController::Channel::ROTATION: + rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, 1); + if(rotation == static_cast(UINT64_MAX)) { success = false; } + break; + case ADMTController::Channel::ANGLE: + angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, 1); + if(angle == static_cast(UINT64_MAX)) { success = false; } + break; + case ADMTController::Channel::COUNT: + count = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, 1); + if(count == static_cast(UINT64_MAX)) { success = false; } break; - case ADMTController::MotorAttribute::RAMP_MODE: - label->setText(QString::number(ramp_mode)); + case ADMTController::Channel::TEMPERATURE: + temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, 1); + if(temp == static_cast(UINT64_MAX)) { success = false; } break; } + return success; } -void HarmonicCalibration::calibrationUITask() -{ - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); - updateFaultStatusLEDColor(calibrationFaultRegisterLEDWidget, deviceStatusFault); +void HarmonicCalibration::updateLineEditValue(QLineEdit* lineEdit, double value){ + if(value == static_cast(UINT64_MAX)) { lineEdit->setText("N/A"); } + else { lineEdit->setText(QString::number(value)); } +} - if(isStartMotor) - { - if(isPostCalibration){ - postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); - postCalibrationRawDataPlotWidget->replot(); - } - else{ - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotWidget->replot(); - } - } +void HarmonicCalibration::toggleWidget(QPushButton *widget, bool value){ + widget->setEnabled(value); } -void HarmonicCalibration::getCalibrationSamples() +void HarmonicCalibration::changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel) { - if(resetCurrentPositionToZero()){ - if(isPostCalibration){ - int currentSamplesCount = graphPostDataList.size(); - while(isStartMotor && currentSamplesCount < totalSamplesCount){ - target_pos = current_pos + -408; - moveMotorToPosition(target_pos, true); - updateChannelValue(ADMTController::Channel::ANGLE); - graphPostDataList.append(angle); - currentSamplesCount++; - } - } - else{ - int currentSamplesCount = graphDataList.size(); - while(isStartMotor && currentSamplesCount < totalSamplesCount){ - target_pos = current_pos + -408; - if(moveMotorToPosition(target_pos, true) == false) { m_admtController->disconnectADMT(); } - if(updateChannelValue(ADMTController::Channel::ANGLE)) { break; } - graphDataList.append(angle); - currentSamplesCount++; - } - } - } + customSwitch->setOnText(onLabel); + customSwitch->setOffText(offLabel); +} - stopMotor(); +void HarmonicCalibration::changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked) +{ + menuControlButton->setColor(color); + menuControlButton->checkBox()->setChecked(checked); } -bool HarmonicCalibration::resetCurrentPositionToZero() +void HarmonicCalibration::updateFaultStatusLEDColor(MenuControlButton *widget, bool value) { - bool success = false; - if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) - { - if(current_pos != 0 && - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0) == 0 && - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) - { - while(current_pos != 0){ - if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) != 0) break; - QThread::msleep(readMotorDebounce); - } - if(current_pos == 0) - { - resetToZero = false; - success = true; - } - } - else{ - success = true; - } - } - - return success; + if(value) changeStatusLEDColor(widget, faultLEDColor); + else changeStatusLEDColor(widget, statusLEDColor); } -void HarmonicCalibration::startMotor() +MenuControlButton *HarmonicCalibration::createStatusLEDWidget(const QString title, QColor color, QWidget *parent) { - toggleTabSwitching(false); - toggleMotorControls(false); + MenuControlButton *menuControlButton = new MenuControlButton(parent); + menuControlButton->setName(title); + menuControlButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); + menuControlButton->setOpenMenuChecksThis(true); + menuControlButton->setDoubleClickToOpenMenu(true); + menuControlButton->setColor(color); + menuControlButton->button()->setVisible(false); + menuControlButton->setCheckable(true); + menuControlButton->checkBox()->setChecked(false); + menuControlButton->setEnabled(false); + menuControlButton->layout()->setMargin(8); + return menuControlButton; +} - if(resetToZero && !isPostCalibration){ - clearCalibrationSamples(); - clearPostCalibrationSamples(); - clearAngleErrorGraphs(); - clearCorrectedAngleErrorGraphs(); - } +MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString title, QColor color, QWidget *parent) +{ + MenuControlButton *menuControlButton = new MenuControlButton(parent); + menuControlButton->setName(title); + menuControlButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); + menuControlButton->setOpenMenuChecksThis(true); + menuControlButton->setDoubleClickToOpenMenu(true); + menuControlButton->setColor(color); + menuControlButton->button()->setVisible(false); + menuControlButton->setCheckable(false); + menuControlButton->checkBox()->setChecked(true); + menuControlButton->layout()->setMargin(0); + return menuControlButton; +} +#pragma endregion - if(isPostCalibration) - postCalibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); - else - calibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); - if(isPostCalibration) - calibrationDataGraphTabWidget->setCurrentIndex(1); // Set tab to Post Calibration Samples - else - calibrationDataGraphTabWidget->setCurrentIndex(0); // Set tab to Calibration Samples - clearCalibrateDataButton->setEnabled(false); - QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getCalibrationSamples); - QFutureWatcher *watcher = new QFutureWatcher(this); - connect(watcher, &QFutureWatcher::finished, this, [=]() { - toggleTabSwitching(true); - toggleMotorControls(true); - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotChannel->xAxis()->setMax(graphDataList.size()); - calibrationRawDataPlotWidget->replot(); - isStartMotor = false; - calibrationStartMotorButton->setChecked(false); - clearCalibrateDataButton->setEnabled(true); - - if(isPostCalibration) - { - if(static_cast(graphPostDataList.size()) == totalSamplesCount) - { - computeSineCosineOfAngles(graphPostDataList); - m_admtController->postcalibrate(vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, samplesPerCycle); - populateCorrectedAngleErrorGraphs(); - isPostCalibration = false; - isStartMotor = false; - resetToZero = true; - canCalibrate(false); - } - } - else{ - if(static_cast(graphDataList.size()) == totalSamplesCount) - { - computeSineCosineOfAngles(graphDataList); - calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); - populateAngleErrorGraphs(); - calculateHarmonicValues(); - canStartMotor(false); - canCalibrate(true); - } - else{ - resetToZero = true; - } - } - }); - connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater())); - watcher->setFuture(future); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#pragma region Connect Methods +void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max) +{ + QIntValidator *validator = new QIntValidator(min, max, this); + lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, min, max]() { + bool ok; + int value = lineEdit->text().toInt(&ok); + if (ok && value >= min && value <= max) { + variable = value; + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + +void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit) +{ + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, unit]() { + bool ok; + double value = lineEdit->text().replace(unit, "").trimmed().toDouble(&ok); + if (ok) { + variable = value; + + } else { + lineEdit->setText(QString::number(variable) + " " + unit); + } + }); +} + +void HarmonicCalibration::connectLineEditToDouble(QLineEdit* lineEdit, double& variable) +{ + // QDoubleValidator *validator = new QDoubleValidator(this); + // validator->setNotation(QDoubleValidator::StandardNotation); + // lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok){ + variable = value; + } else { + lineEdit->setText(QString::number(variable, 'f', 2)); + } + }); } -void HarmonicCalibration::toggleTabSwitching(bool value) +void HarmonicCalibration::connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute) { - tabWidget->setTabEnabled(0, value); - tabWidget->setTabEnabled(2, value); - tabWidget->setTabEnabled(3, value); + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, [=, &variable]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok) { + variable = value; + writeMotorAttributeValue(attribute, variable); + + } else { + lineEdit->setText(QString::number(variable)); + } + }); } -void HarmonicCalibration::populateCorrectedAngleErrorGraphs() +void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, double& variable) { - QVector correctedError(m_admtController->correctedError.begin(), m_admtController->correctedError.end()); - QVector FFTCorrectedErrorMagnitude(m_admtController->FFTCorrectedErrorMagnitude.begin(), m_admtController->FFTCorrectedErrorMagnitude.end()); - QVector FFTCorrectedErrorPhase(m_admtController->FFTCorrectedErrorPhase.begin(), m_admtController->FFTCorrectedErrorPhase.end()); - - correctedErrorPlotChannel->curve()->setSamples(correctedError); - auto correctedErrorMagnitudeMinMax = std::minmax_element(correctedError.begin(), correctedError.end()); - correctedErrorYPlotAxis->setInterval(*correctedErrorMagnitudeMinMax.first, *correctedErrorMagnitudeMinMax.second); - correctedErrorXPlotAxis->setMax(correctedError.size()); - correctedErrorPlotWidget->replot(); - - FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); - FFTCorrectedErrorMagnitudeChannel->curve()->setSamples(FFTCorrectedErrorMagnitude); - auto FFTCorrectedErrorMagnitudeMinMax = std::minmax_element(FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); - auto FFTCorrectedErrorPhaseMinMax = std::minmax_element(FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); - double FFTCorrectedErrorPlotMin = *FFTCorrectedErrorMagnitudeMinMax.first < *FFTCorrectedErrorPhaseMinMax.first ? *FFTCorrectedErrorMagnitudeMinMax.first : *FFTCorrectedErrorPhaseMinMax.first; - double FFTCorrectedErrorPlotMax = *FFTCorrectedErrorMagnitudeMinMax.second > *FFTCorrectedErrorPhaseMinMax.second ? *FFTCorrectedErrorMagnitudeMinMax.second : *FFTCorrectedErrorPhaseMinMax.second; - FFTCorrectedErrorYPlotAxis->setInterval(FFTCorrectedErrorPlotMin, FFTCorrectedErrorPlotMax); - FFTCorrectedErrorXPlotAxis->setMax(FFTCorrectedErrorMagnitude.size()); - FFTCorrectedErrorPlotWidget->replot(); - - resultDataTabWidget->setCurrentIndex(2); // Set tab to Angle Error + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), [=, &variable]() { + variable = qvariant_cast(combo->currentData()); + }); } -void HarmonicCalibration::populateAngleErrorGraphs() +void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, int& variable) { - QVector angleError = QVector(m_admtController->angleError.begin(), m_admtController->angleError.end()); - QVector FFTAngleErrorMagnitude = QVector(m_admtController->FFTAngleErrorMagnitude.begin(), m_admtController->FFTAngleErrorMagnitude.end()); - QVector FFTAngleErrorPhase = QVector(m_admtController->FFTAngleErrorPhase.begin(), m_admtController->FFTAngleErrorPhase.end()); - - angleErrorPlotChannel->curve()->setSamples(angleError); - auto angleErrorMinMax = std::minmax_element(angleError.begin(), angleError.end()); - angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, *angleErrorMinMax.second); - angleErrorXPlotAxis->setInterval(0, angleError.size()); - angleErrorPlotWidget->replot(); - - FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); - FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); - auto angleErrorMagnitudeMinMax = std::minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); - auto angleErrorPhaseMinMax = std::minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); - double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first ? *angleErrorMagnitudeMinMax.first : *angleErrorPhaseMinMax.first; - double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second ? *angleErrorMagnitudeMinMax.second : *angleErrorPhaseMinMax.second; - FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); - FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); - FFTAngleErrorPlotWidget->replot(); - - resultDataTabWidget->setCurrentIndex(0); // Set tab to Angle Error + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), [=, &variable]() { + variable = qvariant_cast(combo->currentData()); + }); } -void HarmonicCalibration::canStartMotor(bool value) +void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax) { - calibrationStartMotorButton->setEnabled(value); + connect(lineEdit, &QLineEdit::editingFinished, [=, &vmax]() { + bool ok; + double rps = lineEdit->text().toDouble(&ok); + if (ok) { + vmax = convertRPStoVMAX(rps); + // StatusBarManager::pushMessage("Converted VMAX: " + QString::number(vmax)); + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + amax = convertAccelTimetoAMAX(motorAccelTimeSpinBox->lineEdit()->text().toDouble()); + // StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + } else { + lineEdit->setText(QString::number(convertVMAXtoRPS(vmax))); + } + }); } -void HarmonicCalibration::flashHarmonicValues() +void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit* lineEdit, double& amax) { - if(changeCNVPage(0x02)){ - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), 0x01, 0x02); - - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), - H1_MAG_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), - H1_PHASE_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), - H2_MAG_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), - H2_PHASE_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), - H3_MAG_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), - H3_PHASE_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), - H8_MAG_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), - H8_PHASE_HEX); - - isCalculatedCoeff = true; - displayCalculatedCoeff(); - } - else{ - calibrationLogWrite("Unabled to flash Harmonic Registers!"); - } + connect(lineEdit, &QLineEdit::editingFinished, [=, &amax]() { + bool ok; + double accelTime = lineEdit->text().toDouble(&ok); + if (ok) { + amax = convertAccelTimetoAMAX(accelTime); + // StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); + } else { + lineEdit->setText(QString::number(convertAMAXtoAccelTime(amax))); + } + }); } -void HarmonicCalibration::calculateHarmonicValues() +void HarmonicCalibration::connectRegisterBlockToRegistry(RegisterBlockWidget* widget) { - uint32_t *h1MagCurrent = new uint32_t, - *h1PhaseCurrent = new uint32_t, - *h2MagCurrent = new uint32_t, - *h2PhaseCurrent = new uint32_t, - *h3MagCurrent = new uint32_t, - *h3PhaseCurrent = new uint32_t, - *h8MagCurrent = new uint32_t, - *h8PhaseCurrent = new uint32_t; - - if(changeCNVPage(0x02)) - { - // Read and store current harmonic values - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); - - // Calculate harmonic coefficients (Hex) - H1_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_1), static_cast(*h1MagCurrent), "h1")); - H2_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_2), static_cast(*h2MagCurrent), "h2")); - H3_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_3), static_cast(*h3MagCurrent), "h3")); - H8_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_8), static_cast(*h8MagCurrent), "h8")); - H1_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_1), static_cast(*h1PhaseCurrent))); - H2_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_2), static_cast(*h2PhaseCurrent))); - H3_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_3), static_cast(*h3PhaseCurrent))); - H8_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_8), static_cast(*h8PhaseCurrent))); + uint32_t *readValue = new uint32_t; + connect(widget->readButton(), &QPushButton::clicked, this, [=]{ + bool ok = false, success = false; - calibrationLogWrite(); - calibrationLogWrite(QString("Calculated H1 Mag (Hex): 0x%1").arg(QString::number(H1_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H1 Phase (Hex): 0x%1").arg(QString::number(H1_PHASE_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H2 Mag (Hex): 0x%1").arg(QString::number(H2_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H2 Phase (Hex): 0x%1").arg(QString::number(H2_PHASE_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H3 Mag (Hex): 0x%1").arg(QString::number(H3_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H3 Phase (Hex): 0x%1").arg(QString::number(H3_PHASE_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H8 Mag (Hex): 0x%1").arg(QString::number(H8_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H8 Phase (Hex): 0x%1").arg(QString::number(H8_PHASE_HEX, 16).rightJustified(4, '0'))); + if(widget->getCnvPage() != UINT32_MAX) + { + ok = this->changeCNVPage(widget->getCnvPage()); + } + else { ok = true; } - // Get actual harmonic values from hex - H1_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H1_MAG_HEX), "h1mag"); - H1_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H1_PHASE_HEX), "h1phase"); - H2_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H2_MAG_HEX), "h2mag"); - H2_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H2_PHASE_HEX), "h2phase"); - H3_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H3_MAG_HEX), "h3mag"); - H3_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H3_PHASE_HEX), "h3phase"); - H8_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H8_MAG_HEX), "h8mag"); - H8_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H8_PHASE_HEX), "h8phase"); + if(ok){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) + { widget->setValue(*readValue); } + } + else{ StatusBarManager::pushMessage("Failed to read registry"); } + }); + if(widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::READWRITE || + widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::WRITE){ + connect(widget->writeButton(), &QPushButton::clicked, this, [=]{ + bool ok = false, success = false; - calibrationLogWrite(); - calibrationLogWrite(QString("Calculated H1 Mag (Angle): 0x%1").arg(QString::number(H1_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H1 Phase (Angle): 0x%1").arg(QString::number(H1_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H2 Mag (Angle): 0x%1").arg(QString::number(H2_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H2 Phase (Angle): 0x%1").arg(QString::number(H2_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H3 Mag (Angle): 0x%1").arg(QString::number(H3_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H3 Phase (Angle): 0x%1").arg(QString::number(H3_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H8 Mag (Angle): 0x%1").arg(QString::number(H8_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H8 Phase (Angle): 0x%1").arg(QString::number(H8_PHASE_ANGLE))); + if(widget->getCnvPage() != UINT32_MAX) + { + ok = this->changeCNVPage(widget->getCnvPage()); + } + else { ok = true; } - if(isAngleDisplayFormat) updateCalculatedCoeffAngle(); - else updateCalculatedCoeffHex(); - isCalculatedCoeff = true; + if(ok){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), widget->getValue()) == 0) + { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) + { + widget->setValue(*readValue); + success = true; + } + } + } + + if(!success) { StatusBarManager::pushMessage("Failed to write to registry"); } + }); } } +#pragma endregion -void HarmonicCalibration::postCalibrateData() -{ - calibrationLogWrite("==== Post Calibration Start ====\n"); - flashHarmonicValues(); - calibrationDataGraphTabWidget->setCurrentIndex(1); - isPostCalibration = true; - isStartMotor = true; - resetToZero = true; - startMotor(); -} - -void HarmonicCalibration::updateCalculatedCoeffAngle() -{ - calibrationH1MagLabel->setText(QString::number(H1_MAG_ANGLE, 'f', 2) + "°"); - calibrationH2MagLabel->setText(QString::number(H2_MAG_ANGLE, 'f', 2) + "°"); - calibrationH3MagLabel->setText(QString::number(H3_MAG_ANGLE, 'f', 2) + "°"); - calibrationH8MagLabel->setText(QString::number(H8_MAG_ANGLE, 'f', 2) + "°"); - calibrationH1PhaseLabel->setText("Φ " + QString::number(H1_PHASE_ANGLE, 'f', 2)); - calibrationH2PhaseLabel->setText("Φ " + QString::number(H2_PHASE_ANGLE, 'f', 2)); - calibrationH3PhaseLabel->setText("Φ " + QString::number(H3_PHASE_ANGLE, 'f', 2)); - calibrationH8PhaseLabel->setText("Φ " + QString::number(H8_PHASE_ANGLE, 'f', 2)); +#pragma region Convert Methods +double HarmonicCalibration::convertRPStoVMAX(double rps) +{ + return (rps * motorMicrostepPerRevolution * motorTimeUnit); } -void HarmonicCalibration::resetCalculatedCoeffAngle() +double HarmonicCalibration::convertVMAXtoRPS(double vmax) { - calibrationH1MagLabel->setText("--.--°"); - calibrationH2MagLabel->setText("--.--°"); - calibrationH3MagLabel->setText("--.--°"); - calibrationH8MagLabel->setText("--.--°"); - calibrationH1PhaseLabel->setText("Φ --.--"); - calibrationH2PhaseLabel->setText("Φ --.--"); - calibrationH3PhaseLabel->setText("Φ --.--"); - calibrationH8PhaseLabel->setText("Φ --.--"); + return (vmax / motorMicrostepPerRevolution / motorTimeUnit); } -void HarmonicCalibration::updateCalculatedCoeffHex() +double HarmonicCalibration::convertAccelTimetoAMAX(double accelTime) { - calibrationH1MagLabel->setText(QString("0x%1").arg(H1_MAG_HEX, 4, 16, QChar('0'))); - calibrationH2MagLabel->setText(QString("0x%1").arg(H2_MAG_HEX, 4, 16, QChar('0'))); - calibrationH3MagLabel->setText(QString("0x%1").arg(H3_MAG_HEX, 4, 16, QChar('0'))); - calibrationH8MagLabel->setText(QString("0x%1").arg(H8_MAG_HEX, 4, 16, QChar('0'))); - calibrationH1PhaseLabel->setText(QString("0x%1").arg(H1_PHASE_HEX, 4, 16, QChar('0'))); - calibrationH2PhaseLabel->setText(QString("0x%1").arg(H2_PHASE_HEX, 4, 16, QChar('0'))); - calibrationH3PhaseLabel->setText(QString("0x%1").arg(H3_PHASE_HEX, 4, 16, QChar('0'))); - calibrationH8PhaseLabel->setText(QString("0x%1").arg(H8_PHASE_HEX, 4, 16, QChar('0'))); + return (rotate_vmax * 131072 / accelTime / motorfCLK); } -void HarmonicCalibration::resetCalculatedCoeffHex() +double HarmonicCalibration::convertAMAXtoAccelTime(double amax) { - calibrationH1MagLabel->setText("0x----"); - calibrationH2MagLabel->setText("0x----"); - calibrationH3MagLabel->setText("0x----"); - calibrationH8MagLabel->setText("0x----"); - calibrationH1PhaseLabel->setText("0x----"); - calibrationH2PhaseLabel->setText("0x----"); - calibrationH3PhaseLabel->setText("0x----"); - calibrationH8PhaseLabel->setText("0x----"); + return ((rotate_vmax * 131072) / (amax * motorfCLK)); } +#pragma endregion + + + + -void HarmonicCalibration::displayCalculatedCoeff() -{ - if(isAngleDisplayFormat){ - if(isCalculatedCoeff){ - updateCalculatedCoeffAngle(); - } - else{ - resetCalculatedCoeffAngle(); - } - } - else{ - if(isCalculatedCoeff){ - updateCalculatedCoeffHex(); - } - else{ - resetCalculatedCoeffHex(); - } - } -} -void HarmonicCalibration::calibrationLogWrite(QString message) -{ - logsPlainTextEdit->appendPlainText(message); -} -void HarmonicCalibration::commandLogWrite(QString message) -{ - commandLogPlainTextEdit->appendPlainText(message); -} -void HarmonicCalibration::extractCalibrationData() -{ - QStringList filter; - filter += QString(tr("Comma-separated values files (*.csv)")); - filter += QString(tr("Tab-delimited values files (*.txt)")); - filter += QString(tr("All Files(*)")); - QString selectedFilter = filter[0]; - QString fileName = QFileDialog::getSaveFileName(this, tr("Export"), "", filter.join(";;"), &selectedFilter, QFileDialog::Options()); - if(fileName.split(".").size() <= 1) { - // file name w/o extension. Let's append it - QString ext = selectedFilter.split(".")[1].split(")")[0]; - fileName += "." + ext; - } - if(!fileName.isEmpty()) { - bool withScopyHeader = false; - FileManager fm("HarmonicCalibration"); - fm.open(fileName, FileManager::EXPORT); - QVector preCalibrationAngleErrorsFFTMagnitude(m_admtController->angle_errors_fft_pre.begin(), m_admtController->angle_errors_fft_pre.end()); - QVector preCalibrationAngleErrorsFFTPhase(m_admtController->angle_errors_fft_phase_pre.begin(), m_admtController->angle_errors_fft_phase_pre.end()); - QVector h1Mag = { H1_MAG_ANGLE }; - QVector h2Mag = { H2_MAG_ANGLE }; - QVector h3Mag = { H3_MAG_ANGLE }; - QVector h8Mag = { H8_MAG_ANGLE }; - QVector h1Phase = { H1_PHASE_ANGLE }; - QVector h2Phase = { H2_PHASE_ANGLE }; - QVector h3Phase = { H3_PHASE_ANGLE }; - QVector h8Phase = { H8_PHASE_ANGLE }; - fm.save(graphDataList, "Raw Data"); - fm.save(preCalibrationAngleErrorsFFTMagnitude, "Pre-Calibration Angle Errors FFT Magnitude"); - fm.save(preCalibrationAngleErrorsFFTPhase, "Pre-Calibration Angle Errors FFT Phase"); - fm.save(h1Mag, "H1 Mag"); - fm.save(h2Mag, "H2 Mag"); - fm.save(h3Mag, "H3 Mag"); - fm.save(h8Mag, "H8 Mag"); - fm.save(h1Phase, "H1 Phase"); - fm.save(h2Phase, "H2 Phase"); - fm.save(h3Phase, "H3 Phase"); - fm.save(h8Phase, "H8 Phase"); - fm.performWrite(withScopyHeader); - } -} -void HarmonicCalibration::importCalibrationData() -{ - QString fileName = QFileDialog::getOpenFileName( - this, tr("Import"), "", - tr("Comma-separated values files (*.csv);;" - "Tab-delimited values files (*.txt)"), - nullptr, QFileDialog::Options()); - FileManager fm("HarmonicCalibration"); - try { - fm.open(fileName, FileManager::IMPORT); - graphDataList = fm.read(0); - if(graphDataList.size() > 0) - { - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataXPlotAxis->setInterval(0, graphDataList.size()); - calibrationRawDataPlotWidget->replot(); - computeSineCosineOfAngles(graphDataList); - calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); - populateAngleErrorGraphs(); - canStartMotor(false); - canCalibrate(true); - } - } catch(FileManagerException &ex) { - calibrationLogWrite(QString(ex.what())); - } -} -void HarmonicCalibration::computeSineCosineOfAngles(QVector graphDataList) -{ - m_admtController->computeSineCosineOfAngles(vector(graphDataList.begin(), graphDataList.end())); - if(isPostCalibration){ - postCalibrationSineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_sine_scaled.data(), m_admtController->calibration_samples_sine_scaled.size()); - postCalibrationCosineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_cosine_scaled.data(), m_admtController->calibration_samples_cosine_scaled.size()); - postCalibrationRawDataPlotWidget->replot(); - } - else{ - calibrationSineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_sine_scaled.data(), m_admtController->calibration_samples_sine_scaled.size()); - calibrationCosineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_cosine_scaled.data(), m_admtController->calibration_samples_cosine_scaled.size()); - calibrationRawDataPlotWidget->replot(); - } -} -bool HarmonicCalibration::moveMotorToPosition(double& position, bool validate) -{ - bool success = false; - bool canRead = true; - if(writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, position) == 0){ - if(validate){ - if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) - { - while(target_pos != current_pos && canRead) { - canRead = readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0 ? true : false; - } - if(canRead) success = true; - } - } - } - return success; -} -void HarmonicCalibration::startMotorContinuous() -{ - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); -} -void HarmonicCalibration::stopMotor() -{ - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); -} -void HarmonicCalibration::resetAllCalibrationState() -{ - clearCalibrationSamples(); - clearPostCalibrationSamples(); - calibrationDataGraphTabWidget->setCurrentIndex(0); - clearAngleErrorGraphs(); - clearCorrectedAngleErrorGraphs(); - resultDataTabWidget->setCurrentIndex(0); - canStartMotor(true); - canCalibrate(false); - calibrateDataButton->setChecked(false); - isPostCalibration = false; - isCalculatedCoeff = false; - resetToZero = true; - displayCalculatedCoeff(); -} -void HarmonicCalibration::clearCalibrationSamples() -{ - graphDataList.clear(); - calibrationRawDataPlotChannel->curve()->setData(nullptr); - calibrationSineDataPlotChannel->curve()->setData(nullptr); - calibrationCosineDataPlotChannel->curve()->setData(nullptr); - calibrationRawDataPlotWidget->replot(); -} -void HarmonicCalibration::clearCalibrationSineCosine() -{ - calibrationSineDataPlotChannel->curve()->setData(nullptr); - calibrationCosineDataPlotChannel->curve()->setData(nullptr); - calibrationRawDataPlotWidget->replot(); -} -void HarmonicCalibration::clearPostCalibrationSamples() -{ - graphPostDataList.clear(); - postCalibrationRawDataPlotChannel->curve()->setData(nullptr); - postCalibrationSineDataPlotChannel->curve()->setData(nullptr); - postCalibrationCosineDataPlotChannel->curve()->setData(nullptr); - postCalibrationRawDataPlotWidget->replot(); -} -void HarmonicCalibration::clearAngleErrorGraphs() -{ - angleErrorPlotChannel->curve()->setData(nullptr); - angleErrorPlotWidget->replot(); - FFTAngleErrorMagnitudeChannel->curve()->setData(nullptr); - FFTAngleErrorPhaseChannel->curve()->setData(nullptr); - FFTAngleErrorPlotWidget->replot(); -} -void HarmonicCalibration::clearCorrectedAngleErrorGraphs() -{ - correctedErrorPlotChannel->curve()->setData(nullptr); - correctedErrorPlotWidget->replot(); - FFTCorrectedErrorMagnitudeChannel->curve()->setData(nullptr); - FFTCorrectedErrorPhaseChannel->curve()->setData(nullptr); - FFTCorrectedErrorPlotWidget->replot(); -} -void HarmonicCalibration::applyTextStyle(QWidget *widget, const QString& styleHelperColor, bool isBold) -{ - QString existingStyle = widget->styleSheet(); - QString style = QString(R"css( - font-family: Open Sans; - font-size: 16px; - font-weight: &&fontweight&&; - text-align: right; - color: &&colorname&&; - )css"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor(styleHelperColor)); - QString fontWeight = QString("normal"); - if(isBold){ - fontWeight = QString("bold"); - } - style = style.replace(QString("&&fontweight&&"), fontWeight); - widget->setStyleSheet(existingStyle + style); -} -void HarmonicCalibration::applyLabelStyle(QLabel *widget) -{ - applyTextStyle(widget); - QString existingStyle = widget->styleSheet(); - QString style = QString(R"css( - background-color: black; - border-radius: 4px; - border: none; - )css"); - widget->setStyleSheet(existingStyle + style); - widget->setFixedHeight(30); - widget->setContentsMargins(12, 4, 12, 4); -} -void HarmonicCalibration::applyTabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor) -{ - QString style = QString(R"css( - QTabWidget::tab-bar { - left: 5px; /* move to the right by 5px */ - } - QTabBar::tab { - min-width: 100px; - min-height: 32px; - padding-bottom: 5px; - padding-left: 16px; - padding-right: 16px; - background-color: &&UIElementBackground&&; - font: normal; - } - QTabBar::tab:selected { - color: white; - border-bottom: 2px solid &&ScopyBlue&&; - margin-top: 0px; - } - )css"); - style.replace("&&ScopyBlue&&", StyleHelper::getColor(styleHelperColor)); - style.replace("&&UIElementBackground&&", StyleHelper::getColor("UIElementBackground")); - widget->tabBar()->setStyleSheet(style); -} -void HarmonicCalibration::requestDisconnect() -{ - isStartAcquisition = false; - isDeviceStatusMonitor = false; - m_deviceStatusThread.cancel(); - m_acquisitionDataThread.cancel(); - m_acquisitionGraphThread.cancel(); - m_deviceStatusWatcher.waitForFinished(); - m_acquisitionDataWatcher.waitForFinished(); - m_acquisitionGraphWatcher.waitForFinished(); -} \ No newline at end of file From 036690374d6734378c46c7909177513602efa4fe Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 15 Jan 2025 16:12:11 +0800 Subject: [PATCH 080/112] admt: Added disable states for tab widget while calibrating Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 2 + plugins/admt/src/admtstylehelper.cpp | 3 ++ plugins/admt/src/harmoniccalibration.cpp | 42 +++++++++++++++---- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 59caee6ed3..5ee8584333 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -227,6 +227,8 @@ public Q_SLOTS: void startCalibrationDeviceStatusMonitor(); void calibrationUITask(); void getCalibrationSamples(); + void startCalibration(); + void stopCalibration(); void startMotor(); void startMotorContinuous(); void postCalibrateData(); diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp index 982547efbd..1f561525a9 100644 --- a/plugins/admt/src/admtstylehelper.cpp +++ b/plugins/admt/src/admtstylehelper.cpp @@ -254,6 +254,9 @@ void ADMTStyleHelper::TabWidgetStyle(QTabWidget *widget, const QString& styleHel border-bottom: 2px solid &&ScopyBlue&&; margin-top: 0px; } + QTabBar::tab:disabled{ + color: grey; + } )css"); style.replace("&&ScopyBlue&&", StyleHelper::getColor(styleHelperColor)); style.replace("&&UIElementBackground&&", StyleHelper::getColor("UIElementBackground")); diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 01d72e7a17..b0c2a4bbcc 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -126,6 +126,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QHBoxLayout *lay = new QHBoxLayout(this); tabWidget = new QTabWidget(this); + ADMTStyleHelper::TabWidgetStyle(tabWidget); setLayout(lay); lay->setMargin(0); @@ -921,19 +922,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma endregion #pragma region Acquire Calibration Samples Button - calibrationStartMotorButton = new QPushButton(calibrationSettingsGroupWidget); + calibrationStartMotorButton = new QPushButton(" Acquire Samples", calibrationSettingsGroupWidget); ADMTStyleHelper::StartButtonStyle(calibrationStartMotorButton); - calibrationStartMotorButton->setText(" Acquire Samples"); connect(calibrationStartMotorButton, &QPushButton::toggled, this, [=](bool toggled) { calibrationStartMotorButton->setText(toggled ? " Stop Acquisition" : " Acquire Samples"); - totalSamplesCount = cycleCount * samplesPerCycle; isStartMotor = toggled; if(toggled){ isPostCalibration = false; - graphPostDataList.reserve(totalSamplesCount); - graphDataList.reserve(totalSamplesCount); - startMotor(); + startCalibration(); + } + else{ + stopCalibration(); } }); #pragma endregion @@ -947,6 +947,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(calibrateDataButton, &QPushButton::toggled, this, [=](bool toggled) { calibrateDataButton->setText(toggled ? " Stop Calibration" : " Calibrate"); if(toggled) postCalibrateData(); + else stopCalibration(); }); #pragma endregion @@ -2294,17 +2295,40 @@ void HarmonicCalibration::getCalibrationSamples() stopMotor(); } -void HarmonicCalibration::startMotor() +void HarmonicCalibration::startCalibration() { + totalSamplesCount = cycleCount * samplesPerCycle; + + graphPostDataList.reserve(totalSamplesCount); + graphPostDataList.squeeze(); + graphDataList.reserve(totalSamplesCount); + graphDataList.squeeze(); + toggleTabSwitching(false); toggleMotorControls(false); + startMotor(); +} + +void HarmonicCalibration::stopCalibration() +{ + isStartMotor = false; + + toggleTabSwitching(true); + toggleMotorControls(true); +} + +void HarmonicCalibration::startMotor() +{ if(resetToZero && !isPostCalibration){ clearCalibrationSamples(); clearPostCalibrationSamples(); clearAngleErrorGraphs(); clearCorrectedAngleErrorGraphs(); } + else if(resetToZero){ + clearPostCalibrationSamples(); + } if(isPostCalibration) postCalibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); @@ -2376,6 +2400,10 @@ void HarmonicCalibration::postCalibrateData() isPostCalibration = true; isStartMotor = true; resetToZero = true; + + toggleTabSwitching(false); + toggleMotorControls(false); + startMotor(); } From 3ea2220ca24604dedd7d2111cd208837987a1008 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 16 Jan 2025 14:14:41 +0800 Subject: [PATCH 081/112] admt: Adjusted GPIO Monitor and Control - Included input and output for GPIO and disable function based on hardware - Fixed sequence section not updating on switch tabs - Added initialize for ADMT DIGIOEN register Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 7 +- plugins/admt/src/harmoniccalibration.cpp | 224 ++++++++---------- 2 files changed, 106 insertions(+), 125 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 5ee8584333..abe9a3b0c9 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -198,6 +198,7 @@ public Q_SLOTS: ToolTemplate* createUtilityWidget(); void readDeviceProperties(); + void initializeADMT(); bool readSequence(); void applySequence(); bool changeCNVPage(uint32_t page); @@ -218,6 +219,7 @@ public Q_SLOTS: void acquisitionPlotTask(int sampleRate); void acquisitionUITask(); void updateSequenceWidget(); + void applySequenceAndUpdate(); void updateGeneralSettingEnabled(bool value); void connectCheckBoxToAcquisitionGraph(QCheckBox* widget, PlotChannel* channel, AcquisitionDataKey key); void GMRReset(); @@ -273,11 +275,10 @@ public Q_SLOTS: void updateMTDiagnostics(); void updateMTDiagRegister(); void updateFaultRegister(); - void toggleDIGIOEN(string DIGIOENName, bool& value); - void toggleAllDIGIOEN(bool value); + void toggleDIGIOEN(string DIGIOENName, bool value); void toggleMTDiagnostics(int mode); void toggleFaultRegisterMode(int mode); - void resetDIGIO(); + bool resetDIGIO(); void commandLogWrite(QString message); void clearCommandLog(); #pragma endregion diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index b0c2a4bbcc..4f2e81ef05 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -116,6 +116,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool ADMTStyleHelper::GetInstance()->initColorMap(); readDeviceProperties(); readSequence(); + initializeADMT(); initializeMotor(); rotationChannelName = m_admtController->getChannelId(ADMTController::Channel::ROTATION); @@ -154,6 +155,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool { acquisitionUITimer->start(acquisitionUITimerRate); readSequence(); + updateSequenceWidget(); } else { @@ -519,7 +521,7 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() applySequenceButton = new QPushButton("Apply", sequenceSection); StyleHelper::BlueButton(applySequenceButton, "applySequenceButton"); - connect(applySequenceButton, &QPushButton::clicked, this, &HarmonicCalibration::applySequence); + connect(applySequenceButton, &QPushButton::clicked, this, &HarmonicCalibration::applySequenceAndUpdate); sequenceSection->contentLayout()->addWidget(sequenceTypeMenuCombo); sequenceSection->contentLayout()->addWidget(conversionTypeMenuCombo); @@ -1472,12 +1474,12 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection("DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOMonitorSectionWidget); DIGIOMonitorSectionWidget->contentLayout()->addWidget(DIGIOMonitorCollapseSection); - DIGIOBusyStatusLED = createStatusLEDWidget("BUSY", statusLEDColor, DIGIOMonitorCollapseSection); - DIGIOCNVStatusLED = createStatusLEDWidget("CNV", statusLEDColor, DIGIOMonitorCollapseSection); - DIGIOSENTStatusLED = createStatusLEDWidget("SENT", statusLEDColor, DIGIOMonitorCollapseSection); - DIGIOACALCStatusLED = createStatusLEDWidget("ACALC", statusLEDColor, DIGIOMonitorCollapseSection); - DIGIOFaultStatusLED = createStatusLEDWidget("FAULT", statusLEDColor, DIGIOMonitorCollapseSection); - DIGIOBootloaderStatusLED = createStatusLEDWidget("BOOTLOADER", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOBusyStatusLED = createStatusLEDWidget("BUSY (Output)", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOCNVStatusLED = createStatusLEDWidget("CNV (Input)", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOSENTStatusLED = createStatusLEDWidget("SENT (Output)", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOACALCStatusLED = createStatusLEDWidget("ACALC (Output)", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOFaultStatusLED = createStatusLEDWidget("FAULT (Output)", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOBootloaderStatusLED = createStatusLEDWidget("BOOTLOADER (Output)", statusLEDColor, DIGIOMonitorCollapseSection); DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBusyStatusLED); DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOCNVStatusLED); @@ -1490,9 +1492,10 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() #pragma region DIGIO Control MenuSectionWidget *DIGIOControlSectionWidget = new MenuSectionWidget(DIGIOWidget); MenuCollapseSection *DIGIOControlCollapseSection = new MenuCollapseSection("DIGIO Control", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOControlSectionWidget); + DIGIOControlCollapseSection->contentLayout()->setSpacing(8); DIGIOControlSectionWidget->contentLayout()->addWidget(DIGIOControlCollapseSection); - QWidget *DIGIOControlGridWidget = new QWidget(DIGIOControlSectionWidget); + QWidget *DIGIOControlGridWidget = new QWidget(DIGIOControlCollapseSection); QGridLayout *DIGIOControlGridLayout = new QGridLayout(DIGIOControlGridWidget); DIGIOControlGridWidget->setLayout(DIGIOControlGridLayout); DIGIOControlGridLayout->setMargin(0); @@ -1504,7 +1507,8 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() QLabel *DIGIO3Label = new QLabel("DIGIO3", DIGIOControlGridWidget); QLabel *DIGIO4Label = new QLabel("DIGIO4", DIGIOControlGridWidget); QLabel *DIGIO5Label = new QLabel("DIGIO5", DIGIOControlGridWidget); - QLabel *DIGIOALLLabel = new QLabel("All DIGIO Output", DIGIOControlGridWidget); + QLabel *DIGIOFunctionLabel = new QLabel("DIGIO Function", DIGIOControlGridWidget); + QLabel *GPIOModeLabel = new QLabel("GPIO Mode", DIGIOControlGridWidget); ADMTStyleHelper::MenuSmallLabel(DIGIO0Label); ADMTStyleHelper::MenuSmallLabel(DIGIO1Label); @@ -1512,10 +1516,11 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() ADMTStyleHelper::MenuSmallLabel(DIGIO3Label); ADMTStyleHelper::MenuSmallLabel(DIGIO4Label); ADMTStyleHelper::MenuSmallLabel(DIGIO5Label); - ADMTStyleHelper::MenuSmallLabel(DIGIOALLLabel); + ADMTStyleHelper::MenuSmallLabel(DIGIOFunctionLabel); + ADMTStyleHelper::MenuSmallLabel(GPIOModeLabel); DIGIO0ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Enable", "Disable"); + changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Output", "Input"); connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO0EN", value); }); @@ -1527,7 +1532,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() }); DIGIO1ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO1ENToggleSwitch, "Enable", "Disable"); + changeCustomSwitchLabel(DIGIO1ENToggleSwitch, "Output", "Input"); connect(DIGIO1ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO1EN", value); }); @@ -1539,7 +1544,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() }); DIGIO2ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO2ENToggleSwitch, "Enable", "Disable"); + changeCustomSwitchLabel(DIGIO2ENToggleSwitch, "Output", "Input"); connect(DIGIO2ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO2EN", value); }); @@ -1551,7 +1556,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() }); DIGIO3ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO3ENToggleSwitch, "Enable", "Disable"); + changeCustomSwitchLabel(DIGIO3ENToggleSwitch, "Output", "Input"); connect(DIGIO3ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO3EN", value); }); @@ -1563,7 +1568,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() }); DIGIO4ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO4ENToggleSwitch, "Enable", "Disable"); + changeCustomSwitchLabel(DIGIO4ENToggleSwitch, "Output", "Input"); connect(DIGIO4ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO4EN", value); }); @@ -1575,7 +1580,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() }); DIGIO5ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO5ENToggleSwitch, "Enable", "Disable"); + changeCustomSwitchLabel(DIGIO5ENToggleSwitch, "Output", "Input"); connect(DIGIO5ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ toggleDIGIOEN("DIGIO5EN", value); }); @@ -1586,13 +1591,6 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() toggleDIGIOEN("BOOTLOAD", value); }); - DIGIOALLToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIOALLToggleSwitch, "Enable", "Disable"); - connect(DIGIOALLToggleSwitch, &CustomSwitch::toggled, [=](bool value){ - toggleAllDIGIOEN(value); - // toggleAllDIGIO(value); - }); - QPushButton *DIGIOResetButton = new QPushButton("Reset DIGIO", DIGIOControlGridWidget); DIGIOResetButton->setFixedWidth(100); StyleHelper::BlueButton(DIGIOResetButton); @@ -1600,37 +1598,45 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() resetDIGIO(); updateDIGIOToggle(); }); - - DIGIOControlGridLayout->addWidget(DIGIOALLLabel, 0, 0); - DIGIOControlGridLayout->addWidget(DIGIOALLToggleSwitch, 0, 1); - DIGIOControlGridLayout->addWidget(DIGIOResetButton, 0, 2); - - DIGIOControlGridLayout->addItem(new QSpacerItem(0, 4, QSizePolicy::Fixed, QSizePolicy::Expanding), 1, 0, 1, 2); - QFrame *line = new QFrame(); - ADMTStyleHelper::LineStyle(line); - DIGIOControlGridLayout->addWidget(line, 2, 0, 1, 2); - DIGIOControlGridLayout->addItem(new QSpacerItem(0, 4, QSizePolicy::Fixed, QSizePolicy::Expanding), 3, 0, 1, 3); - - DIGIOControlGridLayout->addWidget(DIGIO0Label, 4, 0); - DIGIOControlGridLayout->addWidget(DIGIO0ENToggleSwitch, 4, 1); - DIGIOControlGridLayout->addWidget(DIGIO0FNCToggleSwitch, 4, 2); - DIGIOControlGridLayout->addWidget(DIGIO1Label, 5, 0); - DIGIOControlGridLayout->addWidget(DIGIO1ENToggleSwitch, 5, 1); - DIGIOControlGridLayout->addWidget(DIGIO1FNCToggleSwitch, 5, 2); - DIGIOControlGridLayout->addWidget(DIGIO2Label, 6, 0); - DIGIOControlGridLayout->addWidget(DIGIO2ENToggleSwitch, 6, 1); - DIGIOControlGridLayout->addWidget(DIGIO2FNCToggleSwitch, 6, 2); - DIGIOControlGridLayout->addWidget(DIGIO3Label, 7, 0); - DIGIOControlGridLayout->addWidget(DIGIO3ENToggleSwitch, 7, 1); - DIGIOControlGridLayout->addWidget(DIGIO3FNCToggleSwitch, 7, 2); - DIGIOControlGridLayout->addWidget(DIGIO4Label, 8, 0); - DIGIOControlGridLayout->addWidget(DIGIO4ENToggleSwitch, 8, 1); - DIGIOControlGridLayout->addWidget(DIGIO4FNCToggleSwitch, 8, 2); - DIGIOControlGridLayout->addWidget(DIGIO5Label, 9, 0); - DIGIOControlGridLayout->addWidget(DIGIO5ENToggleSwitch, 9, 1); - DIGIOControlGridLayout->addWidget(DIGIO5FNCToggleSwitch, 9, 2); - - DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOControlGridWidget, 1); + + DIGIOControlGridLayout->addWidget(DIGIOFunctionLabel, 0, 1); + DIGIOControlGridLayout->addWidget(GPIOModeLabel, 0, 2); + + DIGIOControlGridLayout->addWidget(DIGIO0Label, 1, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO0FNCToggleSwitch, 1, 1); + DIGIOControlGridLayout->addWidget(DIGIO0ENToggleSwitch, 1, 2); + + DIGIOControlGridLayout->addWidget(DIGIO1Label, 2, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO1FNCToggleSwitch, 2, 1); + DIGIOControlGridLayout->addWidget(DIGIO1ENToggleSwitch, 2, 2); + + DIGIOControlGridLayout->addWidget(DIGIO2Label, 3, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO2FNCToggleSwitch, 3, 1); + DIGIOControlGridLayout->addWidget(DIGIO2ENToggleSwitch, 3, 2); + + DIGIOControlGridLayout->addWidget(DIGIO3Label, 4, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO3FNCToggleSwitch, 4, 1); + DIGIOControlGridLayout->addWidget(DIGIO3ENToggleSwitch, 4, 2); + + DIGIOControlGridLayout->addWidget(DIGIO4Label, 5, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO4FNCToggleSwitch, 5, 1); + DIGIOControlGridLayout->addWidget(DIGIO4ENToggleSwitch, 5, 2); + + DIGIOControlGridLayout->addWidget(DIGIO5Label, 6, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO5FNCToggleSwitch, 6, 1); + DIGIOControlGridLayout->addWidget(DIGIO5ENToggleSwitch, 6, 2); + + DIGIOControlGridLayout->setColumnStretch(0, 1); + + DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOControlGridWidget); + DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOResetButton); + + if(generalRegisterMap.at("Sequence Type") == 0) + { + DIGIO2FNCToggleSwitch->setVisible(false); + DIGIO4FNCToggleSwitch->setVisible(false); + } + #pragma endregion DIGIOLayout->addWidget(DIGIOMonitorSectionWidget); @@ -1815,6 +1821,13 @@ void HarmonicCalibration::readDeviceProperties() if(!success) { StatusBarManager::pushMessage("Failed to read device properties"); } } +void HarmonicCalibration::initializeADMT() +{ + bool success = resetDIGIO(); + + if(!success){ StatusBarManager::pushMessage("Failed initialize ADMT"); } +} + bool HarmonicCalibration::readSequence(){ uint32_t *generalRegValue = new uint32_t; uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); @@ -2153,6 +2166,12 @@ void HarmonicCalibration::updateSequenceWidget(){ eighthHarmonicMenuCombo->combo()->setCurrentIndex(eighthHarmonicMenuCombo->combo()->findData(generalRegisterMap.at("8th Harmonic"))); } +void HarmonicCalibration::applySequenceAndUpdate() +{ + applySequence(); + updateSequenceWidget(); +} + void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { graphUpdateIntervalLineEdit->setEnabled(value); @@ -2930,91 +2949,91 @@ void HarmonicCalibration::updateDigioMonitor(){ if(digioBitMapping.at("DIGIO0EN")){ if(!digioBitMapping.at("BUSY")){ changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor); - DIGIOBusyStatusLED->setName("BUSY"); + DIGIOBusyStatusLED->setName("BUSY (Output)"); } else{ changeStatusLEDColor(DIGIOBusyStatusLED, gpioLEDColor); - DIGIOBusyStatusLED->setName("GPIO0"); + DIGIOBusyStatusLED->setName("GPIO0 (Output)"); } } else { - changeStatusLEDColor(DIGIOBusyStatusLED, faultLEDColor, false); - DIGIOBusyStatusLED->setName("DIGIO0"); + changeStatusLEDColor(DIGIOBusyStatusLED, gpioLEDColor); + DIGIOBusyStatusLED->setName("GPIO0 (Input)"); } if(digioBitMapping.at("DIGIO1EN")){ if(!digioBitMapping.at("CNV")){ changeStatusLEDColor(DIGIOCNVStatusLED, statusLEDColor); - DIGIOCNVStatusLED->setName("CNV"); + DIGIOCNVStatusLED->setName("CNV (Input)"); } else{ changeStatusLEDColor(DIGIOCNVStatusLED, gpioLEDColor); - DIGIOCNVStatusLED->setName("GPIO1"); + DIGIOCNVStatusLED->setName("GPIO1 (Output)"); } } else { - changeStatusLEDColor(DIGIOCNVStatusLED, faultLEDColor, false); - DIGIOCNVStatusLED->setName("DIGIO1"); + changeStatusLEDColor(DIGIOCNVStatusLED, gpioLEDColor); + DIGIOCNVStatusLED->setName("GPIO1 (Input)"); } if(digioBitMapping.at("DIGIO2EN")){ if(!digioBitMapping.at("SENT")){ changeStatusLEDColor(DIGIOSENTStatusLED, statusLEDColor); - DIGIOSENTStatusLED->setName("SENT"); + DIGIOSENTStatusLED->setName("SENT (Output)"); } else{ changeStatusLEDColor(DIGIOSENTStatusLED, gpioLEDColor); - DIGIOSENTStatusLED->setName("GPIO2"); + DIGIOSENTStatusLED->setName("GPIO2 (Output)"); } } else { - changeStatusLEDColor(DIGIOSENTStatusLED, faultLEDColor, false); - DIGIOSENTStatusLED->setName("DIGIO2"); + changeStatusLEDColor(DIGIOSENTStatusLED, gpioLEDColor); + DIGIOSENTStatusLED->setName("GPIO2 (Input)"); } if(digioBitMapping.at("DIGIO3EN")){ if(!digioBitMapping.at("ACALC")){ changeStatusLEDColor(DIGIOACALCStatusLED, statusLEDColor); - DIGIOACALCStatusLED->setName("ACALC"); + DIGIOACALCStatusLED->setName("ACALC (Output)"); } else{ changeStatusLEDColor(DIGIOACALCStatusLED, gpioLEDColor); - DIGIOACALCStatusLED->setName("GPIO3"); + DIGIOACALCStatusLED->setName("GPIO3 (Output)"); } } else { - changeStatusLEDColor(DIGIOACALCStatusLED, faultLEDColor, false); - DIGIOACALCStatusLED->setName("DIGIO3"); + changeStatusLEDColor(DIGIOACALCStatusLED, gpioLEDColor); + DIGIOACALCStatusLED->setName("GPIO3 (Input)"); } if(digioBitMapping.at("DIGIO4EN")){ if(!digioBitMapping.at("FAULT")){ changeStatusLEDColor(DIGIOFaultStatusLED, statusLEDColor); - DIGIOFaultStatusLED->setName("FAULT"); + DIGIOFaultStatusLED->setName("FAULT (Output)"); } else{ changeStatusLEDColor(DIGIOFaultStatusLED, gpioLEDColor); - DIGIOFaultStatusLED->setName("GPIO4"); + DIGIOFaultStatusLED->setName("GPIO4 (Output)"); } } else { - changeStatusLEDColor(DIGIOFaultStatusLED, faultLEDColor, false); - DIGIOFaultStatusLED->setName("DIGIO4"); + changeStatusLEDColor(DIGIOFaultStatusLED, gpioLEDColor); + DIGIOFaultStatusLED->setName("GPIO4 (Input)"); } if(digioBitMapping.at("DIGIO5EN")){ if(!digioBitMapping.at("BOOTLOAD")){ changeStatusLEDColor(DIGIOBootloaderStatusLED, statusLEDColor); - DIGIOBootloaderStatusLED->setName("BOOTLOAD"); + DIGIOBootloaderStatusLED->setName("BOOTLOAD (Output)"); } else{ changeStatusLEDColor(DIGIOBootloaderStatusLED, gpioLEDColor); - DIGIOBootloaderStatusLED->setName("GPIO5"); + DIGIOBootloaderStatusLED->setName("GPIO5 (Output)"); } } else { - changeStatusLEDColor(DIGIOBootloaderStatusLED, faultLEDColor, false); - DIGIOBootloaderStatusLED->setName("DIGIO5"); + changeStatusLEDColor(DIGIOBootloaderStatusLED, gpioLEDColor); + DIGIOBootloaderStatusLED->setName("GPIO5 (Input)"); } commandLogWrite("DIGIOEN: 0b" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); @@ -3166,7 +3185,7 @@ void HarmonicCalibration::updateFaultRegister(){ else{ commandLogWrite("Failed to read FAULT Register"); } } -void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool& value) +void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) { toggleUtilityTask(false); @@ -3183,7 +3202,7 @@ void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool& value) { map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); - DIGIOSettings[DIGIOENName] = value; + DIGIOSettings.at(DIGIOENName) = value; uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); @@ -3204,45 +3223,6 @@ void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool& value) toggleUtilityTask(true); } -void HarmonicCalibration::toggleAllDIGIOEN(bool value) -{ - toggleUtilityTask(false); - uint32_t *DIGIOENRegisterValue = new uint32_t; - uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - - bool success = false; - - if(changeCNVPage(DIGIOENPage)) - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) - { - map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue));; - DIGIOSettings["DIGIO5EN"] = value; - DIGIOSettings["DIGIO4EN"] = value; - DIGIOSettings["DIGIO3EN"] = value; - DIGIOSettings["DIGIO2EN"] = value; - DIGIOSettings["DIGIO1EN"] = value; - DIGIOSettings["DIGIO0EN"] = value; - uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); - - if(changeCNVPage(DIGIOENPage)){ - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - static_cast(newRegisterValue)) != -1) - { - success = updateDIGIOToggle(); - } - } - } - } - - if(!success) { StatusBarManager::pushMessage("Failed to toggle all GPIO outputs " + QString(value ? "on" : "off")); } - - toggleUtilityTask(true); -} - void HarmonicCalibration::toggleMTDiagnostics(int mode) { switch(mode){ @@ -3279,11 +3259,11 @@ void HarmonicCalibration::toggleFaultRegisterMode(int mode) } } -void HarmonicCalibration::resetDIGIO() +bool HarmonicCalibration::resetDIGIO() { - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + return (m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - 0x241b); + 0x241b) == 0 ? true : false); } void HarmonicCalibration::commandLogWrite(QString message) From 8a109ffca928b4ff2a59964cae0f100957c3e128 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 17 Jan 2025 17:21:26 +0800 Subject: [PATCH 082/112] admt: Applied latest dev branch - Applied new style method Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 2 +- plugins/admt/src/admtplugin.cpp | 4 - plugins/admt/src/admtstylehelper.cpp | 19 +-- plugins/admt/src/harmoniccalibration.cpp | 147 +++++++----------- .../admt/src/widgets/horizontalspinbox.cpp | 9 +- .../admt/src/widgets/registerblockwidget.cpp | 26 +--- 6 files changed, 75 insertions(+), 132 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index abe9a3b0c9..f7576fc6ad 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -112,7 +112,7 @@ public Q_SLOTS: *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; QButtonGroup *rightMenuButtonGroup; - QLineEdit *graphUpdateIntervalLineEdit, *displayLengthLineEdit, + QLineEdit *motorTargetPositionLineEdit, *graphUpdateIntervalLineEdit, *displayLengthLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, *acquisitionMotorCurrentPositionLineEdit, *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index 49e1fb57de..75a204bab0 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -9,8 +9,6 @@ Q_LOGGING_CATEGORY(CAT_ADMTPLUGIN, "ADMTPlugin") using namespace scopy; -// using namespace scopy::grutil; -// using namespace scopy::m2kgui; using namespace scopy::admt; const bool isDebug = false; @@ -96,8 +94,6 @@ bool ADMTPlugin::onConnect() m_toolList[0]->setEnabled(true); m_toolList[0]->setRunBtnVisible(false); - //auto recipe = createRecipe(m_ctx); - m_admtController = new ADMTController(m_param, this); m_admtController->connectADMT(); harmonicCalibration = new HarmonicCalibration(m_admtController, isDebug); diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp index 1f561525a9..e0417a63c4 100644 --- a/plugins/admt/src/admtstylehelper.cpp +++ b/plugins/admt/src/admtstylehelper.cpp @@ -1,5 +1,6 @@ #include "admtstylehelper.h" #include "stylehelper.h" +#include using namespace scopy::admt; @@ -68,7 +69,7 @@ void ADMTStyleHelper::TopContainerButtonStyle(QPushButton *btn, QString objectNa background-color:#272730; } })css"); - style.replace("&&ScopyBlue&&", StyleHelper::getColor("ScopyBlue")); + style.replace("&&ScopyBlue&&", Style::getAttribute(json::theme::interactive_primary_idle)); btn->setStyleSheet(style); } @@ -136,7 +137,7 @@ void ADMTStyleHelper::ComboBoxStyle(QComboBox *widget, QString objectName) selection-color: transparent; } )css"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); widget->setStyleSheet(style); widget->setFixedHeight(30); } @@ -161,7 +162,7 @@ void ADMTStyleHelper::LineEditStyle(QLineEdit *widget, QString objectName) color: #9c4600; } )css"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); widget->setStyleSheet(style); widget->setFixedHeight(30); widget->setContentsMargins(0, 0, 0, 0); @@ -190,7 +191,7 @@ void ADMTStyleHelper::ColoredSquareCheckbox(QCheckBox *chk, QColor color, QStrin QCheckBox::indicator:checked { background-color: &&colorname&&; } )css"); style.replace("&&colorname&&", color.name()); - style.replace("&&UIElementBackground&&", StyleHelper::getColor("UIElementBackground")); + style.replace("&&UIElementBackground&&", Style::getAttribute(json::theme::background_primary)); chk->setStyleSheet(style); } @@ -258,8 +259,8 @@ void ADMTStyleHelper::TabWidgetStyle(QTabWidget *widget, const QString& styleHel color: grey; } )css"); - style.replace("&&ScopyBlue&&", StyleHelper::getColor(styleHelperColor)); - style.replace("&&UIElementBackground&&", StyleHelper::getColor("UIElementBackground")); + style.replace("&&ScopyBlue&&", Style::getAttribute(json::theme::interactive_primary_idle)); + style.replace("&&UIElementBackground&&", Style::getAttribute(json::theme::background_primary)); widget->tabBar()->setStyleSheet(style); } @@ -275,7 +276,7 @@ void ADMTStyleHelper::TextStyle(QWidget *widget, const QString& styleHelperColor text-align: right; color: &&colorname&&; )css"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor(styleHelperColor)); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::content_default)); QString fontWeight = QString("normal"); if(isBold){ fontWeight = QString("bold"); @@ -328,7 +329,7 @@ void ADMTStyleHelper::UIBackgroundStyle(QWidget *widget, QString objectName) QString style = QString(R"css( background-color: &&colorname&&; )css"); - style.replace(QString("&&colorname&&"), StyleHelper::getColor("UIElementBackground")); + style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::background_primary)); widget->setStyleSheet(style); } @@ -352,7 +353,7 @@ void ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(QWidget *widget, QHBoxLayout background-color: &&colorname&&; border-radius: 4px; )css"); - style.replace(QString("&&colorname&&"), StyleHelper::getColor("ScopyBackground")); + style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::background_primary)); widget->setStyleSheet(style); widget->setFixedHeight(30); widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 4f2e81ef05..e569309b84 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -1,5 +1,6 @@ #include "harmoniccalibration.h" #include "qtconcurrentrun.h" +#include "style.h" #include #include @@ -34,8 +35,6 @@ static double motorTimeUnit = 1.048576; // t = 2^24/16Mhz static int motorMicrostepPerRevolution = 51200; static int motorfCLK = 16000000; // 16Mhz -// static bool autoCalibrate = false; - static uint32_t h1MagDeviceRegister = 0x15; static uint32_t h2MagDeviceRegister = 0x17; static uint32_t h3MagDeviceRegister = 0x19; @@ -50,22 +49,22 @@ static QVector acquisitionAngleList, acquisitionABSAngleList, acquisitio acquisitionTmp1List, acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, graphDataList, graphPostDataList; -static const QColor scopyBlueColor = scopy::StyleHelper::getColor("ScopyBlue"); +static const QColor scopyBlueColor = scopy::Style::getColor(json::theme::interactive_primary_idle); static const QColor sineColor = QColor("#85e94c"); static const QColor cosineColor = QColor("#91e6cf"); static const QColor faultLEDColor = QColor("#c81a28"); -static const QColor gpioLEDColor = scopyBlueColor; +static const QColor gpioLEDColor = scopy::Style::getColor(json::theme::interactive_secondary_idle); static const QColor statusLEDColor = QColor("#2e9e6f"); static const QPen scopyBluePen(scopyBlueColor); -static const QPen channel0Pen(scopy::StyleHelper::getColor("CH0")); -static const QPen channel1Pen(scopy::StyleHelper::getColor("CH1")); -static const QPen channel2Pen(scopy::StyleHelper::getColor("CH2")); -static const QPen channel3Pen(scopy::StyleHelper::getColor("CH3")); -static const QPen channel4Pen(scopy::StyleHelper::getColor("CH4")); -static const QPen channel5Pen(scopy::StyleHelper::getColor("CH5")); -static const QPen channel6Pen(scopy::StyleHelper::getColor("CH6")); -static const QPen channel7Pen(scopy::StyleHelper::getColor("CH7")); +static const QPen channel0Pen(scopy::Style::getAttribute(json::global::ch0)); +static const QPen channel1Pen(scopy::Style::getAttribute(json::global::ch1)); +static const QPen channel2Pen(scopy::Style::getAttribute(json::global::ch2)); +static const QPen channel3Pen(scopy::Style::getAttribute(json::global::ch3)); +static const QPen channel4Pen(scopy::Style::getAttribute(json::global::ch4)); +static const QPen channel5Pen(scopy::Style::getAttribute(json::global::ch5)); +static const QPen channel6Pen(scopy::Style::getAttribute(json::global::ch6)); +static const QPen channel7Pen(scopy::Style::getAttribute(json::global::ch7)); static const QPen sinePen(sineColor); static const QPen cosinePen(cosineColor); @@ -127,7 +126,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QHBoxLayout *lay = new QHBoxLayout(this); tabWidget = new QTabWidget(this); - ADMTStyleHelper::TabWidgetStyle(tabWidget); setLayout(lay); lay->setMargin(0); @@ -206,7 +204,7 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() QPushButton *resetGMRButton = new QPushButton(this); resetGMRButton->setText("GMR Reset"); - ADMTStyleHelper::TopContainerButtonStyle(resetGMRButton); + Style::setStyle(resetGMRButton, style::properties::button::singleButton); connect(resetGMRButton, &QPushButton::clicked, this, &HarmonicCalibration::GMRReset); rightMenuButtonGroup->addButton(settingsButton); @@ -243,13 +241,9 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() tempWidget->contentLayout()->addWidget(tempSection); rotationValueLabel = new QLabel(rotationSection); - StyleHelper::MenuControlLabel(rotationValueLabel, "rotationValueLabel"); angleValueLabel = new QLabel(angleSection); - StyleHelper::MenuControlLabel(angleValueLabel, "angleValueLabel"); countValueLabel = new QLabel(countSection); - StyleHelper::MenuControlLabel(countValueLabel, "countValueLabel"); tempValueLabel = new QLabel(tempSection); - StyleHelper::MenuControlLabel(tempValueLabel, "tempValueLabel"); rotationValueLabel->setText("--.--°"); angleValueLabel->setText("--.--°"); @@ -292,18 +286,18 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() motorControlSectionWidget->contentLayout()->setSpacing(8); motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); - StyleHelper::MenuSmallLabel(currentPositionLabel, "currentPositionLabel"); acquisitionMotorCurrentPositionLineEdit = new QLineEdit("--.--", motorControlSectionWidget); acquisitionMotorCurrentPositionLineEdit->setReadOnly(true); - ADMTStyleHelper::LineEditStyle(acquisitionMotorCurrentPositionLineEdit); connectLineEditToDouble(acquisitionMotorCurrentPositionLineEdit, current_pos); - motorTargetPositionSpinBox = new HorizontalSpinBox("Target Position", target_pos, "", motorControlSectionWidget); + QLabel *targetPositionLabel = new QLabel("Target Position", motorControlSectionWidget); + motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), motorControlSectionWidget); motorControlCollapseSection->contentLayout()->setSpacing(8); motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); motorControlCollapseSection->contentLayout()->addWidget(acquisitionMotorCurrentPositionLineEdit); - motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionSpinBox); + motorControlCollapseSection->contentLayout()->addWidget(targetPositionLabel); + motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionLineEdit); #pragma endregion rawDataLayout->addWidget(angleWidget); @@ -373,7 +367,6 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() #pragma region Channel Selection QWidget *acquisitionGraphChannelWidget = new QWidget(acquisitionGraphSectionWidget); QGridLayout *acquisitionGraphChannelGridLayout = new QGridLayout(acquisitionGraphChannelWidget); - // QHBoxLayout *acquisitionGraphChannelLayout = new QHBoxLayout(acquisitionGraphChannelWidget); acquisitionGraphChannelGridLayout->setContentsMargins(16, 8, 8, 16); acquisitionGraphChannelGridLayout->setSpacing(8); @@ -386,10 +379,6 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() ADMTStyleHelper::ColoredSquareCheckbox(absAngleCheckBox, channel1Pen.color()); connectCheckBoxToAcquisitionGraph(absAngleCheckBox, acquisitionABSAnglePlotChannel, ABSANGLE); - // QCheckBox *countCheckBox = new QCheckBox("Count", acquisitionGraphChannelWidget); - // ADMTStyleHelper::ColoredSquareCheckbox(countCheckBox, channel2Pen.color()); - // connectCheckBoxToAcquisitionGraph(countCheckBox, acquisitionTurnCountPlotChannel, TURNCOUNT); - QCheckBox *temp0CheckBox = new QCheckBox("Temp 0", acquisitionGraphChannelWidget); ADMTStyleHelper::ColoredSquareCheckbox(temp0CheckBox, channel3Pen.color()); connectCheckBoxToAcquisitionGraph(temp0CheckBox, acquisitionTmp0PlotChannel, TMP0); @@ -424,7 +413,6 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); } - // acquisitionGraphChannelGridLayout->addWidget(countCheckBox, 0, 2); #pragma endregion acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphPlotWidget); @@ -453,24 +441,20 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() // Graph Update Interval QLabel *graphUpdateIntervalLabel = new QLabel(generalSection); graphUpdateIntervalLabel->setText("Graph Update Interval (ms)"); - StyleHelper::MenuSmallLabel(graphUpdateIntervalLabel, "graphUpdateIntervalLabel"); graphUpdateIntervalLineEdit = new QLineEdit(generalSection); - ADMTStyleHelper::LineEditStyle(graphUpdateIntervalLineEdit); graphUpdateIntervalLineEdit->setText(QString::number(acquisitionGraphSampleRate)); connectLineEditToNumber(graphUpdateIntervalLineEdit, acquisitionGraphSampleRate, 1, 5000); // Data Sample Size QLabel *displayLengthLabel = new QLabel("Display Length", generalSection); - StyleHelper::MenuSmallLabel(displayLengthLabel); displayLengthLineEdit = new QLineEdit(generalSection); - ADMTStyleHelper::LineEditStyle(displayLengthLineEdit); displayLengthLineEdit->setText(QString::number(acquisitionDisplayLength)); connectLineEditToNumber(displayLengthLineEdit, acquisitionDisplayLength, 1, 2048); QPushButton *resetYAxisButton = new QPushButton("Reset Y-Axis Scale", generalSection); - StyleHelper::BlueButton(resetYAxisButton, "resetYAxisButton"); + StyleHelper::BasicButton(resetYAxisButton); connect(resetYAxisButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAcquisitionYAxisScale); generalSection->contentLayout()->addWidget(graphUpdateIntervalLabel); @@ -491,36 +475,31 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() { sequenceTypeComboBox->addItem("Mode 2", QVariant(1)); } - ADMTStyleHelper::ComboBoxStyle(sequenceTypeComboBox); conversionTypeMenuCombo = new MenuCombo("Conversion Type", sequenceSection); QComboBox *conversionTypeComboBox = conversionTypeMenuCombo->combo(); conversionTypeComboBox->addItem("Continuous conversions", QVariant(0)); conversionTypeComboBox->addItem("One-shot conversion", QVariant(1)); - ADMTStyleHelper::ComboBoxStyle(conversionTypeComboBox); convertSynchronizationMenuCombo = new MenuCombo("Convert Synchronization", sequenceSection); QComboBox *convertSynchronizationComboBox = convertSynchronizationMenuCombo->combo(); convertSynchronizationComboBox->addItem("Enabled", QVariant(1)); convertSynchronizationComboBox->addItem("Disabled", QVariant(0)); - ADMTStyleHelper::ComboBoxStyle(convertSynchronizationComboBox); angleFilterMenuCombo = new MenuCombo("Angle Filter", sequenceSection); QComboBox *angleFilterComboBox = angleFilterMenuCombo->combo(); angleFilterComboBox->addItem("Enabled", QVariant(1)); angleFilterComboBox->addItem("Disabled", QVariant(0)); - ADMTStyleHelper::ComboBoxStyle(angleFilterComboBox); eighthHarmonicMenuCombo = new MenuCombo("8th Harmonic", sequenceSection); QComboBox *eighthHarmonicComboBox = eighthHarmonicMenuCombo->combo(); eighthHarmonicComboBox->addItem("User-Supplied Values", QVariant(1)); eighthHarmonicComboBox->addItem("ADI Factory Values", QVariant(0)); - ADMTStyleHelper::ComboBoxStyle(eighthHarmonicComboBox); updateSequenceWidget(); applySequenceButton = new QPushButton("Apply", sequenceSection); - StyleHelper::BlueButton(applySequenceButton, "applySequenceButton"); + StyleHelper::BasicButton(applySequenceButton); connect(applySequenceButton, &QPushButton::clicked, this, &HarmonicCalibration::applySequenceAndUpdate); sequenceSection->contentLayout()->addWidget(sequenceTypeMenuCombo); @@ -581,7 +560,7 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); connectLineEditToNumberWrite(motorMaxDisplacementSpinBox->lineEdit(), dmax, ADMTController::MotorAttribute::DMAX); - connectLineEditToNumberWrite(motorTargetPositionSpinBox->lineEdit(), target_pos, ADMTController::MotorAttribute::TARGET_POS); + connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, ADMTController::MotorAttribute::TARGET_POS); connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); acquisitionUITimer = new QTimer(this); @@ -609,7 +588,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); - ADMTStyleHelper::TabWidgetStyle(calibrationDataGraphTabWidget); + calibrationDataGraphTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 160px; }"); calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); @@ -723,12 +702,14 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() MenuSectionWidget *resultDataSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); resultDataTabWidget = new QTabWidget(resultDataSectionWidget); - ADMTStyleHelper::TabWidgetStyle(resultDataTabWidget); + resultDataTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 160px; }"); resultDataSectionWidget->contentLayout()->setSpacing(8); resultDataSectionWidget->contentLayout()->addWidget(resultDataTabWidget); - QPen magnitudePen = QPen(StyleHelper::getColor("CH0")); - QPen phasePen = QPen(StyleHelper::getColor("CH1")); + QColor magnitudeColor = Style::getColor(json::global::ch0); + QColor phaseColor = Style::getColor(json::global::ch1); + QPen magnitudePen = QPen(magnitudeColor); + QPen phasePen = QPen(phaseColor); #pragma region Angle Error Widget QWidget *angleErrorWidget = new QWidget(); @@ -796,8 +777,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QHBoxLayout *FFTAngleErrorChannelsLayout = new QHBoxLayout(FFTAngleErrorChannelsWidget); ADMTStyleHelper::GraphChannelStyle(FFTAngleErrorChannelsWidget, FFTAngleErrorChannelsLayout); - MenuControlButton *toggleFFTAngleErrorMagnitudeButton = createChannelToggleWidget("Magnitude", QColor(StyleHelper::getColor("CH0")), FFTAngleErrorChannelsWidget); - MenuControlButton *toggleFFTAngleErrorPhaseButton = createChannelToggleWidget("Phase", QColor(StyleHelper::getColor("CH1")), FFTAngleErrorChannelsWidget); + MenuControlButton *toggleFFTAngleErrorMagnitudeButton = createChannelToggleWidget("Magnitude", magnitudeColor, FFTAngleErrorChannelsWidget); + MenuControlButton *toggleFFTAngleErrorPhaseButton = createChannelToggleWidget("Phase", phaseColor, FFTAngleErrorChannelsWidget); FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorMagnitudeButton); FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorPhaseButton); @@ -873,8 +854,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QHBoxLayout *FFTCorrectedErrorChannelsLayout = new QHBoxLayout(FFTCorrectedErrorChannelsWidget); ADMTStyleHelper::GraphChannelStyle(FFTCorrectedErrorChannelsWidget, FFTCorrectedErrorChannelsLayout); - MenuControlButton *toggleFFTCorrectedErrorMagnitudeButton = createChannelToggleWidget("Magnitude", QColor(StyleHelper::getColor("CH0")), FFTCorrectedErrorChannelsWidget); - MenuControlButton *toggleFFTCorrectedErrorPhaseButton = createChannelToggleWidget("Phase", QColor(StyleHelper::getColor("CH1")), FFTCorrectedErrorChannelsWidget); + MenuControlButton *toggleFFTCorrectedErrorMagnitudeButton = createChannelToggleWidget("Magnitude", magnitudeColor, FFTCorrectedErrorChannelsWidget); + MenuControlButton *toggleFFTCorrectedErrorPhaseButton = createChannelToggleWidget("Phase", phaseColor, FFTCorrectedErrorChannelsWidget); FFTCorrectedErrorChannelsLayout->addWidget(toggleFFTCorrectedErrorMagnitudeButton); FFTCorrectedErrorChannelsLayout->addWidget(toggleFFTCorrectedErrorPhaseButton); @@ -955,7 +936,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Reset Calibration Button clearCalibrateDataButton = new QPushButton("Reset Calibration", calibrationSettingsGroupWidget); - StyleHelper::BlueButton(clearCalibrateDataButton); + StyleHelper::BasicButton(clearCalibrateDataButton); QIcon resetIcon; resetIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/refresh.svg", "white", 1), QIcon::Normal, QIcon::Off); clearCalibrateDataButton->setIcon(resetIcon); @@ -980,10 +961,10 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() MenuSectionWidget *calibrationCoeffSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); QLabel *calibrationDisplayFormatLabel = new QLabel(calibrationCoeffSectionWidget); calibrationDisplayFormatLabel->setText("Display Format"); - StyleHelper::MenuCollapseHeaderLabel(calibrationDisplayFormatLabel, "calibrationDisplayFormatLabel"); + Style::setStyle(calibrationDisplayFormatLabel, style::properties::label::menuMedium); QLabel *calibrationCalculatedCoeffLabel = new QLabel(calibrationCoeffSectionWidget); calibrationCalculatedCoeffLabel->setText("Calculated Coefficients"); - StyleHelper::MenuCollapseHeaderLabel(calibrationCalculatedCoeffLabel, "calibrationCalculatedCoeffLabel"); + Style::setStyle(calibrationCalculatedCoeffLabel, style::properties::label::menuMedium); calibrationDisplayFormatSwitch = new CustomSwitch(); calibrationDisplayFormatSwitch->setOffText("Hex"); @@ -1045,16 +1026,12 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDatasetConfigSectionWidget->contentLayout()->addWidget(calibrationDatasetConfigCollapseSection); QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", calibrationDatasetConfigCollapseSection); - StyleHelper::MenuSmallLabel(calibrationCycleCountLabel); QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(calibrationDatasetConfigCollapseSection); - ADMTStyleHelper::LineEditStyle(calibrationCycleCountLineEdit); calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 1000); QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", calibrationDatasetConfigCollapseSection); - StyleHelper::MenuSmallLabel(calibrationSamplesPerCycleLabel); QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationDatasetConfigCollapseSection); - ADMTStyleHelper::LineEditStyle(calibrationSamplesPerCycleLineEdit); calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); calibrationSamplesPerCycleLineEdit->setReadOnly(true); connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, 1, 5000); @@ -1075,8 +1052,8 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() QPushButton *importSamplesButton = new QPushButton("Import Samples", calibrationDataCollapseSection); QPushButton *extractDataButton = new QPushButton("Save to CSV", calibrationDataCollapseSection); - StyleHelper::BlueButton(importSamplesButton); - StyleHelper::BlueButton(extractDataButton); + StyleHelper::BasicButton(importSamplesButton); + StyleHelper::BasicButton(extractDataButton); calibrationDataCollapseSection->contentLayout()->setSpacing(8); calibrationDataCollapseSection->contentLayout()->addWidget(importSamplesButton); @@ -1114,18 +1091,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() motorControlSectionWidget->contentLayout()->setSpacing(8); motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); - StyleHelper::MenuSmallLabel(currentPositionLabel, "currentPositionLabel"); calibrationMotorCurrentPositionLineEdit = new QLineEdit("--.--", motorControlSectionWidget); calibrationMotorCurrentPositionLineEdit->setReadOnly(true); - ADMTStyleHelper::LineEditStyle(calibrationMotorCurrentPositionLineEdit); connectLineEditToDouble(calibrationMotorCurrentPositionLineEdit, current_pos); - motorTargetPositionSpinBox = new HorizontalSpinBox("Target Position", target_pos, "", motorControlSectionWidget); + QLabel *targetPositionLabel = new QLabel("Target Position", motorControlSectionWidget); + motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), motorControlSectionWidget); motorControlCollapseSection->contentLayout()->setSpacing(8); motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); motorControlCollapseSection->contentLayout()->addWidget(calibrationMotorCurrentPositionLineEdit); - motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionSpinBox); + motorControlCollapseSection->contentLayout()->addWidget(targetPositionLabel); + motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionLineEdit); #pragma endregion #pragma region Logs Section Widget @@ -1138,6 +1115,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() logsPlainTextEdit = new QPlainTextEdit(logsSectionWidget); logsPlainTextEdit->setReadOnly(true); logsPlainTextEdit->setFixedHeight(320); + logsPlainTextEdit->setStyleSheet("QPlainTextEdit { border: none; }"); logsCollapseSection->contentLayout()->setSpacing(8); logsCollapseSection->contentLayout()->addWidget(logsPlainTextEdit); @@ -1173,7 +1151,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); connectLineEditToNumberWrite(motorMaxDisplacementSpinBox->lineEdit(), dmax, ADMTController::MotorAttribute::DMAX); - connectLineEditToNumberWrite(motorTargetPositionSpinBox->lineEdit(), target_pos, ADMTController::MotorAttribute::TARGET_POS); + connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, ADMTController::MotorAttribute::TARGET_POS); connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); connect(toggleAngleButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); @@ -1237,7 +1215,7 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerLayout->setSpacing(8); QLabel *registerConfigurationLabel = new QLabel("Configuration", registerWidget); - StyleHelper::MenuControlLabel(registerConfigurationLabel, "registerConfigurationLabel"); + Style::setStyle(registerConfigurationLabel, style::properties::label::menuBig); QWidget *registerConfigurationGridWidget = new QWidget(registerWidget); QGridLayout *registerConfigurationGridLayout = new QGridLayout(registerConfigurationGridWidget); registerConfigurationGridWidget->setLayout(registerConfigurationGridLayout); @@ -1245,7 +1223,7 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerConfigurationGridLayout->setSpacing(8); QLabel *registerDeviceIDLabel = new QLabel("Device ID", registerWidget); - StyleHelper::MenuControlLabel(registerDeviceIDLabel, "registerDeviceIDLabel"); + Style::setStyle(registerDeviceIDLabel, style::properties::label::menuBig); QWidget *registerDeviceIDGridWidget = new QWidget(registerWidget); QGridLayout *registerDeviceIDGridLayout = new QGridLayout(registerDeviceIDGridWidget); registerDeviceIDGridWidget->setLayout(registerDeviceIDGridLayout); @@ -1253,7 +1231,7 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerDeviceIDGridLayout->setSpacing(8); QLabel *registerHarmonicsLabel = new QLabel("Harmonics", registerWidget); - StyleHelper::MenuControlLabel(registerHarmonicsLabel, "registerHarmonicsLabel"); + Style::setStyle(registerHarmonicsLabel, style::properties::label::menuBig); QWidget *registerHarmonicsGridWidget = new QWidget(registerWidget); QGridLayout *registerHarmonicsGridLayout = new QGridLayout(registerHarmonicsGridWidget); registerHarmonicsGridWidget->setLayout(registerHarmonicsGridLayout); @@ -1261,7 +1239,7 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerHarmonicsGridLayout->setSpacing(8); QLabel *registerSensorDataLabel = new QLabel("Sensor Data", registerWidget); - StyleHelper::MenuControlLabel(registerSensorDataLabel, "registerSensorDataLabel"); + Style::setStyle(registerSensorDataLabel, style::properties::label::menuBig); QWidget *registerSensorDataGridWidget = new QWidget(registerWidget); QGridLayout *registerSensorDataGridLayout = new QGridLayout(registerSensorDataGridWidget); registerSensorDataGridWidget->setLayout(registerSensorDataGridLayout); @@ -1350,7 +1328,7 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() for(int c=0; c < registerSensorDataGridLayout->columnCount(); ++c) registerSensorDataGridLayout->setColumnStretch(c,1); readAllRegistersButton = new QPushButton("Read All Registers", registerWidget); - StyleHelper::BlueButton(readAllRegistersButton, "readAllRegistersButton"); + StyleHelper::BasicButton(readAllRegistersButton); readAllRegistersButton->setFixedWidth(270); connect(readAllRegistersButton, &QPushButton::clicked, this, &HarmonicCalibration::readAllRegisters); @@ -1438,9 +1416,10 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() commandLogPlainTextEdit = new QPlainTextEdit(commandLogSectionWidget); commandLogPlainTextEdit->setReadOnly(true); commandLogPlainTextEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + commandLogPlainTextEdit->setStyleSheet("QPlainTextEdit { border: none; }"); clearCommandLogButton = new QPushButton("Clear Command Logs", commandLogSectionWidget); - StyleHelper::BlueButton(clearCommandLogButton, "clearCommandLogButton"); + StyleHelper::BasicButton(clearCommandLogButton); connect(clearCommandLogButton, &QPushButton::clicked, this, &HarmonicCalibration::clearCommandLog); commandLogCollapseSection->contentLayout()->addWidget(commandLogPlainTextEdit); @@ -1510,15 +1489,6 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() QLabel *DIGIOFunctionLabel = new QLabel("DIGIO Function", DIGIOControlGridWidget); QLabel *GPIOModeLabel = new QLabel("GPIO Mode", DIGIOControlGridWidget); - ADMTStyleHelper::MenuSmallLabel(DIGIO0Label); - ADMTStyleHelper::MenuSmallLabel(DIGIO1Label); - ADMTStyleHelper::MenuSmallLabel(DIGIO2Label); - ADMTStyleHelper::MenuSmallLabel(DIGIO3Label); - ADMTStyleHelper::MenuSmallLabel(DIGIO4Label); - ADMTStyleHelper::MenuSmallLabel(DIGIO5Label); - ADMTStyleHelper::MenuSmallLabel(DIGIOFunctionLabel); - ADMTStyleHelper::MenuSmallLabel(GPIOModeLabel); - DIGIO0ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Output", "Input"); connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ @@ -1593,7 +1563,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() QPushButton *DIGIOResetButton = new QPushButton("Reset DIGIO", DIGIOControlGridWidget); DIGIOResetButton->setFixedWidth(100); - StyleHelper::BlueButton(DIGIOResetButton); + StyleHelper::BasicButton(DIGIOResetButton); connect(DIGIOResetButton, &QPushButton::clicked, [=]{ resetDIGIO(); updateDIGIOToggle(); @@ -1683,18 +1653,15 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MTDiagnosticsCollapseSection->contentLayout()->setSpacing(8); QLabel *AFEDIAG0Label = new QLabel("AFEDIAG0 (%)"); - StyleHelper::MenuSmallLabel(AFEDIAG0Label, "AFEDIAG0Label"); + Style::setStyle(AFEDIAG0Label, style::properties::label::menuSmall); QLabel *AFEDIAG1Label = new QLabel("AFEDIAG1 (%)"); - StyleHelper::MenuSmallLabel(AFEDIAG1Label, "AFEDIAG1Label"); + Style::setStyle(AFEDIAG1Label, style::properties::label::menuSmall); QLabel *AFEDIAG2Label = new QLabel("AFEDIAG2 (V)"); - StyleHelper::MenuSmallLabel(AFEDIAG2Label, "AFEDIAG2Label"); + Style::setStyle(AFEDIAG2Label, style::properties::label::menuSmall); AFEDIAG0LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); AFEDIAG1LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); AFEDIAG2LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); - ADMTStyleHelper::LineEditStyle(AFEDIAG0LineEdit); - ADMTStyleHelper::LineEditStyle(AFEDIAG1LineEdit); - ADMTStyleHelper::LineEditStyle(AFEDIAG2LineEdit); AFEDIAG0LineEdit->setReadOnly(true); AFEDIAG1LineEdit->setReadOnly(true); AFEDIAG2LineEdit->setReadOnly(true); @@ -2159,7 +2126,6 @@ void HarmonicCalibration::updateSequenceWidget(){ if(generalRegisterMap.at("Sequence Type") == -1){ sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); } else{ sequenceTypeMenuCombo->combo()->setCurrentIndex(sequenceTypeMenuCombo->combo()->findData(generalRegisterMap.at("Sequence Type"))); } conversionTypeMenuCombo->combo()->setCurrentIndex(conversionTypeMenuCombo->combo()->findData(generalRegisterMap.at("Conversion Type"))); - // cnvSourceMenuCombo->combo()->setCurrentValue(generalRegisterMap.at("Sequence Type")); if(generalRegisterMap.at("Convert Synchronization") == -1){ convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); } else{ convertSynchronizationMenuCombo->combo()->setCurrentIndex(convertSynchronizationMenuCombo->combo()->findData(generalRegisterMap.at("Convert Synchronization"))); } angleFilterMenuCombo->combo()->setCurrentIndex(angleFilterMenuCombo->combo()->findData(generalRegisterMap.at("Angle Filter"))); @@ -2176,8 +2142,6 @@ void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { graphUpdateIntervalLineEdit->setEnabled(value); displayLengthLineEdit->setEnabled(value); - // dataGraphSamplesLineEdit->setEnabled(value); - // tempGraphSamplesLineEdit->setEnabled(value); } void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox* widget, PlotChannel* channel, AcquisitionDataKey key) @@ -2733,7 +2697,6 @@ void HarmonicCalibration::extractCalibrationData() QString fileName = QFileDialog::getSaveFileName(this, tr("Export"), "", filter.join(";;"), &selectedFilter, QFileDialog::Options()); if(fileName.split(".").size() <= 1) { - // file name w/o extension. Let's append it QString ext = selectedFilter.split(".")[1].split(")")[0]; fileName += "." + ext; } @@ -2794,7 +2757,7 @@ void HarmonicCalibration::toggleMotorControls(bool value) motorAccelTimeSpinBox->setEnabled(value); motorMaxDisplacementSpinBox->setEnabled(value); m_calibrationMotorRampModeMenuCombo->setEnabled(value); - motorTargetPositionSpinBox->setEnabled(value); + motorTargetPositionLineEdit->setEnabled(value); } void HarmonicCalibration::clearCalibrationSamples() @@ -3561,9 +3524,6 @@ void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& v void HarmonicCalibration::connectLineEditToDouble(QLineEdit* lineEdit, double& variable) { - // QDoubleValidator *validator = new QDoubleValidator(this); - // validator->setNotation(QDoubleValidator::StandardNotation); - // lineEdit->setValidator(validator); connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { bool ok; double value = lineEdit->text().toDouble(&ok); @@ -3616,11 +3576,9 @@ void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit* lineEdit, do double rps = lineEdit->text().toDouble(&ok); if (ok) { vmax = convertRPStoVMAX(rps); - // StatusBarManager::pushMessage("Converted VMAX: " + QString::number(vmax)); writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, vmax); writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); amax = convertAccelTimetoAMAX(motorAccelTimeSpinBox->lineEdit()->text().toDouble()); - // StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); } else { lineEdit->setText(QString::number(convertVMAXtoRPS(vmax))); @@ -3635,7 +3593,6 @@ void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit* lineEdit, d double accelTime = lineEdit->text().toDouble(&ok); if (ok) { amax = convertAccelTimetoAMAX(accelTime); - // StatusBarManager::pushMessage("Converted AMAX: " + QString::number(amax)); } else { lineEdit->setText(QString::number(convertAMAXtoAccelTime(amax))); } diff --git a/plugins/admt/src/widgets/horizontalspinbox.cpp b/plugins/admt/src/widgets/horizontalspinbox.cpp index aecbf29c0b..dcec5d0655 100644 --- a/plugins/admt/src/widgets/horizontalspinbox.cpp +++ b/plugins/admt/src/widgets/horizontalspinbox.cpp @@ -1,4 +1,5 @@ #include +#include #include "widgets/horizontalspinbox.h" using namespace scopy::admt; @@ -15,7 +16,7 @@ HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, QStrin if(header != ""){ QLabel *headerLabel = new QLabel(header, this); - StyleHelper::MenuSmallLabel(headerLabel, "headerLabel"); + Style::setStyle(headerLabel, style::properties::label::menuSmall); container->addWidget(headerLabel); } @@ -132,7 +133,7 @@ void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) color: #9c4600; } )css"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); widget->setStyleSheet(style); widget->setFixedHeight(30); widget->setAlignment(Qt::AlignRight); @@ -160,7 +161,7 @@ void HorizontalSpinBox::applyPushButtonStyle(QPushButton *widget, int topLeftBor color: #2d3d9c; } )css"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("ScopyBlue")); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::interactive_primary_idle)); style = style.replace(QString("&&topLeftBorderRadius&&"), QString::number(topLeftBorderRadius)); style = style.replace(QString("&&topRightBorderRadius&&"), QString::number(topRightBorderRadius)); style = style.replace(QString("&&bottomLeftBorderRadius&&"), QString::number(bottomLeftBorderRadius)); @@ -182,7 +183,7 @@ void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget, bool isEnabled) )css"); if(isEnabled){ style = style.replace(QString("&&backgroundcolor&&"), "black"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); } else{ style = style.replace(QString("&&backgroundcolor&&"), "#18181d"); diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp index f2b22f97a2..779b504e51 100644 --- a/plugins/admt/src/widgets/registerblockwidget.cpp +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -1,4 +1,5 @@ #include +#include #include "widgets/registerblockwidget.h" using namespace scopy; @@ -22,27 +23,14 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui menuSectionWidget->contentLayout()->addWidget(menuCollapseSection); QLabel *descriptionLabel = new QLabel(description, menuSectionWidget); - QString labelStyle = QString(R"css( - QLabel { - color: white; - background-color: rgba(255,255,255,0); - font-weight: 500; - font-family: Open Sans; - font-size: 12px; - font-style: normal; - } - QLabel:disabled { - color: grey; - } - )css"); - descriptionLabel->setStyleSheet(labelStyle); descriptionLabel->setWordWrap(true); descriptionLabel->setMinimumHeight(24); descriptionLabel->setAlignment(Qt::AlignTop); descriptionLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); m_spinBox = new PaddedSpinBox(menuSectionWidget); - applySpinBoxStyle(m_spinBox); + Style::setStyle(m_spinBox, style::properties::lineedit::headerLineEdit, "", true); + m_spinBox->setButtonSymbols(m_spinBox->ButtonSymbols::NoButtons); m_value = 0x00; m_spinBox->setValue(m_value); @@ -100,7 +88,7 @@ RegisterBlockWidget::ACCESS_PERMISSION RegisterBlockWidget::getAccessPermission( void RegisterBlockWidget::addReadButton(QWidget *parent) { m_readButton = new QPushButton("Read", parent); - StyleHelper::BlueButton(m_readButton, "readButton"); + StyleHelper::BasicButton(m_readButton); parent->layout()->addWidget(m_readButton); } @@ -109,7 +97,7 @@ QPushButton *RegisterBlockWidget::readButton() { return m_readButton; } void RegisterBlockWidget::addWriteButton(QWidget *parent) { m_writeButton = new QPushButton("Write", parent); - StyleHelper::BlueButton(m_writeButton, "writeButton"); + StyleHelper::BasicButton(m_writeButton); parent->layout()->addWidget(m_writeButton); } @@ -126,7 +114,7 @@ void RegisterBlockWidget::applyLineEditStyle(QLineEdit *widget) border-radius: 4px; qproperty-frame: false; )css"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); widget->setStyleSheet(style); widget->setFixedHeight(30); widget->setAlignment(Qt::AlignRight); @@ -145,7 +133,7 @@ void RegisterBlockWidget::applySpinBoxStyle(QSpinBox *widget) border-radius: 4px; font-weight: normal; )css"); - style = style.replace(QString("&&colorname&&"), StyleHelper::getColor("CH0")); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); widget->setStyleSheet(style); widget->setFixedHeight(30); widget->setAlignment(Qt::AlignRight); From 8b4e39dcffd0dd62079ed65c0987e12425c78870 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 22 Jan 2025 16:25:06 +0800 Subject: [PATCH 083/112] admt: Added spinbox to new style property - Adjusted calibration tab UI elements Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/CMakeLists.txt | 3 +++ plugins/admt/include/admt/admtstylehelper.h | 3 ++- plugins/admt/src/admtstylehelper.cpp | 13 ++++++------- plugins/admt/src/harmoniccalibration.cpp | 2 +- plugins/admt/src/widgets/registerblockwidget.cpp | 3 ++- plugins/admt/style/qss/properties/admt/spinBox.qss | 8 ++++++++ 6 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 plugins/admt/style/qss/properties/admt/spinBox.qss diff --git a/plugins/admt/CMakeLists.txt b/plugins/admt/CMakeLists.txt index 4890cb7880..b6fbb65d14 100644 --- a/plugins/admt/CMakeLists.txt +++ b/plugins/admt/CMakeLists.txt @@ -77,6 +77,9 @@ generate_export_header( ${PROJECT_NAME} EXPORT_FILE_NAME ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}/${PROJECT_NAME}_export.h ) +include(ScopyStyle) +generate_style("--plugin" ${CMAKE_CURRENT_SOURCE_DIR}/style ${CMAKE_CURRENT_SOURCE_DIR}/include/admt) + configure_file( include/${SCOPY_MODULE}/scopy-${SCOPY_MODULE}_config.h.cmakein ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}/scopy-${SCOPY_MODULE}_config.h @ONLY diff --git a/plugins/admt/include/admt/admtstylehelper.h b/plugins/admt/include/admt/admtstylehelper.h index 60406c31ea..bf722248b9 100644 --- a/plugins/admt/include/admt/admtstylehelper.h +++ b/plugins/admt/include/admt/admtstylehelper.h @@ -3,6 +3,7 @@ #include "scopy-admt_export.h" #include "stylehelper.h" +#include "style.h" #include #include @@ -37,7 +38,7 @@ class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject static void ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName = ""); static void StartButtonStyle(QPushButton *btn, QString objectName = ""); static void TabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor = "ScopyBlue", QString objectName = ""); - static void TextStyle(QWidget *widget, const QString& styleHelperColor, bool isBold = false, QString objectName = ""); + static void TextStyle(QWidget *widget, const char *styleHelperColor = json::global::white, bool isBold = false, QString objectName = "");// void TextStyle(QWidget *widget, const QString& styleHelperColor, bool isBold = false, QString objectName = ""); static void MenuSmallLabel(QLabel *label, QString objectName = ""); static void LineStyle(QFrame *line, QString objectName = ""); static void UIBackgroundStyle(QWidget *widget, QString objectName = ""); diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp index e0417a63c4..cd3bf2855e 100644 --- a/plugins/admt/src/admtstylehelper.cpp +++ b/plugins/admt/src/admtstylehelper.cpp @@ -264,19 +264,18 @@ void ADMTStyleHelper::TabWidgetStyle(QTabWidget *widget, const QString& styleHel widget->tabBar()->setStyleSheet(style); } -void ADMTStyleHelper::TextStyle(QWidget *widget, const QString& styleHelperColor, bool isBold, QString objectName) +void ADMTStyleHelper::TextStyle(QWidget *widget, const char *styleHelperColor, bool isBold, QString objectName) { if(!objectName.isEmpty()) widget->setObjectName(objectName); QString existingStyle = widget->styleSheet(); QString style = QString(R"css( - font-family: Open Sans; font-size: 16px; font-weight: &&fontweight&&; text-align: right; color: &&colorname&&; )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::content_default)); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(styleHelperColor)); QString fontWeight = QString("normal"); if(isBold){ fontWeight = QString("bold"); @@ -353,15 +352,15 @@ void ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(QWidget *widget, QHBoxLayout background-color: &&colorname&&; border-radius: 4px; )css"); - style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::background_primary)); + style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::background_subtle)); widget->setStyleSheet(style); widget->setFixedHeight(30); widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); layout->setContentsMargins(12, 4, 12, 4); - ADMTStyleHelper::TextStyle(hLabel, "LabelText", true); - ADMTStyleHelper::TextStyle(hMagLabel, "CH0"); - ADMTStyleHelper::TextStyle(hPhaseLabel, "CH1"); + ADMTStyleHelper::TextStyle(hLabel, json::global::white, true); + ADMTStyleHelper::TextStyle(hMagLabel, json::global::ch0); + ADMTStyleHelper::TextStyle(hPhaseLabel, json::global::ch1); hLabel->setFixedWidth(24); hMagLabel->setContentsMargins(0, 0, 32, 0); diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index e569309b84..d45d3dd667 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -588,7 +588,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); - calibrationDataGraphTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 160px; }"); + calibrationDataGraphTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 176px; }"); calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp index 779b504e51..f9c0ef4af3 100644 --- a/plugins/admt/src/widgets/registerblockwidget.cpp +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -1,6 +1,7 @@ #include #include #include "widgets/registerblockwidget.h" +#include "style_properties.h" using namespace scopy; using namespace scopy::admt; @@ -29,7 +30,7 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui descriptionLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); m_spinBox = new PaddedSpinBox(menuSectionWidget); - Style::setStyle(m_spinBox, style::properties::lineedit::headerLineEdit, "", true); + Style::setStyle(m_spinBox, style::properties::admt::spinBox); m_spinBox->setButtonSymbols(m_spinBox->ButtonSymbols::NoButtons); m_value = 0x00; diff --git a/plugins/admt/style/qss/properties/admt/spinBox.qss b/plugins/admt/style/qss/properties/admt/spinBox.qss new file mode 100644 index 0000000000..b71c89ad12 --- /dev/null +++ b/plugins/admt/style/qss/properties/admt/spinBox.qss @@ -0,0 +1,8 @@ +QSpinBox[&&property&&=true]{ + height: &unit_2&; + border: &border_width& solid &interactive_subtle_idle&; + border-bottom: &border_width_interactive& solid &interactive_subtle_idle&; + border-radius: &radius_interactive&; + padding: 0 &padding_interactive& 0 &padding_interactive&; + selection-background-color: &interactive_subtle_pressed&; +} \ No newline at end of file From b5daa22263e0014801ab96d7e3b3311d6efe1d3d Mon Sep 17 00:00:00 2001 From: "U-ANALOG\\JJuanill" Date: Fri, 31 Jan 2025 14:00:22 +0800 Subject: [PATCH 084/112] admt: Replaced timers with threads for utility tab - Added style for checkbox LED Signed-off-by: U-ANALOG\JJuanill Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 77 +- plugins/admt/src/harmoniccalibration.cpp | 896 ++++++++++-------- .../style/qss/properties/admt/checkBoxLED.qss | 20 + 3 files changed, 572 insertions(+), 421 deletions(-) create mode 100644 plugins/admt/style/qss/properties/admt/checkBoxLED.qss diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index f7576fc6ad..a351514114 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include @@ -90,9 +92,24 @@ public Q_SLOTS: void stop(); void start(); void restart(); + void commandLogWrite(QString message); + void updateFaultStatus(bool value); + void updateMotorPosition(double position); + void updateDIGIOUI(uint32_t *registerValue); + void updateFaultRegisterUI(uint32_t *registerValue); + void updateMTDiagnosticRegisterUI(uint32_t *registerValue); + void updateMTDiagnosticsUI(uint32_t *registerValue); Q_SIGNALS: void runningChanged(bool); void canCalibrateChanged(bool); + void updateUtilityUI(); + void commandLogWriteSignal(QString message); + void updateFaultStatusSignal(bool value); + void motorPositionChanged(double position); + void DIGIORegisterChanged(uint32_t *registerValue); + void FaultRegisterChanged(uint32_t *registerValue); + void DIAG1RegisterChanged(uint32_t *registerValue); + void DIAG2RegisterChanged(uint32_t *registerValue); private: ADMTController *m_admtController; iio_context *m_ctx; @@ -148,7 +165,12 @@ public Q_SLOTS: QPlainTextEdit *logsPlainTextEdit, *commandLogPlainTextEdit; - QCheckBox *autoCalibrateCheckBox; + QCheckBox *acquisitionFaultRegisterLEDWidget, *calibrationFaultRegisterLEDWidget, + *DIGIOBusyStatusLED ,*DIGIOCNVStatusLED ,*DIGIOSENTStatusLED ,*DIGIOACALCStatusLED ,*DIGIOFaultStatusLED ,*DIGIOBootloaderStatusLED, + *R0StatusLED, *R1StatusLED, *R2StatusLED, *R3StatusLED, *R4StatusLED, *R5StatusLED, *R6StatusLED, *R7StatusLED, + *VDDUnderVoltageStatusLED, *VDDOverVoltageStatusLED, *VDRIVEUnderVoltageStatusLED, *VDRIVEOverVoltageStatusLED, *AFEDIAGStatusLED, + *NVMCRCFaultStatusLED, *ECCDoubleBitErrorStatusLED, *OscillatorDriftStatusLED, *CountSensorFalseStateStatusLED, *AngleCrossCheckStatusLED, + *TurnCountSensorLevelsStatusLED, *MTDIAGStatusLED, *TurnCounterCrossCheckStatusLED, *RadiusCheckStatusLED, *SequencerWatchdogStatusLED; QScrollArea *MTDiagnosticsScrollArea; @@ -169,12 +191,6 @@ public Q_SLOTS: HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, *motorMaxDisplacementSpinBox, *motorTargetPositionSpinBox; - MenuControlButton *acquisitionFaultRegisterLEDWidget, *calibrationFaultRegisterLEDWidget, *DIGIOBusyStatusLED ,*DIGIOCNVStatusLED ,*DIGIOSENTStatusLED ,*DIGIOACALCStatusLED ,*DIGIOFaultStatusLED ,*DIGIOBootloaderStatusLED, - *R0StatusLED, *R1StatusLED, *R2StatusLED, *R3StatusLED, *R4StatusLED, *R5StatusLED, *R6StatusLED, *R7StatusLED, - *VDDUnderVoltageStatusLED, *VDDOverVoltageStatusLED, *VDRIVEUnderVoltageStatusLED, *VDRIVEOverVoltageStatusLED, - *AFEDIAGStatusLED, *NVMCRCFaultStatusLED, *ECCDoubleBitErrorStatusLED, *OscillatorDriftStatusLED, *CountSensorFalseStateStatusLED, - *AngleCrossCheckStatusLED, *TurnCountSensorLevelsStatusLED, *MTDIAGStatusLED, *TurnCounterCrossCheckStatusLED, *RadiusCheckStatusLED, *SequencerWatchdogStatusLED; - CustomSwitch *calibrationDisplayFormatSwitch, *DIGIO0ENToggleSwitch, *DIGIO0FNCToggleSwitch, *DIGIO1ENToggleSwitch, *DIGIO1FNCToggleSwitch, @@ -186,11 +202,12 @@ public Q_SLOTS: RegisterBlockWidget *cnvPageRegisterBlock, *digIORegisterBlock, *faultRegisterBlock, *generalRegisterBlock, *digIOEnRegisterBlock, *angleCkRegisterBlock, *eccDcdeRegisterBlock, *eccDisRegisterBlock, *absAngleRegisterBlock, *angleRegisterBlock, *angleSecRegisterBlock, *sineRegisterBlock, *cosineRegisterBlock, *secAnglIRegisterBlock, *secAnglQRegisterBlock, *radiusRegisterBlock, *diag1RegisterBlock, *diag2RegisterBlock, *tmp0RegisterBlock, *tmp1RegisterBlock, *cnvCntRegisterBlock, *uniqID0RegisterBlock, *uniqID1RegisterBlock, *uniqID2RegisterBlock, *uniqID3RegisterBlock, *h1MagRegisterBlock, *h1PhRegisterBlock, *h2MagRegisterBlock, *h2PhRegisterBlock, *h3MagRegisterBlock, *h3PhRegisterBlock, *h8MagRegisterBlock, *h8PhRegisterBlock; - QFuture m_deviceStatusThread, m_acquisitionDataThread, m_acquisitionGraphThread; - QFutureWatcher m_deviceStatusWatcher, m_acquisitionDataWatcher, m_acquisitionGraphWatcher; - - QTimer *acquisitionUITimer, *calibrationUITimer, *utilityTimer; - + QFuture m_deviceStatusThread, m_currentMotorPositionThread, + m_acquisitionUIThread, m_acquisitionDataThread, m_acquisitionGraphThread, + m_calibrationUIThread, m_utilityUIThread, m_utilityThread; + QFutureWatcher m_deviceStatusWatcher, m_currentMotorPositionWatcher, + m_acquisitionUIWatcher, m_acquisitionDataWatcher, m_acquisitionGraphWatcher, + m_calibrationUIWatcher, m_utilityUIWatcher, m_utilityWatcher; ToolTemplate* createAcquisitionWidget(); ToolTemplate* createCalibrationWidget(); @@ -203,21 +220,29 @@ public Q_SLOTS: void applySequence(); bool changeCNVPage(uint32_t page); void initializeMotor(); + void startDeviceStatusMonitor(); + void stopDeviceStatusMonitor(); void getDeviceFaultStatus(int sampleRate); + void startCurrentMotorPositionMonitor(); + void stopCurrentMotorPositionMonitor(); + void currentMotorPositionTask(int sampleRate); + bool resetGENERAL(); #pragma region Acquisition Methods bool updateChannelValues(); void updateCountValue(); void updateLineEditValues(); void startAcquisition(); - void startAcquisitionDeviceStatusMonitor(); + void stopAcquisition(); void getAcquisitionSamples(int sampleRate); double getAcquisitionParameterValue(const AcquisitionDataKey &key); void plotAcquisition(QVector& list, PlotChannel* channel); void prependAcquisitionData(const double& data, QVector& list); void resetAcquisitionYAxisScale(); void acquisitionPlotTask(int sampleRate); - void acquisitionUITask(); + void acquisitionUITask(int sampleRate); + void startAcquisitionUITask(); + void stopAcquisitionUITask(); void updateSequenceWidget(); void applySequenceAndUpdate(); void updateGeneralSettingEnabled(bool value); @@ -226,8 +251,9 @@ public Q_SLOTS: #pragma endregion #pragma region Calibration Methods - void startCalibrationDeviceStatusMonitor(); - void calibrationUITask(); + void startCalibrationUITask(); + void stopCalibrationUITask(); + void calibrationUITask(int sampleRate); void getCalibrationSamples(); void startCalibration(); void stopCalibration(); @@ -268,18 +294,20 @@ public Q_SLOTS: #pragma endregion #pragma region Utility Methods - void utilityTask(); + void startUtilityTask(); + void stopUtilityTask(); + void utilityTask(int sampleRate); void toggleUtilityTask(bool run); - void updateDigioMonitor(); - bool updateDIGIOToggle(); - void updateMTDiagnostics(); - void updateMTDiagRegister(); - void updateFaultRegister(); + void getDIGIOENRegister(); + void updateDIGIOMonitorUI(); + void updateDIGIOControlUI(); + void getDIAG2Register(); + void getDIAG1Register(); + void getFAULTRegister(); void toggleDIGIOEN(string DIGIOENName, bool value); void toggleMTDiagnostics(int mode); void toggleFaultRegisterMode(int mode); bool resetDIGIO(); - void commandLogWrite(QString message); void clearCommandLog(); #pragma endregion @@ -296,8 +324,11 @@ public Q_SLOTS: void toggleWidget(QPushButton *widget, bool value); void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel); void changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked = true); + void changeStatusLEDColor(QCheckBox *widget, const char *colorAttribute); void updateFaultStatusLEDColor(MenuControlButton *widget, bool value); + void toggleStatusLEDColor(QCheckBox *widget, const char *trueAttribute, const char* falseAttribute, bool value); MenuControlButton *createStatusLEDWidget(const QString title, QColor color, QWidget *parent = nullptr); + QCheckBox *createStatusLEDWidget(const QString &text, const char *colorAttribute, bool checked = false, QWidget *parent = nullptr); MenuControlButton *createChannelToggleWidget(const QString title, QColor color, QWidget *parent = nullptr); #pragma endregion diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index d45d3dd667..48a94258f3 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -1,18 +1,21 @@ #include "harmoniccalibration.h" #include "qtconcurrentrun.h" #include "style.h" +#include "style_properties.h" #include #include #include -static int acquisitionUITimerRate = 500; +static int acquisitionUITimerRate = 500; // In ms +static int acquisitionSampleRate = 20; +static int acquisitionGraphSampleRate = 100; + static int calibrationUITimerRate = 500; -static int utilityTimerRate = 1000; +static int utilityUITimerRate = 1000; -static int deviceStatusMonitorRate = 500; // In ms -static int acquisitionSampleRate = 20; // In ms -static int acquisitionGraphSampleRate = 100; // In ms +static int deviceStatusMonitorRate = 500; +static int motorPositionMonitorRate = 500; static int bufferSize = 1; static int dataGraphSamples = 100; @@ -70,6 +73,12 @@ static const QPen cosinePen(cosineColor); static map deviceRegisterMap; static map generalRegisterMap; +static map DIGIOENRegisterMap; +static map FAULTRegisterMap; +static map DIAG1RegisterMap; +static map DIAG2RegisterMap; +static map DIAG1AFERegisterMap; + static QString deviceName = ""; static QString deviceType = ""; static bool is5V = false; @@ -79,13 +88,21 @@ static uint32_t H1_MAG_HEX, H2_MAG_HEX, H3_MAG_HEX, H8_MAG_HEX, H1_PHASE_HEX, H2 static int acquisitionGraphYMin = 0; static int acquisitionGraphYMax = 360; + static bool deviceStatusFault = false; + +static bool isAcquisitionTab = false; +static bool isCalibrationTab = false; +static bool isUtilityTab = false; + static bool isStartAcquisition = false; + static bool isDeviceStatusMonitor = false; +static bool isMotorPositionMonitor = false; static int readMotorDebounce = 50; // In ms -static std::map acquisitionDataMap = { +static map acquisitionDataMap = { {RADIUS, false}, {ANGLE, false}, {TURNCOUNT, false}, @@ -141,44 +158,48 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 0 || index == 1) { if(isDeviceStatusMonitor) isDeviceStatusMonitor = false; + if(isMotorPositionMonitor) isMotorPositionMonitor = false; - if(index == 0) startAcquisitionDeviceStatusMonitor(); - else startCalibrationDeviceStatusMonitor(); + startDeviceStatusMonitor(); + if(index == 1) startCurrentMotorPositionMonitor(); } else{ isDeviceStatusMonitor = false; + isMotorPositionMonitor = false; } if(index == 0) // Acquisition Tab { - acquisitionUITimer->start(acquisitionUITimerRate); + startAcquisitionUITask(); readSequence(); updateSequenceWidget(); } else { - acquisitionUITimer->stop(); + stopAcquisitionUITask(); stop(); } if(index == 1) // Calibration Tab { - calibrationUITimer->start(calibrationUITimerRate); + startCalibrationUITask(); } else { - calibrationUITimer->stop(); + stopCalibrationUITask(); } if(index == 2) // Utility Tab { - utilityTimer->start(utilityTimerRate); readSequence(); toggleFaultRegisterMode(generalRegisterMap.at("Sequence Type")); toggleMTDiagnostics(generalRegisterMap.at("Sequence Type")); - updateDIGIOToggle(); + toggleUtilityTask(true); } - else { utilityTimer->stop(); } + else + { + toggleUtilityTask(false); + } if(index == 3) // Registers Tab { @@ -187,11 +208,24 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool } }); - acquisitionUITimer->start(acquisitionUITimerRate); - startAcquisitionDeviceStatusMonitor(); + connect(this, &HarmonicCalibration::updateFaultStatusSignal, this, &HarmonicCalibration::updateFaultStatus); + connect(this, &HarmonicCalibration::motorPositionChanged, this, &HarmonicCalibration::updateMotorPosition); + + connect(this, &HarmonicCalibration::commandLogWriteSignal, this, &HarmonicCalibration::commandLogWrite); + connect(this, &HarmonicCalibration::DIGIORegisterChanged, this, &HarmonicCalibration::updateDIGIOUI); + connect(this, &HarmonicCalibration::FaultRegisterChanged, this, &HarmonicCalibration::updateFaultRegisterUI); + connect(this, &HarmonicCalibration::DIAG1RegisterChanged, this, &HarmonicCalibration::updateMTDiagnosticRegisterUI); + connect(this, &HarmonicCalibration::DIAG2RegisterChanged, this, &HarmonicCalibration::updateMTDiagnosticsUI); + + startAcquisitionUITask(); + startDeviceStatusMonitor(); + startCurrentMotorPositionMonitor(); } -HarmonicCalibration::~HarmonicCalibration() {} +HarmonicCalibration::~HarmonicCalibration() +{ + requestDisconnect(); +} ToolTemplate* HarmonicCalibration::createAcquisitionWidget() { @@ -516,13 +550,13 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() acquisitionDeviceStatusSection->contentLayout()->setSpacing(8); acquisitionDeviceStatusWidget->contentLayout()->addWidget(acquisitionDeviceStatusSection); - acquisitionFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", statusLEDColor, acquisitionDeviceStatusSection); + acquisitionFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", json::theme::content_success, true, acquisitionDeviceStatusSection); acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionFaultRegisterLEDWidget); if(deviceType == "Automotive" && generalRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 { - MenuControlButton *acquisitionSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", statusLEDColor, acquisitionDeviceStatusSection); - MenuControlButton *acquisitionSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", statusLEDColor, acquisitionDeviceStatusSection); + QCheckBox *acquisitionSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", json::theme::content_success, true, acquisitionDeviceStatusSection); + QCheckBox *acquisitionSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", json::theme::content_success, true, acquisitionDeviceStatusSection); acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPICRCLEDWidget); acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPIFlagLEDWidget); } @@ -563,15 +597,6 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, ADMTController::MotorAttribute::TARGET_POS); connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); - acquisitionUITimer = new QTimer(this); - connect(acquisitionUITimer, &QTimer::timeout, this, &HarmonicCalibration::acquisitionUITask); - - calibrationUITimer = new QTimer(this); - connect(calibrationUITimer, &QTimer::timeout, this, &HarmonicCalibration::calibrationUITask); - - utilityTimer = new QTimer(this); - connect(utilityTimer, &QTimer::timeout, this, &HarmonicCalibration::utilityTask); - return tool; } @@ -892,13 +917,13 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDeviceStatusSection->contentLayout()->setSpacing(8); calibrationDeviceStatusWidget->contentLayout()->addWidget(calibrationDeviceStatusSection); - calibrationFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", statusLEDColor, calibrationDeviceStatusSection); + calibrationFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", json::theme::content_success, true, calibrationDeviceStatusSection); calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationFaultRegisterLEDWidget); if(deviceType == "Automotive" && generalRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 { - MenuControlButton *calibrationSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", statusLEDColor, calibrationDeviceStatusSection); - MenuControlButton *calibrationSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", statusLEDColor, calibrationDeviceStatusSection); + QCheckBox *calibrationSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", json::theme::content_success, true, calibrationDeviceStatusSection); + QCheckBox *calibrationSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", json::theme::content_success, true, calibrationDeviceStatusSection); calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPICRCLEDWidget); calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPIFlagLEDWidget); } @@ -1446,19 +1471,20 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() QVBoxLayout *DIGIOLayout = new QVBoxLayout(DIGIOWidget); DIGIOWidget->setLayout(DIGIOLayout); DIGIOLayout->setMargin(0); - DIGIOLayout->setSpacing(5); + DIGIOLayout->setSpacing(8); #pragma region DIGIO Monitor MenuSectionWidget *DIGIOMonitorSectionWidget = new MenuSectionWidget(DIGIOWidget); MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection("DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOMonitorSectionWidget); DIGIOMonitorSectionWidget->contentLayout()->addWidget(DIGIOMonitorCollapseSection); + DIGIOMonitorCollapseSection->contentLayout()->setSpacing(8); - DIGIOBusyStatusLED = createStatusLEDWidget("BUSY (Output)", statusLEDColor, DIGIOMonitorCollapseSection); - DIGIOCNVStatusLED = createStatusLEDWidget("CNV (Input)", statusLEDColor, DIGIOMonitorCollapseSection); - DIGIOSENTStatusLED = createStatusLEDWidget("SENT (Output)", statusLEDColor, DIGIOMonitorCollapseSection); - DIGIOACALCStatusLED = createStatusLEDWidget("ACALC (Output)", statusLEDColor, DIGIOMonitorCollapseSection); - DIGIOFaultStatusLED = createStatusLEDWidget("FAULT (Output)", statusLEDColor, DIGIOMonitorCollapseSection); - DIGIOBootloaderStatusLED = createStatusLEDWidget("BOOTLOADER (Output)", statusLEDColor, DIGIOMonitorCollapseSection); + DIGIOBusyStatusLED = createStatusLEDWidget("BUSY (Output)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); + DIGIOCNVStatusLED = createStatusLEDWidget("CNV (Input)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); + DIGIOSENTStatusLED = createStatusLEDWidget("SENT (Output)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); + DIGIOACALCStatusLED = createStatusLEDWidget("ACALC (Output)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); + DIGIOFaultStatusLED = createStatusLEDWidget("FAULT (Output)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); + DIGIOBootloaderStatusLED = createStatusLEDWidget("BOOTLOADER (Output)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBusyStatusLED); DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOCNVStatusLED); @@ -1565,8 +1591,9 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() DIGIOResetButton->setFixedWidth(100); StyleHelper::BasicButton(DIGIOResetButton); connect(DIGIOResetButton, &QPushButton::clicked, [=]{ + toggleUtilityTask(false); resetDIGIO(); - updateDIGIOToggle(); + toggleUtilityTask(true); }); DIGIOControlGridLayout->addWidget(DIGIOFunctionLabel, 0, 1); @@ -1617,15 +1644,16 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MenuSectionWidget *MTDIAG1SectionWidget = new MenuSectionWidget(centerUtilityWidget); MenuCollapseSection *MTDIAG1CollapseSection = new MenuCollapseSection("MT Diagnostic Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, MTDIAG1SectionWidget); MTDIAG1SectionWidget->contentLayout()->addWidget(MTDIAG1CollapseSection); + MTDIAG1CollapseSection->contentLayout()->setSpacing(8); - R0StatusLED = createStatusLEDWidget("R0", statusLEDColor, MTDIAG1SectionWidget); - R1StatusLED = createStatusLEDWidget("R1", statusLEDColor, MTDIAG1SectionWidget); - R2StatusLED = createStatusLEDWidget("R2", statusLEDColor, MTDIAG1SectionWidget); - R3StatusLED = createStatusLEDWidget("R3", statusLEDColor, MTDIAG1SectionWidget); - R4StatusLED = createStatusLEDWidget("R4", statusLEDColor, MTDIAG1SectionWidget); - R5StatusLED = createStatusLEDWidget("R5", statusLEDColor, MTDIAG1SectionWidget); - R6StatusLED = createStatusLEDWidget("R6", statusLEDColor, MTDIAG1SectionWidget); - R7StatusLED = createStatusLEDWidget("R7", statusLEDColor, MTDIAG1SectionWidget); + R0StatusLED = createStatusLEDWidget("R0", json::theme::background_primary, true, MTDIAG1SectionWidget); + R1StatusLED = createStatusLEDWidget("R1", json::theme::background_primary, true, MTDIAG1SectionWidget); + R2StatusLED = createStatusLEDWidget("R2", json::theme::background_primary, true, MTDIAG1SectionWidget); + R3StatusLED = createStatusLEDWidget("R3", json::theme::background_primary, true, MTDIAG1SectionWidget); + R4StatusLED = createStatusLEDWidget("R4", json::theme::background_primary, true, MTDIAG1SectionWidget); + R5StatusLED = createStatusLEDWidget("R5", json::theme::background_primary, true, MTDIAG1SectionWidget); + R6StatusLED = createStatusLEDWidget("R6", json::theme::background_primary, true, MTDIAG1SectionWidget); + R7StatusLED = createStatusLEDWidget("R7", json::theme::background_primary, true, MTDIAG1SectionWidget); MTDIAG1CollapseSection->contentLayout()->addWidget(R0StatusLED); MTDIAG1CollapseSection->contentLayout()->addWidget(R1StatusLED); @@ -1645,7 +1673,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() QVBoxLayout *MTDiagnosticsLayout = new QVBoxLayout(MTDiagnosticsWidget); MTDiagnosticsWidget->setLayout(MTDiagnosticsLayout); MTDiagnosticsLayout->setMargin(0); - MTDiagnosticsLayout->setSpacing(5); + MTDiagnosticsLayout->setSpacing(8); MenuSectionWidget *MTDiagnosticsSectionWidget = new MenuSectionWidget(centerUtilityWidget); MenuCollapseSection *MTDiagnosticsCollapseSection = new MenuCollapseSection("MT Diagnostics", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, MTDiagnosticsSectionWidget); @@ -1699,22 +1727,23 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MenuSectionWidget *faultRegisterSectionWidget = new MenuSectionWidget(rightUtilityWidget); MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection("Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, faultRegisterSectionWidget); faultRegisterSectionWidget->contentLayout()->addWidget(faultRegisterCollapseSection); + faultRegisterCollapseSection->contentLayout()->setSpacing(8); - VDDUnderVoltageStatusLED = createStatusLEDWidget("VDD Under Voltage", faultLEDColor, faultRegisterCollapseSection); - VDDOverVoltageStatusLED = createStatusLEDWidget("VDD Over Voltage", faultLEDColor, faultRegisterCollapseSection); - VDRIVEUnderVoltageStatusLED = createStatusLEDWidget("VDRIVE Under Voltage", faultLEDColor, faultRegisterCollapseSection); - VDRIVEOverVoltageStatusLED = createStatusLEDWidget("VDRIVE Over Voltage", faultLEDColor, faultRegisterCollapseSection); - AFEDIAGStatusLED = createStatusLEDWidget("AFEDIAG", faultLEDColor, faultRegisterCollapseSection); - NVMCRCFaultStatusLED = createStatusLEDWidget("NVM CRC Fault", faultLEDColor, faultRegisterCollapseSection); - ECCDoubleBitErrorStatusLED = createStatusLEDWidget("ECC Double Bit Error", faultLEDColor, faultRegisterCollapseSection); - OscillatorDriftStatusLED = createStatusLEDWidget("Oscillator Drift", faultLEDColor, faultRegisterCollapseSection); - CountSensorFalseStateStatusLED = createStatusLEDWidget("Count Sensor False State", faultLEDColor, faultRegisterCollapseSection); - AngleCrossCheckStatusLED = createStatusLEDWidget("Angle Cross Check", faultLEDColor, faultRegisterCollapseSection); - TurnCountSensorLevelsStatusLED = createStatusLEDWidget("Turn Count Sensor Levels", faultLEDColor, faultRegisterCollapseSection); - MTDIAGStatusLED = createStatusLEDWidget("MTDIAG", faultLEDColor, faultRegisterCollapseSection); - TurnCounterCrossCheckStatusLED = createStatusLEDWidget("Turn Counter Cross Check", faultLEDColor, faultRegisterCollapseSection); - RadiusCheckStatusLED = createStatusLEDWidget("Radius Check", faultLEDColor, faultRegisterCollapseSection); - SequencerWatchdogStatusLED = createStatusLEDWidget("Sequencer Watchdog", faultLEDColor, faultRegisterCollapseSection); + VDDUnderVoltageStatusLED = createStatusLEDWidget("VDD Under Voltage", json::theme::content_error, true, faultRegisterCollapseSection); + VDDOverVoltageStatusLED = createStatusLEDWidget("VDD Over Voltage", json::theme::content_error, true, faultRegisterCollapseSection); + VDRIVEUnderVoltageStatusLED = createStatusLEDWidget("VDRIVE Under Voltage", json::theme::content_error, true, faultRegisterCollapseSection); + VDRIVEOverVoltageStatusLED = createStatusLEDWidget("VDRIVE Over Voltage", json::theme::content_error, true, faultRegisterCollapseSection); + AFEDIAGStatusLED = createStatusLEDWidget("AFEDIAG", json::theme::content_error, true, faultRegisterCollapseSection); + NVMCRCFaultStatusLED = createStatusLEDWidget("NVM CRC Fault", json::theme::content_error, true, faultRegisterCollapseSection); + ECCDoubleBitErrorStatusLED = createStatusLEDWidget("ECC Double Bit Error", json::theme::content_error, true, faultRegisterCollapseSection); + OscillatorDriftStatusLED = createStatusLEDWidget("Oscillator Drift", json::theme::content_error, true, faultRegisterCollapseSection); + CountSensorFalseStateStatusLED = createStatusLEDWidget("Count Sensor False State", json::theme::content_error, true, faultRegisterCollapseSection); + AngleCrossCheckStatusLED = createStatusLEDWidget("Angle Cross Check", json::theme::content_error, true, faultRegisterCollapseSection); + TurnCountSensorLevelsStatusLED = createStatusLEDWidget("Turn Count Sensor Levels", json::theme::content_error, true, faultRegisterCollapseSection); + MTDIAGStatusLED = createStatusLEDWidget("MTDIAG", json::theme::content_error, true, faultRegisterCollapseSection); + TurnCounterCrossCheckStatusLED = createStatusLEDWidget("Turn Counter Cross Check", json::theme::content_error, true, faultRegisterCollapseSection); + RadiusCheckStatusLED = createStatusLEDWidget("Radius Check", json::theme::content_error, true, faultRegisterCollapseSection); + SequencerWatchdogStatusLED = createStatusLEDWidget("Sequencer Watchdog", json::theme::content_error, true, faultRegisterCollapseSection); faultRegisterCollapseSection->contentLayout()->addWidget(VDDUnderVoltageStatusLED); faultRegisterCollapseSection->contentLayout()->addWidget(VDDOverVoltageStatusLED); @@ -1742,8 +1771,8 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() tool->leftContainer()->setVisible(true); tool->rightContainer()->setVisible(true); tool->bottomContainer()->setVisible(false); - tool->setLeftContainerWidth(270); - tool->setRightContainerWidth(270); + tool->setLeftContainerWidth(240); + tool->setRightContainerWidth(224); tool->openBottomContainerHelper(false); tool->openTopContainerHelper(false); @@ -1791,6 +1820,7 @@ void HarmonicCalibration::readDeviceProperties() void HarmonicCalibration::initializeADMT() { bool success = resetDIGIO(); + success = resetGENERAL(); if(!success){ StatusBarManager::pushMessage("Failed initialize ADMT"); } } @@ -1823,7 +1853,7 @@ void HarmonicCalibration::applySequence(){ }); uint32_t *generalRegValue = new uint32_t; uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); - std::map settings; + map settings; settings["Convert Synchronization"] = qvariant_cast(convertSynchronizationMenuCombo->combo()->currentData()); // convertSync; settings["Angle Filter"] = qvariant_cast(angleFilterMenuCombo->combo()->currentData()); // angleFilter; @@ -1900,27 +1930,46 @@ void HarmonicCalibration::initializeMotor() readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); } +void HarmonicCalibration::startDeviceStatusMonitor() +{ + isDeviceStatusMonitor = true; + m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); + m_deviceStatusWatcher.setFuture(m_deviceStatusThread); +} + +void HarmonicCalibration::stopDeviceStatusMonitor() +{ + isDeviceStatusMonitor = false; + if(m_deviceStatusThread.isRunning()) + { + m_deviceStatusThread.cancel(); + m_deviceStatusWatcher.waitForFinished(); + } +} + void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) { + uint32_t *readValue = new uint32_t; + bool registerFault = false; while(isDeviceStatusMonitor) { - uint32_t *readValue = new uint32_t; if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), 0) == 0) { if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), readValue) == 0) { - deviceStatusFault = m_admtController->checkRegisterFault(static_cast(*readValue), generalRegisterMap.at("Sequence Type") == 0 ? true : false); + registerFault = m_admtController->checkRegisterFault(static_cast(*readValue), generalRegisterMap.at("Sequence Type") == 0 ? true : false); + Q_EMIT updateFaultStatusSignal(registerFault); } else { - deviceStatusFault = true; + Q_EMIT updateFaultStatusSignal(true); } } else { - deviceStatusFault = true; + Q_EMIT updateFaultStatusSignal(true); } QThread::msleep(sampleRate); @@ -1929,16 +1978,67 @@ void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) void HarmonicCalibration::requestDisconnect() { - isStartAcquisition = false; - isDeviceStatusMonitor = false; + stopAcquisition(); + + stopAcquisitionUITask(); + stopCalibrationUITask(); + stopUtilityTask(); + + stopDeviceStatusMonitor(); + stopCurrentMotorPositionMonitor(); +} + +void HarmonicCalibration::startCurrentMotorPositionMonitor() +{ + isMotorPositionMonitor = true; + m_currentMotorPositionThread = QtConcurrent::run(this, &HarmonicCalibration::currentMotorPositionTask, motorPositionMonitorRate); + m_currentMotorPositionWatcher.setFuture(m_currentMotorPositionThread); +} + +void HarmonicCalibration::stopCurrentMotorPositionMonitor() +{ + isMotorPositionMonitor = false; + if(m_currentMotorPositionThread.isRunning()) + { + m_currentMotorPositionThread.cancel(); + m_currentMotorPositionWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::currentMotorPositionTask(int sampleRate) +{ + double motorPosition = 0; + while(isMotorPositionMonitor) + { + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, motorPosition); + + Q_EMIT motorPositionChanged(motorPosition); + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::updateMotorPosition(double position) +{ + current_pos = position; + if(isAcquisitionTab) updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); + else if(isCalibrationTab) updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); +} - m_deviceStatusThread.cancel(); - m_acquisitionDataThread.cancel(); - m_acquisitionGraphThread.cancel(); +bool HarmonicCalibration::resetGENERAL() +{ + bool success = false; + + uint32_t resetValue = 0x0000; + if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { resetValue = 0x1230; } // Industrial or ASIL QM + else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { resetValue = 0x1200; } // Automotive or ASIL B + + if(resetValue != 0x0000){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL), resetValue) == 0) { success = true; } + } - m_deviceStatusWatcher.waitForFinished(); - m_acquisitionDataWatcher.waitForFinished(); - m_acquisitionGraphWatcher.waitForFinished(); + return success; } #pragma region Acquisition Methods @@ -1987,13 +2087,36 @@ void HarmonicCalibration::startAcquisition() m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); m_acquisitionGraphThread = QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, acquisitionGraphSampleRate); m_acquisitionGraphWatcher.setFuture(m_acquisitionGraphThread); + + startCurrentMotorPositionMonitor(); } -void HarmonicCalibration::startAcquisitionDeviceStatusMonitor() +void HarmonicCalibration::stopAcquisition() { - isDeviceStatusMonitor = true; - m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); - m_deviceStatusWatcher.setFuture(m_deviceStatusThread); + isStartAcquisition = false; + if(m_acquisitionDataThread.isRunning()) + { + m_acquisitionDataThread.cancel(); + m_acquisitionDataWatcher.waitForFinished(); + } + if(m_acquisitionGraphThread.isRunning()) + { + m_acquisitionGraphThread.cancel(); + m_acquisitionGraphWatcher.waitForFinished(); + } + + stopCurrentMotorPositionMonitor(); +} + +void HarmonicCalibration::updateFaultStatus(bool status) +{ + bool isChanged = (deviceStatusFault != status); + if(isChanged) + { + deviceStatusFault = status; + toggleStatusLEDColor(acquisitionFaultRegisterLEDWidget, json::theme::content_error, json::theme::content_success, deviceStatusFault); + toggleStatusLEDColor(calibrationFaultRegisterLEDWidget, json::theme::content_error, json::theme::content_success, deviceStatusFault); + } } void HarmonicCalibration::getAcquisitionSamples(int sampleRate) @@ -2063,7 +2186,7 @@ double HarmonicCalibration::getAcquisitionParameterValue(const AcquisitionDataKe void HarmonicCalibration::plotAcquisition(QVector& list, PlotChannel* channel) { channel->curve()->setSamples(list); - auto result = std::minmax_element(list.begin(), list.end()); + auto result = minmax_element(list.begin(), list.end()); if(*result.first < acquisitionGraphYMin) acquisitionGraphYMin = *result.first; if(*result.second > acquisitionGraphYMax) acquisitionGraphYMax = *result.second; } @@ -2110,15 +2233,30 @@ void HarmonicCalibration::acquisitionPlotTask(int sampleRate) } } -void HarmonicCalibration::acquisitionUITask() +void HarmonicCalibration::acquisitionUITask(int sampleRate) { - updateFaultStatusLEDColor(acquisitionFaultRegisterLEDWidget, deviceStatusFault); + while(isAcquisitionTab) + { + if(isStartAcquisition) updateLineEditValues(); - if(isStartAcquisition) + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::startAcquisitionUITask() +{ + isAcquisitionTab = true; + m_acquisitionUIThread = QtConcurrent::run(this, &HarmonicCalibration::acquisitionUITask, acquisitionUITimerRate); + m_acquisitionUIWatcher.setFuture(m_acquisitionUIThread); +} + +void HarmonicCalibration::stopAcquisitionUITask() +{ + isAcquisitionTab = false; + if(m_acquisitionUIThread.isRunning()) { - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - updateLineEditValues(); - updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); + m_acquisitionUIThread.cancel(); + m_acquisitionUIWatcher.waitForFinished(); } } @@ -2224,29 +2362,40 @@ void HarmonicCalibration::run(bool b) #pragma endregion #pragma region Calibration Methods -void HarmonicCalibration::startCalibrationDeviceStatusMonitor() +void HarmonicCalibration::startCalibrationUITask() { - isDeviceStatusMonitor = true; - m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); - m_deviceStatusWatcher.setFuture(m_deviceStatusThread); + isCalibrationTab = true; + m_calibrationUIThread = QtConcurrent::run(this, &HarmonicCalibration::calibrationUITask, calibrationUITimerRate); + m_calibrationUIWatcher.setFuture(m_calibrationUIThread); } -void HarmonicCalibration::calibrationUITask() +void HarmonicCalibration::stopCalibrationUITask() { - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); - updateFaultStatusLEDColor(calibrationFaultRegisterLEDWidget, deviceStatusFault); + isCalibrationTab = false; + if(m_calibrationUIThread.isRunning()) + { + m_calibrationUIThread.cancel(); + m_calibrationUIWatcher.waitForFinished(); + } +} - if(isStartMotor) +void HarmonicCalibration::calibrationUITask(int sampleRate) +{ + while (isCalibrationTab) { - if(isPostCalibration){ - postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); - postCalibrationRawDataPlotWidget->replot(); - } - else{ - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotWidget->replot(); + if(isStartMotor) + { + if(isPostCalibration){ + postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); + postCalibrationRawDataPlotWidget->replot(); + } + else{ + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotWidget->replot(); + } } + + QThread::msleep(sampleRate); } } @@ -2431,15 +2580,15 @@ void HarmonicCalibration::populateAngleErrorGraphs() QVector FFTAngleErrorPhase = QVector(m_admtController->FFTAngleErrorPhase.begin(), m_admtController->FFTAngleErrorPhase.end()); angleErrorPlotChannel->curve()->setSamples(angleError); - auto angleErrorMinMax = std::minmax_element(angleError.begin(), angleError.end()); + auto angleErrorMinMax = minmax_element(angleError.begin(), angleError.end()); angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, *angleErrorMinMax.second); angleErrorXPlotAxis->setInterval(0, angleError.size()); angleErrorPlotWidget->replot(); FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); - auto angleErrorMagnitudeMinMax = std::minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); - auto angleErrorPhaseMinMax = std::minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); + auto angleErrorMagnitudeMinMax = minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); + auto angleErrorPhaseMinMax = minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first ? *angleErrorMagnitudeMinMax.first : *angleErrorPhaseMinMax.first; double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second ? *angleErrorMagnitudeMinMax.second : *angleErrorPhaseMinMax.second; FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); @@ -2456,15 +2605,15 @@ void HarmonicCalibration::populateCorrectedAngleErrorGraphs() QVector FFTCorrectedErrorPhase(m_admtController->FFTCorrectedErrorPhase.begin(), m_admtController->FFTCorrectedErrorPhase.end()); correctedErrorPlotChannel->curve()->setSamples(correctedError); - auto correctedErrorMagnitudeMinMax = std::minmax_element(correctedError.begin(), correctedError.end()); + auto correctedErrorMagnitudeMinMax = minmax_element(correctedError.begin(), correctedError.end()); correctedErrorYPlotAxis->setInterval(*correctedErrorMagnitudeMinMax.first, *correctedErrorMagnitudeMinMax.second); correctedErrorXPlotAxis->setMax(correctedError.size()); correctedErrorPlotWidget->replot(); FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); FFTCorrectedErrorMagnitudeChannel->curve()->setSamples(FFTCorrectedErrorMagnitude); - auto FFTCorrectedErrorMagnitudeMinMax = std::minmax_element(FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); - auto FFTCorrectedErrorPhaseMinMax = std::minmax_element(FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); + auto FFTCorrectedErrorMagnitudeMinMax = minmax_element(FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); + auto FFTCorrectedErrorPhaseMinMax = minmax_element(FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); double FFTCorrectedErrorPlotMin = *FFTCorrectedErrorMagnitudeMinMax.first < *FFTCorrectedErrorPhaseMinMax.first ? *FFTCorrectedErrorMagnitudeMinMax.first : *FFTCorrectedErrorPhaseMinMax.first; double FFTCorrectedErrorPlotMax = *FFTCorrectedErrorMagnitudeMinMax.second > *FFTCorrectedErrorPhaseMinMax.second ? *FFTCorrectedErrorMagnitudeMinMax.second : *FFTCorrectedErrorPhaseMinMax.second; FFTCorrectedErrorYPlotAxis->setInterval(FFTCorrectedErrorPlotMin, FFTCorrectedErrorPlotMax); @@ -2880,27 +3029,53 @@ int HarmonicCalibration::writeMotorAttributeValue(ADMTController::MotorAttribute #pragma endregion #pragma region Utility Methods -void HarmonicCalibration::utilityTask(){ - updateDigioMonitor(); - updateFaultRegister(); - if(hasMTDiagnostics){ - updateMTDiagRegister(); - updateMTDiagnostics(); +void HarmonicCalibration::startUtilityTask() +{ + isUtilityTab = true; + m_utilityThread = QtConcurrent::run(this, &HarmonicCalibration::utilityTask, utilityUITimerRate); + m_utilityWatcher.setFuture(m_utilityThread); +} + +void HarmonicCalibration::stopUtilityTask() +{ + isUtilityTab = false; + if(m_utilityThread.isRunning()) + { + m_utilityThread.cancel(); + m_utilityWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::utilityTask(int sampleRate){ + while(isUtilityTab) + { + getDIGIOENRegister(); + getFAULTRegister(); + if(hasMTDiagnostics) + { + getDIAG1Register(); + getDIAG2Register(); + } + + Q_EMIT commandLogWriteSignal(""); + + QThread::msleep(sampleRate); } - commandLogWrite(""); } void HarmonicCalibration::toggleUtilityTask(bool run) { - if(run){ - utilityTimer->start(utilityTimerRate); + if(run) + { + startUtilityTask(); } - else{ - utilityTimer->stop(); + else + { + stopUtilityTask(); } } -void HarmonicCalibration::updateDigioMonitor(){ +void HarmonicCalibration::getDIGIOENRegister(){ uint32_t *digioRegValue = new uint32_t; uint32_t digioEnPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); if(changeCNVPage(digioEnPage)) @@ -2908,187 +3083,149 @@ void HarmonicCalibration::updateDigioMonitor(){ uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN); if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), digioRegisterAddress, digioRegValue) != -1){ - std::map digioBitMapping = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*digioRegValue)); - if(digioBitMapping.at("DIGIO0EN")){ - if(!digioBitMapping.at("BUSY")){ - changeStatusLEDColor(DIGIOBusyStatusLED, statusLEDColor); - DIGIOBusyStatusLED->setName("BUSY (Output)"); - } - else{ - changeStatusLEDColor(DIGIOBusyStatusLED, gpioLEDColor); - DIGIOBusyStatusLED->setName("GPIO0 (Output)"); - } - } - else { - changeStatusLEDColor(DIGIOBusyStatusLED, gpioLEDColor); - DIGIOBusyStatusLED->setName("GPIO0 (Input)"); - } - if(digioBitMapping.at("DIGIO1EN")){ - if(!digioBitMapping.at("CNV")){ - changeStatusLEDColor(DIGIOCNVStatusLED, statusLEDColor); - DIGIOCNVStatusLED->setName("CNV (Input)"); - } - else{ - changeStatusLEDColor(DIGIOCNVStatusLED, gpioLEDColor); - DIGIOCNVStatusLED->setName("GPIO1 (Output)"); - } - } - else { - changeStatusLEDColor(DIGIOCNVStatusLED, gpioLEDColor); - DIGIOCNVStatusLED->setName("GPIO1 (Input)"); - } + Q_EMIT DIGIORegisterChanged(digioRegValue); - if(digioBitMapping.at("DIGIO2EN")){ - if(!digioBitMapping.at("SENT")){ - changeStatusLEDColor(DIGIOSENTStatusLED, statusLEDColor); - DIGIOSENTStatusLED->setName("SENT (Output)"); - } - else{ - changeStatusLEDColor(DIGIOSENTStatusLED, gpioLEDColor); - DIGIOSENTStatusLED->setName("GPIO2 (Output)"); - } - } - else { - changeStatusLEDColor(DIGIOSENTStatusLED, gpioLEDColor); - DIGIOSENTStatusLED->setName("GPIO2 (Input)"); - } + Q_EMIT commandLogWriteSignal("DIGIOEN: 0b" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); + } + else{ Q_EMIT commandLogWriteSignal("Failed to read DIGIOEN Register"); } + } - if(digioBitMapping.at("DIGIO3EN")){ - if(!digioBitMapping.at("ACALC")){ - changeStatusLEDColor(DIGIOACALCStatusLED, statusLEDColor); - DIGIOACALCStatusLED->setName("ACALC (Output)"); - } - else{ - changeStatusLEDColor(DIGIOACALCStatusLED, gpioLEDColor); - DIGIOACALCStatusLED->setName("GPIO3 (Output)"); - } - } - else { - changeStatusLEDColor(DIGIOACALCStatusLED, gpioLEDColor); - DIGIOACALCStatusLED->setName("GPIO3 (Input)"); - } + delete digioRegValue; +} - if(digioBitMapping.at("DIGIO4EN")){ - if(!digioBitMapping.at("FAULT")){ - changeStatusLEDColor(DIGIOFaultStatusLED, statusLEDColor); - DIGIOFaultStatusLED->setName("FAULT (Output)"); - } - else{ - changeStatusLEDColor(DIGIOFaultStatusLED, gpioLEDColor); - DIGIOFaultStatusLED->setName("GPIO4 (Output)"); - } - } - else { - changeStatusLEDColor(DIGIOFaultStatusLED, gpioLEDColor); - DIGIOFaultStatusLED->setName("GPIO4 (Input)"); - } +void HarmonicCalibration::updateDIGIOUI(uint32_t *registerValue) +{ + DIGIOENRegisterMap = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*registerValue)); + updateDIGIOMonitorUI(); + updateDIGIOControlUI(); +} - if(digioBitMapping.at("DIGIO5EN")){ - if(!digioBitMapping.at("BOOTLOAD")){ - changeStatusLEDColor(DIGIOBootloaderStatusLED, statusLEDColor); - DIGIOBootloaderStatusLED->setName("BOOTLOAD (Output)"); - } - else{ - changeStatusLEDColor(DIGIOBootloaderStatusLED, gpioLEDColor); - DIGIOBootloaderStatusLED->setName("GPIO5 (Output)"); - } - } - else { - changeStatusLEDColor(DIGIOBootloaderStatusLED, gpioLEDColor); - DIGIOBootloaderStatusLED->setName("GPIO5 (Input)"); - } +void HarmonicCalibration::updateDIGIOMonitorUI() +{ + map registerMap = DIGIOENRegisterMap; + if(!registerMap.at("BUSY")){ + changeStatusLEDColor(DIGIOBusyStatusLED, json::theme::content_success); + DIGIOBusyStatusLED->setText("BUSY (Output)"); + } + else{ + changeStatusLEDColor(DIGIOBusyStatusLED, json::theme::interactive_primary_idle); + if(registerMap.at("DIGIO0EN")) DIGIOBusyStatusLED->setText("GPIO0 (Output)"); + else DIGIOBusyStatusLED->setText("GPIO0 (Input)"); + } - commandLogWrite("DIGIOEN: 0b" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); - } - else{ commandLogWrite("Failed to read DIGIOEN Register"); } + if(!registerMap.at("CNV")){ + changeStatusLEDColor(DIGIOCNVStatusLED, json::theme::content_success); + DIGIOCNVStatusLED->setText("CNV (Input)"); + } + else{ + changeStatusLEDColor(DIGIOCNVStatusLED, json::theme::interactive_primary_idle); + if(registerMap.at("DIGIO1EN")) DIGIOCNVStatusLED->setText("GPIO1 (Output)"); + else DIGIOCNVStatusLED->setText("GPIO1 (Input)"); } + if(!registerMap.at("SENT")){ + changeStatusLEDColor(DIGIOSENTStatusLED, json::theme::content_success); + DIGIOSENTStatusLED->setText("SENT (Output)"); + } + else{ + changeStatusLEDColor(DIGIOSENTStatusLED, json::theme::interactive_primary_idle); + if(registerMap.at("DIGIO2EN")) DIGIOSENTStatusLED->setText("GPIO2 (Output)"); + else DIGIOSENTStatusLED->setText("GPIO2 (Input)"); + } + + if(!registerMap.at("ACALC")){ + changeStatusLEDColor(DIGIOACALCStatusLED, json::theme::content_success); + DIGIOACALCStatusLED->setText("ACALC (Output)"); + } + else{ + changeStatusLEDColor(DIGIOACALCStatusLED, json::theme::interactive_primary_idle); + if(registerMap.at("DIGIO3EN")) DIGIOACALCStatusLED->setText("GPIO3 (Output)"); + else DIGIOACALCStatusLED->setText("GPIO3 (Input)"); + } + + if(!registerMap.at("FAULT")){ + changeStatusLEDColor(DIGIOFaultStatusLED, json::theme::content_success); + DIGIOFaultStatusLED->setText("FAULT (Output)"); + } + else{ + changeStatusLEDColor(DIGIOFaultStatusLED, json::theme::interactive_primary_idle); + if(registerMap.at("DIGIO4EN")) DIGIOFaultStatusLED->setText("GPIO4 (Output)"); + else DIGIOFaultStatusLED->setText("GPIO4 (Input)"); + } + + if(!registerMap.at("BOOTLOAD")){ + changeStatusLEDColor(DIGIOBootloaderStatusLED, json::theme::content_success); + DIGIOBootloaderStatusLED->setText("BOOTLOAD (Output)"); + } + else{ + changeStatusLEDColor(DIGIOBootloaderStatusLED, json::theme::interactive_primary_idle); + if(registerMap.at("DIGIO5EN")) DIGIOBootloaderStatusLED->setText("GPIO5 (Output)"); + else DIGIOBootloaderStatusLED->setText("GPIO5 (Input)"); + } } -bool HarmonicCalibration::updateDIGIOToggle() +void HarmonicCalibration::updateDIGIOControlUI() { - uint32_t *DIGIOENRegisterValue = new uint32_t; - uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - bool success = false; + map registerMap = DIGIOENRegisterMap; - if(changeCNVPage(DIGIOENPage)){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) - { - map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); - DIGIO0ENToggleSwitch->setChecked(DIGIOSettings["DIGIO0EN"]); - DIGIO1ENToggleSwitch->setChecked(DIGIOSettings["DIGIO1EN"]); - DIGIO2ENToggleSwitch->setChecked(DIGIOSettings["DIGIO2EN"]); - DIGIO3ENToggleSwitch->setChecked(DIGIOSettings["DIGIO3EN"]); - DIGIO4ENToggleSwitch->setChecked(DIGIOSettings["DIGIO4EN"]); - DIGIO5ENToggleSwitch->setChecked(DIGIOSettings["DIGIO5EN"]); - DIGIO0FNCToggleSwitch->setChecked(DIGIOSettings["BUSY"]); - DIGIO1FNCToggleSwitch->setChecked(DIGIOSettings["CNV"]); - DIGIO2FNCToggleSwitch->setChecked(DIGIOSettings["SENT"]); - DIGIO3FNCToggleSwitch->setChecked(DIGIOSettings["ACALC"]); - DIGIO4FNCToggleSwitch->setChecked(DIGIOSettings["FAULT"]); - DIGIO5FNCToggleSwitch->setChecked(DIGIOSettings["BOOTLOAD"]); - success = true; - } - } - return success; + DIGIO0ENToggleSwitch->setChecked(registerMap.at("DIGIO0EN")); + DIGIO1ENToggleSwitch->setChecked(registerMap.at("DIGIO1EN")); + DIGIO2ENToggleSwitch->setChecked(registerMap.at("DIGIO2EN")); + DIGIO3ENToggleSwitch->setChecked(registerMap.at("DIGIO3EN")); + DIGIO4ENToggleSwitch->setChecked(registerMap.at("DIGIO4EN")); + DIGIO5ENToggleSwitch->setChecked(registerMap.at("DIGIO5EN")); + DIGIO0FNCToggleSwitch->setChecked(registerMap.at("BUSY")); + DIGIO1FNCToggleSwitch->setChecked(registerMap.at("CNV")); + DIGIO2FNCToggleSwitch->setChecked(registerMap.at("SENT")); + DIGIO3FNCToggleSwitch->setChecked(registerMap.at("ACALC")); + DIGIO4FNCToggleSwitch->setChecked(registerMap.at("FAULT")); + DIGIO5FNCToggleSwitch->setChecked(registerMap.at("BOOTLOAD")); } -void HarmonicCalibration::updateMTDiagnostics(){ - uint32_t *mtDiag1RegValue = new uint32_t; +void HarmonicCalibration::getDIAG2Register(){ uint32_t *mtDiag2RegValue = new uint32_t; uint32_t *cnvPageRegValue = new uint32_t; - uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1); uint32_t mtDiag2RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG2); - uint32_t mtDiag1PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); uint32_t mtDiag2PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2); uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag1PageValue) != -1){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ - if(*cnvPageRegValue == mtDiag1PageValue){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1){ - std::map mtDiag1BitMapping = m_admtController->getDiag1RegisterBitMapping_Afe(static_cast(*mtDiag1RegValue), is5V); - - afeDiag2 = mtDiag1BitMapping.at("AFE Diagnostic 2"); - AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); - } - else{ commandLogWrite("Failed to read MT Diagnostic 1 Register"); } - } - else{ commandLogWrite("CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); } - } - else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 1"); } - } - else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 1"); } - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag2PageValue) != -1){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ if(*cnvPageRegValue == mtDiag2PageValue){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag2RegisterAddress, mtDiag2RegValue) != -1){ - std::map mtDiag2BitMapping = m_admtController->getDiag2RegisterBitMapping(static_cast(*mtDiag2RegValue)); - afeDiag0 = mtDiag2BitMapping.at("AFE Diagnostic 0 (-57%)"); - afeDiag1 = mtDiag2BitMapping.at("AFE Diagnostic 1 (+57%)"); - AFEDIAG0LineEdit->setText(QString::number(afeDiag0) + " V"); - AFEDIAG1LineEdit->setText(QString::number(afeDiag1) + " V"); + Q_EMIT DIAG2RegisterChanged(mtDiag2RegValue); - commandLogWrite("DIAG2: 0b" + QString::number(static_cast(*mtDiag2RegValue), 2).rightJustified(16, '0')); + Q_EMIT commandLogWriteSignal("DIAG2: 0b" + QString::number(static_cast(*mtDiag2RegValue), 2).rightJustified(16, '0')); } - else{ commandLogWrite("Failed to read MT Diagnostic 2 Register"); } + else{ Q_EMIT commandLogWriteSignal("Failed to read MT Diagnostic 2 Register"); } } - else{ commandLogWrite("CNVPAGE for MT Diagnostic 2 is a different value, abort reading"); } + else{ Q_EMIT commandLogWriteSignal("CNVPAGE for MT Diagnostic 2 is a different value, abort reading"); } } - else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 2"); } + else{ Q_EMIT commandLogWriteSignal("Failed to read CNVPAGE for MT Diagnostic 2"); } } - else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 2"); } + else{ Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 2"); } + + delete mtDiag2RegValue; + delete cnvPageRegValue; } -void HarmonicCalibration::updateMTDiagRegister(){ +void HarmonicCalibration::updateMTDiagnosticsUI(uint32_t *registerValue) +{ + DIAG2RegisterMap = m_admtController->getDiag2RegisterBitMapping(static_cast(*registerValue)); + + map regmap = DIAG2RegisterMap; + afeDiag0 = regmap.at("AFE Diagnostic 0 (-57%)"); + afeDiag1 = regmap.at("AFE Diagnostic 1 (+57%)"); + AFEDIAG0LineEdit->setText(QString::number(afeDiag0) + " V"); + AFEDIAG1LineEdit->setText(QString::number(afeDiag1) + " V"); +} + +void HarmonicCalibration::getDIAG1Register(){ uint32_t *mtDiag1RegValue = new uint32_t; uint32_t *cnvPageRegValue = new uint32_t; uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1); @@ -3099,53 +3236,78 @@ void HarmonicCalibration::updateMTDiagRegister(){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ if(*cnvPageRegValue == mtDiag1PageValue){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1){ - std::map mtDiag1BitMapping = m_admtController->getDiag1RegisterBitMapping_Register(static_cast(*mtDiag1RegValue)); - changeStatusLEDColor(R0StatusLED, statusLEDColor, mtDiag1BitMapping.at("R0")); - changeStatusLEDColor(R1StatusLED, statusLEDColor, mtDiag1BitMapping.at("R1")); - changeStatusLEDColor(R2StatusLED, statusLEDColor, mtDiag1BitMapping.at("R2")); - changeStatusLEDColor(R3StatusLED, statusLEDColor, mtDiag1BitMapping.at("R3")); - changeStatusLEDColor(R4StatusLED, statusLEDColor, mtDiag1BitMapping.at("R4")); - changeStatusLEDColor(R5StatusLED, statusLEDColor, mtDiag1BitMapping.at("R5")); - changeStatusLEDColor(R6StatusLED, statusLEDColor, mtDiag1BitMapping.at("R6")); - changeStatusLEDColor(R7StatusLED, statusLEDColor, mtDiag1BitMapping.at("R7")); - commandLogWrite("DIAG1: 0b" + QString::number(static_cast(*mtDiag1RegValue), 2).rightJustified(16, '0')); + + Q_EMIT DIAG1RegisterChanged(mtDiag1RegValue); + + Q_EMIT commandLogWriteSignal("DIAG1: 0b" + QString::number(static_cast(*mtDiag1RegValue), 2).rightJustified(16, '0')); } - else{ commandLogWrite("Failed to read MT Diagnostic 1 Register"); } + else{ Q_EMIT commandLogWriteSignal("Failed to read MT Diagnostic 1 Register"); } } - else{ commandLogWrite("CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); } + else{ Q_EMIT commandLogWriteSignal("CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); } } - else{ commandLogWrite("Failed to read CNVPAGE for MT Diagnostic 1"); } + else{ Q_EMIT commandLogWriteSignal("Failed to read CNVPAGE for MT Diagnostic 1"); } } - else{ commandLogWrite("Failed to write CNVPAGE for MT Diagnostic 1"); } + else{ Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 1"); } + + delete mtDiag1RegValue; + delete cnvPageRegValue; +} + +void HarmonicCalibration::updateMTDiagnosticRegisterUI(uint32_t *registerValue) +{ + DIAG1RegisterMap = m_admtController->getDiag1RegisterBitMapping_Register(static_cast(*registerValue)); + DIAG1AFERegisterMap = m_admtController->getDiag1RegisterBitMapping_Afe(static_cast(*registerValue), is5V); + + map regmap = DIAG1RegisterMap; + map afeRegmap = DIAG1AFERegisterMap; + toggleStatusLEDColor(R0StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R0")); + toggleStatusLEDColor(R1StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R1")); + toggleStatusLEDColor(R2StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R2")); + toggleStatusLEDColor(R3StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R3")); + toggleStatusLEDColor(R4StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R4")); + toggleStatusLEDColor(R5StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R5")); + toggleStatusLEDColor(R6StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R6")); + toggleStatusLEDColor(R7StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R7")); + afeDiag2 = afeRegmap.at("AFE Diagnostic 2"); + AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); } -void HarmonicCalibration::updateFaultRegister(){ +void HarmonicCalibration::getFAULTRegister(){ uint32_t *faultRegValue = new uint32_t; uint32_t faultRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT); m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, 0); // Write all zeros to fault before read m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, faultRegValue); if(*faultRegValue != -1){ - std::map faultBitMapping = m_admtController->getFaultRegisterBitMapping(static_cast(*faultRegValue)); - changeStatusLEDColor(VDDUnderVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDD Under Voltage")); - changeStatusLEDColor(VDDOverVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDD Over Voltage")); - changeStatusLEDColor(VDRIVEUnderVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDRIVE Under Voltage")); - changeStatusLEDColor(VDRIVEOverVoltageStatusLED, faultLEDColor, faultBitMapping.at("VDRIVE Over Voltage")); - changeStatusLEDColor(AFEDIAGStatusLED, faultLEDColor, faultBitMapping.at("AFE Diagnostic")); - changeStatusLEDColor(NVMCRCFaultStatusLED, faultLEDColor, faultBitMapping.at("NVM CRC Fault")); - changeStatusLEDColor(ECCDoubleBitErrorStatusLED, faultLEDColor, faultBitMapping.at("ECC Double Bit Error")); - changeStatusLEDColor(OscillatorDriftStatusLED, faultLEDColor, faultBitMapping.at("Oscillator Drift")); - changeStatusLEDColor(CountSensorFalseStateStatusLED, faultLEDColor, faultBitMapping.at("Count Sensor False State")); - changeStatusLEDColor(AngleCrossCheckStatusLED, faultLEDColor, faultBitMapping.at("Angle Cross Check")); - changeStatusLEDColor(TurnCountSensorLevelsStatusLED, faultLEDColor, faultBitMapping.at("Turn Count Sensor Levels")); - changeStatusLEDColor(MTDIAGStatusLED, faultLEDColor, faultBitMapping.at("MT Diagnostic")); - changeStatusLEDColor(TurnCounterCrossCheckStatusLED, faultLEDColor, faultBitMapping.at("Turn Counter Cross Check")); - changeStatusLEDColor(RadiusCheckStatusLED, faultLEDColor, faultBitMapping.at("AMR Radius Check")); - changeStatusLEDColor(SequencerWatchdogStatusLED, faultLEDColor, faultBitMapping.at("Sequencer Watchdog")); - - commandLogWrite("FAULT: 0b" + QString::number(static_cast(*faultRegValue), 2).rightJustified(16, '0')); - } - else{ commandLogWrite("Failed to read FAULT Register"); } + Q_EMIT FaultRegisterChanged(faultRegValue); + + Q_EMIT commandLogWriteSignal("FAULT: 0b" + QString::number(static_cast(*faultRegValue), 2).rightJustified(16, '0')); + } + else{ Q_EMIT commandLogWriteSignal("Failed to read FAULT Register"); } + + delete faultRegValue; +} + +void HarmonicCalibration::updateFaultRegisterUI(uint32_t *faultRegValue) +{ + FAULTRegisterMap = m_admtController->getFaultRegisterBitMapping(static_cast(*faultRegValue)); + + map regmap = FAULTRegisterMap; + toggleStatusLEDColor(VDDUnderVoltageStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("VDD Under Voltage")); + toggleStatusLEDColor(VDDOverVoltageStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("VDD Over Voltage")); + toggleStatusLEDColor(VDRIVEUnderVoltageStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("VDRIVE Under Voltage")); + toggleStatusLEDColor(VDRIVEOverVoltageStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("VDRIVE Over Voltage")); + toggleStatusLEDColor(AFEDIAGStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("AFE Diagnostic")); + toggleStatusLEDColor(NVMCRCFaultStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("NVM CRC Fault")); + toggleStatusLEDColor(ECCDoubleBitErrorStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("ECC Double Bit Error")); + toggleStatusLEDColor(OscillatorDriftStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Oscillator Drift")); + toggleStatusLEDColor(CountSensorFalseStateStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Count Sensor False State")); + toggleStatusLEDColor(AngleCrossCheckStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Angle Cross Check")); + toggleStatusLEDColor(TurnCountSensorLevelsStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Turn Count Sensor Levels")); + toggleStatusLEDColor(MTDIAGStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("MT Diagnostic")); + toggleStatusLEDColor(TurnCounterCrossCheckStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Turn Counter Cross Check")); + toggleStatusLEDColor(RadiusCheckStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("AMR Radius Check")); + toggleStatusLEDColor(SequencerWatchdogStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Sequencer Watchdog")); } void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) @@ -3155,8 +3317,6 @@ void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) uint32_t *DIGIOENRegisterValue = new uint32_t; uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - bool success = false; - if(changeCNVPage(DIGIOENPage)) { if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), @@ -3174,15 +3334,13 @@ void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), static_cast(newRegisterValue)) != -1) { - success = updateDIGIOToggle(); + updateDIGIOControlUI(); } } } } - if(!success) { StatusBarManager::pushMessage("Failed to toggle" + QString::fromStdString(DIGIOENName) + " " + QString(value ? "on" : "off")); } - toggleUtilityTask(true); } @@ -3408,12 +3566,31 @@ void HarmonicCalibration::changeStatusLEDColor(MenuControlButton *menuControlBut menuControlButton->checkBox()->setChecked(checked); } +void HarmonicCalibration::changeStatusLEDColor(QCheckBox *widget, const char *colorAttribute) +{ + Style::setStyle(widget, style::properties::admt::checkBoxLED, true, true); + QString style = QString(R"css( + QCheckBox::indicator:checked { + background-color: &&LEDColor&&; + } + )css"); + style.replace("&&LEDColor&&", Style::getAttribute(colorAttribute)); + widget->setStyleSheet(widget->styleSheet() + "\n" + style); + widget->update(); +} + void HarmonicCalibration::updateFaultStatusLEDColor(MenuControlButton *widget, bool value) { if(value) changeStatusLEDColor(widget, faultLEDColor); else changeStatusLEDColor(widget, statusLEDColor); } +void HarmonicCalibration::toggleStatusLEDColor(QCheckBox *widget, const char *trueAttribute, const char* falseAttribute, bool value) +{ + if(value) changeStatusLEDColor(widget, trueAttribute); + else changeStatusLEDColor(widget, falseAttribute); +} + MenuControlButton *HarmonicCalibration::createStatusLEDWidget(const QString title, QColor color, QWidget *parent) { MenuControlButton *menuControlButton = new MenuControlButton(parent); @@ -3430,6 +3607,15 @@ MenuControlButton *HarmonicCalibration::createStatusLEDWidget(const QString titl return menuControlButton; } +QCheckBox *HarmonicCalibration::createStatusLEDWidget(const QString &text, const char *colorAttribute, bool checked, QWidget *parent) +{ + QCheckBox *checkBox = new QCheckBox(text, parent); + Style::setStyle(checkBox, style::properties::admt::checkBoxLED, true, true); + checkBox->setChecked(checked); + checkBox->setEnabled(false); + return checkBox; +} + MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString title, QColor color, QWidget *parent) { MenuControlButton *menuControlButton = new MenuControlButton(parent); @@ -3446,52 +3632,6 @@ MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString } #pragma endregion - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #pragma region Connect Methods void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max) { @@ -3665,44 +3805,4 @@ double HarmonicCalibration::convertAMAXtoAccelTime(double amax) { return ((rotate_vmax * 131072) / (amax * motorfCLK)); } -#pragma endregion - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#pragma endregion \ No newline at end of file diff --git a/plugins/admt/style/qss/properties/admt/checkBoxLED.qss b/plugins/admt/style/qss/properties/admt/checkBoxLED.qss new file mode 100644 index 0000000000..c79e2d6418 --- /dev/null +++ b/plugins/admt/style/qss/properties/admt/checkBoxLED.qss @@ -0,0 +1,20 @@ +QCheckBox[&&property&&=true] { + width: &unit_1&; + height: &unit_1&; + background-color: transparent; + color: &content_default&; +} +QCheckBox::indicator[&&property&&=true] { + width: 12px; + height: 12px; + border: 1px solid &content_default&; + border-radius: 7px; + image: none; + background-color: &background_primary&; +} +QCheckBox::indicator:checked { + background-color: &background_primary&; +} +QCheckBox::indicator[&&property&&=true]::unchecked { + background-color: &background_primary&; +} \ No newline at end of file From 9db87d8e9e0a0cf6dcb3947cba78bdc694cd1cc2 Mon Sep 17 00:00:00 2001 From: "U-ANALOG\\JJuanill" Date: Fri, 31 Jan 2025 15:00:23 +0800 Subject: [PATCH 085/112] admt: Added license headers Signed-off-by: U-ANALOG\JJuanill Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 21 +++++++++++++++++++ plugins/admt/include/admt/admtplugin.h | 21 +++++++++++++++++++ plugins/admt/include/admt/admtstylehelper.h | 21 +++++++++++++++++++ .../admt/include/admt/harmoniccalibration.h | 21 +++++++++++++++++++ .../include/admt/widgets/horizontalspinbox.h | 21 +++++++++++++++++++ .../admt/widgets/registerblockwidget.h | 21 +++++++++++++++++++ plugins/admt/src/admtcontroller.cpp | 21 +++++++++++++++++++ plugins/admt/src/admtplugin.cpp | 21 +++++++++++++++++++ plugins/admt/src/admtstylehelper.cpp | 21 +++++++++++++++++++ plugins/admt/src/harmoniccalibration.cpp | 21 +++++++++++++++++++ .../admt/src/widgets/horizontalspinbox.cpp | 21 +++++++++++++++++++ .../admt/src/widgets/registerblockwidget.cpp | 21 +++++++++++++++++++ 12 files changed, 252 insertions(+) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 52d6f1d632..c1e27dd5a2 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #ifndef ADMTCONTROLLER_H #define ADMTCONTROLLER_H diff --git a/plugins/admt/include/admt/admtplugin.h b/plugins/admt/include/admt/admtplugin.h index 945d9afee6..9fa16a0668 100644 --- a/plugins/admt/include/admt/admtplugin.h +++ b/plugins/admt/include/admt/admtplugin.h @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #ifndef ADMTPLUGIN_H #define ADMTPLUGIN_H diff --git a/plugins/admt/include/admt/admtstylehelper.h b/plugins/admt/include/admt/admtstylehelper.h index bf722248b9..22b13f9f16 100644 --- a/plugins/admt/include/admt/admtstylehelper.h +++ b/plugins/admt/include/admt/admtstylehelper.h @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #ifndef ADMTSTYLEHELPER_H #define ADMTSTYLEHELPER_H diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index a351514114..716f613add 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #ifndef HARMONICCALIBRATION_H #define HARMONICCALIBRATION_H diff --git a/plugins/admt/include/admt/widgets/horizontalspinbox.h b/plugins/admt/include/admt/widgets/horizontalspinbox.h index 61c29a081d..ddeccadab2 100644 --- a/plugins/admt/include/admt/widgets/horizontalspinbox.h +++ b/plugins/admt/include/admt/widgets/horizontalspinbox.h @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #ifndef HORIZONTALSPINBOX_H #define HORIZONTALSPINBOX_H diff --git a/plugins/admt/include/admt/widgets/registerblockwidget.h b/plugins/admt/include/admt/widgets/registerblockwidget.h index 8e05d6c247..6e326e9ff2 100644 --- a/plugins/admt/include/admt/widgets/registerblockwidget.h +++ b/plugins/admt/include/admt/widgets/registerblockwidget.h @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #ifndef REGISTERBLOCKWIDGET_H #define REGISTERBLOCKWIDGET_H diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 4ee4240054..1bd8bd96cf 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #include "admtcontroller.h" #include diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index 75a204bab0..c030a8e027 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #include "admtplugin.h" #include "admtcontroller.h" #include "harmoniccalibration.h" diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp index cd3bf2855e..4bfc578873 100644 --- a/plugins/admt/src/admtstylehelper.cpp +++ b/plugins/admt/src/admtstylehelper.cpp @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #include "admtstylehelper.h" #include "stylehelper.h" #include diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 48a94258f3..a6fa101788 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #include "harmoniccalibration.h" #include "qtconcurrentrun.h" #include "style.h" diff --git a/plugins/admt/src/widgets/horizontalspinbox.cpp b/plugins/admt/src/widgets/horizontalspinbox.cpp index dcec5d0655..968821432d 100644 --- a/plugins/admt/src/widgets/horizontalspinbox.cpp +++ b/plugins/admt/src/widgets/horizontalspinbox.cpp @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #include #include #include "widgets/horizontalspinbox.h" diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp index f9c0ef4af3..e3b3d55d2f 100644 --- a/plugins/admt/src/widgets/registerblockwidget.cpp +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #include #include #include "widgets/registerblockwidget.h" From 3bcf131272953197a2b31456b2a9768aa92fd517 Mon Sep 17 00:00:00 2001 From: "U-ANALOG\\JJuanill" Date: Fri, 31 Jan 2025 15:05:55 +0800 Subject: [PATCH 086/112] admt: Cleanup license headers for remaining files Signed-off-by: U-ANALOG\JJuanill Signed-off-by: JJuanill --- plugins/admt/test/CMakeLists.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 plugins/admt/test/CMakeLists.txt diff --git a/plugins/admt/test/CMakeLists.txt b/plugins/admt/test/CMakeLists.txt new file mode 100644 index 0000000000..2b852586f3 --- /dev/null +++ b/plugins/admt/test/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# Copyright (c) 2025 Analog Devices Inc. +# +# This file is part of Scopy +# (see https://www.github.com/analogdevicesinc/scopy). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +cmake_minimum_required(VERSION 3.5) + +include(ScopyTest) + +setup_scopy_tests(pluginloader) \ No newline at end of file From ed51605ed17c5bdf8e856f69081cc1abe5c48d82 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 3 Feb 2025 14:34:20 +0800 Subject: [PATCH 087/112] admt: Added regmap debug method Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 4 ++- .../admt/include/admt/harmoniccalibration.h | 7 ++++- plugins/admt/src/admtcontroller.cpp | 15 +++++++++ plugins/admt/src/harmoniccalibration.cpp | 31 ++++++++++++------- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index c1e27dd5a2..bf0cd2c225 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -96,6 +96,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject SDP_GPIO_CTRL, SDP_GPIO0_BUSY, SDP_COIL_RS, + REGMAP_DUMP, DEVICE_ATTR_COUNT }; @@ -172,7 +173,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject const char* ChannelIds[CHANNEL_COUNT] = { "rot", "angl", "count", "temp" }; const char* DeviceIds[DEVICE_COUNT] = { "admt4000", "tmc5240" }; - const char* DeviceAttributes[DEVICE_ATTR_COUNT] = { "page", "sequencer_mode", "angle_filt", "conversion_mode", "h8_ctrl", "sdp_gpio_ctrl", "sdp_gpio0_busy", "sdp_coil_rs" }; + const char* DeviceAttributes[DEVICE_ATTR_COUNT] = { "page", "sequencer_mode", "angle_filt", "conversion_mode", "h8_ctrl", "sdp_gpio_ctrl", "sdp_gpio0_busy", "sdp_coil_rs", "regmap_dump" }; const char* MotorAttributes[MOTOR_ATTR_COUNT] = { "amax", "rotate_vmax", "dmax", "disable", "target_pos", "current_pos", "ramp_mode" }; @@ -203,6 +204,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject int getChannelIndex(const char *deviceName, const char *channelName); double getChannelValue(const char *deviceName, const char *channelName, int bufferSize = 1); int getDeviceAttributeValue(const char *deviceName, const char *attributeName, double *returnValue); + int getDeviceAttributeValueString(const char *deviceName, const char *attributeName, char *returnValue, size_t byteLength = 512); int setDeviceAttributeValue(const char *deviceName, const char *attributeName, double writeValue); QString calibrate(vector PANG, int cycles = 11, int samplesPerCycle = 256); int writeDeviceRegistry(const char *deviceName, uint32_t address, uint32_t value); diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 716f613add..4bc2a33027 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -160,7 +160,8 @@ public Q_SLOTS: *calibrationMotorCurrentPositionLineEdit, *AFEDIAG0LineEdit, *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; - QLabel *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, + QLabel *rawAngleValueLabel, + *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, *motorAmaxValueLabel, *motorRotateVmaxValueLabel, *motorDmaxValueLabel, *motorDisableValueLabel, *motorTargetPosValueLabel, *motorCurrentPosValueLabel, *motorRampModeValueLabel, @@ -371,6 +372,10 @@ public Q_SLOTS: double convertAccelTimetoAMAX(double accelTime); double convertAMAXtoAccelTime(double amax); #pragma endregion + + #pragma region Debug Methods + QString readRegmapDumpAttributeValue(); + #pragma endregion }; } // namespace admt } // namespace scopy diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 1bd8bd96cf..3dda2697c2 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -314,6 +314,21 @@ int ADMTController::getDeviceAttributeValue(const char *deviceName, const char * return result; } +int ADMTController::getDeviceAttributeValueString(const char *deviceName, const char *attributeName, char *returnValue, size_t byteLength) +{ + if(!m_iioCtx) { return -1; } + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount == 0) { return result; } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) { return result; } + const char* hasAttr = iio_device_find_attr(iioDevice, attributeName); + if(hasAttr == NULL) { return result; } + result = iio_device_attr_read(iioDevice, attributeName, returnValue, byteLength); + + return result; +} + /** @brief Set the attribute value of a device * @param deviceName A pointer to the device name * @param attributeName A NULL-terminated string corresponding to the name of the diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index a6fa101788..6501d5daac 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -295,15 +295,10 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() countWidget->contentLayout()->addWidget(countSection); tempWidget->contentLayout()->addWidget(tempSection); - rotationValueLabel = new QLabel(rotationSection); - angleValueLabel = new QLabel(angleSection); - countValueLabel = new QLabel(countSection); - tempValueLabel = new QLabel(tempSection); - - rotationValueLabel->setText("--.--°"); - angleValueLabel->setText("--.--°"); - countValueLabel->setText("--"); - tempValueLabel->setText("--.-- °C"); + rotationValueLabel = new QLabel("--.--°", rotationSection); + angleValueLabel = new QLabel("--.--°", angleSection); + countValueLabel = new QLabel("--", countSection); + tempValueLabel = new QLabel("--.-- °C", tempSection); rotationSection->contentLayout()->addWidget(rotationValueLabel); angleSection->contentLayout()->addWidget(angleValueLabel); @@ -2079,8 +2074,8 @@ bool HarmonicCalibration::updateChannelValues(){ void HarmonicCalibration::updateCountValue(){ uint32_t *absAngleRegValue = new uint32_t; bool success = false; - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0x0000) != -1){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), absAngleRegValue) != -1){ + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0x0000) == 0){ + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), absAngleRegValue) == 0){ count = m_admtController->getAbsAngleTurnCount(static_cast(*absAngleRegValue)); success = true; } @@ -3826,4 +3821,18 @@ double HarmonicCalibration::convertAMAXtoAccelTime(double amax) { return ((rotate_vmax * 131072) / (amax * motorfCLK)); } +#pragma endregion + +#pragma region Debug Methods +QString HarmonicCalibration::readRegmapDumpAttributeValue() +{ + QString output = ""; + char value[1024]; + int result = -1; + result = m_admtController->getDeviceAttributeValueString(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getDeviceAttribute(ADMTController::DeviceAttribute::REGMAP_DUMP), + value, 1024); + output = QString(value); + return output; +} #pragma endregion \ No newline at end of file From 7d65183a18c4e3328e9c187e3528096ef8432a16 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 26 Feb 2025 08:00:50 +0800 Subject: [PATCH 088/112] admt: Implemented continuous calibration - Migrating styles to separate .qss - Changed status LED behavior Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- gui/style/json/Harmonic dark.json | 2 + gui/style/json/Harmonic light.json | 4 +- gui/style/json/Scopy.json | 2 + plugins/admt/include/admt/admtcontroller.h | 41 +- plugins/admt/include/admt/admtstylehelper.h | 1 - .../admt/include/admt/harmoniccalibration.h | 77 +- .../admt/widgets/registerblockwidget.h | 2 - plugins/admt/src/admtcontroller.cpp | 221 ++- plugins/admt/src/admtstylehelper.cpp | 31 - plugins/admt/src/harmoniccalibration.cpp | 1515 +++++++++++------ .../admt/src/widgets/registerblockwidget.cpp | 60 +- .../style/qss/properties/admt/checkBoxLED.qss | 63 +- .../properties/admt/fullWidthRunButton.qss | 24 + .../admt/style/qss/properties/admt/tabBar.qss | 39 + .../style/qss/properties/admt/tabWidget.qss | 3 + 15 files changed, 1420 insertions(+), 665 deletions(-) create mode 100644 plugins/admt/style/qss/properties/admt/fullWidthRunButton.qss create mode 100644 plugins/admt/style/qss/properties/admt/tabBar.qss create mode 100644 plugins/admt/style/qss/properties/admt/tabWidget.qss diff --git a/gui/style/json/Harmonic dark.json b/gui/style/json/Harmonic dark.json index f0faaf4051..4e002173fd 100644 --- a/gui/style/json/Harmonic dark.json +++ b/gui/style/json/Harmonic dark.json @@ -10,10 +10,12 @@ "interactive_primary_hover": "#C6D8F6", "interactive_primary_pressed": "#abc4ed", "interactive_primary_disabled": "#0067B9", +"interactive_primary_faint": "#00549A", "interactive_secondary_idle": "#92BEFC", "interactive_secondary_hover": "#C6D8F6", "interactive_secondary_pressed": "#abc4ed", "interactive_secondary_disabled": "#4B545D", +"interactive_silent_hover": "#3A424B", "content_default": "#FFFFFF", "content_subtle": "#B7BBC3", "content_silent": "#848B95", diff --git a/gui/style/json/Harmonic light.json b/gui/style/json/Harmonic light.json index ecf2f8de2d..e0a89ee08f 100644 --- a/gui/style/json/Harmonic light.json +++ b/gui/style/json/Harmonic light.json @@ -10,10 +10,12 @@ "interactive_primary_hover": "#00427A", "interactive_primary_pressed": "#003969", "interactive_primary_disabled": "#92BEFC", +"interactive_primary_faint": "#C6D8F6", "interactive_secondary_idle": "#0067B9", "interactive_secondary_hover": "#00427A", "interactive_secondary_pressed": "#003969", -"interactive_secondary_disabled": "#d5d7db", +"interactive_secondary_disabled": "#c1c3c7", +"interactive_silent_hover": "#D5D8DC", "content_default": "#101820", "content_subtle": "#5E6773", "content_silent": "#9FA4AD", diff --git a/gui/style/json/Scopy.json b/gui/style/json/Scopy.json index 35ea15834f..c0cf475cb5 100644 --- a/gui/style/json/Scopy.json +++ b/gui/style/json/Scopy.json @@ -10,10 +10,12 @@ "interactive_primary_hover": "#697EFF", "interactive_primary_pressed": "#7084fa", "interactive_primary_disabled": "#2E3874", +"interactive_primary_faint": "#00549A", "interactive_secondary_idle": "#5b5b6b", "interactive_secondary_hover": "#535361", "interactive_secondary_pressed": "#4c4c59", "interactive_secondary_disabled": "#35353d", +"interactive_silent_hover": "#3A424B", "content_default": "#e1e1e3", "content_subtle": "#bac2cc", "content_silent": "#848491", diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index bf0cd2c225..390d245e4b 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -53,7 +54,16 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject ADMTController(QString uri, QObject *parent = nullptr); ~ADMTController(); - int HAR_MAG_1, HAR_MAG_2, HAR_MAG_3, HAR_MAG_8 ,HAR_PHASE_1 ,HAR_PHASE_2 ,HAR_PHASE_3 ,HAR_PHASE_8; + int HAR_MAG_1, HAR_MAG_2, HAR_MAG_3, HAR_MAG_8 ,HAR_PHASE_1 ,HAR_PHASE_2 ,HAR_PHASE_3 ,HAR_PHASE_8, + sampleCount = 0; + + bool stopStream = false; + + double streamedValue = 0.0; + QVector streamBufferedValues; + QVector streamBufferedIntervals; + + QElapsedTimer elapsedStreamTimer; vector angle_errors_fft_pre, angle_errors_fft_phase_pre, @@ -171,6 +181,15 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject UNIQID_REGISTER_COUNT }; + enum RampGeneratorDriverFeatureControlRegister + { + VDCMIN, + SW_MODE, + RAMP_STAT, + XLATCH, + RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT + }; + const char* ChannelIds[CHANNEL_COUNT] = { "rot", "angl", "count", "temp" }; const char* DeviceIds[DEVICE_COUNT] = { "admt4000", "tmc5240" }; const char* DeviceAttributes[DEVICE_ATTR_COUNT] = { "page", "sequencer_mode", "angle_filt", "conversion_mode", "h8_ctrl", "sdp_gpio_ctrl", "sdp_gpio0_busy", "sdp_coil_rs", "regmap_dump" }; @@ -186,6 +205,8 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = { 0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14 }; const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }; + const uint32_t RampGeneratorDriverFeatureControlRegisters[RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT] = { 0x33, 0x34, 0x35, 0x36 }; + const char* getChannelId(Channel channel); const char* getDeviceId(Device device); const char* getDeviceAttribute(DeviceAttribute attribute); @@ -199,6 +220,8 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject const uint32_t getSensorRegister(SensorRegister registerID); const uint32_t getSensorPage(SensorRegister registerID); + const uint32_t getRampGeneratorDriverFeatureControlRegister(RampGeneratorDriverFeatureControlRegister registerID); + void connectADMT(); void disconnectADMT(); int getChannelIndex(const char *deviceName, const char *channelName); @@ -206,7 +229,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject int getDeviceAttributeValue(const char *deviceName, const char *attributeName, double *returnValue); int getDeviceAttributeValueString(const char *deviceName, const char *attributeName, char *returnValue, size_t byteLength = 512); int setDeviceAttributeValue(const char *deviceName, const char *attributeName, double writeValue); - QString calibrate(vector PANG, int cycles = 11, int samplesPerCycle = 256); + QString calibrate(vector PANG, int cycles, int samplesPerCycle, bool CCW); int writeDeviceRegistry(const char *deviceName, uint32_t address, uint32_t value); int readDeviceRegistry(const char *deviceName, uint32_t address, uint32_t *returnValue); void computeSineCosineOfAngles(const vector& angles); @@ -221,7 +244,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject map getDiag1RegisterBitMapping_Afe(uint16_t registerValue, bool is5V); map getDiag2RegisterBitMapping(uint16_t registerValue); uint16_t setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings); - void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle); + void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle, bool CCW); int getAbsAngleTurnCount(uint16_t registerValue); uint16_t setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings); uint16_t setDIGIORegisterBitMapping(uint16_t currentRegisterValue, map settings); @@ -235,7 +258,17 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject map getSecAnglIRegisterBitMapping(uint16_t registerValue); map getTmp1RegisterBitMapping(uint16_t registerValue, bool is5V); bool checkRegisterFault(uint16_t registerValue, bool isMode1); - + int streamIO(); + void bufferedStreamIO(int totalSamples, int targetSampleRate); + bool checkVelocityReachedFlag(uint16_t registerValue); +public Q_SLOTS: + void handleStreamData(double value); + void handleStreamBufferedData(const QVector &value); + void handleStreamBufferedDataInterval(const QVector &value); +Q_SIGNALS: + void streamData(double value); + void streamBufferedData(const QVector &value); + void streamBufferedDataInterval(const QVector &value); private: iio_context *m_iioCtx; iio_buffer *m_iioBuffer; diff --git a/plugins/admt/include/admt/admtstylehelper.h b/plugins/admt/include/admt/admtstylehelper.h index 22b13f9f16..3b5898033c 100644 --- a/plugins/admt/include/admt/admtstylehelper.h +++ b/plugins/admt/include/admt/admtstylehelper.h @@ -58,7 +58,6 @@ class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject static void LineEditStyle(QLineEdit *widget, QString objectName = ""); static void ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName = ""); static void StartButtonStyle(QPushButton *btn, QString objectName = ""); - static void TabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor = "ScopyBlue", QString objectName = ""); static void TextStyle(QWidget *widget, const char *styleHelperColor = json::global::white, bool isBold = false, QString objectName = "");// void TextStyle(QWidget *widget, const QString& styleHelperColor, bool isBold = false, QString objectName = ""); static void MenuSmallLabel(QLabel *label, QString objectName = ""); static void LineStyle(QFrame *line, QString objectName = ""); diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 4bc2a33027..a86ba940e4 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -113,24 +113,26 @@ public Q_SLOTS: void stop(); void start(); void restart(); - void commandLogWrite(QString message); + void calibrationLogWrite(QString message = ""); + void commandLogWrite(QString message = ""); void updateFaultStatus(bool value); void updateMotorPosition(double position); - void updateDIGIOUI(uint32_t *registerValue); - void updateFaultRegisterUI(uint32_t *registerValue); - void updateMTDiagnosticRegisterUI(uint32_t *registerValue); - void updateMTDiagnosticsUI(uint32_t *registerValue); + void updateDIGIOUI(uint16_t *registerValue); + void updateFaultRegisterUI(uint16_t *registerValue); + void updateMTDiagnosticRegisterUI(uint16_t *registerValue); + void updateMTDiagnosticsUI(uint16_t *registerValue); Q_SIGNALS: void runningChanged(bool); void canCalibrateChanged(bool); void updateUtilityUI(); + void calibrationLogWriteSignal(QString message); void commandLogWriteSignal(QString message); void updateFaultStatusSignal(bool value); void motorPositionChanged(double position); - void DIGIORegisterChanged(uint32_t *registerValue); - void FaultRegisterChanged(uint32_t *registerValue); - void DIAG1RegisterChanged(uint32_t *registerValue); - void DIAG2RegisterChanged(uint32_t *registerValue); + void DIGIORegisterChanged(uint16_t *registerValue); + void FaultRegisterChanged(uint16_t *registerValue); + void DIAG1RegisterChanged(uint16_t *registerValue); + void DIAG2RegisterChanged(uint16_t *registerValue); private: ADMTController *m_admtController; iio_context *m_ctx; @@ -142,7 +144,8 @@ public Q_SLOTS: const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; - double rotation, angle, count, temp = 0.0, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode, + double rotation, angle, count, temp = 0.0, + motor_rpm, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode, afeDiag0, afeDiag1, afeDiag2; QPushButton *openLastMenuButton, *calibrationStartMotorButton, @@ -150,7 +153,7 @@ public Q_SLOTS: *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; QButtonGroup *rightMenuButtonGroup; - QLineEdit *motorTargetPositionLineEdit, *graphUpdateIntervalLineEdit, *displayLengthLineEdit, + QLineEdit *acquisitionMotorRPMLineEdit, *calibrationMotorRPMLineEdit, *motorTargetPositionLineEdit, *graphUpdateIntervalLineEdit, *displayLengthLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, *acquisitionMotorCurrentPositionLineEdit, *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, @@ -179,7 +182,8 @@ public Q_SLOTS: MenuSectionWidget *rightMenuSectionWidget; MenuCollapseSection *rotationCollapse, *angleCollapse, *countCollapse, *tempCollapse; MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo, *m_calibrationMotorRampModeMenuCombo, - *sequenceTypeMenuCombo, *conversionTypeMenuCombo, *cnvSourceMenuCombo, *convertSynchronizationMenuCombo, *angleFilterMenuCombo, *eighthHarmonicMenuCombo; + *sequenceTypeMenuCombo, *conversionTypeMenuCombo, *cnvSourceMenuCombo, *convertSynchronizationMenuCombo, *angleFilterMenuCombo, *eighthHarmonicMenuCombo, + *calibrationModeMenuCombo; QTabWidget *tabWidget, *calibrationDataGraphTabWidget, *resultDataTabWidget; @@ -213,7 +217,7 @@ public Q_SLOTS: HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, *motorMaxDisplacementSpinBox, *motorTargetPositionSpinBox; - CustomSwitch *calibrationDisplayFormatSwitch, + CustomSwitch *acquisitionMotorDirectionSwitch, *calibrationMotorDirectionSwitch, *calibrationDisplayFormatSwitch, *DIGIO0ENToggleSwitch, *DIGIO0FNCToggleSwitch, *DIGIO1ENToggleSwitch, *DIGIO1FNCToggleSwitch, *DIGIO2ENToggleSwitch, *DIGIO2FNCToggleSwitch, @@ -226,10 +230,12 @@ public Q_SLOTS: QFuture m_deviceStatusThread, m_currentMotorPositionThread, m_acquisitionUIThread, m_acquisitionDataThread, m_acquisitionGraphThread, - m_calibrationUIThread, m_utilityUIThread, m_utilityThread; + m_calibrationUIThread, m_calibrationStreamThread, m_calibrationWaitVelocityThread, m_calibrationContinuousThread, + m_resetMotorToZeroThread, m_utilityUIThread, m_utilityThread; QFutureWatcher m_deviceStatusWatcher, m_currentMotorPositionWatcher, m_acquisitionUIWatcher, m_acquisitionDataWatcher, m_acquisitionGraphWatcher, - m_calibrationUIWatcher, m_utilityUIWatcher, m_utilityWatcher; + m_calibrationUIWatcher, m_calibrationStreamWatcher, m_calibrationWaitVelocityWatcher, m_calibrationContinuousWatcher, + m_resetMotorToZeroWatcher, m_utilityUIWatcher, m_utilityWatcher; ToolTemplate* createAcquisitionWidget(); ToolTemplate* createCalibrationWidget(); @@ -239,6 +245,7 @@ public Q_SLOTS: void readDeviceProperties(); void initializeADMT(); bool readSequence(); + bool writeSequence(const map &settings); void applySequence(); bool changeCNVPage(uint32_t page); void initializeMotor(); @@ -256,6 +263,8 @@ public Q_SLOTS: void updateLineEditValues(); void startAcquisition(); void stopAcquisition(); + void updateAcquisitionMotorRPM(); + void updateAcquisitionMotorRotationDirection(); void getAcquisitionSamples(int sampleRate); double getAcquisitionParameterValue(const AcquisitionDataKey &key); void plotAcquisition(QVector& list, PlotChannel* channel); @@ -276,16 +285,29 @@ public Q_SLOTS: void startCalibrationUITask(); void stopCalibrationUITask(); void calibrationUITask(int sampleRate); + void updateCalibrationMotorRPM(); + void updateCalibrationMotorRotationDirection(); void getCalibrationSamples(); void startCalibration(); void stopCalibration(); - void startMotor(); - void startMotorContinuous(); + void startContinuousCalibration(); + void stopContinuousCalibration(); + void startCalibrationStreamThread(); + void stopCalibrationStreamThread(); + void startWaitForVelocityReachedThread(int mode); + void stopWaitForVelocityReachedThread(); + void waitForVelocityReached(int mode, int sampleRate); + int calculateContinuousCalibrationSampleRate(double motorRPS, int samplesPerCycle); + void configureConversionType(int mode); + void configureCalibrationSequenceSettings(); + void getStreamedCalibrationSamples(int microSampleRate); + void startOneShotCalibration(); void postCalibrateData(); void resetAllCalibrationState(); void computeSineCosineOfAngles(QVector graphDataList); void populateAngleErrorGraphs(); void populateCorrectedAngleErrorGraphs(); + void clearHarmonicRegisters(); void flashHarmonicValues(); void calculateHarmonicValues(); void updateCalculatedCoeffAngle(); @@ -293,13 +315,13 @@ public Q_SLOTS: void resetCalculatedCoeffAngle(); void resetCalculatedCoeffHex(); void displayCalculatedCoeff(); - void calibrationLogWrite(QString message = ""); void importCalibrationData(); void extractCalibrationData(); void toggleTabSwitching(bool value); + void toggleCalibrationButtonState(int state); void canStartMotor(bool value); void canCalibrate(bool); - void toggleMotorControls(bool value); + void toggleCalibrationControls(bool value); void clearCalibrationSamples(); void clearCalibrationSineCosine(); void clearPostCalibrationSamples(); @@ -309,10 +331,17 @@ public Q_SLOTS: #pragma region Motor Methods bool moveMotorToPosition(double& position, bool validate = true); + void moveMotorContinuous(); bool resetCurrentPositionToZero(); void stopMotor(); int readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value); int writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); + int readMotorRegisterValue(uint32_t address, uint32_t *value); + void setRampMode(bool motorRotationClockwise); + void getRampMode(); + void startResetMotorToZero(); + void stopResetMotorToZero(); + void resetMotorToZero(); #pragma endregion #pragma region Utility Methods @@ -345,12 +374,7 @@ public Q_SLOTS: void updateLineEditValue(QLineEdit* lineEdit, double value); void toggleWidget(QPushButton *widget, bool value); void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel); - void changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked = true); - void changeStatusLEDColor(QCheckBox *widget, const char *colorAttribute); - void updateFaultStatusLEDColor(MenuControlButton *widget, bool value); - void toggleStatusLEDColor(QCheckBox *widget, const char *trueAttribute, const char* falseAttribute, bool value); - MenuControlButton *createStatusLEDWidget(const QString title, QColor color, QWidget *parent = nullptr); - QCheckBox *createStatusLEDWidget(const QString &text, const char *colorAttribute, bool checked = false, QWidget *parent = nullptr); + QCheckBox *createStatusLEDWidget(const QString &text, QVariant variant = true, bool checked = false, QWidget *parent = nullptr); MenuControlButton *createChannelToggleWidget(const QString title, QColor color, QWidget *parent = nullptr); #pragma endregion @@ -364,6 +388,7 @@ public Q_SLOTS: void connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax); void connectLineEditToAMAXConversion(QLineEdit* lineEdit, double& amax); void connectRegisterBlockToRegistry(RegisterBlockWidget* widget); + void connectLineEditToRPM(QLineEdit* lineEdit, double& variable); #pragma endregion #pragma region Convert Methods @@ -371,6 +396,8 @@ public Q_SLOTS: double convertVMAXtoRPS(double vmax); double convertAccelTimetoAMAX(double accelTime); double convertAMAXtoAccelTime(double amax); + double convertRPMtoRPS(double rpm); + double convertRPStoRPM(double rps); #pragma endregion #pragma region Debug Methods diff --git a/plugins/admt/include/admt/widgets/registerblockwidget.h b/plugins/admt/include/admt/widgets/registerblockwidget.h index 6e326e9ff2..50171c7f4c 100644 --- a/plugins/admt/include/admt/widgets/registerblockwidget.h +++ b/plugins/admt/include/admt/widgets/registerblockwidget.h @@ -65,8 +65,6 @@ namespace scopy::admt { void addReadButton(QWidget *parent); void addWriteButton(QWidget *parent); - void applyLineEditStyle(QLineEdit *widget); - void applySpinBoxStyle(QSpinBox *widget); }; class SCOPY_ADMT_EXPORT PaddedSpinBox : public QSpinBox diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 3dda2697c2..7c7deaab09 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -22,7 +22,6 @@ #include "admtcontroller.h" #include - #include #include #include @@ -37,9 +36,12 @@ #include #include #include +#include static const size_t maxAttrSize = 512; +static char *streamBuffer = new char[maxAttrSize]; + using namespace scopy::admt; using namespace std; @@ -47,6 +49,9 @@ ADMTController::ADMTController(QString uri, QObject *parent) :QObject(parent) , uri(uri) { + connect(this, &ADMTController::streamData, this, &ADMTController::handleStreamData); + connect(this, &ADMTController::streamBufferedData, this, &ADMTController::handleStreamBufferedData); + connect(this, &ADMTController::streamBufferedDataInterval, this, &ADMTController::handleStreamBufferedDataInterval); } ADMTController::~ADMTController() {} @@ -164,6 +169,14 @@ const uint32_t ADMTController::getUniqueIdPage(UniqueIDRegister registerID) return UINT32_MAX; } +const uint32_t ADMTController::getRampGeneratorDriverFeatureControlRegister(RampGeneratorDriverFeatureControlRegister registerID) +{ + if(registerID >= 0 && registerID < RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT){ + return RampGeneratorDriverFeatureControlRegisters[registerID]; + } + return UINT32_MAX; +} + int ADMTController::getChannelIndex(const char *deviceName, const char *channelName) { iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); @@ -529,8 +542,8 @@ void ADMTController::unwrapAngles(vector& angles_rad) { } } -QString ADMTController::calibrate(vector PANG, int cycleCount, int samplesPerCycle) { - int CCW = 0, circshiftData = 0; +QString ADMTController::calibrate(vector PANG, int cycleCount, int samplesPerCycle, bool CCW) { + int circshiftData = 0; QString result = ""; /* Check CCW flag to know if array is to be reversed */ @@ -551,10 +564,10 @@ QString ADMTController::calibrate(vector PANG, int cycleCount, int sampl getPreCalibrationFFT(PANG, angle_errors_fft_pre, angle_errors_fft_phase_pre, cycleCount, samplesPerCycle); // Extract HMag parameters - double H1Mag = angle_errors_fft_pre[cycleCount + 1]; - double H2Mag = angle_errors_fft_pre[2 * cycleCount + 1]; - double H3Mag = angle_errors_fft_pre[3 * cycleCount + 1]; - double H8Mag = angle_errors_fft_pre[8 * cycleCount + 1]; + double H1Mag = angle_errors_fft_pre[cycleCount]; + double H2Mag = angle_errors_fft_pre[2 * cycleCount]; + double H3Mag = angle_errors_fft_pre[3 * cycleCount]; + double H8Mag = angle_errors_fft_pre[8 * cycleCount]; /* Display HMAG values */ result.append("H1Mag = " + QString::number(H1Mag) + "\n"); @@ -563,10 +576,10 @@ QString ADMTController::calibrate(vector PANG, int cycleCount, int sampl result.append("H8Mag = " + QString::number(H8Mag) + "\n"); // Extract HPhase parameters - double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycleCount + 1]); - double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycleCount + 1]); - double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycleCount + 1]); - double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycleCount + 1]); + double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycleCount]); + double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycleCount]); + double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycleCount]); + double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycleCount]); /* Display HPHASE values */ result.append("H1Phase = " + QString::number(H1Phase) + "\n"); @@ -580,7 +593,7 @@ QString ADMTController::calibrate(vector PANG, int cycleCount, int sampl double H8 = H8Mag * cos(M_PI / 180 * (H8Phase)); double init_err = H1 + H2 + H3 + H8; - double init_angle = PANG[1] - init_err; + double init_angle = PANG[0] - init_err; double H1PHcor, H2PHcor, H3PHcor, H8PHcor; @@ -654,15 +667,10 @@ void ADMTController::getPreCalibrationFFT(const vector& PANG, vector PANG, int cycleCount, int samplesPerCycle){ - int CCW = 0, circshiftData = 0; +void ADMTController::postcalibrate(vector PANG, int cycleCount, int samplesPerCycle, bool CCW){ + int circshiftData = 0; QString result = ""; /* Check CCW flag to know if array is to be reversed */ @@ -1583,4 +1591,179 @@ bool ADMTController::checkRegisterFault(uint16_t registerValue, bool isMode1) { ((registerValue >> 1) & 0x01) || // VDD Over Voltage ((registerValue >> 0) & 0x01); // VDD Under Voltage } +} + +int ADMTController::streamIO() +{ + int result = -1; + const char *deviceName = "admt4000"; + const char *channelName = "rot"; + const char *scaleAttrName = "scale"; + const char *offsetAttrName = "offset"; + size_t samples = 1; + bool isOutput = false; + bool isCyclic = false; + + unsigned int i, j, major, minor; + char git_tag[8]; + iio_library_get_version(&major, &minor, git_tag); + bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; + + double *scaleAttrValue = new double(1); + int offsetAttrValue = 0; + char *offsetDst = new char[maxAttrSize]; + + if(!m_iioCtx) return result; // Check if the context is valid + if(iio_context_get_devices_count(m_iioCtx) < 1) return result; // Check if there are devices in the context + struct iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); // Find the ADMT device + if(admtDevice == NULL) return result; + struct iio_channel *channel = iio_device_find_channel(admtDevice, channelName, isOutput); // Find the rotation channel + if(channel == NULL) return result; + iio_channel_enable(channel); // Enable the channel + int scaleRet = iio_channel_attr_read_double(channel, scaleAttrName, scaleAttrValue); // Read the scale attribute + if(scaleRet != 0) return scaleRet; + iio_channel_attr_read(channel, offsetAttrName, offsetDst, maxAttrSize); // Read the offset attribute + offsetAttrValue = atoi(offsetDst); + struct iio_buffer *buffer = iio_device_create_buffer(admtDevice, samples, isCyclic); // Create a buffer + + while(!stopStream) + { + ssize_t numBytesRead; + char *pointerData, *pointerEnd; + ptrdiff_t pointerIncrement; + + numBytesRead = iio_buffer_refill(buffer); + if(numBytesRead < 0) break; + + pointerIncrement = iio_buffer_step(buffer); + pointerEnd = static_cast(iio_buffer_end(buffer)); + + const struct iio_data_format *format = iio_channel_get_data_format(channel); + unsigned int repeat = has_repeat ? format->repeat : 1; + + for(pointerData = static_cast(iio_buffer_first(buffer, channel)); pointerData < pointerEnd; pointerData += pointerIncrement) + { + for(int j = 0; j < repeat; j++) + { + if(format->length / 8 == sizeof(int16_t)) + { + int16_t rawValue = (reinterpret_cast(pointerData))[j]; + double scaledValue = (rawValue - offsetAttrValue) * *scaleAttrValue; + Q_EMIT streamData(scaledValue); + } + } + } + } + + iio_buffer_destroy(buffer); + return 0; +} + +void ADMTController::handleStreamData(double value) +{ + streamedValue = value; +} + +void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) +{ + streamBufferedIntervals.clear(); + QVector bufferedValues; + vector rawBufferedValues; + sampleCount = 0; + + int result = -1; + const char *deviceName = "admt4000"; + const char *channelName = "rot"; + const char *scaleAttrName = "scale"; + const char *offsetAttrName = "offset"; + size_t samples = 1; + bool isOutput = false; + bool isCyclic = true; + + unsigned int i, j, major, minor; + char git_tag[8]; + iio_library_get_version(&major, &minor, git_tag); + bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; + + double *scaleAttrValue = new double(1); + int offsetAttrValue = 0; + char *offsetDst = new char[maxAttrSize]; + + if(!m_iioCtx) return; // result; // Check if the context is valid + if(iio_context_get_devices_count(m_iioCtx) < 1) return; // result; // Check if there are devices in the context + struct iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); // Find the ADMT device + if(admtDevice == NULL) return; // result; + struct iio_channel *channel = iio_device_find_channel(admtDevice, channelName, isOutput); // Find the rotation channel + if(channel == NULL) return; // result; + iio_channel_enable(channel); // Enable the channel + int scaleRet = iio_channel_attr_read_double(channel, scaleAttrName, scaleAttrValue); // Read the scale attribute + if(scaleRet != 0) return; // scaleRet; + iio_channel_attr_read(channel, offsetAttrName, offsetDst, maxAttrSize); // Read the offset attribute + offsetAttrValue = atoi(offsetDst); + struct iio_buffer *buffer = iio_device_create_buffer(admtDevice, samples, isCyclic); // Create a buffer + + while(!stopStream && sampleCount < totalSamples) + { + elapsedStreamTimer.start(); + + ssize_t numBytesRead; + char *pointerData, *pointerEnd; + ptrdiff_t pointerIncrement; + + numBytesRead = iio_buffer_refill(buffer); + if(numBytesRead < 0) break; + + pointerIncrement = iio_buffer_step(buffer); + pointerEnd = static_cast(iio_buffer_end(buffer)); + + const struct iio_data_format *format = iio_channel_get_data_format(channel); + unsigned int repeat = has_repeat ? format->repeat : 1; + int j = 0; + + for(pointerData = static_cast(iio_buffer_first(buffer, channel)); pointerData < pointerEnd; pointerData += pointerIncrement) + { + for(j = 0; j < repeat; j++) + { + if(format->length / 8 == sizeof(int16_t)) + { + rawBufferedValues.push_back((reinterpret_cast(pointerData))[j]); + sampleCount++; + continue; + } + } + } + + qint64 elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); + while(elapsedNanoseconds < targetSampleRate) + { + elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); + } + streamBufferedIntervals.append(elapsedNanoseconds); + } + iio_buffer_destroy(buffer); + + for(int i = 0; i < rawBufferedValues.size(); i++) + { + double scaledValue = (rawBufferedValues[i] - offsetAttrValue) * *scaleAttrValue; + bufferedValues.append(scaledValue); + } + + Q_EMIT streamBufferedData(bufferedValues); + Q_EMIT streamBufferedDataInterval(streamBufferedIntervals); +} + +void ADMTController::handleStreamBufferedData(const QVector &value) +{ + streamBufferedValues = value; +} + +bool ADMTController::checkVelocityReachedFlag(uint16_t registerValue) +{ + // Bit 8 - 1: Signals that the target velocity is reached. This flag becomes set while VACTUAL and VMAX match. + return ((registerValue >> 8) & 0x01) ? true : false; +} + +void ADMTController::handleStreamBufferedDataInterval(const QVector &value) +{ + streamBufferedIntervals = value; } \ No newline at end of file diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp index 4bfc578873..a6e77831b9 100644 --- a/plugins/admt/src/admtstylehelper.cpp +++ b/plugins/admt/src/admtstylehelper.cpp @@ -254,37 +254,6 @@ void ADMTStyleHelper::StartButtonStyle(QPushButton *btn, QString objectName) btn->setIconSize(QSize(64, 64)); } -void ADMTStyleHelper::TabWidgetStyle(QTabWidget *widget, const QString& styleHelperColor, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - QString style = QString(R"css( - QTabWidget::tab-bar { - left: 5px; /* move to the right by 5px */ - } - QTabBar::tab { - min-width: 100px; - min-height: 32px; - padding-bottom: 5px; - padding-left: 16px; - padding-right: 16px; - background-color: &&UIElementBackground&&; - font: normal; - } - QTabBar::tab:selected { - color: white; - border-bottom: 2px solid &&ScopyBlue&&; - margin-top: 0px; - } - QTabBar::tab:disabled{ - color: grey; - } - )css"); - style.replace("&&ScopyBlue&&", Style::getAttribute(json::theme::interactive_primary_idle)); - style.replace("&&UIElementBackground&&", Style::getAttribute(json::theme::background_primary)); - widget->tabBar()->setStyleSheet(style); -} - void ADMTStyleHelper::TextStyle(QWidget *widget, const char *styleHelperColor, bool isBold, QString objectName) { if(!objectName.isEmpty()) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 6501d5daac..6fed3edefb 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -28,22 +28,22 @@ #include #include +using namespace scopy; +using namespace scopy::admt; + static int acquisitionUITimerRate = 500; // In ms static int acquisitionSampleRate = 20; static int acquisitionGraphSampleRate = 100; +static int motorWaitVelocityReachedSampleRate = 50; static int calibrationUITimerRate = 500; static int utilityUITimerRate = 1000; +static int continuousCalibrationSampleRate = 10000000; // In nanoseconds static int deviceStatusMonitorRate = 500; static int motorPositionMonitorRate = 500; static int bufferSize = 1; -static int dataGraphSamples = 100; -static int tempGraphSamples = 100; -static bool running = false; -static double *dataGraphValue; -static double *tempGraphValue; static int cycleCount = 11; static int samplesPerCycle = 256; @@ -54,46 +54,44 @@ static bool isCalculatedCoeff = false; static bool isAngleDisplayFormat = false; static bool resetToZero = true; static bool hasMTDiagnostics = false; +static bool isMotorRotationClockwise = true; +static double fast_motor_rpm = 300; -static double motorTimeUnit = 1.048576; // t = 2^24/16Mhz -static int motorMicrostepPerRevolution = 51200; -static int motorfCLK = 16000000; // 16Mhz +static double motorFullStepAngle = 0.9; // TODO input as configuration +static double microStepResolution = 256; // TODO input as configuration +static int motorfCLK = 12500000; // 12.5 Mhz, TODO input as configuration +static double motorAccelTime = 1; // In seconds -static uint32_t h1MagDeviceRegister = 0x15; -static uint32_t h2MagDeviceRegister = 0x17; -static uint32_t h3MagDeviceRegister = 0x19; -static uint32_t h8MagDeviceRegister = 0x1B; -static uint32_t h1PhaseDeviceRegister = 0x16; -static uint32_t h2PhaseDeviceRegister = 0x18; -static uint32_t h3PhaseDeviceRegister = 0x1A; -static uint32_t h8PhaseDeviceRegister = 0x1C; +static double motorFullStepPerRevolution = 360 / motorFullStepAngle; +static double motorMicrostepPerRevolution = motorFullStepPerRevolution * microStepResolution; +static double motorTimeUnit = static_cast(1 << 24) / motorfCLK; // t = 2^24/16Mhz static int acquisitionDisplayLength = 200; static QVector acquisitionAngleList, acquisitionABSAngleList, acquisitionTurnCountList, acquisitionTmp0List, acquisitionTmp1List, acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, graphDataList, graphPostDataList; -static const QColor scopyBlueColor = scopy::Style::getColor(json::theme::interactive_primary_idle); +static const QColor scopyBlueColor = Style::getColor(json::theme::interactive_primary_idle); static const QColor sineColor = QColor("#85e94c"); static const QColor cosineColor = QColor("#91e6cf"); static const QColor faultLEDColor = QColor("#c81a28"); -static const QColor gpioLEDColor = scopy::Style::getColor(json::theme::interactive_secondary_idle); +static const QColor gpioLEDColor = Style::getColor(json::theme::interactive_secondary_idle); static const QColor statusLEDColor = QColor("#2e9e6f"); static const QPen scopyBluePen(scopyBlueColor); -static const QPen channel0Pen(scopy::Style::getAttribute(json::global::ch0)); -static const QPen channel1Pen(scopy::Style::getAttribute(json::global::ch1)); -static const QPen channel2Pen(scopy::Style::getAttribute(json::global::ch2)); -static const QPen channel3Pen(scopy::Style::getAttribute(json::global::ch3)); -static const QPen channel4Pen(scopy::Style::getAttribute(json::global::ch4)); -static const QPen channel5Pen(scopy::Style::getAttribute(json::global::ch5)); -static const QPen channel6Pen(scopy::Style::getAttribute(json::global::ch6)); -static const QPen channel7Pen(scopy::Style::getAttribute(json::global::ch7)); +static const QPen channel0Pen(Style::getAttribute(json::global::ch0)); +static const QPen channel1Pen(Style::getAttribute(json::global::ch1)); +static const QPen channel2Pen(Style::getAttribute(json::global::ch2)); +static const QPen channel3Pen(Style::getAttribute(json::global::ch3)); +static const QPen channel4Pen(Style::getAttribute(json::global::ch4)); +static const QPen channel5Pen(Style::getAttribute(json::global::ch5)); +static const QPen channel6Pen(Style::getAttribute(json::global::ch6)); +static const QPen channel7Pen(Style::getAttribute(json::global::ch7)); static const QPen sinePen(sineColor); static const QPen cosinePen(cosineColor); static map deviceRegisterMap; -static map generalRegisterMap; +static map GENERALRegisterMap; static map DIGIOENRegisterMap; static map FAULTRegisterMap; static map DIAG1RegisterMap; @@ -120,8 +118,15 @@ static bool isStartAcquisition = false; static bool isDeviceStatusMonitor = false; static bool isMotorPositionMonitor = false; +static bool isMotorVelocityCheck = false; +static bool isMotorVelocityReached = false; +static bool isResetMotorToZero = false; static int readMotorDebounce = 50; // In ms +static int calibrationMode = 0; + +static int globalSpacingSmall = Style::getDimension(json::global::unit_0_5); +static int globalSpacingMedium = Style::getDimension(json::global::unit_1); static map acquisitionDataMap = { {RADIUS, false}, @@ -142,9 +147,6 @@ static map acquisitionDataMap = { {SPIFAULT, false} }; -using namespace scopy; -using namespace scopy::admt; - HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool isDebug, QWidget *parent) : QWidget(parent) , isDebug(isDebug) @@ -152,9 +154,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool { ADMTStyleHelper::GetInstance()->initColorMap(); readDeviceProperties(); - readSequence(); initializeADMT(); initializeMotor(); + readSequence(); rotationChannelName = m_admtController->getChannelId(ADMTController::Channel::ROTATION); angleChannelName = m_admtController->getChannelId(ADMTController::Channel::ANGLE); @@ -168,6 +170,11 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool setLayout(lay); lay->setMargin(0); lay->insertWidget(1, tabWidget); + tabWidget->setStyleSheet(""); + tabWidget->tabBar()->setStyleSheet(""); + Style::setStyle(tabWidget, style::properties::admt::tabWidget); + Style::setStyle(tabWidget->tabBar(), style::properties::admt::tabBar); + tabWidget->addTab(createAcquisitionWidget(), "Acquisition"); tabWidget->addTab(createCalibrationWidget(), "Calibration"); tabWidget->addTab(createUtilityWidget(), "Utility"); @@ -178,15 +185,12 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 0 || index == 1) { - if(isDeviceStatusMonitor) isDeviceStatusMonitor = false; - if(isMotorPositionMonitor) isMotorPositionMonitor = false; - startDeviceStatusMonitor(); - if(index == 1) startCurrentMotorPositionMonitor(); + startCurrentMotorPositionMonitor(); } else{ - isDeviceStatusMonitor = false; - isMotorPositionMonitor = false; + stopDeviceStatusMonitor(); + stopCurrentMotorPositionMonitor(); } if(index == 0) // Acquisition Tab @@ -194,6 +198,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool startAcquisitionUITask(); readSequence(); updateSequenceWidget(); + updateAcquisitionMotorRPM(); + updateAcquisitionMotorRotationDirection(); } else { @@ -204,6 +210,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 1) // Calibration Tab { startCalibrationUITask(); + updateCalibrationMotorRPM(); + updateCalibrationMotorRotationDirection(); } else { @@ -213,8 +221,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 2) // Utility Tab { readSequence(); - toggleFaultRegisterMode(generalRegisterMap.at("Sequence Type")); - toggleMTDiagnostics(generalRegisterMap.at("Sequence Type")); + toggleFaultRegisterMode(GENERALRegisterMap.at("Sequence Type")); + toggleMTDiagnostics(GENERALRegisterMap.at("Sequence Type")); toggleUtilityTask(true); } else @@ -225,13 +233,14 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 3) // Registers Tab { readSequence(); - toggleRegisters(generalRegisterMap.at("Sequence Type")); + toggleRegisters(GENERALRegisterMap.at("Sequence Type")); } }); connect(this, &HarmonicCalibration::updateFaultStatusSignal, this, &HarmonicCalibration::updateFaultStatus); connect(this, &HarmonicCalibration::motorPositionChanged, this, &HarmonicCalibration::updateMotorPosition); + connect(this, &HarmonicCalibration::calibrationLogWriteSignal, this, &HarmonicCalibration::calibrationLogWrite); connect(this, &HarmonicCalibration::commandLogWriteSignal, this, &HarmonicCalibration::commandLogWrite); connect(this, &HarmonicCalibration::DIGIORegisterChanged, this, &HarmonicCalibration::updateDIGIOUI); connect(this, &HarmonicCalibration::FaultRegisterChanged, this, &HarmonicCalibration::updateFaultRegisterUI); @@ -277,18 +286,18 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() MenuSectionWidget *angleWidget = new MenuSectionWidget(rawDataWidget); MenuSectionWidget *countWidget = new MenuSectionWidget(rawDataWidget); MenuSectionWidget *tempWidget = new MenuSectionWidget(rawDataWidget); - rotationWidget->contentLayout()->setSpacing(8); - angleWidget->contentLayout()->setSpacing(8); - countWidget->contentLayout()->setSpacing(8); - tempWidget->contentLayout()->setSpacing(8); + Style::setStyle(rotationWidget, style::properties::widget::basicComponent); + Style::setStyle(angleWidget, style::properties::widget::basicComponent); + Style::setStyle(countWidget, style::properties::widget::basicComponent); + Style::setStyle(tempWidget, style::properties::widget::basicComponent); MenuCollapseSection *rotationSection = new MenuCollapseSection("ABS Angle", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, rotationWidget); MenuCollapseSection *angleSection = new MenuCollapseSection("Angle", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, angleWidget); MenuCollapseSection *countSection = new MenuCollapseSection("Count", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, countWidget); MenuCollapseSection *tempSection = new MenuCollapseSection("Temp 0", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, tempWidget); - rotationSection->contentLayout()->setSpacing(8); - angleSection->contentLayout()->setSpacing(8); - countSection->contentLayout()->setSpacing(8); - tempSection->contentLayout()->setSpacing(8); + rotationSection->contentLayout()->setSpacing(globalSpacingSmall); + angleSection->contentLayout()->setSpacing(globalSpacingSmall); + countSection->contentLayout()->setSpacing(globalSpacingSmall); + tempSection->contentLayout()->setSpacing(globalSpacingSmall); rotationWidget->contentLayout()->addWidget(rotationSection); angleWidget->contentLayout()->addWidget(angleSection); @@ -305,78 +314,100 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() countSection->contentLayout()->addWidget(countValueLabel); tempSection->contentLayout()->addWidget(tempValueLabel); - #pragma region Acquisition Motor Configuration Section Widget - MenuSectionWidget *motorConfigurationSectionWidget = new MenuSectionWidget(rawDataWidget); - MenuCollapseSection *motorConfigurationCollapseSection = new MenuCollapseSection("Motor Configuration", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorConfigurationSectionWidget); - motorConfigurationCollapseSection->header()->toggle(); - motorConfigurationSectionWidget->contentLayout()->addWidget(motorConfigurationCollapseSection); - - motorMaxVelocitySpinBox = new HorizontalSpinBox("Max Velocity", convertVMAXtoRPS(rotate_vmax), "rps", motorConfigurationSectionWidget); - motorMaxVelocitySpinBox->setValue(1); - motorAccelTimeSpinBox = new HorizontalSpinBox("Acceleration Time", convertAMAXtoAccelTime(amax), "sec", motorConfigurationSectionWidget); - motorAccelTimeSpinBox->setValue(1); - motorMaxDisplacementSpinBox = new HorizontalSpinBox("Max Displacement", dmax, "", motorConfigurationSectionWidget); - - m_calibrationMotorRampModeMenuCombo = new MenuCombo("Ramp Mode", motorConfigurationSectionWidget); - auto calibrationMotorRampModeCombo = m_calibrationMotorRampModeMenuCombo->combo(); - calibrationMotorRampModeCombo->addItem("Position", QVariant(ADMTController::MotorRampMode::POSITION)); - calibrationMotorRampModeCombo->addItem("Ramp Mode 1", QVariant(ADMTController::MotorRampMode::RAMP_MODE_1)); - ADMTStyleHelper::ComboBoxStyle(calibrationMotorRampModeCombo); - - motorConfigurationCollapseSection->contentLayout()->setSpacing(8); - motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxVelocitySpinBox); - motorConfigurationCollapseSection->contentLayout()->addWidget(motorAccelTimeSpinBox); - motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxDisplacementSpinBox); - motorConfigurationCollapseSection->contentLayout()->addWidget(m_calibrationMotorRampModeMenuCombo); - #pragma endregion - #pragma region Acquisition Motor Control Section Widget MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(rawDataWidget); + Style::setStyle(motorControlSectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection("Motor Control", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorControlSectionWidget); - motorControlSectionWidget->contentLayout()->setSpacing(8); motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); - QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); - acquisitionMotorCurrentPositionLineEdit = new QLineEdit("--.--", motorControlSectionWidget); + + QWidget *motorRPMWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); + motorRPMWidget->setLayout(motorRPMLayout); + motorRPMLayout->setMargin(0); + motorRPMLayout->setSpacing(0); + QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); + acquisitionMotorRPMLineEdit = new QLineEdit(QString::number(motor_rpm), motorRPMWidget); + connectLineEditToRPM(acquisitionMotorRPMLineEdit, motor_rpm); + motorRPMLayout->addWidget(motorRPMLabel); + motorRPMLayout->addWidget(acquisitionMotorRPMLineEdit); + + QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); + currentPositionWidget->setLayout(currentPositionLayout); + currentPositionLayout->setMargin(0); + currentPositionLayout->setSpacing(0); + QLabel *currentPositionLabel = new QLabel("Current Position", currentPositionWidget); + acquisitionMotorCurrentPositionLineEdit = new QLineEdit("--.--", currentPositionWidget); acquisitionMotorCurrentPositionLineEdit->setReadOnly(true); connectLineEditToDouble(acquisitionMotorCurrentPositionLineEdit, current_pos); - - QLabel *targetPositionLabel = new QLabel("Target Position", motorControlSectionWidget); - motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), motorControlSectionWidget); - - motorControlCollapseSection->contentLayout()->setSpacing(8); - motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); - motorControlCollapseSection->contentLayout()->addWidget(acquisitionMotorCurrentPositionLineEdit); - motorControlCollapseSection->contentLayout()->addWidget(targetPositionLabel); - motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionLineEdit); + currentPositionLayout->addWidget(currentPositionLabel); + currentPositionLayout->addWidget(acquisitionMotorCurrentPositionLineEdit); + + QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); + targetPositionWidget->setLayout(targetPositionLayout); + targetPositionLayout->setMargin(0); + targetPositionLayout->setSpacing(0); + QLabel *targetPositionLabel = new QLabel("Target Position", targetPositionWidget); + motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), targetPositionWidget); + connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, ADMTController::MotorAttribute::TARGET_POS); + targetPositionLayout->addWidget(targetPositionLabel); + targetPositionLayout->addWidget(motorTargetPositionLineEdit); + + QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); + motorDirectionWidget->setLayout(motorDirectionLayout); + motorDirectionLayout->setMargin(0); + motorDirectionLayout->setSpacing(0); + QLabel *motorDirectionLabel = new QLabel("Rotation Direction", motorDirectionWidget); + acquisitionMotorDirectionSwitch = new CustomSwitch("CW", "CCW", motorControlSectionWidget); + acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); + connect(acquisitionMotorDirectionSwitch, &CustomSwitch::toggled, this, [=](bool b){ + isMotorRotationClockwise = b; + }); + motorDirectionLayout->addWidget(motorDirectionLabel); + motorDirectionLayout->addWidget(acquisitionMotorDirectionSwitch); + + QPushButton *continuousRotationButton = new QPushButton("Continuous Rotation", motorControlSectionWidget); + StyleHelper::BasicButton(continuousRotationButton); + connect(continuousRotationButton, &QPushButton::clicked, this, &HarmonicCalibration::moveMotorContinuous); + + QPushButton *stopMotorButton = new QPushButton("Stop Motor", motorControlSectionWidget); + StyleHelper::BasicButton(stopMotorButton); + connect(stopMotorButton, &QPushButton::clicked, this, &HarmonicCalibration::stopMotor); + + motorControlCollapseSection->contentLayout()->setSpacing(globalSpacingSmall); + motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); + motorControlCollapseSection->contentLayout()->addWidget(currentPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); + motorControlCollapseSection->contentLayout()->addWidget(continuousRotationButton); + motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); #pragma endregion + rawDataLayout->setSpacing(globalSpacingSmall); rawDataLayout->addWidget(angleWidget); rawDataLayout->addWidget(rotationWidget); rawDataLayout->addWidget(countWidget); rawDataLayout->addWidget(tempWidget); - rawDataLayout->addWidget(motorConfigurationSectionWidget); rawDataLayout->addWidget(motorControlSectionWidget); rawDataLayout->addStretch(); #pragma endregion #pragma region Acquisition Graph Section Widget MenuSectionWidget *acquisitionGraphSectionWidget = new MenuSectionWidget(this); + Style::setStyle(acquisitionGraphSectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *acquisitionGraphCollapseSection = new MenuCollapseSection("Captured Data", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, acquisitionGraphSectionWidget); acquisitionGraphSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); acquisitionGraphSectionWidget->contentLayout()->addWidget(acquisitionGraphCollapseSection); acquisitionGraphCollapseSection->contentLayout()->setSpacing(8); acquisitionGraphPlotWidget = new PlotWidget(); - ADMTStyleHelper::PlotWidgetStyle(acquisitionGraphPlotWidget); acquisitionGraphPlotWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - acquisitionGraphPlotWidget->setShowXAxisLabels(true); - acquisitionGraphPlotWidget->setShowYAxisLabels(true); - acquisitionGraphPlotWidget->showAxisLabels(); - - acquisitionXPlotAxis = new PlotAxis(QwtAxis::XBottom, acquisitionGraphPlotWidget, channel0Pen); + acquisitionXPlotAxis = new PlotAxis(QwtAxis::XBottom, acquisitionGraphPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); - acquisitionYPlotAxis = new PlotAxis(QwtAxis::YLeft, acquisitionGraphPlotWidget, channel0Pen); + acquisitionYPlotAxis = new PlotAxis(QwtAxis::YLeft, acquisitionGraphPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); acquisitionYPlotAxis->setInterval(0, 360); acquisitionAnglePlotChannel = new PlotChannel("Angle", channel0Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); @@ -412,6 +443,9 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() acquisitionSecAnglIPlotChannel->setEnabled(true); acquisitionGraphPlotWidget->selectChannel(acquisitionAnglePlotChannel); + acquisitionGraphPlotWidget->setShowXAxisLabels(true); + acquisitionGraphPlotWidget->setShowYAxisLabels(true); + acquisitionGraphPlotWidget->showAxisLabels(); acquisitionGraphPlotWidget->replot(); #pragma region Channel Selection @@ -445,7 +479,7 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() ADMTStyleHelper::ColoredSquareCheckbox(radiusCheckBox, channel5Pen.color()); connectCheckBoxToAcquisitionGraph(radiusCheckBox, acquisitionRadiusPlotChannel, RADIUS); - if(generalRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 + if(GENERALRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 { acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); @@ -454,7 +488,7 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); } - else if(generalRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 + else if(GENERALRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 { acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); @@ -479,44 +513,56 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() generalSettingWidget->setLayout(generalSettingLayout); header = new MenuHeaderWidget(deviceName + " " + deviceType, scopyBluePen, this); + Style::setStyle(header, style::properties::widget::basicComponent); // General Setting Widget MenuSectionWidget *generalWidget = new MenuSectionWidget(generalSettingWidget); - generalWidget->contentLayout()->setSpacing(8); + Style::setStyle(generalWidget, style::properties::widget::basicComponent); MenuCollapseSection *generalSection = new MenuCollapseSection("Data Acquisition", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); generalSection->header()->toggle(); - generalSection->contentLayout()->setSpacing(8); + generalSection->contentLayout()->setSpacing(globalSpacingSmall); generalWidget->contentLayout()->addWidget(generalSection); // Graph Update Interval - QLabel *graphUpdateIntervalLabel = new QLabel(generalSection); + QWidget *graphUpdateIntervalWidget = new QWidget(generalSection); + QVBoxLayout *graphUpdateIntervalLayout = new QVBoxLayout(graphUpdateIntervalWidget); + graphUpdateIntervalWidget->setLayout(graphUpdateIntervalLayout); + graphUpdateIntervalLayout->setMargin(0); + graphUpdateIntervalLayout->setSpacing(0); + QLabel *graphUpdateIntervalLabel = new QLabel(graphUpdateIntervalWidget); graphUpdateIntervalLabel->setText("Graph Update Interval (ms)"); - graphUpdateIntervalLineEdit = new QLineEdit(generalSection); + graphUpdateIntervalLineEdit = new QLineEdit(graphUpdateIntervalWidget); graphUpdateIntervalLineEdit->setText(QString::number(acquisitionGraphSampleRate)); - connectLineEditToNumber(graphUpdateIntervalLineEdit, acquisitionGraphSampleRate, 1, 5000); + graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLabel); + graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLineEdit); // Data Sample Size - QLabel *displayLengthLabel = new QLabel("Display Length", generalSection); - displayLengthLineEdit = new QLineEdit(generalSection); + QWidget *displayLengthWidget = new QWidget(generalSection); + QVBoxLayout *displayLengthLayout = new QVBoxLayout(displayLengthWidget); + displayLengthWidget->setLayout(displayLengthLayout); + displayLengthLayout->setMargin(0); + displayLengthLayout->setSpacing(0); + QLabel *displayLengthLabel = new QLabel("Display Length", displayLengthWidget); + displayLengthLineEdit = new QLineEdit(displayLengthWidget); displayLengthLineEdit->setText(QString::number(acquisitionDisplayLength)); - connectLineEditToNumber(displayLengthLineEdit, acquisitionDisplayLength, 1, 2048); + displayLengthLayout->addWidget(displayLengthLabel); + displayLengthLayout->addWidget(displayLengthLineEdit); QPushButton *resetYAxisButton = new QPushButton("Reset Y-Axis Scale", generalSection); StyleHelper::BasicButton(resetYAxisButton); connect(resetYAxisButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAcquisitionYAxisScale); - generalSection->contentLayout()->addWidget(graphUpdateIntervalLabel); - generalSection->contentLayout()->addWidget(graphUpdateIntervalLineEdit); - generalSection->contentLayout()->addWidget(displayLengthLabel); - generalSection->contentLayout()->addWidget(displayLengthLineEdit); + generalSection->contentLayout()->addWidget(graphUpdateIntervalWidget); + generalSection->contentLayout()->addWidget(displayLengthWidget); generalSection->contentLayout()->addWidget(resetYAxisButton); MenuSectionWidget *sequenceWidget = new MenuSectionWidget(generalSettingWidget); + Style::setStyle(sequenceWidget, style::properties::widget::basicComponent); MenuCollapseSection *sequenceSection = new MenuCollapseSection("Sequence", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, sequenceWidget); sequenceWidget->contentLayout()->addWidget(sequenceSection); - sequenceSection->contentLayout()->setSpacing(8); + sequenceSection->contentLayout()->setSpacing(globalSpacingSmall); sequenceTypeMenuCombo = new MenuCombo("Sequence Type", sequenceSection); QComboBox *sequenceTypeComboBox = sequenceTypeMenuCombo->combo(); @@ -561,29 +607,29 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() #pragma region Device Status Widget MenuSectionWidget *acquisitionDeviceStatusWidget = new MenuSectionWidget(generalSettingWidget); - acquisitionDeviceStatusWidget->contentLayout()->setSpacing(8); + Style::setStyle(acquisitionDeviceStatusWidget, style::properties::widget::basicComponent); MenuCollapseSection *acquisitionDeviceStatusSection = new MenuCollapseSection("Device Status", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); - acquisitionDeviceStatusSection->contentLayout()->setSpacing(8); + acquisitionDeviceStatusSection->contentLayout()->setSpacing(globalSpacingSmall); acquisitionDeviceStatusWidget->contentLayout()->addWidget(acquisitionDeviceStatusSection); - acquisitionFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", json::theme::content_success, true, acquisitionDeviceStatusSection); + acquisitionFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", "status", false, acquisitionDeviceStatusSection); acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionFaultRegisterLEDWidget); - if(deviceType == "Automotive" && generalRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 + if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 { - QCheckBox *acquisitionSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", json::theme::content_success, true, acquisitionDeviceStatusSection); - QCheckBox *acquisitionSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", json::theme::content_success, true, acquisitionDeviceStatusSection); + QCheckBox *acquisitionSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", "status", false, acquisitionDeviceStatusSection); + QCheckBox *acquisitionSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", "status", false, acquisitionDeviceStatusSection); acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPICRCLEDWidget); acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPIFlagLEDWidget); } #pragma endregion + generalSettingLayout->setSpacing(globalSpacingSmall); generalSettingLayout->addWidget(acquisitionDeviceStatusWidget); generalSettingLayout->addWidget(header); - generalSettingLayout->addSpacerItem(new QSpacerItem(0, 3, QSizePolicy::Fixed, QSizePolicy::Fixed)); generalSettingLayout->addWidget(sequenceWidget); generalSettingLayout->addWidget(generalWidget); - generalSettingLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + generalSettingLayout->addStretch(); #pragma endregion tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -607,12 +653,7 @@ ToolTemplate* HarmonicCalibration::createAcquisitionWidget() connect(runButton, &QPushButton::toggled, this, &HarmonicCalibration::setRunning); connect(this, &HarmonicCalibration::runningChanged, this, &HarmonicCalibration::run); connect(this, &HarmonicCalibration::runningChanged, runButton, &QAbstractButton::setChecked); - connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); - connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); - connectLineEditToNumberWrite(motorMaxDisplacementSpinBox->lineEdit(), dmax, ADMTController::MotorAttribute::DMAX); - connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, ADMTController::MotorAttribute::TARGET_POS); - connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); - + return tool; } @@ -628,6 +669,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDataGraphLayout->setSpacing(5); MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); + Style::setStyle(calibrationDataGraphSectionWidget, style::properties::widget::basicComponent); calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); calibrationDataGraphTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 176px; }"); calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); @@ -635,17 +677,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Calibration Samples QWidget *calibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); + Style::setStyle(calibrationSamplesWidget, style::properties::widget::basicBackground); QVBoxLayout *calibrationSamplesLayout = new QVBoxLayout(calibrationSamplesWidget); calibrationSamplesWidget->setLayout(calibrationSamplesLayout); calibrationSamplesLayout->setMargin(0); calibrationSamplesLayout->setSpacing(0); calibrationRawDataPlotWidget = new PlotWidget(); - ADMTStyleHelper::PlotWidgetStyle(calibrationRawDataPlotWidget); + calibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); - calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, scopyBluePen); + calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); calibrationRawDataXPlotAxis->setMin(0); - calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, scopyBluePen); + calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); calibrationRawDataYPlotAxis->setInterval(0, 360); calibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); @@ -663,7 +706,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationRawDataPlotWidget->setShowXAxisLabels(true); calibrationRawDataPlotWidget->setShowYAxisLabels(true); calibrationRawDataPlotWidget->showAxisLabels(); - calibrationRawDataPlotWidget->replot(); QWidget *calibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); @@ -688,19 +730,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Post Calibration Samples QWidget *postCalibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); + Style::setStyle(postCalibrationSamplesWidget, style::properties::widget::basicBackground); QVBoxLayout *postCalibrationSamplesLayout = new QVBoxLayout(postCalibrationSamplesWidget); postCalibrationSamplesWidget->setLayout(postCalibrationSamplesLayout); postCalibrationSamplesLayout->setMargin(0); postCalibrationSamplesLayout->setSpacing(0); postCalibrationRawDataPlotWidget = new PlotWidget(); - ADMTStyleHelper::PlotWidgetStyle(postCalibrationRawDataPlotWidget); - postCalibrationRawDataPlotWidget->xAxis()->setVisible(false); - postCalibrationRawDataPlotWidget->yAxis()->setVisible(false); + postCalibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); - postCalibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, postCalibrationRawDataPlotWidget, scopyBluePen); + postCalibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, postCalibrationRawDataPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); postCalibrationRawDataXPlotAxis->setMin(0); - postCalibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, postCalibrationRawDataPlotWidget, scopyBluePen); + postCalibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, postCalibrationRawDataPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); postCalibrationRawDataYPlotAxis->setInterval(0, 360); postCalibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); @@ -715,11 +756,11 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() postCalibrationCosineDataPlotChannel->setEnabled(true); postCalibrationRawDataPlotChannel->setEnabled(true); postCalibrationRawDataPlotWidget->selectChannel(postCalibrationRawDataPlotChannel); - postCalibrationRawDataPlotWidget->replot(); - + postCalibrationRawDataPlotWidget->setShowXAxisLabels(true); postCalibrationRawDataPlotWidget->setShowYAxisLabels(true); postCalibrationRawDataPlotWidget->showAxisLabels(); + postCalibrationRawDataPlotWidget->replot(); QWidget *postCalibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); QHBoxLayout *postCalibrationDataGraphChannelsLayout = new QHBoxLayout(postCalibrationDataGraphChannelsWidget); @@ -742,6 +783,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDataGraphTabWidget->addTab(postCalibrationSamplesWidget, "Post Calibration Samples"); MenuSectionWidget *resultDataSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); + Style::setStyle(resultDataSectionWidget, style::properties::widget::basicComponent); resultDataTabWidget = new QTabWidget(resultDataSectionWidget); resultDataTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 160px; }"); resultDataSectionWidget->contentLayout()->setSpacing(8); @@ -754,50 +796,47 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Angle Error Widget QWidget *angleErrorWidget = new QWidget(); + Style::setStyle(angleErrorWidget, style::properties::widget::basicBackground); QVBoxLayout *angleErrorLayout = new QVBoxLayout(angleErrorWidget); angleErrorWidget->setLayout(angleErrorLayout); angleErrorLayout->setMargin(0); angleErrorLayout->setSpacing(0); angleErrorPlotWidget = new PlotWidget(); - ADMTStyleHelper::PlotWidgetStyle(angleErrorPlotWidget); - angleErrorPlotWidget->xAxis()->setVisible(false); - angleErrorPlotWidget->yAxis()->setVisible(false); - - angleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, angleErrorPlotWidget, scopyBluePen); + angleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + angleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, angleErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); angleErrorXPlotAxis->setMin(0); - angleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, angleErrorPlotWidget, scopyBluePen); + angleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, angleErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); angleErrorYPlotAxis->setInterval(-4, 4); angleErrorPlotChannel = new PlotChannel("Angle Error", scopyBluePen, angleErrorXPlotAxis, angleErrorYPlotAxis); + angleErrorPlotWidget->addPlotChannel(angleErrorPlotChannel); - angleErrorPlotChannel->setEnabled(true); angleErrorPlotWidget->selectChannel(angleErrorPlotChannel); - angleErrorPlotWidget->replot(); - + angleErrorPlotWidget->setShowXAxisLabels(true); angleErrorPlotWidget->setShowYAxisLabels(true); angleErrorPlotWidget->showAxisLabels(); + angleErrorPlotWidget->replot(); angleErrorLayout->addWidget(angleErrorPlotWidget); #pragma endregion #pragma region FFT Angle Error Widget QWidget *FFTAngleErrorWidget = new QWidget(); + Style::setStyle(FFTAngleErrorWidget, style::properties::widget::basicBackground); QVBoxLayout *FFTAngleErrorLayout = new QVBoxLayout(FFTAngleErrorWidget); FFTAngleErrorWidget->setLayout(FFTAngleErrorLayout); FFTAngleErrorLayout->setMargin(0); FFTAngleErrorLayout->setSpacing(0); FFTAngleErrorPlotWidget = new PlotWidget(); - ADMTStyleHelper::PlotWidgetStyle(FFTAngleErrorPlotWidget); - FFTAngleErrorPlotWidget->xAxis()->setVisible(false); - FFTAngleErrorPlotWidget->yAxis()->setVisible(false); + FFTAngleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - FFTAngleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTAngleErrorPlotWidget, scopyBluePen); + FFTAngleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTAngleErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); FFTAngleErrorXPlotAxis->setMin(0); - FFTAngleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTAngleErrorPlotWidget, scopyBluePen); + FFTAngleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTAngleErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); FFTAngleErrorYPlotAxis->setInterval(-4, 4); FFTAngleErrorMagnitudeChannel = new PlotChannel("FFT Angle Error Magnitude", magnitudePen, FFTAngleErrorXPlotAxis, FFTAngleErrorYPlotAxis); @@ -808,11 +847,11 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTAngleErrorPhaseChannel->setEnabled(true); FFTAngleErrorMagnitudeChannel->setEnabled(true); FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); - FFTAngleErrorPlotWidget->replot(); - + FFTAngleErrorPlotWidget->setShowXAxisLabels(true); FFTAngleErrorPlotWidget->setShowYAxisLabels(true); FFTAngleErrorPlotWidget->showAxisLabels(); + FFTAngleErrorPlotWidget->replot(); QWidget *FFTAngleErrorChannelsWidget = new QWidget(); QHBoxLayout *FFTAngleErrorChannelsLayout = new QHBoxLayout(FFTAngleErrorChannelsWidget); @@ -831,19 +870,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Corrected Error Widget QWidget *correctedErrorWidget = new QWidget(); + Style::setStyle(correctedErrorWidget, style::properties::widget::basicBackground); QVBoxLayout *correctedErrorLayout = new QVBoxLayout(correctedErrorWidget); correctedErrorWidget->setLayout(correctedErrorLayout); correctedErrorLayout->setMargin(0); correctedErrorLayout->setSpacing(0); correctedErrorPlotWidget = new PlotWidget(); - ADMTStyleHelper::PlotWidgetStyle(correctedErrorPlotWidget); - correctedErrorPlotWidget->xAxis()->setVisible(false); - correctedErrorPlotWidget->yAxis()->setVisible(false); + correctedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - correctedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, correctedErrorPlotWidget, scopyBluePen); + correctedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, correctedErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); correctedErrorXPlotAxis->setMin(0); - correctedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, correctedErrorPlotWidget, scopyBluePen); + correctedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, correctedErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); correctedErrorYPlotAxis->setInterval(-4, 4); correctedErrorPlotChannel = new PlotChannel("Corrected Error", scopyBluePen, correctedErrorXPlotAxis, correctedErrorYPlotAxis); @@ -851,30 +889,29 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() correctedErrorPlotChannel->setEnabled(true); correctedErrorPlotWidget->selectChannel(correctedErrorPlotChannel); - correctedErrorPlotWidget->replot(); - + correctedErrorPlotWidget->setShowXAxisLabels(true); correctedErrorPlotWidget->setShowYAxisLabels(true); correctedErrorPlotWidget->showAxisLabels(); + correctedErrorPlotWidget->replot(); correctedErrorLayout->addWidget(correctedErrorPlotWidget); #pragma endregion #pragma region FFT Corrected Error Widget QWidget *FFTCorrectedErrorWidget = new QWidget(); + Style::setStyle(FFTCorrectedErrorWidget, style::properties::widget::basicBackground); QVBoxLayout *FFTCorrectedErrorLayout = new QVBoxLayout(FFTCorrectedErrorWidget); FFTCorrectedErrorWidget->setLayout(FFTCorrectedErrorLayout); FFTCorrectedErrorLayout->setMargin(0); FFTCorrectedErrorLayout->setSpacing(0); FFTCorrectedErrorPlotWidget = new PlotWidget(); - ADMTStyleHelper::PlotWidgetStyle(FFTCorrectedErrorPlotWidget); - FFTCorrectedErrorPlotWidget->xAxis()->setVisible(false); - FFTCorrectedErrorPlotWidget->yAxis()->setVisible(false); + FFTCorrectedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - FFTCorrectedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTCorrectedErrorPlotWidget, scopyBluePen); + FFTCorrectedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTCorrectedErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); FFTCorrectedErrorXPlotAxis->setMin(0); - FFTCorrectedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTCorrectedErrorPlotWidget, scopyBluePen); + FFTCorrectedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTCorrectedErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); FFTCorrectedErrorYPlotAxis->setInterval(-4, 4); FFTCorrectedErrorMagnitudeChannel = new PlotChannel("FFT Corrected Error Magnitude", magnitudePen, FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); @@ -885,11 +922,11 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() FFTCorrectedErrorPhaseChannel->setEnabled(true); FFTCorrectedErrorMagnitudeChannel->setEnabled(true); FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); - FFTCorrectedErrorPlotWidget->replot(); - + FFTCorrectedErrorPlotWidget->setShowXAxisLabels(true); FFTCorrectedErrorPlotWidget->setShowYAxisLabels(true); FFTCorrectedErrorPlotWidget->showAxisLabels(); + FFTCorrectedErrorPlotWidget->replot(); QWidget *FFTCorrectedErrorChannelsWidget = new QWidget(); QHBoxLayout *FFTCorrectedErrorChannelsLayout = new QHBoxLayout(FFTCorrectedErrorChannelsWidget); @@ -928,18 +965,19 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Device Status Widget MenuSectionWidget *calibrationDeviceStatusWidget = new MenuSectionWidget(calibrationSettingsGroupWidget); + Style::setStyle(calibrationDeviceStatusWidget, style::properties::widget::basicComponent); calibrationDeviceStatusWidget->contentLayout()->setSpacing(8); MenuCollapseSection *calibrationDeviceStatusSection = new MenuCollapseSection("Device Status", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationSettingsGroupWidget); calibrationDeviceStatusSection->contentLayout()->setSpacing(8); calibrationDeviceStatusWidget->contentLayout()->addWidget(calibrationDeviceStatusSection); - calibrationFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", json::theme::content_success, true, calibrationDeviceStatusSection); + calibrationFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", "status", false, calibrationDeviceStatusSection); calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationFaultRegisterLEDWidget); - if(deviceType == "Automotive" && generalRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 + if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 { - QCheckBox *calibrationSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", json::theme::content_success, true, calibrationDeviceStatusSection); - QCheckBox *calibrationSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", json::theme::content_success, true, calibrationDeviceStatusSection); + QCheckBox *calibrationSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", "status", false, calibrationDeviceStatusSection); + QCheckBox *calibrationSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", "status", false, calibrationDeviceStatusSection); calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPICRCLEDWidget); calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPIFlagLEDWidget); } @@ -947,8 +985,18 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Acquire Calibration Samples Button calibrationStartMotorButton = new QPushButton(" Acquire Samples", calibrationSettingsGroupWidget); - ADMTStyleHelper::StartButtonStyle(calibrationStartMotorButton); - + Style::setStyle(calibrationStartMotorButton, style::properties::admt::fullWidthRunButton); + calibrationStartMotorButton->setCheckable(true); + calibrationStartMotorButton->setChecked(false); + QIcon icon1; + icon1.addPixmap(Style::getPixmap(":/gui/icons/play.svg", Style::getColor(json::theme::content_inverse)), + QIcon::Normal, QIcon::Off); + icon1.addPixmap(Style::getPixmap(":/gui/icons/" + Style::getAttribute(json::theme::icon_theme_folder) + + "/icons/play_stop.svg", + Style::getColor(json::theme::content_inverse)), + QIcon::Normal, QIcon::On); + calibrationStartMotorButton->setIcon(icon1); + connect(calibrationStartMotorButton, &QPushButton::toggled, this, [=](bool toggled) { calibrationStartMotorButton->setText(toggled ? " Stop Acquisition" : " Acquire Samples"); isStartMotor = toggled; @@ -963,10 +1011,12 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma endregion #pragma region Start Calibration Button - calibrateDataButton = new QPushButton(calibrationSettingsGroupWidget); - ADMTStyleHelper::StartButtonStyle(calibrateDataButton); - calibrateDataButton->setText(" Calibrate"); + calibrateDataButton = new QPushButton(" Calibrate", calibrationSettingsGroupWidget); + Style::setStyle(calibrateDataButton, style::properties::admt::fullWidthRunButton); + calibrateDataButton->setCheckable(true); + calibrateDataButton->setChecked(false); calibrateDataButton->setEnabled(false); + calibrateDataButton->setIcon(icon1); connect(calibrateDataButton, &QPushButton::toggled, this, [=](bool toggled) { calibrateDataButton->setText(toggled ? " Stop Calibration" : " Calibrate"); @@ -979,7 +1029,9 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() clearCalibrateDataButton = new QPushButton("Reset Calibration", calibrationSettingsGroupWidget); StyleHelper::BasicButton(clearCalibrateDataButton); QIcon resetIcon; - resetIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/refresh.svg", "white", 1), QIcon::Normal, QIcon::Off); + // resetIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/refresh.svg", "white", 1), QIcon::Normal, QIcon::Off); + resetIcon.addPixmap(Style::getPixmap(":/gui/icons/refresh.svg", Style::getColor(json::theme::content_inverse)), + QIcon::Normal, QIcon::Off); clearCalibrateDataButton->setIcon(resetIcon); clearCalibrateDataButton->setIconSize(QSize(26, 26)); #pragma endregion @@ -1000,6 +1052,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Calibration Coefficient Section Widget MenuSectionWidget *calibrationCoeffSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(calibrationCoeffSectionWidget, style::properties::widget::basicComponent); QLabel *calibrationDisplayFormatLabel = new QLabel(calibrationCoeffSectionWidget); calibrationDisplayFormatLabel->setText("Display Format"); Style::setStyle(calibrationDisplayFormatLabel, style::properties::label::menuMedium); @@ -1018,7 +1071,7 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationCalculatedCoeffWidget->setLayout(calibrationCalculatedCoeffLayout); calibrationCalculatedCoeffLayout->setMargin(0); calibrationCalculatedCoeffLayout->setVerticalSpacing(4); - ADMTStyleHelper::UIBackgroundStyle(calibrationCalculatedCoeffWidget); + Style::setStyle(calibrationCalculatedCoeffWidget, style::properties::widget::basicBackground); QWidget *h1RowContainer = new QWidget(calibrationCalculatedCoeffWidget); QHBoxLayout *h1RowLayout = new QHBoxLayout(h1RowContainer); @@ -1062,31 +1115,53 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() #pragma region Calibration Dataset Configuration MenuSectionWidget *calibrationDatasetConfigSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(calibrationDatasetConfigSectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *calibrationDatasetConfigCollapseSection = new MenuCollapseSection("Dataset Configuration", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationDatasetConfigSectionWidget); calibrationDatasetConfigSectionWidget->contentLayout()->setSpacing(8); calibrationDatasetConfigSectionWidget->contentLayout()->addWidget(calibrationDatasetConfigCollapseSection); - QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", calibrationDatasetConfigCollapseSection); - QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(calibrationDatasetConfigCollapseSection); + #pragma region Continuous Calibration Toggle + calibrationModeMenuCombo = new MenuCombo("Calibration Mode", calibrationDatasetConfigCollapseSection); + auto calibrationModeCombo = calibrationModeMenuCombo->combo(); + calibrationModeCombo->addItem("Continuous", QVariant(0)); + calibrationModeCombo->addItem("One Shot", QVariant(1)); + connectMenuComboToNumber(calibrationModeMenuCombo, calibrationMode); + #pragma endregion + + QWidget *calibrationCycleCountWidget = new QWidget(calibrationDatasetConfigCollapseSection); + QVBoxLayout *calibrationCycleCountLayout = new QVBoxLayout(calibrationCycleCountWidget); + calibrationCycleCountWidget->setLayout(calibrationCycleCountLayout); + calibrationCycleCountLayout->setMargin(0); + calibrationCycleCountLayout->setSpacing(0); + QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", calibrationCycleCountWidget); + QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(calibrationCycleCountWidget); calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 1000); - - QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", calibrationDatasetConfigCollapseSection); - QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationDatasetConfigCollapseSection); + calibrationCycleCountLayout->addWidget(calibrationCycleCountLabel); + calibrationCycleCountLayout->addWidget(calibrationCycleCountLineEdit); + + QWidget *calibrationSamplesPerCycleWidget = new QWidget(calibrationDatasetConfigCollapseSection); + QVBoxLayout *calibrationSamplesPerCycleLayout = new QVBoxLayout(calibrationSamplesPerCycleWidget); + calibrationSamplesPerCycleWidget->setLayout(calibrationSamplesPerCycleLayout); + calibrationSamplesPerCycleLayout->setMargin(0); + calibrationSamplesPerCycleLayout->setSpacing(0); + QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", calibrationSamplesPerCycleWidget); + QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationSamplesPerCycleWidget); calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); - calibrationSamplesPerCycleLineEdit->setReadOnly(true); connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, 1, 5000); + calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLabel); + calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLineEdit); calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(8); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountLabel); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountLineEdit); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleLabel); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleLineEdit); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationModeMenuCombo); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountWidget); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleWidget); #pragma endregion #pragma region Calibration Data Section Widget MenuSectionWidget *calibrationDataSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(calibrationDataSectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection("Calibration Data", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationDataSectionWidget); calibrationDataSectionWidget->contentLayout()->setSpacing(8); calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); @@ -1101,53 +1176,81 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); #pragma endregion - #pragma region Motor Configuration Section Widget - MenuSectionWidget *motorConfigurationSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - MenuCollapseSection *motorConfigurationCollapseSection = new MenuCollapseSection("Motor Configuration", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorConfigurationSectionWidget); - motorConfigurationCollapseSection->header()->toggle(); - motorConfigurationSectionWidget->contentLayout()->addWidget(motorConfigurationCollapseSection); - - motorMaxVelocitySpinBox = new HorizontalSpinBox("Max Velocity", convertVMAXtoRPS(rotate_vmax), "rps", motorConfigurationSectionWidget); - motorMaxVelocitySpinBox->setValue(1); - motorAccelTimeSpinBox = new HorizontalSpinBox("Acceleration Time", convertAMAXtoAccelTime(amax), "sec", motorConfigurationSectionWidget); - motorAccelTimeSpinBox->setValue(1); - motorMaxDisplacementSpinBox = new HorizontalSpinBox("Max Displacement", dmax, "", motorConfigurationSectionWidget); - - m_calibrationMotorRampModeMenuCombo = new MenuCombo("Ramp Mode", motorConfigurationSectionWidget); - auto calibrationMotorRampModeCombo = m_calibrationMotorRampModeMenuCombo->combo(); - calibrationMotorRampModeCombo->addItem("Position", QVariant(ADMTController::MotorRampMode::POSITION)); - calibrationMotorRampModeCombo->addItem("Ramp Mode 1", QVariant(ADMTController::MotorRampMode::RAMP_MODE_1)); - ADMTStyleHelper::ComboBoxStyle(calibrationMotorRampModeCombo); - - motorConfigurationCollapseSection->contentLayout()->setSpacing(8); - motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxVelocitySpinBox); - motorConfigurationCollapseSection->contentLayout()->addWidget(motorAccelTimeSpinBox); - motorConfigurationCollapseSection->contentLayout()->addWidget(motorMaxDisplacementSpinBox); - motorConfigurationCollapseSection->contentLayout()->addWidget(m_calibrationMotorRampModeMenuCombo); - #pragma endregion - #pragma region Motor Control Section Widget MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(motorControlSectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection("Motor Control", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorControlSectionWidget); motorControlSectionWidget->contentLayout()->setSpacing(8); motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); - QLabel *currentPositionLabel = new QLabel("Current Position", motorControlSectionWidget); - calibrationMotorCurrentPositionLineEdit = new QLineEdit("--.--", motorControlSectionWidget); + + QWidget *motorRPMWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); + motorRPMWidget->setLayout(motorRPMLayout); + motorRPMLayout->setMargin(0); + motorRPMLayout->setSpacing(0); + QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); + calibrationMotorRPMLineEdit = new QLineEdit(QString::number(motor_rpm), motorRPMWidget); + connectLineEditToRPM(calibrationMotorRPMLineEdit, motor_rpm); + motorRPMLayout->addWidget(motorRPMLabel); + motorRPMLayout->addWidget(calibrationMotorRPMLineEdit); + + QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); + currentPositionWidget->setLayout(currentPositionLayout); + currentPositionLayout->setMargin(0); + currentPositionLayout->setSpacing(0); + QLabel *currentPositionLabel = new QLabel("Current Position", currentPositionWidget); + calibrationMotorCurrentPositionLineEdit = new QLineEdit("--.--", currentPositionWidget); calibrationMotorCurrentPositionLineEdit->setReadOnly(true); connectLineEditToDouble(calibrationMotorCurrentPositionLineEdit, current_pos); + currentPositionLayout->addWidget(currentPositionLabel); + currentPositionLayout->addWidget(calibrationMotorCurrentPositionLineEdit); + + QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); + targetPositionWidget->setLayout(targetPositionLayout); + targetPositionLayout->setMargin(0); + targetPositionLayout->setSpacing(0); + QLabel *targetPositionLabel = new QLabel("Target Position", targetPositionWidget); + motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), targetPositionWidget); + connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, ADMTController::MotorAttribute::TARGET_POS); + targetPositionLayout->addWidget(targetPositionLabel); + targetPositionLayout->addWidget(motorTargetPositionLineEdit); + + QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); + motorDirectionWidget->setLayout(motorDirectionLayout); + motorDirectionLayout->setMargin(0); + motorDirectionLayout->setSpacing(0); + QLabel *motorDirectionLabel = new QLabel("Rotation Direction", motorDirectionWidget); + calibrationMotorDirectionSwitch = new CustomSwitch("CW", "CCW", motorControlSectionWidget); + calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); + connect(calibrationMotorDirectionSwitch, &CustomSwitch::toggled, this, [=](bool b){ + isMotorRotationClockwise = b; + }); + motorDirectionLayout->addWidget(motorDirectionLabel); + motorDirectionLayout->addWidget(calibrationMotorDirectionSwitch); - QLabel *targetPositionLabel = new QLabel("Target Position", motorControlSectionWidget); - motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), motorControlSectionWidget); + QPushButton *continuousRotationButton = new QPushButton("Continuous Rotation", motorControlSectionWidget); + StyleHelper::BasicButton(continuousRotationButton); + connect(continuousRotationButton, &QPushButton::clicked, this, &HarmonicCalibration::moveMotorContinuous); + + QPushButton *stopMotorButton = new QPushButton("Stop Motor", motorControlSectionWidget); + StyleHelper::BasicButton(stopMotorButton); + connect(stopMotorButton, &QPushButton::clicked, this, &HarmonicCalibration::stopMotor); motorControlCollapseSection->contentLayout()->setSpacing(8); - motorControlCollapseSection->contentLayout()->addWidget(currentPositionLabel); - motorControlCollapseSection->contentLayout()->addWidget(calibrationMotorCurrentPositionLineEdit); - motorControlCollapseSection->contentLayout()->addWidget(targetPositionLabel); - motorControlCollapseSection->contentLayout()->addWidget(motorTargetPositionLineEdit); + motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); + motorControlCollapseSection->contentLayout()->addWidget(currentPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); + motorControlCollapseSection->contentLayout()->addWidget(continuousRotationButton); + motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); #pragma endregion #pragma region Logs Section Widget MenuSectionWidget *logsSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(logsSectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *logsCollapseSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, logsSectionWidget); logsCollapseSection->header()->toggle(); logsSectionWidget->contentLayout()->setSpacing(8); @@ -1164,9 +1267,9 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() calibrationSettingsLayout->setMargin(0); calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); - calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); calibrationSettingsLayout->addWidget(motorControlSectionWidget); - calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); + calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); + // calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); calibrationSettingsLayout->addWidget(logsSectionWidget); calibrationSettingsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); @@ -1189,11 +1292,6 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); connect(importSamplesButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAllCalibrationState); - connectLineEditToRPSConversion(motorMaxVelocitySpinBox->lineEdit(), rotate_vmax); - connectLineEditToAMAXConversion(motorAccelTimeSpinBox->lineEdit(), amax); - connectLineEditToNumberWrite(motorMaxDisplacementSpinBox->lineEdit(), dmax, ADMTController::MotorAttribute::DMAX); - connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, ADMTController::MotorAttribute::TARGET_POS); - connectMenuComboToNumber(m_calibrationMotorRampModeMenuCombo, ramp_mode); connect(toggleAngleButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); @@ -1239,6 +1337,79 @@ ToolTemplate* HarmonicCalibration::createCalibrationWidget() displayCalculatedCoeff(); }); + connect(&m_calibrationWaitVelocityWatcher, &QFutureWatcher::finished, this, [=]() { + if(isMotorVelocityReached) + { + startCalibrationStreamThread(); + } + else + { + startCurrentMotorPositionMonitor(); + startDeviceStatusMonitor(); + } + }); + + connect(&m_resetMotorToZeroWatcher, &QFutureWatcher::finished, this, [=]() { + startWaitForVelocityReachedThread(1); + }); + + connect(&m_calibrationStreamWatcher, &QFutureWatcher::started, [=]() { + QThread *thread = QThread::currentThread(); + thread->setPriority(QThread::TimeCriticalPriority); + }); + + connect(&m_calibrationStreamWatcher, &QFutureWatcher::finished, this, [=]() { + stopMotor(); + isStartMotor = false; + toggleTabSwitching(true); + toggleCalibrationControls(true); + + QString log = "Calibration Stream Timing: \n"; + for(auto& value : m_admtController->streamBufferedIntervals) { log += QString::number(value) + "\n"; } + Q_EMIT calibrationLogWriteSignal(log); + + if(isPostCalibration) + { + graphPostDataList = m_admtController->streamBufferedValues; + postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); + postCalibrationRawDataPlotWidget->replot(); + if(static_cast(graphPostDataList.size()) == totalSamplesCount) + { + computeSineCosineOfAngles(graphPostDataList); + m_admtController->postcalibrate(vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, samplesPerCycle, !isMotorRotationClockwise); + populateCorrectedAngleErrorGraphs(); + isPostCalibration = false; + isStartMotor = false; + resetToZero = true; + toggleCalibrationButtonState(4); + } + } + else + { + graphDataList = m_admtController->streamBufferedValues; + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotWidget->replot(); + if(static_cast(graphDataList.size()) >= totalSamplesCount) + { + computeSineCosineOfAngles(graphDataList); + calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle, !isMotorRotationClockwise)); + populateAngleErrorGraphs(); + calculateHarmonicValues(); + toggleCalibrationButtonState(2); + } + else + { + resetToZero = true; + toggleCalibrationButtonState(0); + } + } + + startCurrentMotorPositionMonitor(); + startDeviceStatusMonitor(); + }); + + + return tool; } @@ -1248,44 +1419,45 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() QScrollArea *registerScrollArea = new QScrollArea(); QWidget *registerWidget = new QWidget(registerScrollArea); + registerWidget->setContentsMargins(0, 0, Style::getDimension(json::global::unit_0_5), 0); QVBoxLayout *registerLayout = new QVBoxLayout(registerWidget); registerScrollArea->setWidgetResizable(true); registerScrollArea->setWidget(registerWidget); registerWidget->setLayout(registerLayout); registerLayout->setMargin(0); - registerLayout->setSpacing(8); + registerLayout->setSpacing(globalSpacingSmall); - QLabel *registerConfigurationLabel = new QLabel("Configuration", registerWidget); - Style::setStyle(registerConfigurationLabel, style::properties::label::menuBig); + MenuCollapseSection *registerConfigurationCollapseSection = new MenuCollapseSection("Configuration", MenuCollapseSection::MHCW_ARROW, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); QWidget *registerConfigurationGridWidget = new QWidget(registerWidget); QGridLayout *registerConfigurationGridLayout = new QGridLayout(registerConfigurationGridWidget); registerConfigurationGridWidget->setLayout(registerConfigurationGridLayout); registerConfigurationGridLayout->setMargin(0); - registerConfigurationGridLayout->setSpacing(8); + registerConfigurationGridLayout->setSpacing(globalSpacingSmall); + registerConfigurationCollapseSection->contentLayout()->addWidget(registerConfigurationGridWidget); + + MenuCollapseSection *registerSensorDataCollapseSection = new MenuCollapseSection("Sensor Data", MenuCollapseSection::MHCW_ARROW, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); + QWidget *registerSensorDataGridWidget = new QWidget(registerWidget); + QGridLayout *registerSensorDataGridLayout = new QGridLayout(registerSensorDataGridWidget); + registerSensorDataGridWidget->setLayout(registerSensorDataGridLayout); + registerSensorDataGridLayout->setMargin(0); + registerSensorDataGridLayout->setSpacing(globalSpacingSmall); + registerSensorDataCollapseSection->contentLayout()->addWidget(registerSensorDataGridWidget); - QLabel *registerDeviceIDLabel = new QLabel("Device ID", registerWidget); - Style::setStyle(registerDeviceIDLabel, style::properties::label::menuBig); + MenuCollapseSection *registerDeviceIDCollapseSection = new MenuCollapseSection("Device ID", MenuCollapseSection::MHCW_ARROW, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); QWidget *registerDeviceIDGridWidget = new QWidget(registerWidget); QGridLayout *registerDeviceIDGridLayout = new QGridLayout(registerDeviceIDGridWidget); registerDeviceIDGridWidget->setLayout(registerDeviceIDGridLayout); registerDeviceIDGridLayout->setMargin(0); - registerDeviceIDGridLayout->setSpacing(8); + registerDeviceIDGridLayout->setSpacing(globalSpacingSmall); + registerDeviceIDCollapseSection->contentLayout()->addWidget(registerDeviceIDGridWidget); - QLabel *registerHarmonicsLabel = new QLabel("Harmonics", registerWidget); - Style::setStyle(registerHarmonicsLabel, style::properties::label::menuBig); + MenuCollapseSection *registerHarmonicsCollapseSection = new MenuCollapseSection("Harmonics", MenuCollapseSection::MHCW_ARROW, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); QWidget *registerHarmonicsGridWidget = new QWidget(registerWidget); QGridLayout *registerHarmonicsGridLayout = new QGridLayout(registerHarmonicsGridWidget); registerHarmonicsGridWidget->setLayout(registerHarmonicsGridLayout); registerHarmonicsGridLayout->setMargin(0); - registerHarmonicsGridLayout->setSpacing(8); - - QLabel *registerSensorDataLabel = new QLabel("Sensor Data", registerWidget); - Style::setStyle(registerSensorDataLabel, style::properties::label::menuBig); - QWidget *registerSensorDataGridWidget = new QWidget(registerWidget); - QGridLayout *registerSensorDataGridLayout = new QGridLayout(registerSensorDataGridWidget); - registerSensorDataGridWidget->setLayout(registerSensorDataGridLayout); - registerSensorDataGridLayout->setMargin(0); - registerSensorDataGridLayout->setSpacing(8); + registerHarmonicsGridLayout->setSpacing(globalSpacingSmall); + registerHarmonicsCollapseSection->contentLayout()->addWidget(registerHarmonicsGridWidget); cnvPageRegisterBlock = new RegisterBlockWidget("CNVPAGE", "Convert Start and Page Select", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::CNVPAGE), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); digIORegisterBlock = new RegisterBlockWidget("DIGIO", "Digital Input Output", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIO), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIO), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); @@ -1351,7 +1523,7 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() registerDeviceIDGridLayout->addWidget(uniqID1RegisterBlock, 0, 1); registerDeviceIDGridLayout->addWidget(uniqID2RegisterBlock, 0, 2); registerDeviceIDGridLayout->addWidget(uniqID3RegisterBlock, 0, 3); - QSpacerItem *registerDeviceSpacer = new QSpacerItem(0, 0, QSizePolicy::Preferred, QSizePolicy::Preferred); + QSpacerItem *registerDeviceSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred); registerDeviceIDGridLayout->addItem(registerDeviceSpacer, 0, 4); registerHarmonicsGridLayout->addWidget(h1MagRegisterBlock, 0, 0); @@ -1368,35 +1540,38 @@ ToolTemplate* HarmonicCalibration::createRegistersWidget() for(int c=0; c < registerHarmonicsGridLayout->columnCount(); ++c) registerHarmonicsGridLayout->setColumnStretch(c,1); for(int c=0; c < registerSensorDataGridLayout->columnCount(); ++c) registerSensorDataGridLayout->setColumnStretch(c,1); + QWidget *registerActionsWidget = new QWidget(registerWidget); + QHBoxLayout *registerActionsLayout = new QHBoxLayout(registerActionsWidget); + registerActionsWidget->setLayout(registerActionsLayout); + registerActionsLayout->setMargin(0); + registerActionsLayout->setSpacing(globalSpacingSmall); readAllRegistersButton = new QPushButton("Read All Registers", registerWidget); StyleHelper::BasicButton(readAllRegistersButton); readAllRegistersButton->setFixedWidth(270); connect(readAllRegistersButton, &QPushButton::clicked, this, &HarmonicCalibration::readAllRegisters); + registerActionsLayout->addWidget(readAllRegistersButton); - registerLayout->addWidget(readAllRegistersButton); - registerLayout->addWidget(registerConfigurationLabel); - registerLayout->addWidget(registerConfigurationGridWidget); - registerLayout->addWidget(registerSensorDataLabel); - registerLayout->addWidget(registerSensorDataGridWidget); - registerLayout->addWidget(registerDeviceIDLabel); - registerLayout->addWidget(registerDeviceIDGridWidget); - registerLayout->addWidget(registerHarmonicsLabel); - registerLayout->addWidget(registerHarmonicsGridWidget); + registerLayout->addWidget(registerConfigurationCollapseSection); + registerLayout->addWidget(registerSensorDataCollapseSection); + registerLayout->addWidget(registerDeviceIDCollapseSection); + registerLayout->addWidget(registerHarmonicsCollapseSection); registerLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - tool->topContainer()->setVisible(false); + tool->topContainer()->setVisible(true); tool->topContainerMenuControl()->setVisible(false); tool->leftContainer()->setVisible(false); tool->rightContainer()->setVisible(false); tool->bottomContainer()->setVisible(false); - tool->setLeftContainerWidth(270); - tool->setRightContainerWidth(270); tool->openBottomContainerHelper(false); tool->openTopContainerHelper(false); + tool->addWidgetToTopContainerHelper(registerActionsWidget, ToolTemplateAlignment::TTA_LEFT); tool->addWidgetToCentralContainerHelper(registerScrollArea); + tool->layout()->setMargin(0); + tool->layout()->setContentsMargins(globalSpacingSmall, globalSpacingSmall, Style::getDimension(json::global::unit_0_5), globalSpacingSmall); + connectRegisterBlockToRegistry(cnvPageRegisterBlock); connectRegisterBlockToRegistry(digIORegisterBlock); connectRegisterBlockToRegistry(faultRegisterBlock); @@ -1449,6 +1624,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() leftUtilityLayout->setSpacing(8); #pragma region Command Log Widget MenuSectionWidget *commandLogSectionWidget = new MenuSectionWidget(leftUtilityWidget); + Style::setStyle(commandLogSectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *commandLogCollapseSection = new MenuCollapseSection("Command Log", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, commandLogSectionWidget); commandLogSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); commandLogSectionWidget->contentLayout()->addWidget(commandLogCollapseSection); @@ -1491,16 +1667,17 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() #pragma region DIGIO Monitor MenuSectionWidget *DIGIOMonitorSectionWidget = new MenuSectionWidget(DIGIOWidget); + Style::setStyle(DIGIOMonitorSectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection("DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOMonitorSectionWidget); DIGIOMonitorSectionWidget->contentLayout()->addWidget(DIGIOMonitorCollapseSection); DIGIOMonitorCollapseSection->contentLayout()->setSpacing(8); - DIGIOBusyStatusLED = createStatusLEDWidget("BUSY (Output)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); - DIGIOCNVStatusLED = createStatusLEDWidget("CNV (Input)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); - DIGIOSENTStatusLED = createStatusLEDWidget("SENT (Output)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); - DIGIOACALCStatusLED = createStatusLEDWidget("ACALC (Output)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); - DIGIOFaultStatusLED = createStatusLEDWidget("FAULT (Output)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); - DIGIOBootloaderStatusLED = createStatusLEDWidget("BOOTLOADER (Output)", json::theme::background_primary, true, DIGIOMonitorCollapseSection); + DIGIOBusyStatusLED = createStatusLEDWidget("BUSY (Output)", "digio", false, DIGIOMonitorCollapseSection); + DIGIOCNVStatusLED = createStatusLEDWidget("CNV (Input)", "digio", false, DIGIOMonitorCollapseSection); + DIGIOSENTStatusLED = createStatusLEDWidget("SENT (Output)", "digio", false, DIGIOMonitorCollapseSection); + DIGIOACALCStatusLED = createStatusLEDWidget("ACALC (Output)", "digio", false, DIGIOMonitorCollapseSection); + DIGIOFaultStatusLED = createStatusLEDWidget("FAULT (Output)", "digio", false, DIGIOMonitorCollapseSection); + DIGIOBootloaderStatusLED = createStatusLEDWidget("BOOTLOADER (Output)", "digio", false, DIGIOMonitorCollapseSection); DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBusyStatusLED); DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOCNVStatusLED); @@ -1512,6 +1689,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() #pragma region DIGIO Control MenuSectionWidget *DIGIOControlSectionWidget = new MenuSectionWidget(DIGIOWidget); + Style::setStyle(DIGIOControlSectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *DIGIOControlCollapseSection = new MenuCollapseSection("DIGIO Control", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOControlSectionWidget); DIGIOControlCollapseSection->contentLayout()->setSpacing(8); DIGIOControlSectionWidget->contentLayout()->addWidget(DIGIOControlCollapseSection); @@ -1644,7 +1822,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOControlGridWidget); DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOResetButton); - if(generalRegisterMap.at("Sequence Type") == 0) + if(GENERALRegisterMap.at("Sequence Type") == 0) { DIGIO2FNCToggleSwitch->setVisible(false); DIGIO4FNCToggleSwitch->setVisible(false); @@ -1658,18 +1836,19 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() #pragma region MTDIAG1 Widget MenuSectionWidget *MTDIAG1SectionWidget = new MenuSectionWidget(centerUtilityWidget); + Style::setStyle(MTDIAG1SectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *MTDIAG1CollapseSection = new MenuCollapseSection("MT Diagnostic Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, MTDIAG1SectionWidget); MTDIAG1SectionWidget->contentLayout()->addWidget(MTDIAG1CollapseSection); MTDIAG1CollapseSection->contentLayout()->setSpacing(8); - R0StatusLED = createStatusLEDWidget("R0", json::theme::background_primary, true, MTDIAG1SectionWidget); - R1StatusLED = createStatusLEDWidget("R1", json::theme::background_primary, true, MTDIAG1SectionWidget); - R2StatusLED = createStatusLEDWidget("R2", json::theme::background_primary, true, MTDIAG1SectionWidget); - R3StatusLED = createStatusLEDWidget("R3", json::theme::background_primary, true, MTDIAG1SectionWidget); - R4StatusLED = createStatusLEDWidget("R4", json::theme::background_primary, true, MTDIAG1SectionWidget); - R5StatusLED = createStatusLEDWidget("R5", json::theme::background_primary, true, MTDIAG1SectionWidget); - R6StatusLED = createStatusLEDWidget("R6", json::theme::background_primary, true, MTDIAG1SectionWidget); - R7StatusLED = createStatusLEDWidget("R7", json::theme::background_primary, true, MTDIAG1SectionWidget); + R0StatusLED = createStatusLEDWidget("R0", "mtdiag", false, MTDIAG1SectionWidget); + R1StatusLED = createStatusLEDWidget("R1", "mtdiag", false, MTDIAG1SectionWidget); + R2StatusLED = createStatusLEDWidget("R2", "mtdiag", false, MTDIAG1SectionWidget); + R3StatusLED = createStatusLEDWidget("R3", "mtdiag", false, MTDIAG1SectionWidget); + R4StatusLED = createStatusLEDWidget("R4", "mtdiag", false, MTDIAG1SectionWidget); + R5StatusLED = createStatusLEDWidget("R5", "mtdiag", false, MTDIAG1SectionWidget); + R6StatusLED = createStatusLEDWidget("R6", "mtdiag", false, MTDIAG1SectionWidget); + R7StatusLED = createStatusLEDWidget("R7", "mtdiag", false, MTDIAG1SectionWidget); MTDIAG1CollapseSection->contentLayout()->addWidget(R0StatusLED); MTDIAG1CollapseSection->contentLayout()->addWidget(R1StatusLED); @@ -1692,6 +1871,7 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() MTDiagnosticsLayout->setSpacing(8); MenuSectionWidget *MTDiagnosticsSectionWidget = new MenuSectionWidget(centerUtilityWidget); + Style::setStyle(MTDiagnosticsSectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *MTDiagnosticsCollapseSection = new MenuCollapseSection("MT Diagnostics", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, MTDiagnosticsSectionWidget); MTDiagnosticsSectionWidget->contentLayout()->addWidget(MTDiagnosticsCollapseSection); MTDiagnosticsCollapseSection->contentLayout()->setSpacing(8); @@ -1741,25 +1921,26 @@ ToolTemplate* HarmonicCalibration::createUtilityWidget() rightUtilityLayout->setSpacing(8); MenuSectionWidget *faultRegisterSectionWidget = new MenuSectionWidget(rightUtilityWidget); + Style::setStyle(faultRegisterSectionWidget, style::properties::widget::basicComponent); MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection("Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, faultRegisterSectionWidget); faultRegisterSectionWidget->contentLayout()->addWidget(faultRegisterCollapseSection); faultRegisterCollapseSection->contentLayout()->setSpacing(8); - VDDUnderVoltageStatusLED = createStatusLEDWidget("VDD Under Voltage", json::theme::content_error, true, faultRegisterCollapseSection); - VDDOverVoltageStatusLED = createStatusLEDWidget("VDD Over Voltage", json::theme::content_error, true, faultRegisterCollapseSection); - VDRIVEUnderVoltageStatusLED = createStatusLEDWidget("VDRIVE Under Voltage", json::theme::content_error, true, faultRegisterCollapseSection); - VDRIVEOverVoltageStatusLED = createStatusLEDWidget("VDRIVE Over Voltage", json::theme::content_error, true, faultRegisterCollapseSection); - AFEDIAGStatusLED = createStatusLEDWidget("AFEDIAG", json::theme::content_error, true, faultRegisterCollapseSection); - NVMCRCFaultStatusLED = createStatusLEDWidget("NVM CRC Fault", json::theme::content_error, true, faultRegisterCollapseSection); - ECCDoubleBitErrorStatusLED = createStatusLEDWidget("ECC Double Bit Error", json::theme::content_error, true, faultRegisterCollapseSection); - OscillatorDriftStatusLED = createStatusLEDWidget("Oscillator Drift", json::theme::content_error, true, faultRegisterCollapseSection); - CountSensorFalseStateStatusLED = createStatusLEDWidget("Count Sensor False State", json::theme::content_error, true, faultRegisterCollapseSection); - AngleCrossCheckStatusLED = createStatusLEDWidget("Angle Cross Check", json::theme::content_error, true, faultRegisterCollapseSection); - TurnCountSensorLevelsStatusLED = createStatusLEDWidget("Turn Count Sensor Levels", json::theme::content_error, true, faultRegisterCollapseSection); - MTDIAGStatusLED = createStatusLEDWidget("MTDIAG", json::theme::content_error, true, faultRegisterCollapseSection); - TurnCounterCrossCheckStatusLED = createStatusLEDWidget("Turn Counter Cross Check", json::theme::content_error, true, faultRegisterCollapseSection); - RadiusCheckStatusLED = createStatusLEDWidget("Radius Check", json::theme::content_error, true, faultRegisterCollapseSection); - SequencerWatchdogStatusLED = createStatusLEDWidget("Sequencer Watchdog", json::theme::content_error, true, faultRegisterCollapseSection); + VDDUnderVoltageStatusLED = createStatusLEDWidget("VDD Under Voltage", "fault", false, faultRegisterCollapseSection); + VDDOverVoltageStatusLED = createStatusLEDWidget("VDD Over Voltage", "fault", false, faultRegisterCollapseSection); + VDRIVEUnderVoltageStatusLED = createStatusLEDWidget("VDRIVE Under Voltage", "fault", false, faultRegisterCollapseSection); + VDRIVEOverVoltageStatusLED = createStatusLEDWidget("VDRIVE Over Voltage", "fault", false, faultRegisterCollapseSection); + AFEDIAGStatusLED = createStatusLEDWidget("AFEDIAG", "fault", false, faultRegisterCollapseSection); + NVMCRCFaultStatusLED = createStatusLEDWidget("NVM CRC Fault", "fault", false, faultRegisterCollapseSection); + ECCDoubleBitErrorStatusLED = createStatusLEDWidget("ECC Double Bit Error", "fault", false, faultRegisterCollapseSection); + OscillatorDriftStatusLED = createStatusLEDWidget("Oscillator Drift", "fault", false, faultRegisterCollapseSection); + CountSensorFalseStateStatusLED = createStatusLEDWidget("Count Sensor False State", "fault", false, faultRegisterCollapseSection); + AngleCrossCheckStatusLED = createStatusLEDWidget("Angle Cross Check", "fault", false, faultRegisterCollapseSection); + TurnCountSensorLevelsStatusLED = createStatusLEDWidget("Turn Count Sensor Levels", "fault", false, faultRegisterCollapseSection); + MTDIAGStatusLED = createStatusLEDWidget("MTDIAG", "fault", false, faultRegisterCollapseSection); + TurnCounterCrossCheckStatusLED = createStatusLEDWidget("Turn Counter Cross Check", "fault", false, faultRegisterCollapseSection); + RadiusCheckStatusLED = createStatusLEDWidget("Radius Check", "fault", false, faultRegisterCollapseSection); + SequencerWatchdogStatusLED = createStatusLEDWidget("Sequencer Watchdog", "fault", false, faultRegisterCollapseSection); faultRegisterCollapseSection->contentLayout()->addWidget(VDDUnderVoltageStatusLED); faultRegisterCollapseSection->contentLayout()->addWidget(VDDOverVoltageStatusLED); @@ -1851,7 +2032,7 @@ bool HarmonicCalibration::readSequence(){ if(changeCNVPage(generalRegisterPage)){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ if(*generalRegValue != UINT32_MAX){ - generalRegisterMap = m_admtController->getGeneralRegisterBitMapping(static_cast(*generalRegValue)); + GENERALRegisterMap = m_admtController->getGeneralRegisterBitMapping(static_cast(*generalRegValue)); success = true; } } @@ -1860,22 +2041,10 @@ bool HarmonicCalibration::readSequence(){ return success; } -void HarmonicCalibration::applySequence(){ - toggleWidget(applySequenceButton, false); - applySequenceButton->setText("Writing..."); - QTimer::singleShot(1000, this, [this](){ - this->toggleWidget(applySequenceButton, true); - applySequenceButton->setText("Apply"); - }); +bool HarmonicCalibration::writeSequence(const map &settings) +{ uint32_t *generalRegValue = new uint32_t; uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); - map settings; - - settings["Convert Synchronization"] = qvariant_cast(convertSynchronizationMenuCombo->combo()->currentData()); // convertSync; - settings["Angle Filter"] = qvariant_cast(angleFilterMenuCombo->combo()->currentData()); // angleFilter; - settings["8th Harmonic"] = qvariant_cast(eighthHarmonicMenuCombo->combo()->currentData()); // eighthHarmonic; - settings["Sequence Type"] = qvariant_cast(sequenceTypeMenuCombo->combo()->currentData()); // sequenceType; - settings["Conversion Type"] = qvariant_cast(conversionTypeMenuCombo->combo()->currentData()); // conversionType; bool success = false; @@ -1887,13 +2056,12 @@ void HarmonicCalibration::applySequence(){ if(changeCNVPage(generalRegisterPage)){ if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, newGeneralRegValue) != -1){ if(readSequence()){ - if(settings.at("Convert Synchronization") == generalRegisterMap.at("Convert Synchronization") && - settings.at("Angle Filter") == generalRegisterMap.at("Angle Filter") && - settings.at("8th Harmonic") == generalRegisterMap.at("8th Harmonic") && - settings.at("Sequence Type") == generalRegisterMap.at("Sequence Type") && - settings.at("Conversion Type") == generalRegisterMap.at("Conversion Type")) + if(settings.at("Convert Synchronization") == GENERALRegisterMap.at("Convert Synchronization") && + settings.at("Angle Filter") == GENERALRegisterMap.at("Angle Filter") && + settings.at("8th Harmonic") == GENERALRegisterMap.at("8th Harmonic") && + settings.at("Sequence Type") == GENERALRegisterMap.at("Sequence Type") && + settings.at("Conversion Type") == GENERALRegisterMap.at("Conversion Type")) { - StatusBarManager::pushMessage("Sequence settings applied successfully"); success = true; } } @@ -1901,8 +2069,31 @@ void HarmonicCalibration::applySequence(){ } } + return success; +} + +void HarmonicCalibration::applySequence(){ + toggleWidget(applySequenceButton, false); + applySequenceButton->setText("Writing..."); + QTimer::singleShot(1000, this, [this](){ + this->toggleWidget(applySequenceButton, true); + applySequenceButton->setText("Apply"); + }); + uint32_t *generalRegValue = new uint32_t; + uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); + map settings; + + bool success = false; - if(!success){ StatusBarManager::pushMessage("Failed to apply sequence settings"); } + settings["Sequence Type"] = qvariant_cast(sequenceTypeMenuCombo->combo()->currentData()); // sequenceType; + settings["Conversion Type"] = qvariant_cast(conversionTypeMenuCombo->combo()->currentData()); // conversionType; + settings["Convert Synchronization"] = qvariant_cast(convertSynchronizationMenuCombo->combo()->currentData()); // convertSync; + settings["Angle Filter"] = qvariant_cast(angleFilterMenuCombo->combo()->currentData()); // angleFilter; + settings["8th Harmonic"] = qvariant_cast(eighthHarmonicMenuCombo->combo()->currentData()); // eighthHarmonic; + + success = writeSequence(settings); + if(!success) StatusBarManager::pushMessage("Failed to apply sequence settings"); + else StatusBarManager::pushMessage("Sequence settings applied successfully"); } bool HarmonicCalibration::changeCNVPage(uint32_t page){ @@ -1922,12 +2113,12 @@ bool HarmonicCalibration::changeCNVPage(uint32_t page){ void HarmonicCalibration::initializeMotor() { - rotate_vmax = 53687.0912; + motor_rpm = 60; + rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(motor_rpm)); writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - readMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - amax = 439.8046511104; + amax = convertAccelTimetoAMAX(motorAccelTime); writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); @@ -1948,9 +2139,12 @@ void HarmonicCalibration::initializeMotor() void HarmonicCalibration::startDeviceStatusMonitor() { - isDeviceStatusMonitor = true; - m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); - m_deviceStatusWatcher.setFuture(m_deviceStatusThread); + if(!m_deviceStatusThread.isRunning()) + { + isDeviceStatusMonitor = true; + m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); + m_deviceStatusWatcher.setFuture(m_deviceStatusThread); + } } void HarmonicCalibration::stopDeviceStatusMonitor() @@ -1975,7 +2169,7 @@ void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), readValue) == 0) { - registerFault = m_admtController->checkRegisterFault(static_cast(*readValue), generalRegisterMap.at("Sequence Type") == 0 ? true : false); + registerFault = m_admtController->checkRegisterFault(static_cast(*readValue), GENERALRegisterMap.at("Sequence Type") == 0 ? true : false); Q_EMIT updateFaultStatusSignal(registerFault); } else @@ -2000,15 +2194,20 @@ void HarmonicCalibration::requestDisconnect() stopCalibrationUITask(); stopUtilityTask(); + stopCalibrationStreamThread(); + stopDeviceStatusMonitor(); stopCurrentMotorPositionMonitor(); } void HarmonicCalibration::startCurrentMotorPositionMonitor() { - isMotorPositionMonitor = true; - m_currentMotorPositionThread = QtConcurrent::run(this, &HarmonicCalibration::currentMotorPositionTask, motorPositionMonitorRate); - m_currentMotorPositionWatcher.setFuture(m_currentMotorPositionThread); + if(!m_currentMotorPositionThread.isRunning()) + { + isMotorPositionMonitor = true; + m_currentMotorPositionThread = QtConcurrent::run(this, &HarmonicCalibration::currentMotorPositionTask, motorPositionMonitorRate); + m_currentMotorPositionWatcher.setFuture(m_currentMotorPositionThread); + } } void HarmonicCalibration::stopCurrentMotorPositionMonitor() @@ -2046,7 +2245,7 @@ bool HarmonicCalibration::resetGENERAL() bool success = false; uint32_t resetValue = 0x0000; - if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { resetValue = 0x1230; } // Industrial or ASIL QM + if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { resetValue = 0x1231; } // Industrial or ASIL QM else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { resetValue = 0x1200; } // Automotive or ASIL B if(resetValue != 0x0000){ @@ -2103,8 +2302,6 @@ void HarmonicCalibration::startAcquisition() m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); m_acquisitionGraphThread = QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, acquisitionGraphSampleRate); m_acquisitionGraphWatcher.setFuture(m_acquisitionGraphThread); - - startCurrentMotorPositionMonitor(); } void HarmonicCalibration::stopAcquisition() @@ -2130,11 +2327,21 @@ void HarmonicCalibration::updateFaultStatus(bool status) if(isChanged) { deviceStatusFault = status; - toggleStatusLEDColor(acquisitionFaultRegisterLEDWidget, json::theme::content_error, json::theme::content_success, deviceStatusFault); - toggleStatusLEDColor(calibrationFaultRegisterLEDWidget, json::theme::content_error, json::theme::content_success, deviceStatusFault); + acquisitionFaultRegisterLEDWidget->setChecked(deviceStatusFault); + calibrationFaultRegisterLEDWidget->setChecked(deviceStatusFault); } } +void HarmonicCalibration::updateAcquisitionMotorRPM() +{ + acquisitionMotorRPMLineEdit->setText(QString::number(motor_rpm)); +} + +void HarmonicCalibration::updateAcquisitionMotorRotationDirection() +{ + acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); +} + void HarmonicCalibration::getAcquisitionSamples(int sampleRate) { while(isStartAcquisition) @@ -2261,9 +2468,12 @@ void HarmonicCalibration::acquisitionUITask(int sampleRate) void HarmonicCalibration::startAcquisitionUITask() { - isAcquisitionTab = true; - m_acquisitionUIThread = QtConcurrent::run(this, &HarmonicCalibration::acquisitionUITask, acquisitionUITimerRate); - m_acquisitionUIWatcher.setFuture(m_acquisitionUIThread); + if(!m_acquisitionUIThread.isRunning()) + { + isAcquisitionTab = true; + m_acquisitionUIThread = QtConcurrent::run(this, &HarmonicCalibration::acquisitionUITask, acquisitionUITimerRate); + m_acquisitionUIWatcher.setFuture(m_acquisitionUIThread); + } } void HarmonicCalibration::stopAcquisitionUITask() @@ -2277,13 +2487,13 @@ void HarmonicCalibration::stopAcquisitionUITask() } void HarmonicCalibration::updateSequenceWidget(){ - if(generalRegisterMap.at("Sequence Type") == -1){ sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); } - else{ sequenceTypeMenuCombo->combo()->setCurrentIndex(sequenceTypeMenuCombo->combo()->findData(generalRegisterMap.at("Sequence Type"))); } - conversionTypeMenuCombo->combo()->setCurrentIndex(conversionTypeMenuCombo->combo()->findData(generalRegisterMap.at("Conversion Type"))); - if(generalRegisterMap.at("Convert Synchronization") == -1){ convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); } - else{ convertSynchronizationMenuCombo->combo()->setCurrentIndex(convertSynchronizationMenuCombo->combo()->findData(generalRegisterMap.at("Convert Synchronization"))); } - angleFilterMenuCombo->combo()->setCurrentIndex(angleFilterMenuCombo->combo()->findData(generalRegisterMap.at("Angle Filter"))); - eighthHarmonicMenuCombo->combo()->setCurrentIndex(eighthHarmonicMenuCombo->combo()->findData(generalRegisterMap.at("8th Harmonic"))); + if(GENERALRegisterMap.at("Sequence Type") == -1){ sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); } + else{ sequenceTypeMenuCombo->combo()->setCurrentIndex(sequenceTypeMenuCombo->combo()->findData(GENERALRegisterMap.at("Sequence Type"))); } + conversionTypeMenuCombo->combo()->setCurrentIndex(conversionTypeMenuCombo->combo()->findData(GENERALRegisterMap.at("Conversion Type"))); + if(GENERALRegisterMap.at("Convert Synchronization") == -1){ convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); } + else{ convertSynchronizationMenuCombo->combo()->setCurrentIndex(convertSynchronizationMenuCombo->combo()->findData(GENERALRegisterMap.at("Convert Synchronization"))); } + angleFilterMenuCombo->combo()->setCurrentIndex(angleFilterMenuCombo->combo()->findData(GENERALRegisterMap.at("Angle Filter"))); + eighthHarmonicMenuCombo->combo()->setCurrentIndex(eighthHarmonicMenuCombo->combo()->findData(GENERALRegisterMap.at("8th Harmonic"))); } void HarmonicCalibration::applySequenceAndUpdate() @@ -2380,9 +2590,12 @@ void HarmonicCalibration::run(bool b) #pragma region Calibration Methods void HarmonicCalibration::startCalibrationUITask() { - isCalibrationTab = true; - m_calibrationUIThread = QtConcurrent::run(this, &HarmonicCalibration::calibrationUITask, calibrationUITimerRate); - m_calibrationUIWatcher.setFuture(m_calibrationUIThread); + if(!m_calibrationUIThread.isRunning()) + { + isCalibrationTab = true; + m_calibrationUIThread = QtConcurrent::run(this, &HarmonicCalibration::calibrationUITask, calibrationUITimerRate); + m_calibrationUIWatcher.setFuture(m_calibrationUIThread); + } } void HarmonicCalibration::stopCalibrationUITask() @@ -2415,13 +2628,26 @@ void HarmonicCalibration::calibrationUITask(int sampleRate) } } +void HarmonicCalibration::updateCalibrationMotorRPM() +{ + calibrationMotorRPMLineEdit->setText(QString::number(motor_rpm)); +} + +void HarmonicCalibration::updateCalibrationMotorRotationDirection() +{ + calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); +} + void HarmonicCalibration::getCalibrationSamples() { if(resetCurrentPositionToZero()){ + double step = 0; + if(isMotorRotationClockwise) step = motorFullStepPerRevolution; + else step = -motorFullStepPerRevolution; if(isPostCalibration){ int currentSamplesCount = graphPostDataList.size(); while(isStartMotor && currentSamplesCount < totalSamplesCount){ - target_pos = current_pos + -408; + target_pos = current_pos + step; moveMotorToPosition(target_pos, true); updateChannelValue(ADMTController::Channel::ANGLE); graphPostDataList.append(angle); @@ -2431,7 +2657,7 @@ void HarmonicCalibration::getCalibrationSamples() else{ int currentSamplesCount = graphDataList.size(); while(isStartMotor && currentSamplesCount < totalSamplesCount){ - target_pos = current_pos + -408; + target_pos = current_pos + step; if(moveMotorToPosition(target_pos, true) == false) { m_admtController->disconnectADMT(); } if(updateChannelValue(ADMTController::Channel::ANGLE)) { break; } graphDataList.append(angle); @@ -2446,27 +2672,202 @@ void HarmonicCalibration::getCalibrationSamples() void HarmonicCalibration::startCalibration() { totalSamplesCount = cycleCount * samplesPerCycle; - graphPostDataList.reserve(totalSamplesCount); graphPostDataList.squeeze(); graphDataList.reserve(totalSamplesCount); graphDataList.squeeze(); + //configureConversionType(calibrationMode); // TODO uncomment when conversion type is okay + configureCalibrationSequenceSettings(); + clearHarmonicRegisters(); + toggleTabSwitching(false); - toggleMotorControls(false); + toggleCalibrationControls(false); + + calibrationDataGraphTabWidget->setCurrentIndex(0); + calibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); - startMotor(); + toggleCalibrationButtonState(1); + if(calibrationMode == 0) startContinuousCalibration(); + else startOneShotCalibration(); } void HarmonicCalibration::stopCalibration() { isStartMotor = false; + if(calibrationMode == 0) + { + stopContinuousCalibration(); + } toggleTabSwitching(true); - toggleMotorControls(true); + toggleCalibrationControls(true); } -void HarmonicCalibration::startMotor() +void HarmonicCalibration::startContinuousCalibration() +{ + stopCurrentMotorPositionMonitor(); + stopDeviceStatusMonitor(); + + if(isPostCalibration) StatusBarManager::pushMessage("Acquiring Post Calibration Samples, Please Wait..."); + else StatusBarManager::pushMessage("Acquiring Calibration Samples, Please Wait..."); + startResetMotorToZero(); +} + +void HarmonicCalibration::stopContinuousCalibration() +{ + stopMotor(); + stopWaitForVelocityReachedThread(); + stopCalibrationStreamThread(); + + startCurrentMotorPositionMonitor(); + startDeviceStatusMonitor(); +} + +void HarmonicCalibration::startResetMotorToZero() +{ + isResetMotorToZero = true; + if(!m_resetMotorToZeroThread.isRunning()) + { + m_resetMotorToZeroThread = QtConcurrent::run(this, &HarmonicCalibration::resetMotorToZero); + m_resetMotorToZeroWatcher.setFuture(m_resetMotorToZeroThread); + } +} + +void HarmonicCalibration::stopResetMotorToZero() +{ + isResetMotorToZero = false; + if(m_resetMotorToZeroThread.isRunning()) + { + m_resetMotorToZeroThread.cancel(); + m_resetMotorToZeroWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::resetMotorToZero() +{ + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) + { + if(current_pos != 0) + { + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, convertRPStoVMAX(convertRPMtoRPS(fast_motor_rpm))); + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + while(isResetMotorToZero && current_pos != 0){ + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) != 0) break; + QThread::msleep(readMotorDebounce); + } + if(current_pos == 0) + { + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); + } + } + } +} + +void HarmonicCalibration::startCalibrationStreamThread() +{ + if(!m_calibrationStreamThread.isRunning()) + { + m_admtController->stopStream = false; + + continuousCalibrationSampleRate = calculateContinuousCalibrationSampleRate(convertVMAXtoRPS(rotate_vmax), samplesPerCycle); + m_calibrationStreamThread = QtConcurrent::run([this]() { m_admtController->bufferedStreamIO(totalSamplesCount, continuousCalibrationSampleRate); }); + m_calibrationStreamWatcher.setFuture(m_calibrationStreamThread); + } +} + +void HarmonicCalibration::stopCalibrationStreamThread() +{ + m_admtController->stopStream = true; + if(m_calibrationStreamThread.isRunning()) + { + m_calibrationStreamThread.cancel(); + m_calibrationStreamWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::startWaitForVelocityReachedThread(int mode) +{ + if(!m_calibrationWaitVelocityWatcher.isRunning()) + { + isMotorVelocityCheck = true; + m_calibrationWaitVelocityThread = QtConcurrent::run(this, &HarmonicCalibration::waitForVelocityReached, mode, motorWaitVelocityReachedSampleRate); + m_calibrationWaitVelocityWatcher.setFuture(m_calibrationWaitVelocityThread); + } +} + +void HarmonicCalibration::stopWaitForVelocityReachedThread() +{ + isMotorVelocityCheck = false; + if(m_calibrationWaitVelocityWatcher.isRunning()) + { + m_calibrationWaitVelocityThread.cancel(); + m_calibrationWaitVelocityWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::waitForVelocityReached(int mode, int sampleRate) +{ + isMotorVelocityReached = false; + if(mode == 0) + { + QThread::msleep(floor(convertAMAXtoAccelTime(amax) * 1000)); + isMotorVelocityReached = true; + } + else if(mode == 1) + { + moveMotorContinuous(); + uint32_t *registerValue = new uint32_t; + while(isMotorVelocityCheck && !isMotorVelocityReached) + { + if(readMotorRegisterValue(m_admtController->getRampGeneratorDriverFeatureControlRegister(ADMTController::RampGeneratorDriverFeatureControlRegister::RAMP_STAT), registerValue) == 0){ + isMotorVelocityReached = m_admtController->checkVelocityReachedFlag(static_cast(*registerValue)); + } + + QThread::msleep(sampleRate); + } + + delete registerValue; + } +} + +int HarmonicCalibration::calculateContinuousCalibrationSampleRate(double motorRPS, int samplesPerCycle) +{ + return static_cast(floor(1 / motorRPS / samplesPerCycle * 1000 * 1000 * 1000)); // In nanoseconds +} + +void HarmonicCalibration::configureConversionType(int mode) +{ + readSequence(); + GENERALRegisterMap.at("Conversion Type") = mode; + writeSequence(GENERALRegisterMap); +} + +void HarmonicCalibration::configureCalibrationSequenceSettings() +{ + readSequence(); + GENERALRegisterMap.at("8th Harmonic") = 1; // User-supplied 8th Harmonic + writeSequence(GENERALRegisterMap); +} + +void HarmonicCalibration::getStreamedCalibrationSamples(int microSampleRate) +{ + int currentSamplesCount = graphDataList.size(); + moveMotorContinuous(); + while(isStartMotor && currentSamplesCount < totalSamplesCount) + { + graphDataList.append(m_admtController->streamedValue); + // graphPostDataList.append(m_admtController->streamedValue); + currentSamplesCount = graphDataList.size(); + // currentSamplesCount = graphDataPostList.size(); + + QThread::usleep(microSampleRate); + } +} + +void HarmonicCalibration::startOneShotCalibration() { if(resetToZero && !isPostCalibration){ clearCalibrationSamples(); @@ -2478,56 +2879,44 @@ void HarmonicCalibration::startMotor() clearPostCalibrationSamples(); } - if(isPostCalibration) - postCalibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); - else - calibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); - - if(isPostCalibration) - calibrationDataGraphTabWidget->setCurrentIndex(1); // Set tab to Post Calibration Samples - else - calibrationDataGraphTabWidget->setCurrentIndex(0); // Set tab to Calibration Samples - - clearCalibrateDataButton->setEnabled(false); QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getCalibrationSamples); QFutureWatcher *watcher = new QFutureWatcher(this); connect(watcher, &QFutureWatcher::finished, this, [=]() { toggleTabSwitching(true); - toggleMotorControls(true); + toggleCalibrationControls(true); calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); calibrationRawDataPlotChannel->xAxis()->setMax(graphDataList.size()); calibrationRawDataPlotWidget->replot(); isStartMotor = false; - calibrationStartMotorButton->setChecked(false); - clearCalibrateDataButton->setEnabled(true); if(isPostCalibration) { if(static_cast(graphPostDataList.size()) == totalSamplesCount) { computeSineCosineOfAngles(graphPostDataList); - m_admtController->postcalibrate(vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, samplesPerCycle); + m_admtController->postcalibrate(vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, samplesPerCycle, !isMotorRotationClockwise); populateCorrectedAngleErrorGraphs(); isPostCalibration = false; isStartMotor = false; resetToZero = true; - canCalibrate(false); + toggleCalibrationButtonState(4); } + else toggleCalibrationButtonState(2); } else{ if(static_cast(graphDataList.size()) == totalSamplesCount) { computeSineCosineOfAngles(graphDataList); - calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); + calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle, !isMotorRotationClockwise)); populateAngleErrorGraphs(); calculateHarmonicValues(); - canStartMotor(false); - canCalibrate(true); + toggleCalibrationButtonState(2); } else{ resetToZero = true; + toggleCalibrationButtonState(0); } } }); @@ -2535,24 +2924,23 @@ void HarmonicCalibration::startMotor() watcher->setFuture(future); } -void HarmonicCalibration::startMotorContinuous() -{ - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); -} - void HarmonicCalibration::postCalibrateData() { calibrationLogWrite("==== Post Calibration Start ====\n"); flashHarmonicValues(); - calibrationDataGraphTabWidget->setCurrentIndex(1); isPostCalibration = true; isStartMotor = true; resetToZero = true; - + toggleTabSwitching(false); - toggleMotorControls(false); + toggleCalibrationControls(false); - startMotor(); + calibrationDataGraphTabWidget->setCurrentIndex(1); + postCalibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); + + toggleCalibrationButtonState(3); + if(calibrationMode == 0) startContinuousCalibration(); + else startOneShotCalibration(); } void HarmonicCalibration::resetAllCalibrationState() @@ -2565,9 +2953,8 @@ void HarmonicCalibration::resetAllCalibrationState() clearCorrectedAngleErrorGraphs(); resultDataTabWidget->setCurrentIndex(0); - canStartMotor(true); - canCalibrate(false); - calibrateDataButton->setChecked(false); + toggleCalibrationButtonState(0); + isPostCalibration = false; isCalculatedCoeff = false; resetToZero = true; @@ -2639,6 +3026,28 @@ void HarmonicCalibration::populateCorrectedAngleErrorGraphs() resultDataTabWidget->setCurrentIndex(2); // Set tab to Angle Error } +void HarmonicCalibration::clearHarmonicRegisters() +{ + bool success = false; + uint32_t value = 0x0; + uint32_t harmonicCNVPage = m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1MAG); + if(changeCNVPage(harmonicCNVPage)) + { + success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), value) == 0 ? true : false; + success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), value) == 0 ? true : false; + success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), value) == 0 ? true : false; + success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), value) == 0 ? true : false; + success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), value) == 0 ? true : false; + success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), value) == 0 ? true : false; + success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), value) == 0 ? true : false; + success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), value) == 0 ? true : false; + } + + if(!success){ + calibrationLogWrite("Unable to clear Harmonic Registers!"); + } +} + void HarmonicCalibration::flashHarmonicValues() { if(changeCNVPage(0x02)){ @@ -2731,14 +3140,14 @@ void HarmonicCalibration::calculateHarmonicValues() H8_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H8_PHASE_HEX), "h8phase"); calibrationLogWrite(); - calibrationLogWrite(QString("Calculated H1 Mag (Angle): 0x%1").arg(QString::number(H1_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H1 Phase (Angle): 0x%1").arg(QString::number(H1_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H2 Mag (Angle): 0x%1").arg(QString::number(H2_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H2 Phase (Angle): 0x%1").arg(QString::number(H2_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H3 Mag (Angle): 0x%1").arg(QString::number(H3_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H3 Phase (Angle): 0x%1").arg(QString::number(H3_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H8 Mag (Angle): 0x%1").arg(QString::number(H8_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H8 Phase (Angle): 0x%1").arg(QString::number(H8_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H1 Mag (Angle): %1°").arg(QString::number(H1_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H1 Phase (Angle): %1°").arg(QString::number(H1_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H2 Mag (Angle): %1°").arg(QString::number(H2_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H2 Phase (Angle): %1°").arg(QString::number(H2_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H3 Mag (Angle): %1°").arg(QString::number(H3_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H3 Phase (Angle): %1°").arg(QString::number(H3_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H8 Mag (Angle): %1°").arg(QString::number(H8_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H8 Phase (Angle): %1°").arg(QString::number(H8_PHASE_ANGLE))); if(isAngleDisplayFormat) updateCalculatedCoeffAngle(); else updateCalculatedCoeffHex(); @@ -2840,10 +3249,9 @@ void HarmonicCalibration::importCalibrationData() calibrationRawDataPlotWidget->replot(); computeSineCosineOfAngles(graphDataList); - calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle)); + calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle, false)); // TODO: Hard-coded Clockwise populateAngleErrorGraphs(); - canStartMotor(false); - canCalibrate(true); + toggleCalibrationButtonState(2); } } catch(FileManagerException &ex) { calibrationLogWrite(QString(ex.what())); @@ -2906,6 +3314,41 @@ void HarmonicCalibration::toggleTabSwitching(bool value) tabWidget->setTabEnabled(3, value); } +void HarmonicCalibration::toggleCalibrationButtonState(int state) +{ + switch(state) + { + case 0: // Idle + calibrationStartMotorButton->setEnabled(true); + calibrationStartMotorButton->setChecked(false); + calibrateDataButton->setEnabled(false); + calibrateDataButton->setChecked(false); + clearCalibrateDataButton->setEnabled(true); + break; + case 1: // Start Motor + calibrationStartMotorButton->setEnabled(true); + calibrateDataButton->setEnabled(false); + clearCalibrateDataButton->setEnabled(false); + break; + case 2: // After Start Motor + calibrationStartMotorButton->setEnabled(false); + calibrateDataButton->setEnabled(true); + calibrateDataButton->setChecked(false); + clearCalibrateDataButton->setEnabled(true); + break; + case 3: // Post-Calibration + calibrationStartMotorButton->setEnabled(false); + calibrateDataButton->setEnabled(true); + clearCalibrateDataButton->setEnabled(false); + break; + case 4: // After Post-Calibration + calibrationStartMotorButton->setEnabled(false); + calibrateDataButton->setEnabled(false); + clearCalibrateDataButton->setEnabled(true); + break; + } +} + void HarmonicCalibration::canStartMotor(bool value) { calibrationStartMotorButton->setEnabled(value); @@ -2916,13 +3359,14 @@ void HarmonicCalibration::canCalibrate(bool value) calibrateDataButton->setEnabled(value); } -void HarmonicCalibration::toggleMotorControls(bool value) +void HarmonicCalibration::toggleCalibrationControls(bool value) { - motorMaxVelocitySpinBox->setEnabled(value); - motorAccelTimeSpinBox->setEnabled(value); - motorMaxDisplacementSpinBox->setEnabled(value); - m_calibrationMotorRampModeMenuCombo->setEnabled(value); + // motorMaxVelocitySpinBox->setEnabled(value); + // motorAccelTimeSpinBox->setEnabled(value); + // motorMaxDisplacementSpinBox->setEnabled(value); + // m_calibrationMotorRampModeMenuCombo->setEnabled(value); motorTargetPositionLineEdit->setEnabled(value); + calibrationModeMenuCombo->setEnabled(value); } void HarmonicCalibration::clearCalibrationSamples() @@ -2989,6 +3433,12 @@ bool HarmonicCalibration::moveMotorToPosition(double& position, bool validate) return success; } +void HarmonicCalibration::moveMotorContinuous() +{ + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + setRampMode(isMotorRotationClockwise); +} + bool HarmonicCalibration::resetCurrentPositionToZero() { bool success = false; @@ -3042,14 +3492,42 @@ int HarmonicCalibration::writeMotorAttributeValue(ADMTController::MotorAttribute } return result; } + +int HarmonicCalibration::readMotorRegisterValue(uint32_t address, uint32_t *value) +{ + int result = -1; + result = m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::TMC5240), + address, + value); + return result; +} + +void HarmonicCalibration::setRampMode(bool motorRotationClockwise) +{ + // Ramp Mode 1: Clockwise, Ramp Mode 2: Counter-Clockwise + isMotorRotationClockwise = motorRotationClockwise; + int mode = isMotorRotationClockwise ? 1 : 2; + writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, mode); +} + +void HarmonicCalibration::getRampMode() +{ + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + // Ramp Mode 1: Counter-Clockwise, Ramp Mode 2: Clockwise + if(ramp_mode == 1) isMotorRotationClockwise = false; + else if(ramp_mode == 2) isMotorRotationClockwise = true; +} #pragma endregion #pragma region Utility Methods void HarmonicCalibration::startUtilityTask() { - isUtilityTab = true; - m_utilityThread = QtConcurrent::run(this, &HarmonicCalibration::utilityTask, utilityUITimerRate); - m_utilityWatcher.setFuture(m_utilityThread); + if(!m_utilityThread.isRunning()) + { + isUtilityTab = true; + m_utilityThread = QtConcurrent::run(this, &HarmonicCalibration::utilityTask, utilityUITimerRate); + m_utilityWatcher.setFuture(m_utilityThread); + } } void HarmonicCalibration::stopUtilityTask() @@ -3099,10 +3577,14 @@ void HarmonicCalibration::getDIGIOENRegister(){ uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN); if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), digioRegisterAddress, digioRegValue) != -1){ + uint16_t *digioRegValue16 = new uint16_t; + *digioRegValue16 = static_cast(*digioRegValue); + + Q_EMIT DIGIORegisterChanged(digioRegValue16); - Q_EMIT DIGIORegisterChanged(digioRegValue); + Q_EMIT commandLogWriteSignal("DIGIOEN: 0b" + QString::number(*digioRegValue, 2).rightJustified(16, '0')); - Q_EMIT commandLogWriteSignal("DIGIOEN: 0b" + QString::number(static_cast(*digioRegValue), 2).rightJustified(16, '0')); + delete digioRegValue16; } else{ Q_EMIT commandLogWriteSignal("Failed to read DIGIOEN Register"); } } @@ -3110,9 +3592,9 @@ void HarmonicCalibration::getDIGIOENRegister(){ delete digioRegValue; } -void HarmonicCalibration::updateDIGIOUI(uint32_t *registerValue) +void HarmonicCalibration::updateDIGIOUI(uint16_t *registerValue) { - DIGIOENRegisterMap = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*registerValue)); + DIGIOENRegisterMap = m_admtController->getDIGIOENRegisterBitMapping(*registerValue); updateDIGIOMonitorUI(); updateDIGIOControlUI(); } @@ -3120,62 +3602,45 @@ void HarmonicCalibration::updateDIGIOUI(uint32_t *registerValue) void HarmonicCalibration::updateDIGIOMonitorUI() { map registerMap = DIGIOENRegisterMap; - if(!registerMap.at("BUSY")){ - changeStatusLEDColor(DIGIOBusyStatusLED, json::theme::content_success); - DIGIOBusyStatusLED->setText("BUSY (Output)"); - } + DIGIOBusyStatusLED->setChecked(registerMap.at("BUSY")); + DIGIOCNVStatusLED->setChecked(registerMap.at("CNV")); + DIGIOSENTStatusLED->setChecked(registerMap.at("SENT")); + DIGIOACALCStatusLED->setChecked(registerMap.at("ACALC")); + DIGIOFaultStatusLED->setChecked(registerMap.at("FAULT")); + DIGIOBootloaderStatusLED->setChecked(registerMap.at("BOOTLOAD")); + + if(!registerMap.at("BUSY")) DIGIOBusyStatusLED->setText("BUSY (Output)"); else{ - changeStatusLEDColor(DIGIOBusyStatusLED, json::theme::interactive_primary_idle); if(registerMap.at("DIGIO0EN")) DIGIOBusyStatusLED->setText("GPIO0 (Output)"); else DIGIOBusyStatusLED->setText("GPIO0 (Input)"); } - if(!registerMap.at("CNV")){ - changeStatusLEDColor(DIGIOCNVStatusLED, json::theme::content_success); - DIGIOCNVStatusLED->setText("CNV (Input)"); - } + if(!registerMap.at("CNV")) DIGIOCNVStatusLED->setText("CNV (Input)"); else{ - changeStatusLEDColor(DIGIOCNVStatusLED, json::theme::interactive_primary_idle); if(registerMap.at("DIGIO1EN")) DIGIOCNVStatusLED->setText("GPIO1 (Output)"); else DIGIOCNVStatusLED->setText("GPIO1 (Input)"); } - if(!registerMap.at("SENT")){ - changeStatusLEDColor(DIGIOSENTStatusLED, json::theme::content_success); - DIGIOSENTStatusLED->setText("SENT (Output)"); - } + if(!registerMap.at("SENT")) DIGIOSENTStatusLED->setText("SENT (Output)"); else{ - changeStatusLEDColor(DIGIOSENTStatusLED, json::theme::interactive_primary_idle); if(registerMap.at("DIGIO2EN")) DIGIOSENTStatusLED->setText("GPIO2 (Output)"); else DIGIOSENTStatusLED->setText("GPIO2 (Input)"); } - if(!registerMap.at("ACALC")){ - changeStatusLEDColor(DIGIOACALCStatusLED, json::theme::content_success); - DIGIOACALCStatusLED->setText("ACALC (Output)"); - } + if(!registerMap.at("ACALC")) DIGIOACALCStatusLED->setText("ACALC (Output)"); else{ - changeStatusLEDColor(DIGIOACALCStatusLED, json::theme::interactive_primary_idle); if(registerMap.at("DIGIO3EN")) DIGIOACALCStatusLED->setText("GPIO3 (Output)"); else DIGIOACALCStatusLED->setText("GPIO3 (Input)"); } - if(!registerMap.at("FAULT")){ - changeStatusLEDColor(DIGIOFaultStatusLED, json::theme::content_success); - DIGIOFaultStatusLED->setText("FAULT (Output)"); - } + if(!registerMap.at("FAULT")) DIGIOFaultStatusLED->setText("FAULT (Output)"); else{ - changeStatusLEDColor(DIGIOFaultStatusLED, json::theme::interactive_primary_idle); if(registerMap.at("DIGIO4EN")) DIGIOFaultStatusLED->setText("GPIO4 (Output)"); else DIGIOFaultStatusLED->setText("GPIO4 (Input)"); } - if(!registerMap.at("BOOTLOAD")){ - changeStatusLEDColor(DIGIOBootloaderStatusLED, json::theme::content_success); - DIGIOBootloaderStatusLED->setText("BOOTLOAD (Output)"); - } + if(!registerMap.at("BOOTLOAD")) DIGIOBootloaderStatusLED->setText("BOOTLOAD (Output)"); else{ - changeStatusLEDColor(DIGIOBootloaderStatusLED, json::theme::interactive_primary_idle); if(registerMap.at("DIGIO5EN")) DIGIOBootloaderStatusLED->setText("GPIO5 (Output)"); else DIGIOBootloaderStatusLED->setText("GPIO5 (Input)"); } @@ -3202,21 +3667,22 @@ void HarmonicCalibration::updateDIGIOControlUI() void HarmonicCalibration::getDIAG2Register(){ uint32_t *mtDiag2RegValue = new uint32_t; uint32_t *cnvPageRegValue = new uint32_t; - uint32_t mtDiag2RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG2); - uint32_t mtDiag2PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2); - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag2PageValue) != -1){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ if(*cnvPageRegValue == mtDiag2PageValue){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag2RegisterAddress, mtDiag2RegValue) != -1){ - - Q_EMIT DIAG2RegisterChanged(mtDiag2RegValue); + uint16_t *mtDiag2RegValue16 = new uint16_t; + *mtDiag2RegValue16 = static_cast(*mtDiag2RegValue); - Q_EMIT commandLogWriteSignal("DIAG2: 0b" + QString::number(static_cast(*mtDiag2RegValue), 2).rightJustified(16, '0')); + Q_EMIT DIAG2RegisterChanged(mtDiag2RegValue16); + + Q_EMIT commandLogWriteSignal("DIAG2: 0b" + QString::number(*mtDiag2RegValue, 2).rightJustified(16, '0')); + + delete mtDiag2RegValue16; } else{ Q_EMIT commandLogWriteSignal("Failed to read MT Diagnostic 2 Register"); } } @@ -3226,13 +3692,12 @@ void HarmonicCalibration::getDIAG2Register(){ } else{ Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 2"); } - delete mtDiag2RegValue; - delete cnvPageRegValue; + delete mtDiag2RegValue, cnvPageRegValue; } -void HarmonicCalibration::updateMTDiagnosticsUI(uint32_t *registerValue) +void HarmonicCalibration::updateMTDiagnosticsUI(uint16_t *registerValue) { - DIAG2RegisterMap = m_admtController->getDiag2RegisterBitMapping(static_cast(*registerValue)); + DIAG2RegisterMap = m_admtController->getDiag2RegisterBitMapping(*registerValue); map regmap = DIAG2RegisterMap; afeDiag0 = regmap.at("AFE Diagnostic 0 (-57%)"); @@ -3252,10 +3717,13 @@ void HarmonicCalibration::getDIAG1Register(){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ if(*cnvPageRegValue == mtDiag1PageValue){ if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1){ - - Q_EMIT DIAG1RegisterChanged(mtDiag1RegValue); + uint16_t *mtDiag1RegValue16 = new uint16_t; + *mtDiag1RegValue16 = static_cast(*mtDiag1RegValue); + Q_EMIT DIAG1RegisterChanged(mtDiag1RegValue16); + + Q_EMIT commandLogWriteSignal("DIAG1: 0b" + QString::number(*mtDiag1RegValue16, 2).rightJustified(16, '0')); - Q_EMIT commandLogWriteSignal("DIAG1: 0b" + QString::number(static_cast(*mtDiag1RegValue), 2).rightJustified(16, '0')); + delete mtDiag1RegValue16; } else{ Q_EMIT commandLogWriteSignal("Failed to read MT Diagnostic 1 Register"); } } @@ -3265,25 +3733,24 @@ void HarmonicCalibration::getDIAG1Register(){ } else{ Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 1"); } - delete mtDiag1RegValue; - delete cnvPageRegValue; + delete mtDiag1RegValue, cnvPageRegValue; } -void HarmonicCalibration::updateMTDiagnosticRegisterUI(uint32_t *registerValue) +void HarmonicCalibration::updateMTDiagnosticRegisterUI(uint16_t *registerValue) { - DIAG1RegisterMap = m_admtController->getDiag1RegisterBitMapping_Register(static_cast(*registerValue)); - DIAG1AFERegisterMap = m_admtController->getDiag1RegisterBitMapping_Afe(static_cast(*registerValue), is5V); + DIAG1RegisterMap = m_admtController->getDiag1RegisterBitMapping_Register(*registerValue); + DIAG1AFERegisterMap = m_admtController->getDiag1RegisterBitMapping_Afe(*registerValue, is5V); map regmap = DIAG1RegisterMap; map afeRegmap = DIAG1AFERegisterMap; - toggleStatusLEDColor(R0StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R0")); - toggleStatusLEDColor(R1StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R1")); - toggleStatusLEDColor(R2StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R2")); - toggleStatusLEDColor(R3StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R3")); - toggleStatusLEDColor(R4StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R4")); - toggleStatusLEDColor(R5StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R5")); - toggleStatusLEDColor(R6StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R6")); - toggleStatusLEDColor(R7StatusLED, json::theme::content_success, json::theme::background_primary, DIAG1RegisterMap.at("R7")); + R0StatusLED->setChecked(regmap.at("R0")); + R1StatusLED->setChecked(regmap.at("R1")); + R2StatusLED->setChecked(regmap.at("R2")); + R3StatusLED->setChecked(regmap.at("R3")); + R4StatusLED->setChecked(regmap.at("R4")); + R5StatusLED->setChecked(regmap.at("R5")); + R6StatusLED->setChecked(regmap.at("R6")); + R7StatusLED->setChecked(regmap.at("R7")); afeDiag2 = afeRegmap.at("AFE Diagnostic 2"); AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); } @@ -3292,38 +3759,42 @@ void HarmonicCalibration::getFAULTRegister(){ uint32_t *faultRegValue = new uint32_t; uint32_t faultRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT); m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, 0); // Write all zeros to fault before read - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, faultRegValue); - if(*faultRegValue != -1){ - Q_EMIT FaultRegisterChanged(faultRegValue); + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, faultRegValue) != -1){ + uint16_t *faultRegValue16 = new uint16_t; + *faultRegValue16 = static_cast(*faultRegValue); - Q_EMIT commandLogWriteSignal("FAULT: 0b" + QString::number(static_cast(*faultRegValue), 2).rightJustified(16, '0')); + Q_EMIT FaultRegisterChanged(faultRegValue16); + + Q_EMIT commandLogWriteSignal("FAULT: 0b" + QString::number(*faultRegValue, 2).rightJustified(16, '0')); + + delete faultRegValue16; } else{ Q_EMIT commandLogWriteSignal("Failed to read FAULT Register"); } delete faultRegValue; } -void HarmonicCalibration::updateFaultRegisterUI(uint32_t *faultRegValue) +void HarmonicCalibration::updateFaultRegisterUI(uint16_t *faultRegValue) { - FAULTRegisterMap = m_admtController->getFaultRegisterBitMapping(static_cast(*faultRegValue)); + FAULTRegisterMap = m_admtController->getFaultRegisterBitMapping(*faultRegValue); map regmap = FAULTRegisterMap; - toggleStatusLEDColor(VDDUnderVoltageStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("VDD Under Voltage")); - toggleStatusLEDColor(VDDOverVoltageStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("VDD Over Voltage")); - toggleStatusLEDColor(VDRIVEUnderVoltageStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("VDRIVE Under Voltage")); - toggleStatusLEDColor(VDRIVEOverVoltageStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("VDRIVE Over Voltage")); - toggleStatusLEDColor(AFEDIAGStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("AFE Diagnostic")); - toggleStatusLEDColor(NVMCRCFaultStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("NVM CRC Fault")); - toggleStatusLEDColor(ECCDoubleBitErrorStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("ECC Double Bit Error")); - toggleStatusLEDColor(OscillatorDriftStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Oscillator Drift")); - toggleStatusLEDColor(CountSensorFalseStateStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Count Sensor False State")); - toggleStatusLEDColor(AngleCrossCheckStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Angle Cross Check")); - toggleStatusLEDColor(TurnCountSensorLevelsStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Turn Count Sensor Levels")); - toggleStatusLEDColor(MTDIAGStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("MT Diagnostic")); - toggleStatusLEDColor(TurnCounterCrossCheckStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Turn Counter Cross Check")); - toggleStatusLEDColor(RadiusCheckStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("AMR Radius Check")); - toggleStatusLEDColor(SequencerWatchdogStatusLED, json::theme::content_error, json::theme::background_primary, regmap.at("Sequencer Watchdog")); + VDDUnderVoltageStatusLED->setChecked(regmap.at("VDD Under Voltage")); + VDDOverVoltageStatusLED->setChecked(regmap.at("VDD Over Voltage")); + VDRIVEUnderVoltageStatusLED->setChecked(regmap.at("VDRIVE Under Voltage")); + VDRIVEOverVoltageStatusLED->setChecked(regmap.at("VDRIVE Over Voltage")); + AFEDIAGStatusLED->setChecked(regmap.at("AFE Diagnostic")); + NVMCRCFaultStatusLED->setChecked(regmap.at("NVM CRC Fault")); + ECCDoubleBitErrorStatusLED->setChecked(regmap.at("ECC Double Bit Error")); + OscillatorDriftStatusLED->setChecked(regmap.at("Oscillator Drift")); + CountSensorFalseStateStatusLED->setChecked(regmap.at("Count Sensor False State")); + AngleCrossCheckStatusLED->setChecked(regmap.at("Angle Cross Check")); + TurnCountSensorLevelsStatusLED->setChecked(regmap.at("Turn Count Sensor Levels")); + MTDIAGStatusLED->setChecked(regmap.at("MT Diagnostic")); + TurnCounterCrossCheckStatusLED->setChecked(regmap.at("Turn Counter Cross Check")); + RadiusCheckStatusLED->setChecked(regmap.at("AMR Radius Check")); + SequencerWatchdogStatusLED->setChecked(regmap.at("Sequencer Watchdog")); } void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) @@ -3449,7 +3920,7 @@ void HarmonicCalibration::readAllRegisters() h8MagRegisterBlock->readButton()->click(); h8PhRegisterBlock->readButton()->click(); - if(generalRegisterMap.at("Sequence Type") == 1){ + if(GENERALRegisterMap.at("Sequence Type") == 1){ angleSecRegisterBlock->readButton()->click(); secAnglIRegisterBlock->readButton()->click(); secAnglQRegisterBlock->readButton()->click(); @@ -3576,57 +4047,10 @@ void HarmonicCalibration::changeCustomSwitchLabel(CustomSwitch *customSwitch, QS customSwitch->setOffText(offLabel); } -void HarmonicCalibration::changeStatusLEDColor(MenuControlButton *menuControlButton, QColor color, bool checked) -{ - menuControlButton->setColor(color); - menuControlButton->checkBox()->setChecked(checked); -} - -void HarmonicCalibration::changeStatusLEDColor(QCheckBox *widget, const char *colorAttribute) -{ - Style::setStyle(widget, style::properties::admt::checkBoxLED, true, true); - QString style = QString(R"css( - QCheckBox::indicator:checked { - background-color: &&LEDColor&&; - } - )css"); - style.replace("&&LEDColor&&", Style::getAttribute(colorAttribute)); - widget->setStyleSheet(widget->styleSheet() + "\n" + style); - widget->update(); -} - -void HarmonicCalibration::updateFaultStatusLEDColor(MenuControlButton *widget, bool value) -{ - if(value) changeStatusLEDColor(widget, faultLEDColor); - else changeStatusLEDColor(widget, statusLEDColor); -} - -void HarmonicCalibration::toggleStatusLEDColor(QCheckBox *widget, const char *trueAttribute, const char* falseAttribute, bool value) -{ - if(value) changeStatusLEDColor(widget, trueAttribute); - else changeStatusLEDColor(widget, falseAttribute); -} - -MenuControlButton *HarmonicCalibration::createStatusLEDWidget(const QString title, QColor color, QWidget *parent) -{ - MenuControlButton *menuControlButton = new MenuControlButton(parent); - menuControlButton->setName(title); - menuControlButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); - menuControlButton->setOpenMenuChecksThis(true); - menuControlButton->setDoubleClickToOpenMenu(true); - menuControlButton->setColor(color); - menuControlButton->button()->setVisible(false); - menuControlButton->setCheckable(true); - menuControlButton->checkBox()->setChecked(false); - menuControlButton->setEnabled(false); - menuControlButton->layout()->setMargin(8); - return menuControlButton; -} - -QCheckBox *HarmonicCalibration::createStatusLEDWidget(const QString &text, const char *colorAttribute, bool checked, QWidget *parent) +QCheckBox *HarmonicCalibration::createStatusLEDWidget(const QString &text, QVariant variant, bool checked, QWidget *parent) { QCheckBox *checkBox = new QCheckBox(text, parent); - Style::setStyle(checkBox, style::properties::admt::checkBoxLED, true, true); + Style::setStyle(checkBox, style::properties::admt::checkBoxLED, variant, true); checkBox->setChecked(checked); checkBox->setEnabled(false); return checkBox; @@ -3680,13 +4104,16 @@ void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& v void HarmonicCalibration::connectLineEditToDouble(QLineEdit* lineEdit, double& variable) { + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + lineEdit->setValidator(validator); connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { bool ok; double value = lineEdit->text().toDouble(&ok); if (ok){ variable = value; } else { - lineEdit->setText(QString::number(variable, 'f', 2)); + lineEdit->setText(QString::number(variable)); } }); } @@ -3734,8 +4161,10 @@ void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit* lineEdit, do vmax = convertRPStoVMAX(rps); writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, vmax); writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - amax = convertAccelTimetoAMAX(motorAccelTimeSpinBox->lineEdit()->text().toDouble()); + amax = convertAccelTimetoAMAX(motorAccelTime); writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + // StatusBarManager::pushMessage("Applied VMAX: " + QString::number(vmax)); + // StatusBarManager::pushMessage("Applied AMAX: " + QString::number(amax)); } else { lineEdit->setText(QString::number(convertVMAXtoRPS(vmax))); } @@ -3749,6 +4178,7 @@ void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit* lineEdit, d double accelTime = lineEdit->text().toDouble(&ok); if (ok) { amax = convertAccelTimetoAMAX(accelTime); + // StatusBarManager::pushMessage("Applied AMAX: " + QString::number(amax)); } else { lineEdit->setText(QString::number(convertAMAXtoAccelTime(amax))); } @@ -3799,6 +4229,27 @@ void HarmonicCalibration::connectRegisterBlockToRegistry(RegisterBlockWidget* wi }); } } + +void HarmonicCalibration::connectLineEditToRPM(QLineEdit* lineEdit, double& variable) +{ + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, this, [=, &variable]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok){ + variable = value; + rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(variable)); + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + amax = convertAccelTimetoAMAX(motorAccelTime); + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} #pragma endregion #pragma region Convert Methods @@ -3814,12 +4265,22 @@ double HarmonicCalibration::convertVMAXtoRPS(double vmax) double HarmonicCalibration::convertAccelTimetoAMAX(double accelTime) { - return (rotate_vmax * 131072 / accelTime / motorfCLK); + return (rotate_vmax * static_cast(1 << 17) / accelTime / motorfCLK); // 1 << 17 = 2^17 = 131072 } double HarmonicCalibration::convertAMAXtoAccelTime(double amax) { - return ((rotate_vmax * 131072) / (amax * motorfCLK)); + return ((rotate_vmax * static_cast(1 << 17)) / (amax * motorfCLK)); // 1 << 17 = 2^17 = 131072 +} + +double HarmonicCalibration::convertRPMtoRPS(double rpm) +{ + return (rpm / 60); +} + +double HarmonicCalibration::convertRPStoRPM(double rps) +{ + return (rps * 60); } #pragma endregion diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp index e3b3d55d2f..37701b87d0 100644 --- a/plugins/admt/src/widgets/registerblockwidget.cpp +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -38,11 +38,11 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui container->setMargin(0); container->setSpacing(0); MenuSectionWidget *menuSectionWidget = new MenuSectionWidget(this); - MenuCollapseSection *menuCollapseSection = new MenuCollapseSection(header, MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, menuSectionWidget); - menuCollapseSection->contentLayout()->setSpacing(10); + Style::setStyle(menuSectionWidget, style::properties::widget::basicComponent); + QLabel *headerLabel = new QLabel(header, menuSectionWidget); + Style::setStyle(headerLabel, style::properties::label::menuMedium); menuSectionWidget->setFixedHeight(180); - menuSectionWidget->contentLayout()->setSpacing(10); - menuSectionWidget->contentLayout()->addWidget(menuCollapseSection); + menuSectionWidget->contentLayout()->setSpacing(Style::getDimension(json::global::unit_0_5)); QLabel *descriptionLabel = new QLabel(description, menuSectionWidget); descriptionLabel->setWordWrap(true); @@ -62,7 +62,7 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui buttonsWidget->setLayout(buttonsContainer); buttonsContainer->setMargin(0); - buttonsContainer->setSpacing(10); + buttonsContainer->setSpacing(Style::getDimension(json::global::unit_0_5)); switch(m_accessPermission) { case ACCESS_PERMISSION::READWRITE: @@ -78,10 +78,10 @@ RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, ui break; } - menuCollapseSection->contentLayout()->setSpacing(10); - menuCollapseSection->contentLayout()->addWidget(descriptionLabel); - menuCollapseSection->contentLayout()->addWidget(m_spinBox); - menuCollapseSection->contentLayout()->addWidget(buttonsWidget); + menuSectionWidget->contentLayout()->addWidget(headerLabel); + menuSectionWidget->contentLayout()->addWidget(descriptionLabel); + menuSectionWidget->contentLayout()->addWidget(m_spinBox); + menuSectionWidget->contentLayout()->addWidget(buttonsWidget); container->addWidget(menuSectionWidget); container->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Preferred)); @@ -110,7 +110,7 @@ RegisterBlockWidget::ACCESS_PERMISSION RegisterBlockWidget::getAccessPermission( void RegisterBlockWidget::addReadButton(QWidget *parent) { m_readButton = new QPushButton("Read", parent); - StyleHelper::BasicButton(m_readButton); + Style::setStyle(m_readButton, style::properties::button::basicButton); parent->layout()->addWidget(m_readButton); } @@ -119,50 +119,12 @@ QPushButton *RegisterBlockWidget::readButton() { return m_readButton; } void RegisterBlockWidget::addWriteButton(QWidget *parent) { m_writeButton = new QPushButton("Write", parent); - StyleHelper::BasicButton(m_writeButton); + Style::setStyle(m_writeButton, style::properties::button::basicButton); parent->layout()->addWidget(m_writeButton); } QPushButton *RegisterBlockWidget::writeButton() { return m_writeButton; } -void RegisterBlockWidget::applyLineEditStyle(QLineEdit *widget) -{ - QString style = QString(R"css( - background-color: black; - font-family: Open Sans; - font-size: 16px; - color: &&colorname&&; - border: none; - border-radius: 4px; - qproperty-frame: false; - )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setAlignment(Qt::AlignRight); - widget->setContentsMargins(0, 0, 0, 0); - widget->setTextMargins(6, 4, 6, 4); -} - -void RegisterBlockWidget::applySpinBoxStyle(QSpinBox *widget) -{ - QString style = QString(R"css( - background-color: black; - font-family: Open Sans; - font-size: 16px; - color: &&colorname&&; - border: none; - border-radius: 4px; - font-weight: normal; - )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setAlignment(Qt::AlignRight); - widget->setContentsMargins(12, 4, 12, 4); - widget->setButtonSymbols(widget->ButtonSymbols::NoButtons); -} - PaddedSpinBox::PaddedSpinBox(QWidget *parent) : QSpinBox(parent) { diff --git a/plugins/admt/style/qss/properties/admt/checkBoxLED.qss b/plugins/admt/style/qss/properties/admt/checkBoxLED.qss index c79e2d6418..6dbdcbdb91 100644 --- a/plugins/admt/style/qss/properties/admt/checkBoxLED.qss +++ b/plugins/admt/style/qss/properties/admt/checkBoxLED.qss @@ -1,10 +1,46 @@ -QCheckBox[&&property&&=true] { +QCheckBox[&&property&&="status"] { width: &unit_1&; height: &unit_1&; background-color: transparent; color: &content_default&; } -QCheckBox::indicator[&&property&&=true] { +QCheckBox::indicator[&&property&&="status"] { + width: 12px; + height: 12px; + border: 1px solid &content_default&; + border-radius: 7px; + image: none; + background-color: &content_success&; +} +QCheckBox::indicator[&&property&&="status"]:checked { + background-color: &content_error&; +} + +QCheckBox[&&property&&="digio"] { + width: &unit_1&; + height: &unit_1&; + background-color: transparent; + color: &content_default&; +} +QCheckBox::indicator[&&property&&="digio"] { + width: 12px; + height: 12px; + border: 1px solid &content_default&; + border-radius: 7px; + image: none; + background-color: &content_success&; +} +QCheckBox::indicator[&&property&&="digio"]:checked { + background-color: &interactive_primary_idle&; +} + +QCheckBox[&&property&&="fault"] { + width: &unit_1&; + height: &unit_1&; + background-color: transparent; + color: &content_default&; +} +QCheckBox::indicator[&&property&&="fault"] { width: 12px; height: 12px; border: 1px solid &content_default&; @@ -12,9 +48,24 @@ QCheckBox::indicator[&&property&&=true] { image: none; background-color: &background_primary&; } -QCheckBox::indicator:checked { +QCheckBox::indicator[&&property&&="fault"]:checked { + background-color: &content_error&; +} + +QCheckBox[&&property&&="mtdiag"] { + width: &unit_1&; + height: &unit_1&; + background-color: transparent; + color: &content_default&; +} +QCheckBox::indicator[&&property&&="mtdiag"] { + width: 12px; + height: 12px; + border: 1px solid &content_default&; + border-radius: 7px; + image: none; background-color: &background_primary&; } -QCheckBox::indicator[&&property&&=true]::unchecked { - background-color: &background_primary&; -} \ No newline at end of file +QCheckBox::indicator[&&property&&="mtdiag"]:checked { + background-color: &content_success&; +} diff --git a/plugins/admt/style/qss/properties/admt/fullWidthRunButton.qss b/plugins/admt/style/qss/properties/admt/fullWidthRunButton.qss new file mode 100644 index 0000000000..59275f2b47 --- /dev/null +++ b/plugins/admt/style/qss/properties/admt/fullWidthRunButton.qss @@ -0,0 +1,24 @@ +QPushButton[&&property&&=true] { + min-height: &unit_2&; + max-height: &unit_2&; + border-radius: &radius_1&; + text-align: center; + color: &content_inverse&; + background-color: &run_button_color&; +} + +QPushButton[&&property&&=true]:pressed { + background-color: &interactive_accent_pressed&; +} + +QPushButton[&&property&&=true]:hover { + background-color: &interactive_primary_hover&; +} + +QPushButton[&&property&&=true]:checked { + background-color: &interactive_accent_pressed&; +} + +QPushButton[&&property&&=true]:disabled { + background-color: &interactive_subtle_disabled&; +} \ No newline at end of file diff --git a/plugins/admt/style/qss/properties/admt/tabBar.qss b/plugins/admt/style/qss/properties/admt/tabBar.qss new file mode 100644 index 0000000000..5baf558861 --- /dev/null +++ b/plugins/admt/style/qss/properties/admt/tabBar.qss @@ -0,0 +1,39 @@ +QTabBar[&&property&&=true] { + font-size: &font_size_1&; + font-weight: 600; +} + +QTabBar[&&property&&=true]::tab { + height: 48px; + background-color: transparent; + border-top-left-radius: &radius_1&; + border-top-right-radius: &radius_1&; + padding: 0; +} + +QTabBar[&&property&&=true]::tab QLabel { + background-color: transparent; + color: &content_default&; + padding: 0; + margin: 0; +} + +QTabBar[&&property&&=true]::tab:hover { + background-color: &interactive_silent_hover&; + color: &content_default&; + border-bottom: 1px solid &interactive_subtle_hover&; +} + +QTabBar[&&property&&=true]::tab:selected { + background-color: &background_primary&; + color: &interactive_primary_idle&; + border-bottom: 2px solid &interactive_primary_idle&; +} + +QTabBar[&&property&&=true]::tab:selected:hover { + background-color: &interactive_primary_faint&; +} + +QTabBar[&&property&&=true]::tab:disabled { + color: &interactive_subtle_idle&; +} \ No newline at end of file diff --git a/plugins/admt/style/qss/properties/admt/tabWidget.qss b/plugins/admt/style/qss/properties/admt/tabWidget.qss new file mode 100644 index 0000000000..e33d2e1b4a --- /dev/null +++ b/plugins/admt/style/qss/properties/admt/tabWidget.qss @@ -0,0 +1,3 @@ +QTabWidget[&&property&&=true]::pane { + border-top: 1px solid &interactive_silent_hover&; +} \ No newline at end of file From d0d7de45dc95da30489a604b3ccacd1073066116 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 26 Feb 2025 09:39:30 +0800 Subject: [PATCH 089/112] admt: Removed unused libraries in CMakeLists - Removed UI_LIST uses Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/CMakeLists.txt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/admt/CMakeLists.txt b/plugins/admt/CMakeLists.txt index b6fbb65d14..4aec741ab0 100644 --- a/plugins/admt/CMakeLists.txt +++ b/plugins/admt/CMakeLists.txt @@ -59,15 +59,14 @@ file( include/${SCOPY_MODULE}/*.h include/${SCOPY_MODULE}/*.hpp include/${SCOPY_MODULE}/widgets/*.h -) -file(GLOB UI_LIST ui/*.ui) +) set(ENABLE_TESTING ON) if(ENABLE_TESTING) add_subdirectory(test) endif() -set(PROJECT_SOURCES ${SRC_LIST} ${HEADER_LIST} ${UI_LIST}) +set(PROJECT_SOURCES ${SRC_LIST} ${HEADER_LIST}) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS REQUIRED Widgets Core) qt_add_resources(PROJECT_RESOURCES res/resources.qrc) @@ -96,9 +95,7 @@ target_link_libraries( Qt::Core scopy-pluginbase scopy-gui - scopy-iioutil - scopy-gr-util - scopy-iio-widgets + scopy-iioutil ) if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") From dce09f3b70895cdb57b52a30e59f57bf189426dc Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 27 Feb 2025 12:52:37 +0800 Subject: [PATCH 090/112] admt: Format C++ and CMakeLists Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/CMakeLists.txt | 91 +- plugins/admt/include/admt/admtcontroller.h | 451 +- plugins/admt/include/admt/admtplugin.h | 35 +- plugins/admt/include/admt/admtstylehelper.h | 72 +- .../admt/include/admt/harmoniccalibration.h | 753 +- .../include/admt/widgets/horizontalspinbox.h | 61 +- .../admt/widgets/registerblockwidget.h | 81 +- plugins/admt/src/admtcontroller.cpp | 3185 +++--- plugins/admt/src/admtplugin.cpp | 205 +- plugins/admt/src/admtstylehelper.cpp | 298 +- plugins/admt/src/harmoniccalibration.cpp | 9303 +++++++++-------- .../admt/src/widgets/horizontalspinbox.cpp | 266 +- .../admt/src/widgets/registerblockwidget.cpp | 178 +- plugins/admt/test/CMakeLists.txt | 2 +- plugins/admt/test/tst_pluginloader.cpp | 122 + 15 files changed, 8264 insertions(+), 6839 deletions(-) create mode 100644 plugins/admt/test/tst_pluginloader.cpp diff --git a/plugins/admt/CMakeLists.txt b/plugins/admt/CMakeLists.txt index 4aec741ab0..ef93fc4933 100644 --- a/plugins/admt/CMakeLists.txt +++ b/plugins/admt/CMakeLists.txt @@ -24,78 +24,85 @@ set(SCOPY_MODULE admt) message(STATUS "building plugin: " ${SCOPY_MODULE}) -project(scopy-${SCOPY_MODULE} VERSION 0.1 LANGUAGES CXX) +project(scopy-${SCOPY_MODULE} VERSION 0.1 LANGUAGES CXX) set(PLUGIN_DISPLAY_NAME "ADMT") set(PLUGIN_DESCRIPTION "Plugin for ADMT Harmonic Calibration") -include(GenerateExportHeader) +include(GenerateExportHeader) # TODO: split stylesheet/resources and add here TODO: export header files correctly -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/ui) -set(CMAKE_AUTOUIC ON) -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/ui) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) -set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(CMAKE_CXX_VISIBILITY_PRESET hidden) -set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) file( - GLOB - SRC_LIST - src/*.cpp - src/*.cc - src/widgets/*.cpp -) + GLOB + SRC_LIST + src/*.cpp + src/*.cc + src/widgets/*.cpp +) file( - GLOB - HEADER_LIST - include/${SCOPY_MODULE}/*.h - include/${SCOPY_MODULE}/*.hpp - include/${SCOPY_MODULE}/widgets/*.h + GLOB + HEADER_LIST + include/${SCOPY_MODULE}/*.h + include/${SCOPY_MODULE}/*.hpp + include/${SCOPY_MODULE}/widgets/*.h ) set(ENABLE_TESTING ON) -if(ENABLE_TESTING) - add_subdirectory(test) -endif() +if(ENABLE_TESTING) + add_subdirectory(test) +endif() + +set(PROJECT_SOURCES ${SRC_LIST} ${HEADER_LIST}) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS REQUIRED Widgets Core) -set(PROJECT_SOURCES ${SRC_LIST} ${HEADER_LIST}) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS REQUIRED Widgets Core) +qt_add_resources(PROJECT_RESOURCES res/resources.qrc) -qt_add_resources(PROJECT_RESOURCES res/resources.qrc) -add_library(${PROJECT_NAME} SHARED ${PROJECT_SOURCES} ${PROJECT_RESOURCES}) +add_library(${PROJECT_NAME} SHARED ${PROJECT_SOURCES} ${PROJECT_RESOURCES}) -generate_export_header( - ${PROJECT_NAME} EXPORT_FILE_NAME ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}/${PROJECT_NAME}_export.h +generate_export_header( + ${PROJECT_NAME} EXPORT_FILE_NAME ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}/${PROJECT_NAME}_export.h ) include(ScopyStyle) generate_style("--plugin" ${CMAKE_CURRENT_SOURCE_DIR}/style ${CMAKE_CURRENT_SOURCE_DIR}/include/admt) +set(INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE} ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE} + ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE} ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}/widgets +) + configure_file( include/${SCOPY_MODULE}/scopy-${SCOPY_MODULE}_config.h.cmakein ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}/scopy-${SCOPY_MODULE}_config.h @ONLY ) -target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include) -target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/${SCOPY_MODULE}) +target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_include_directories(${PROJECT_NAME} PRIVATE ${INCLUDE_DIRECTORIES}) -target_include_directories(${PROJECT_NAME} PUBLIC scopy-pluginbase scopy-gui) +target_include_directories(${PROJECT_NAME} PUBLIC scopy-pluginbase scopy-gui) +target_include_directories(${PROJECT_NAME} PRIVATE ${IIO_INCLUDE_DIRS} scopy-gui scopy-iioutil) -target_link_libraries( - ${PROJECT_NAME} - PUBLIC Qt::Widgets - Qt::Core - scopy-pluginbase - scopy-gui - scopy-iioutil +target_link_libraries( + ${PROJECT_NAME} + PUBLIC Qt::Widgets + Qt::Core + scopy-pluginbase + scopy-gui + scopy-iioutil ) if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") @@ -103,4 +110,4 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") configureinstallersettings(${SCOPY_MODULE} ${INSTALLER_DESCRIPTION} TRUE) endif() -set(ADMT_TARGET_NAME ${PROJECT_NAME} PARENT_SCOPE) \ No newline at end of file +set(ADMT_TARGET_NAME ${PROJECT_NAME} PARENT_SCOPE) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 390d245e4b..95d0d9ba48 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -24,265 +24,278 @@ #include "scopy-admt_export.h" -#include #include +#include +#include #include #include -#include #include #include -#include #include -#include #include -#include -#include #include -#include #include +#include +#include +#include +#include +#include using namespace std; -namespace scopy::admt { -class SCOPY_ADMT_EXPORT ADMTController : public QObject -{ - Q_OBJECT +namespace scopy::admt { +class SCOPY_ADMT_EXPORT ADMTController : public QObject { + Q_OBJECT public: - ADMTController(QString uri, QObject *parent = nullptr); - ~ADMTController(); + ADMTController(QString uri, QObject *parent = nullptr); + ~ADMTController(); - int HAR_MAG_1, HAR_MAG_2, HAR_MAG_3, HAR_MAG_8 ,HAR_PHASE_1 ,HAR_PHASE_2 ,HAR_PHASE_3 ,HAR_PHASE_8, - sampleCount = 0; + int HAR_MAG_1, HAR_MAG_2, HAR_MAG_3, HAR_MAG_8, HAR_PHASE_1, HAR_PHASE_2, + HAR_PHASE_3, HAR_PHASE_8, sampleCount = 0; - bool stopStream = false; + bool stopStream = false; - double streamedValue = 0.0; - QVector streamBufferedValues; - QVector streamBufferedIntervals; + double streamedValue = 0.0; + QVector streamBufferedValues; + QVector streamBufferedIntervals; - QElapsedTimer elapsedStreamTimer; + QElapsedTimer elapsedStreamTimer; - vector angle_errors_fft_pre, - angle_errors_fft_phase_pre, - angle_errors_fft_post, - angle_errors_fft_phase_post, - calibration_samples_sine, - calibration_samples_cosine, - calibration_samples_sine_scaled, - calibration_samples_cosine_scaled, - angleError, - FFTAngleErrorMagnitude, - FFTAngleErrorPhase, - correctedError, - FFTCorrectedErrorMagnitude, - FFTCorrectedErrorPhase; + vector angle_errors_fft_pre, angle_errors_fft_phase_pre, + angle_errors_fft_post, angle_errors_fft_phase_post, + calibration_samples_sine, calibration_samples_cosine, + calibration_samples_sine_scaled, calibration_samples_cosine_scaled, + angleError, FFTAngleErrorMagnitude, FFTAngleErrorPhase, correctedError, + FFTCorrectedErrorMagnitude, FFTCorrectedErrorPhase; - enum Channel - { - ROTATION, - ANGLE, - COUNT, - TEMPERATURE, - CHANNEL_COUNT - }; + enum Channel { ROTATION, ANGLE, COUNT, TEMPERATURE, CHANNEL_COUNT }; - enum Device - { - ADMT4000, - TMC5240, - DEVICE_COUNT - }; + enum Device { ADMT4000, TMC5240, DEVICE_COUNT }; - enum DeviceAttribute - { - PAGE, - SEQUENCER_MODE, - ANGLE_FILT, - CONVERSION_MODE, - H8_CTRL, - SDP_GPIO_CTRL, - SDP_GPIO0_BUSY, - SDP_COIL_RS, - REGMAP_DUMP, - DEVICE_ATTR_COUNT - }; + enum DeviceAttribute { + PAGE, + SEQUENCER_MODE, + ANGLE_FILT, + CONVERSION_MODE, + H8_CTRL, + SDP_GPIO_CTRL, + SDP_GPIO0_BUSY, + SDP_COIL_RS, + REGMAP_DUMP, + DEVICE_ATTR_COUNT + }; - enum MotorAttribute - { - AMAX, - ROTATE_VMAX, - DMAX, - DISABLE, - TARGET_POS, - CURRENT_POS, - RAMP_MODE, - MOTOR_ATTR_COUNT - }; + enum MotorAttribute { + AMAX, + ROTATE_VMAX, + DMAX, + DISABLE, + TARGET_POS, + CURRENT_POS, + RAMP_MODE, + MOTOR_ATTR_COUNT + }; - enum MotorRampMode - { - POSITION, - RAMP_MODE_1 - }; + enum MotorRampMode { POSITION, RAMP_MODE_1 }; - enum HarmonicRegister - { - H1MAG, - H1PH, - H2MAG, - H2PH, - H3MAG, - H3PH, - H8MAG, - H8PH, - HARMONIC_REGISTER_COUNT - }; + enum HarmonicRegister { + H1MAG, + H1PH, + H2MAG, + H2PH, + H3MAG, + H3PH, + H8MAG, + H8PH, + HARMONIC_REGISTER_COUNT + }; - enum ConfigurationRegister - { - CNVPAGE, - DIGIO, - FAULT, - GENERAL, - DIGIOEN, - ANGLECK, - ECCDCDE, - ECCDIS, - CONFIGURATION_REGISTER_COUNT - }; + enum ConfigurationRegister { + CNVPAGE, + DIGIO, + FAULT, + GENERAL, + DIGIOEN, + ANGLECK, + ECCDCDE, + ECCDIS, + CONFIGURATION_REGISTER_COUNT + }; - enum SensorRegister - { - ABSANGLE, - ANGLEREG, - ANGLESEC, - SINE, - COSINE, - SECANGLI, - SECANGLQ, - RADIUS, - DIAG1, - DIAG2, - TMP0, - TMP1, - CNVCNT, - SENSOR_REGISTER_COUNT - }; + enum SensorRegister { + ABSANGLE, + ANGLEREG, + ANGLESEC, + SINE, + COSINE, + SECANGLI, + SECANGLQ, + RADIUS, + DIAG1, + DIAG2, + TMP0, + TMP1, + CNVCNT, + SENSOR_REGISTER_COUNT + }; - enum UniqueIDRegister - { - UNIQID0, - UNIQID1, - UNIQID2, - UNIQID3, - UNIQID_REGISTER_COUNT - }; + enum UniqueIDRegister { + UNIQID0, + UNIQID1, + UNIQID2, + UNIQID3, + UNIQID_REGISTER_COUNT + }; - enum RampGeneratorDriverFeatureControlRegister - { - VDCMIN, - SW_MODE, - RAMP_STAT, - XLATCH, - RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT - }; + enum RampGeneratorDriverFeatureControlRegister { + VDCMIN, + SW_MODE, + RAMP_STAT, + XLATCH, + RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT + }; - const char* ChannelIds[CHANNEL_COUNT] = { "rot", "angl", "count", "temp" }; - const char* DeviceIds[DEVICE_COUNT] = { "admt4000", "tmc5240" }; - const char* DeviceAttributes[DEVICE_ATTR_COUNT] = { "page", "sequencer_mode", "angle_filt", "conversion_mode", "h8_ctrl", "sdp_gpio_ctrl", "sdp_gpio0_busy", "sdp_coil_rs", "regmap_dump" }; - const char* MotorAttributes[MOTOR_ATTR_COUNT] = { "amax", "rotate_vmax", "dmax", - "disable", "target_pos", "current_pos", - "ramp_mode" }; - const uint32_t ConfigurationRegisters[CONFIGURATION_REGISTER_COUNT] = { 0x01, 0x04, 0x06, 0x10, 0x12, 0x13, 0x1D, 0x23 }; - const uint32_t ConfigurationPages[CONFIGURATION_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x02, 0x02, 0x02, 0x02, 0x02 }; - const uint32_t UniqueIdRegisters[UNIQID_REGISTER_COUNT] = { 0x1E, 0x1F, 0x20, 0x21 }; - const uint32_t UniqueIdPages[UNIQID_REGISTER_COUNT] = { 0x02, 0x02, 0x02, 0x02 }; - const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = { 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C }; - const uint32_t HarmonicPages[HARMONIC_REGISTER_COUNT] = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }; - const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = { 0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14 }; - const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = { UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }; + const char *ChannelIds[CHANNEL_COUNT] = {"rot", "angl", "count", "temp"}; + const char *DeviceIds[DEVICE_COUNT] = {"admt4000", "tmc5240"}; + const char *DeviceAttributes[DEVICE_ATTR_COUNT] = { + "page", "sequencer_mode", "angle_filt", "conversion_mode", + "h8_ctrl", "sdp_gpio_ctrl", "sdp_gpio0_busy", "sdp_coil_rs", + "regmap_dump"}; + const char *MotorAttributes[MOTOR_ATTR_COUNT] = { + "amax", "rotate_vmax", "dmax", "disable", + "target_pos", "current_pos", "ramp_mode"}; + const uint32_t ConfigurationRegisters[CONFIGURATION_REGISTER_COUNT] = { + 0x01, 0x04, 0x06, 0x10, 0x12, 0x13, 0x1D, 0x23}; + const uint32_t ConfigurationPages[CONFIGURATION_REGISTER_COUNT] = { + UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x02, 0x02, 0x02, 0x02, 0x02}; + const uint32_t UniqueIdRegisters[UNIQID_REGISTER_COUNT] = {0x1E, 0x1F, 0x20, + 0x21}; + const uint32_t UniqueIdPages[UNIQID_REGISTER_COUNT] = {0x02, 0x02, 0x02, + 0x02}; + const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = { + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C}; + const uint32_t HarmonicPages[HARMONIC_REGISTER_COUNT] = { + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}; + const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = { + 0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, + 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14}; + const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = { + UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; - const uint32_t RampGeneratorDriverFeatureControlRegisters[RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT] = { 0x33, 0x34, 0x35, 0x36 }; + const uint32_t RampGeneratorDriverFeatureControlRegisters + [RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT] = {0x33, 0x34, + 0x35, 0x36}; - const char* getChannelId(Channel channel); - const char* getDeviceId(Device device); - const char* getDeviceAttribute(DeviceAttribute attribute); - const char* getMotorAttribute(MotorAttribute attribute); - const uint32_t getConfigurationRegister(ConfigurationRegister registerID); - const uint32_t getConfigurationPage(ConfigurationRegister registerID); - const uint32_t getUniqueIdRegister(UniqueIDRegister registerID); - const uint32_t getHarmonicRegister(HarmonicRegister registerID); - const uint32_t getHarmonicPage(HarmonicRegister registerID); - const uint32_t getUniqueIdPage(UniqueIDRegister registerID); - const uint32_t getSensorRegister(SensorRegister registerID); - const uint32_t getSensorPage(SensorRegister registerID); + const char *getChannelId(Channel channel); + const char *getDeviceId(Device device); + const char *getDeviceAttribute(DeviceAttribute attribute); + const char *getMotorAttribute(MotorAttribute attribute); + const uint32_t getConfigurationRegister(ConfigurationRegister registerID); + const uint32_t getConfigurationPage(ConfigurationRegister registerID); + const uint32_t getUniqueIdRegister(UniqueIDRegister registerID); + const uint32_t getHarmonicRegister(HarmonicRegister registerID); + const uint32_t getHarmonicPage(HarmonicRegister registerID); + const uint32_t getUniqueIdPage(UniqueIDRegister registerID); + const uint32_t getSensorRegister(SensorRegister registerID); + const uint32_t getSensorPage(SensorRegister registerID); - const uint32_t getRampGeneratorDriverFeatureControlRegister(RampGeneratorDriverFeatureControlRegister registerID); + const uint32_t getRampGeneratorDriverFeatureControlRegister( + RampGeneratorDriverFeatureControlRegister registerID); - void connectADMT(); - void disconnectADMT(); - int getChannelIndex(const char *deviceName, const char *channelName); - double getChannelValue(const char *deviceName, const char *channelName, int bufferSize = 1); - int getDeviceAttributeValue(const char *deviceName, const char *attributeName, double *returnValue); - int getDeviceAttributeValueString(const char *deviceName, const char *attributeName, char *returnValue, size_t byteLength = 512); - int setDeviceAttributeValue(const char *deviceName, const char *attributeName, double writeValue); - QString calibrate(vector PANG, int cycles, int samplesPerCycle, bool CCW); - int writeDeviceRegistry(const char *deviceName, uint32_t address, uint32_t value); - int readDeviceRegistry(const char *deviceName, uint32_t address, uint32_t *returnValue); - void computeSineCosineOfAngles(const vector& angles); - uint16_t calculateHarmonicCoefficientMagnitude(uint16_t harmonicCoefficient, uint16_t originalValue, const string& key); - uint16_t calculateHarmonicCoefficientPhase(uint16_t harmonicPhase, uint16_t originalValue); - double getActualHarmonicRegisterValue(uint16_t registerValue, const string key); - map getFaultRegisterBitMapping(uint16_t registerValue); - map getGeneralRegisterBitMapping(uint16_t registerValue); - map getDIGIOENRegisterBitMapping(uint16_t registerValue); - map getDIGIORegisterBitMapping(uint16_t registerValue); - map getDiag1RegisterBitMapping_Register(uint16_t registerValue); - map getDiag1RegisterBitMapping_Afe(uint16_t registerValue, bool is5V); - map getDiag2RegisterBitMapping(uint16_t registerValue); - uint16_t setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings); - void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle, bool CCW); - int getAbsAngleTurnCount(uint16_t registerValue); - uint16_t setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings); - uint16_t setDIGIORegisterBitMapping(uint16_t currentRegisterValue, map settings); - void unwrapAngles(vector& angles_rad); - map getUNIQID3RegisterMapping(uint16_t registerValue); - map getSineRegisterBitMapping(uint16_t registerValue); - map getCosineRegisterBitMapping(uint16_t registerValue); - map getRadiusRegisterBitMapping(uint16_t registerValue); - map getAngleSecRegisterBitMapping(uint16_t registerValue); - map getSecAnglQRegisterBitMapping(uint16_t registerValue); - map getSecAnglIRegisterBitMapping(uint16_t registerValue); - map getTmp1RegisterBitMapping(uint16_t registerValue, bool is5V); - bool checkRegisterFault(uint16_t registerValue, bool isMode1); - int streamIO(); - void bufferedStreamIO(int totalSamples, int targetSampleRate); - bool checkVelocityReachedFlag(uint16_t registerValue); + void connectADMT(); + void disconnectADMT(); + int getChannelIndex(const char *deviceName, const char *channelName); + double getChannelValue(const char *deviceName, const char *channelName, + int bufferSize = 1); + int getDeviceAttributeValue(const char *deviceName, const char *attributeName, + double *returnValue); + int getDeviceAttributeValueString(const char *deviceName, + const char *attributeName, + char *returnValue, size_t byteLength = 512); + int setDeviceAttributeValue(const char *deviceName, const char *attributeName, + double writeValue); + QString calibrate(vector PANG, int cycles, int samplesPerCycle, + bool CCW); + int writeDeviceRegistry(const char *deviceName, uint32_t address, + uint32_t value); + int readDeviceRegistry(const char *deviceName, uint32_t address, + uint32_t *returnValue); + void computeSineCosineOfAngles(const vector &angles); + uint16_t calculateHarmonicCoefficientMagnitude(uint16_t harmonicCoefficient, + uint16_t originalValue, + const string &key); + uint16_t calculateHarmonicCoefficientPhase(uint16_t harmonicPhase, + uint16_t originalValue); + double getActualHarmonicRegisterValue(uint16_t registerValue, + const string key); + map getFaultRegisterBitMapping(uint16_t registerValue); + map getGeneralRegisterBitMapping(uint16_t registerValue); + map getDIGIOENRegisterBitMapping(uint16_t registerValue); + map getDIGIORegisterBitMapping(uint16_t registerValue); + map getDiag1RegisterBitMapping_Register(uint16_t registerValue); + map getDiag1RegisterBitMapping_Afe(uint16_t registerValue, + bool is5V); + map getDiag2RegisterBitMapping(uint16_t registerValue); + uint16_t setGeneralRegisterBitMapping(uint16_t currentRegisterValue, + map settings); + void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle, + bool CCW); + int getAbsAngleTurnCount(uint16_t registerValue); + uint16_t setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, + map settings); + uint16_t setDIGIORegisterBitMapping(uint16_t currentRegisterValue, + map settings); + void unwrapAngles(vector &angles_rad); + map getUNIQID3RegisterMapping(uint16_t registerValue); + map getSineRegisterBitMapping(uint16_t registerValue); + map getCosineRegisterBitMapping(uint16_t registerValue); + map getRadiusRegisterBitMapping(uint16_t registerValue); + map getAngleSecRegisterBitMapping(uint16_t registerValue); + map getSecAnglQRegisterBitMapping(uint16_t registerValue); + map getSecAnglIRegisterBitMapping(uint16_t registerValue); + map getTmp1RegisterBitMapping(uint16_t registerValue, + bool is5V); + bool checkRegisterFault(uint16_t registerValue, bool isMode1); + int streamIO(); + void bufferedStreamIO(int totalSamples, int targetSampleRate); + bool checkVelocityReachedFlag(uint16_t registerValue); public Q_SLOTS: - void handleStreamData(double value); - void handleStreamBufferedData(const QVector &value); - void handleStreamBufferedDataInterval(const QVector &value); + void handleStreamData(double value); + void handleStreamBufferedData(const QVector &value); + void handleStreamBufferedDataInterval(const QVector &value); Q_SIGNALS: - void streamData(double value); - void streamBufferedData(const QVector &value); - void streamBufferedDataInterval(const QVector &value); + void streamData(double value); + void streamBufferedData(const QVector &value); + void streamBufferedDataInterval(const QVector &value); + private: - iio_context *m_iioCtx; - iio_buffer *m_iioBuffer; - Connection *m_conn; - QString uri; + iio_context *m_iioCtx; + iio_buffer *m_iioBuffer; + Connection *m_conn; + QString uri; - unsigned int bitReverse(unsigned int x, int log2n); - template - void fft(Iter_T a, Iter_T b, int log2n); - void performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount); - int linear_fit(vector x, vector y, double* slope, double* intercept); - int calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err); - void getPreCalibrationFFT(const vector& PANG, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre, int cycleCount, int samplesPerCycle); - void getPostCalibrationFFT(const vector& updated_PANG, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post, int cycleCount, int samplesPerCycle); + unsigned int bitReverse(unsigned int x, int log2n); + template void fft(Iter_T a, Iter_T b, int log2n); + void performFFT(const vector &angle_errors, + vector &angle_errors_fft, + vector &angle_errors_fft_phase, int cycleCount); + int linear_fit(vector x, vector y, double *slope, + double *intercept); + int calculate_angle_error(vector angle_meas, + vector &angle_error_ret, + double *max_angle_err); + void getPreCalibrationFFT(const vector &PANG, + vector &angle_errors_fft_pre, + vector &angle_errors_fft_phase_pre, + int cycleCount, int samplesPerCycle); + void getPostCalibrationFFT(const vector &updated_PANG, + vector &angle_errors_fft_post, + vector &angle_errors_fft_phase_post, + int cycleCount, int samplesPerCycle); }; } // namespace scopy::admt diff --git a/plugins/admt/include/admt/admtplugin.h b/plugins/admt/include/admt/admtplugin.h index 9fa16a0668..7a3ff7f956 100644 --- a/plugins/admt/include/admt/admtplugin.h +++ b/plugins/admt/include/admt/admtplugin.h @@ -24,8 +24,8 @@ #define SCOPY_PLUGIN_NAME ADMTPlugin -#include "scopy-admt_export.h" #include "admtcontroller.h" +#include "scopy-admt_export.h" #include @@ -39,30 +39,29 @@ namespace scopy { namespace admt { -class SCOPY_ADMT_EXPORT ADMTPlugin : public QObject, public PluginBase -{ - Q_OBJECT - SCOPY_PLUGIN; +class SCOPY_ADMT_EXPORT ADMTPlugin : public QObject, public PluginBase { + Q_OBJECT + SCOPY_PLUGIN; public: - bool compatible(QString m_param, QString category) override; - bool loadPage() override; - bool loadIcon() override; - void loadToolList() override; - void unload() override; - void initMetadata() override; - QString description() override; + bool compatible(QString m_param, QString category) override; + bool loadPage() override; + bool loadIcon() override; + void loadToolList() override; + void unload() override; + void initMetadata() override; + QString description() override; public Q_SLOTS: - bool onConnect() override; - bool onDisconnect() override; + bool onConnect() override; + bool onDisconnect() override; private: - iio_context *m_ctx; - QWidget *harmonicCalibration; - QLineEdit *edit; + iio_context *m_ctx; + QWidget *harmonicCalibration; + QLineEdit *edit; - ADMTController *m_admtController; + ADMTController *m_admtController; }; } // namespace admt } // namespace scopy diff --git a/plugins/admt/include/admt/admtstylehelper.h b/plugins/admt/include/admt/admtstylehelper.h index 3b5898033c..cc17814d02 100644 --- a/plugins/admt/include/admt/admtstylehelper.h +++ b/plugins/admt/include/admt/admtstylehelper.h @@ -23,50 +23,64 @@ #define ADMTSTYLEHELPER_H #include "scopy-admt_export.h" -#include "stylehelper.h" #include "style.h" +#include "stylehelper.h" #include -#include -#include #include +#include #include +#include #include #include #include namespace scopy { -namespace admt{ -class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject -{ - Q_OBJECT +namespace admt { +class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject { + Q_OBJECT protected: - ADMTStyleHelper(QObject *parent = nullptr); - ~ADMTStyleHelper(); + ADMTStyleHelper(QObject *parent = nullptr); + ~ADMTStyleHelper(); + public: - // singleton - ADMTStyleHelper(ADMTStyleHelper &other) = delete; - void operator=(const ADMTStyleHelper &) = delete; - static ADMTStyleHelper *GetInstance(); + // singleton + ADMTStyleHelper(ADMTStyleHelper &other) = delete; + void operator=(const ADMTStyleHelper &) = delete; + static ADMTStyleHelper *GetInstance(); + public: - static void initColorMap(); - static QString getColor(QString id); - static void TopContainerButtonStyle(QPushButton *btn, QString objectName = ""); - static void PlotWidgetStyle(PlotWidget *widget, QString objectName = ""); - static void ComboBoxStyle(QComboBox *widget, QString objectName = ""); - static void LineEditStyle(QLineEdit *widget, QString objectName = ""); - static void ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName = ""); - static void StartButtonStyle(QPushButton *btn, QString objectName = ""); - static void TextStyle(QWidget *widget, const char *styleHelperColor = json::global::white, bool isBold = false, QString objectName = "");// void TextStyle(QWidget *widget, const QString& styleHelperColor, bool isBold = false, QString objectName = ""); - static void MenuSmallLabel(QLabel *label, QString objectName = ""); - static void LineStyle(QFrame *line, QString objectName = ""); - static void UIBackgroundStyle(QWidget *widget, QString objectName = ""); - static void GraphChannelStyle(QWidget *widget, QLayout *layout, QString objectName = ""); - static void CalculatedCoeffWidgetRowStyle(QWidget *widget, QHBoxLayout *layout, QLabel *hLabel, QLabel *hMagLabel, QLabel *hPhaseLabel, QString objectName = ""); + static void initColorMap(); + static QString getColor(QString id); + static void TopContainerButtonStyle(QPushButton *btn, + QString objectName = ""); + static void PlotWidgetStyle(PlotWidget *widget, QString objectName = ""); + static void ComboBoxStyle(QComboBox *widget, QString objectName = ""); + static void LineEditStyle(QLineEdit *widget, QString objectName = ""); + static void ColoredSquareCheckbox(QCheckBox *chk, QColor color, + QString objectName = ""); + static void StartButtonStyle(QPushButton *btn, QString objectName = ""); + static void + TextStyle(QWidget *widget, const char *styleHelperColor = json::global::white, + bool isBold = false, + QString objectName = ""); // void TextStyle(QWidget *widget, const + // QString& styleHelperColor, bool isBold + // = false, QString objectName = ""); + static void MenuSmallLabel(QLabel *label, QString objectName = ""); + static void LineStyle(QFrame *line, QString objectName = ""); + static void UIBackgroundStyle(QWidget *widget, QString objectName = ""); + static void GraphChannelStyle(QWidget *widget, QLayout *layout, + QString objectName = ""); + static void CalculatedCoeffWidgetRowStyle(QWidget *widget, + QHBoxLayout *layout, QLabel *hLabel, + QLabel *hMagLabel, + QLabel *hPhaseLabel, + QString objectName = ""); + private: - QMap colorMap; - static ADMTStyleHelper *pinstance_; + QMap colorMap; + static ADMTStyleHelper *pinstance_; }; } // namespace admt } // namespace scopy diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index a86ba940e4..eb78eb9a35 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -26,383 +26,428 @@ #include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include #include #include -#include +#include +#include #include -#include -#include -#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include -#include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include -#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include -#include -#include +#include +#include +#include +#include +#include -enum AcquisitionDataKey -{ - RADIUS, - ANGLE, - TURNCOUNT, - ABSANGLE, - SINE, - COSINE, - SECANGLI, - SECANGLQ, - ANGLESEC, - DIAG1, - DIAG2, - TMP0, - TMP1, - CNVCNT, - SCRADIUS, - SPIFAULT +enum AcquisitionDataKey { + RADIUS, + ANGLE, + TURNCOUNT, + ABSANGLE, + SINE, + COSINE, + SECANGLI, + SECANGLQ, + ANGLESEC, + DIAG1, + DIAG2, + TMP0, + TMP1, + CNVCNT, + SCRADIUS, + SPIFAULT }; -namespace scopy{ +namespace scopy { namespace admt { -class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget -{ - Q_OBJECT +class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget { + Q_OBJECT public: - HarmonicCalibration(ADMTController *m_admtController, bool isDebug = false, QWidget *parent = nullptr); - ~HarmonicCalibration(); - bool running() const; - void setRunning(bool newRunning); - void requestDisconnect(); + HarmonicCalibration(ADMTController *m_admtController, bool isDebug = false, + QWidget *parent = nullptr); + ~HarmonicCalibration(); + bool running() const; + void setRunning(bool newRunning); + void requestDisconnect(); public Q_SLOTS: - void run(bool); - void stop(); - void start(); - void restart(); - void calibrationLogWrite(QString message = ""); - void commandLogWrite(QString message = ""); - void updateFaultStatus(bool value); - void updateMotorPosition(double position); - void updateDIGIOUI(uint16_t *registerValue); - void updateFaultRegisterUI(uint16_t *registerValue); - void updateMTDiagnosticRegisterUI(uint16_t *registerValue); - void updateMTDiagnosticsUI(uint16_t *registerValue); + void run(bool); + void stop(); + void start(); + void restart(); + void calibrationLogWrite(QString message = ""); + void commandLogWrite(QString message = ""); + void updateFaultStatus(bool value); + void updateMotorPosition(double position); + void updateDIGIOUI(uint16_t *registerValue); + void updateFaultRegisterUI(uint16_t *registerValue); + void updateMTDiagnosticRegisterUI(uint16_t *registerValue); + void updateMTDiagnosticsUI(uint16_t *registerValue); Q_SIGNALS: - void runningChanged(bool); - void canCalibrateChanged(bool); - void updateUtilityUI(); - void calibrationLogWriteSignal(QString message); - void commandLogWriteSignal(QString message); - void updateFaultStatusSignal(bool value); - void motorPositionChanged(double position); - void DIGIORegisterChanged(uint16_t *registerValue); - void FaultRegisterChanged(uint16_t *registerValue); - void DIAG1RegisterChanged(uint16_t *registerValue); - void DIAG2RegisterChanged(uint16_t *registerValue); + void runningChanged(bool); + void canCalibrateChanged(bool); + void updateUtilityUI(); + void calibrationLogWriteSignal(QString message); + void commandLogWriteSignal(QString message); + void updateFaultStatusSignal(bool value); + void motorPositionChanged(double position); + void DIGIORegisterChanged(uint16_t *registerValue); + void FaultRegisterChanged(uint16_t *registerValue); + void DIAG1RegisterChanged(uint16_t *registerValue); + void DIAG2RegisterChanged(uint16_t *registerValue); + private: - ADMTController *m_admtController; - iio_context *m_ctx; - bool m_running, isDebug; - ToolTemplate *tool; - GearBtn *settingsButton; - InfoBtn *infoButton; - RunBtn *runButton; - - const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; - - double rotation, angle, count, temp = 0.0, - motor_rpm, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode, - afeDiag0, afeDiag1, afeDiag2; - - QPushButton *openLastMenuButton, *calibrationStartMotorButton, - *calibrateDataButton, *extractDataButton, *clearCalibrateDataButton, - *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; - QButtonGroup *rightMenuButtonGroup; - - QLineEdit *acquisitionMotorRPMLineEdit, *calibrationMotorRPMLineEdit, *motorTargetPositionLineEdit, *graphUpdateIntervalLineEdit, *displayLengthLineEdit, - *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, - *acquisitionMotorCurrentPositionLineEdit, - *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, - *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, - *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, - *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit, - *calibrationMotorCurrentPositionLineEdit, - *AFEDIAG0LineEdit, *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; - - QLabel *rawAngleValueLabel, - *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, - *motorAmaxValueLabel, *motorRotateVmaxValueLabel, *motorDmaxValueLabel, - *motorDisableValueLabel, *motorTargetPosValueLabel, *motorCurrentPosValueLabel, - *motorRampModeValueLabel, - *calibrationH1MagLabel, - *calibrationH1PhaseLabel, - *calibrationH2MagLabel, - *calibrationH2PhaseLabel, - *calibrationH3MagLabel, - *calibrationH3PhaseLabel, - *calibrationH8MagLabel, - *calibrationH8PhaseLabel; - - MenuHeaderWidget *header; - - MenuSectionWidget *rightMenuSectionWidget; - MenuCollapseSection *rotationCollapse, *angleCollapse, *countCollapse, *tempCollapse; - MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo, *m_calibrationMotorRampModeMenuCombo, - *sequenceTypeMenuCombo, *conversionTypeMenuCombo, *cnvSourceMenuCombo, *convertSynchronizationMenuCombo, *angleFilterMenuCombo, *eighthHarmonicMenuCombo, - *calibrationModeMenuCombo; - - QTabWidget *tabWidget, *calibrationDataGraphTabWidget, *resultDataTabWidget; - - QListWidget *rawDataListWidget; - - QPlainTextEdit *logsPlainTextEdit, *commandLogPlainTextEdit; - - QCheckBox *acquisitionFaultRegisterLEDWidget, *calibrationFaultRegisterLEDWidget, - *DIGIOBusyStatusLED ,*DIGIOCNVStatusLED ,*DIGIOSENTStatusLED ,*DIGIOACALCStatusLED ,*DIGIOFaultStatusLED ,*DIGIOBootloaderStatusLED, - *R0StatusLED, *R1StatusLED, *R2StatusLED, *R3StatusLED, *R4StatusLED, *R5StatusLED, *R6StatusLED, *R7StatusLED, - *VDDUnderVoltageStatusLED, *VDDOverVoltageStatusLED, *VDRIVEUnderVoltageStatusLED, *VDRIVEOverVoltageStatusLED, *AFEDIAGStatusLED, - *NVMCRCFaultStatusLED, *ECCDoubleBitErrorStatusLED, *OscillatorDriftStatusLED, *CountSensorFalseStateStatusLED, *AngleCrossCheckStatusLED, - *TurnCountSensorLevelsStatusLED, *MTDIAGStatusLED, *TurnCounterCrossCheckStatusLED, *RadiusCheckStatusLED, *SequencerWatchdogStatusLED; - - QScrollArea *MTDiagnosticsScrollArea; - - PlotWidget *acquisitionGraphPlotWidget, *angleErrorPlotWidget, *calibrationRawDataPlotWidget, *FFTAngleErrorPlotWidget, - *correctedErrorPlotWidget, *postCalibrationRawDataPlotWidget, *FFTCorrectedErrorPlotWidget; - PlotAxis *acquisitionXPlotAxis, *acquisitionYPlotAxis, *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis, - *angleErrorXPlotAxis, *angleErrorYPlotAxis, *FFTAngleErrorXPlotAxis, *FFTAngleErrorYPlotAxis, - *correctedErrorXPlotAxis, *correctedErrorYPlotAxis, *FFTCorrectedErrorXPlotAxis, *FFTCorrectedErrorYPlotAxis, - *postCalibrationRawDataXPlotAxis, *postCalibrationRawDataYPlotAxis; - PlotChannel *acquisitionAnglePlotChannel, *acquisitionABSAnglePlotChannel, *acquisitionTurnCountPlotChannel, *acquisitionTmp0PlotChannel, - *acquisitionTmp1PlotChannel, *acquisitionSinePlotChannel, *acquisitionCosinePlotChannel, *acquisitionRadiusPlotChannel, - *acquisitionSecAnglQPlotChannel, *acquisitionSecAnglIPlotChannel, - *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel, - *FFTAngleErrorMagnitudeChannel, *FFTAngleErrorPhaseChannel, - *correctedErrorPlotChannel, - *postCalibrationRawDataPlotChannel, *postCalibrationSineDataPlotChannel, *postCalibrationCosineDataPlotChannel, - *FFTCorrectedErrorMagnitudeChannel, *FFTCorrectedErrorPhaseChannel; - - HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, *motorMaxDisplacementSpinBox, *motorTargetPositionSpinBox; - - CustomSwitch *acquisitionMotorDirectionSwitch, *calibrationMotorDirectionSwitch, *calibrationDisplayFormatSwitch, - *DIGIO0ENToggleSwitch, *DIGIO0FNCToggleSwitch, - *DIGIO1ENToggleSwitch, *DIGIO1FNCToggleSwitch, - *DIGIO2ENToggleSwitch, *DIGIO2FNCToggleSwitch, - *DIGIO3ENToggleSwitch, *DIGIO3FNCToggleSwitch, - *DIGIO4ENToggleSwitch, *DIGIO4FNCToggleSwitch, - *DIGIO5ENToggleSwitch, *DIGIO5FNCToggleSwitch, - *DIGIOALLToggleSwitch; - - RegisterBlockWidget *cnvPageRegisterBlock, *digIORegisterBlock, *faultRegisterBlock, *generalRegisterBlock, *digIOEnRegisterBlock, *angleCkRegisterBlock, *eccDcdeRegisterBlock, *eccDisRegisterBlock, *absAngleRegisterBlock, *angleRegisterBlock, *angleSecRegisterBlock, *sineRegisterBlock, *cosineRegisterBlock, *secAnglIRegisterBlock, *secAnglQRegisterBlock, *radiusRegisterBlock, *diag1RegisterBlock, *diag2RegisterBlock, *tmp0RegisterBlock, *tmp1RegisterBlock, *cnvCntRegisterBlock, *uniqID0RegisterBlock, *uniqID1RegisterBlock, *uniqID2RegisterBlock, *uniqID3RegisterBlock, *h1MagRegisterBlock, *h1PhRegisterBlock, *h2MagRegisterBlock, *h2PhRegisterBlock, *h3MagRegisterBlock, *h3PhRegisterBlock, *h8MagRegisterBlock, *h8PhRegisterBlock; - - QFuture m_deviceStatusThread, m_currentMotorPositionThread, - m_acquisitionUIThread, m_acquisitionDataThread, m_acquisitionGraphThread, - m_calibrationUIThread, m_calibrationStreamThread, m_calibrationWaitVelocityThread, m_calibrationContinuousThread, - m_resetMotorToZeroThread, m_utilityUIThread, m_utilityThread; - QFutureWatcher m_deviceStatusWatcher, m_currentMotorPositionWatcher, - m_acquisitionUIWatcher, m_acquisitionDataWatcher, m_acquisitionGraphWatcher, - m_calibrationUIWatcher, m_calibrationStreamWatcher, m_calibrationWaitVelocityWatcher, m_calibrationContinuousWatcher, - m_resetMotorToZeroWatcher, m_utilityUIWatcher, m_utilityWatcher; - - ToolTemplate* createAcquisitionWidget(); - ToolTemplate* createCalibrationWidget(); - ToolTemplate* createRegistersWidget(); - ToolTemplate* createUtilityWidget(); - - void readDeviceProperties(); - void initializeADMT(); - bool readSequence(); - bool writeSequence(const map &settings); - void applySequence(); - bool changeCNVPage(uint32_t page); - void initializeMotor(); - void startDeviceStatusMonitor(); - void stopDeviceStatusMonitor(); - void getDeviceFaultStatus(int sampleRate); - void startCurrentMotorPositionMonitor(); - void stopCurrentMotorPositionMonitor(); - void currentMotorPositionTask(int sampleRate); - bool resetGENERAL(); - - #pragma region Acquisition Methods - bool updateChannelValues(); - void updateCountValue(); - void updateLineEditValues(); - void startAcquisition(); - void stopAcquisition(); - void updateAcquisitionMotorRPM(); - void updateAcquisitionMotorRotationDirection(); - void getAcquisitionSamples(int sampleRate); - double getAcquisitionParameterValue(const AcquisitionDataKey &key); - void plotAcquisition(QVector& list, PlotChannel* channel); - void prependAcquisitionData(const double& data, QVector& list); - void resetAcquisitionYAxisScale(); - void acquisitionPlotTask(int sampleRate); - void acquisitionUITask(int sampleRate); - void startAcquisitionUITask(); - void stopAcquisitionUITask(); - void updateSequenceWidget(); - void applySequenceAndUpdate(); - void updateGeneralSettingEnabled(bool value); - void connectCheckBoxToAcquisitionGraph(QCheckBox* widget, PlotChannel* channel, AcquisitionDataKey key); - void GMRReset(); - #pragma endregion - - #pragma region Calibration Methods - void startCalibrationUITask(); - void stopCalibrationUITask(); - void calibrationUITask(int sampleRate); - void updateCalibrationMotorRPM(); - void updateCalibrationMotorRotationDirection(); - void getCalibrationSamples(); - void startCalibration(); - void stopCalibration(); - void startContinuousCalibration(); - void stopContinuousCalibration(); - void startCalibrationStreamThread(); - void stopCalibrationStreamThread(); - void startWaitForVelocityReachedThread(int mode); - void stopWaitForVelocityReachedThread(); - void waitForVelocityReached(int mode, int sampleRate); - int calculateContinuousCalibrationSampleRate(double motorRPS, int samplesPerCycle); - void configureConversionType(int mode); - void configureCalibrationSequenceSettings(); - void getStreamedCalibrationSamples(int microSampleRate); - void startOneShotCalibration(); - void postCalibrateData(); - void resetAllCalibrationState(); - void computeSineCosineOfAngles(QVector graphDataList); - void populateAngleErrorGraphs(); - void populateCorrectedAngleErrorGraphs(); - void clearHarmonicRegisters(); - void flashHarmonicValues(); - void calculateHarmonicValues(); - void updateCalculatedCoeffAngle(); - void updateCalculatedCoeffHex(); - void resetCalculatedCoeffAngle(); - void resetCalculatedCoeffHex(); - void displayCalculatedCoeff(); - void importCalibrationData(); - void extractCalibrationData(); - void toggleTabSwitching(bool value); - void toggleCalibrationButtonState(int state); - void canStartMotor(bool value); - void canCalibrate(bool); - void toggleCalibrationControls(bool value); - void clearCalibrationSamples(); - void clearCalibrationSineCosine(); - void clearPostCalibrationSamples(); - void clearAngleErrorGraphs(); - void clearCorrectedAngleErrorGraphs(); - #pragma endregion - - #pragma region Motor Methods - bool moveMotorToPosition(double& position, bool validate = true); - void moveMotorContinuous(); - bool resetCurrentPositionToZero(); - void stopMotor(); - int readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value); - int writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); - int readMotorRegisterValue(uint32_t address, uint32_t *value); - void setRampMode(bool motorRotationClockwise); - void getRampMode(); - void startResetMotorToZero(); - void stopResetMotorToZero(); - void resetMotorToZero(); - #pragma endregion - - #pragma region Utility Methods - void startUtilityTask(); - void stopUtilityTask(); - void utilityTask(int sampleRate); - void toggleUtilityTask(bool run); - void getDIGIOENRegister(); - void updateDIGIOMonitorUI(); - void updateDIGIOControlUI(); - void getDIAG2Register(); - void getDIAG1Register(); - void getFAULTRegister(); - void toggleDIGIOEN(string DIGIOENName, bool value); - void toggleMTDiagnostics(int mode); - void toggleFaultRegisterMode(int mode); - bool resetDIGIO(); - void clearCommandLog(); - #pragma endregion - - #pragma region Register Methods - void readAllRegisters(); - void toggleRegisters(int mode); - #pragma endregion - - #pragma region UI Helper Methods - void updateLabelValue(QLabel* label, int channelIndex); - void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); - bool updateChannelValue(int channelIndex); - void updateLineEditValue(QLineEdit* lineEdit, double value); - void toggleWidget(QPushButton *widget, bool value); - void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel); - QCheckBox *createStatusLEDWidget(const QString &text, QVariant variant = true, bool checked = false, QWidget *parent = nullptr); - MenuControlButton *createChannelToggleWidget(const QString title, QColor color, QWidget *parent = nullptr); - #pragma endregion - - #pragma region Connect Methods - void connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max); - void connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit = ""); - void connectLineEditToDouble(QLineEdit* lineEdit, double& variable); - void connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute); - void connectMenuComboToNumber(MenuCombo* menuCombo, double& variable); - void connectMenuComboToNumber(MenuCombo* menuCombo, int& variable); - void connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax); - void connectLineEditToAMAXConversion(QLineEdit* lineEdit, double& amax); - void connectRegisterBlockToRegistry(RegisterBlockWidget* widget); - void connectLineEditToRPM(QLineEdit* lineEdit, double& variable); - #pragma endregion - - #pragma region Convert Methods - double convertRPStoVMAX(double rps); - double convertVMAXtoRPS(double vmax); - double convertAccelTimetoAMAX(double accelTime); - double convertAMAXtoAccelTime(double amax); - double convertRPMtoRPS(double rpm); - double convertRPStoRPM(double rps); - #pragma endregion - - #pragma region Debug Methods - QString readRegmapDumpAttributeValue(); - #pragma endregion + ADMTController *m_admtController; + iio_context *m_ctx; + bool m_running, isDebug; + ToolTemplate *tool; + GearBtn *settingsButton; + InfoBtn *infoButton; + RunBtn *runButton; + + const char *rotationChannelName, *angleChannelName, *countChannelName, + *temperatureChannelName; + + double rotation, angle, count, temp = 0.0, motor_rpm, amax, rotate_vmax, dmax, + disable, target_pos, current_pos, ramp_mode, + afeDiag0, afeDiag1, afeDiag2; + + QPushButton *openLastMenuButton, *calibrationStartMotorButton, + *calibrateDataButton, *extractDataButton, *clearCalibrateDataButton, + *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; + QButtonGroup *rightMenuButtonGroup; + + QLineEdit *acquisitionMotorRPMLineEdit, *calibrationMotorRPMLineEdit, + *motorTargetPositionLineEdit, *graphUpdateIntervalLineEdit, + *displayLengthLineEdit, *dataGraphSamplesLineEdit, + *tempGraphSamplesLineEdit, *acquisitionMotorCurrentPositionLineEdit, + *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, + *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, + *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, + *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit, + *calibrationMotorCurrentPositionLineEdit, *AFEDIAG0LineEdit, + *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; + + QLabel *rawAngleValueLabel, *rotationValueLabel, *angleValueLabel, + *countValueLabel, *tempValueLabel, *motorAmaxValueLabel, + *motorRotateVmaxValueLabel, *motorDmaxValueLabel, *motorDisableValueLabel, + *motorTargetPosValueLabel, *motorCurrentPosValueLabel, + *motorRampModeValueLabel, *calibrationH1MagLabel, + *calibrationH1PhaseLabel, *calibrationH2MagLabel, + *calibrationH2PhaseLabel, *calibrationH3MagLabel, + *calibrationH3PhaseLabel, *calibrationH8MagLabel, + *calibrationH8PhaseLabel; + + MenuHeaderWidget *header; + + MenuSectionWidget *rightMenuSectionWidget; + MenuCollapseSection *rotationCollapse, *angleCollapse, *countCollapse, + *tempCollapse; + MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, + *m_tempGraphDirectionMenuCombo, *m_calibrationMotorRampModeMenuCombo, + *sequenceTypeMenuCombo, *conversionTypeMenuCombo, *cnvSourceMenuCombo, + *convertSynchronizationMenuCombo, *angleFilterMenuCombo, + *eighthHarmonicMenuCombo, *calibrationModeMenuCombo; + + QTabWidget *tabWidget, *calibrationDataGraphTabWidget, *resultDataTabWidget; + + QListWidget *rawDataListWidget; + + QPlainTextEdit *logsPlainTextEdit, *commandLogPlainTextEdit; + + QCheckBox *acquisitionFaultRegisterLEDWidget, + *calibrationFaultRegisterLEDWidget, *DIGIOBusyStatusLED, + *DIGIOCNVStatusLED, *DIGIOSENTStatusLED, *DIGIOACALCStatusLED, + *DIGIOFaultStatusLED, *DIGIOBootloaderStatusLED, *R0StatusLED, + *R1StatusLED, *R2StatusLED, *R3StatusLED, *R4StatusLED, *R5StatusLED, + *R6StatusLED, *R7StatusLED, *VDDUnderVoltageStatusLED, + *VDDOverVoltageStatusLED, *VDRIVEUnderVoltageStatusLED, + *VDRIVEOverVoltageStatusLED, *AFEDIAGStatusLED, *NVMCRCFaultStatusLED, + *ECCDoubleBitErrorStatusLED, *OscillatorDriftStatusLED, + *CountSensorFalseStateStatusLED, *AngleCrossCheckStatusLED, + *TurnCountSensorLevelsStatusLED, *MTDIAGStatusLED, + *TurnCounterCrossCheckStatusLED, *RadiusCheckStatusLED, + *SequencerWatchdogStatusLED; + + QScrollArea *MTDiagnosticsScrollArea; + + PlotWidget *acquisitionGraphPlotWidget, *angleErrorPlotWidget, + *calibrationRawDataPlotWidget, *FFTAngleErrorPlotWidget, + *correctedErrorPlotWidget, *postCalibrationRawDataPlotWidget, + *FFTCorrectedErrorPlotWidget; + PlotAxis *acquisitionXPlotAxis, *acquisitionYPlotAxis, + *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis, + *angleErrorXPlotAxis, *angleErrorYPlotAxis, *FFTAngleErrorXPlotAxis, + *FFTAngleErrorYPlotAxis, *correctedErrorXPlotAxis, + *correctedErrorYPlotAxis, *FFTCorrectedErrorXPlotAxis, + *FFTCorrectedErrorYPlotAxis, *postCalibrationRawDataXPlotAxis, + *postCalibrationRawDataYPlotAxis; + PlotChannel *acquisitionAnglePlotChannel, *acquisitionABSAnglePlotChannel, + *acquisitionTurnCountPlotChannel, *acquisitionTmp0PlotChannel, + *acquisitionTmp1PlotChannel, *acquisitionSinePlotChannel, + *acquisitionCosinePlotChannel, *acquisitionRadiusPlotChannel, + *acquisitionSecAnglQPlotChannel, *acquisitionSecAnglIPlotChannel, + *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, + *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, + *calibrationCosineDataPlotChannel, *FFTAngleErrorMagnitudeChannel, + *FFTAngleErrorPhaseChannel, *correctedErrorPlotChannel, + *postCalibrationRawDataPlotChannel, *postCalibrationSineDataPlotChannel, + *postCalibrationCosineDataPlotChannel, *FFTCorrectedErrorMagnitudeChannel, + *FFTCorrectedErrorPhaseChannel; + + HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, + *motorMaxDisplacementSpinBox, *motorTargetPositionSpinBox; + + CustomSwitch *acquisitionMotorDirectionSwitch, + *calibrationMotorDirectionSwitch, *calibrationDisplayFormatSwitch, + *DIGIO0ENToggleSwitch, *DIGIO0FNCToggleSwitch, *DIGIO1ENToggleSwitch, + *DIGIO1FNCToggleSwitch, *DIGIO2ENToggleSwitch, *DIGIO2FNCToggleSwitch, + *DIGIO3ENToggleSwitch, *DIGIO3FNCToggleSwitch, *DIGIO4ENToggleSwitch, + *DIGIO4FNCToggleSwitch, *DIGIO5ENToggleSwitch, *DIGIO5FNCToggleSwitch, + *DIGIOALLToggleSwitch; + + RegisterBlockWidget *cnvPageRegisterBlock, *digIORegisterBlock, + *faultRegisterBlock, *generalRegisterBlock, *digIOEnRegisterBlock, + *angleCkRegisterBlock, *eccDcdeRegisterBlock, *eccDisRegisterBlock, + *absAngleRegisterBlock, *angleRegisterBlock, *angleSecRegisterBlock, + *sineRegisterBlock, *cosineRegisterBlock, *secAnglIRegisterBlock, + *secAnglQRegisterBlock, *radiusRegisterBlock, *diag1RegisterBlock, + *diag2RegisterBlock, *tmp0RegisterBlock, *tmp1RegisterBlock, + *cnvCntRegisterBlock, *uniqID0RegisterBlock, *uniqID1RegisterBlock, + *uniqID2RegisterBlock, *uniqID3RegisterBlock, *h1MagRegisterBlock, + *h1PhRegisterBlock, *h2MagRegisterBlock, *h2PhRegisterBlock, + *h3MagRegisterBlock, *h3PhRegisterBlock, *h8MagRegisterBlock, + *h8PhRegisterBlock; + + QFuture m_deviceStatusThread, m_currentMotorPositionThread, + m_acquisitionUIThread, m_acquisitionDataThread, m_acquisitionGraphThread, + m_calibrationUIThread, m_calibrationStreamThread, + m_calibrationWaitVelocityThread, m_calibrationContinuousThread, + m_resetMotorToZeroThread, m_utilityUIThread, m_utilityThread; + QFutureWatcher m_deviceStatusWatcher, m_currentMotorPositionWatcher, + m_acquisitionUIWatcher, m_acquisitionDataWatcher, + m_acquisitionGraphWatcher, m_calibrationUIWatcher, + m_calibrationStreamWatcher, m_calibrationWaitVelocityWatcher, + m_calibrationContinuousWatcher, m_resetMotorToZeroWatcher, + m_utilityUIWatcher, m_utilityWatcher; + + ToolTemplate *createAcquisitionWidget(); + ToolTemplate *createCalibrationWidget(); + ToolTemplate *createRegistersWidget(); + ToolTemplate *createUtilityWidget(); + + void readDeviceProperties(); + void initializeADMT(); + bool readSequence(); + bool writeSequence(const map &settings); + void applySequence(); + bool changeCNVPage(uint32_t page); + void initializeMotor(); + void startDeviceStatusMonitor(); + void stopDeviceStatusMonitor(); + void getDeviceFaultStatus(int sampleRate); + void startCurrentMotorPositionMonitor(); + void stopCurrentMotorPositionMonitor(); + void currentMotorPositionTask(int sampleRate); + bool resetGENERAL(); + +#pragma region Acquisition Methods + bool updateChannelValues(); + void updateCountValue(); + void updateLineEditValues(); + void startAcquisition(); + void stopAcquisition(); + void updateAcquisitionMotorRPM(); + void updateAcquisitionMotorRotationDirection(); + void getAcquisitionSamples(int sampleRate); + double getAcquisitionParameterValue(const AcquisitionDataKey &key); + void plotAcquisition(QVector &list, PlotChannel *channel); + void prependAcquisitionData(const double &data, QVector &list); + void resetAcquisitionYAxisScale(); + void acquisitionPlotTask(int sampleRate); + void acquisitionUITask(int sampleRate); + void startAcquisitionUITask(); + void stopAcquisitionUITask(); + void updateSequenceWidget(); + void applySequenceAndUpdate(); + void updateGeneralSettingEnabled(bool value); + void connectCheckBoxToAcquisitionGraph(QCheckBox *widget, + PlotChannel *channel, + AcquisitionDataKey key); + void GMRReset(); +#pragma endregion + +#pragma region Calibration Methods + void startCalibrationUITask(); + void stopCalibrationUITask(); + void calibrationUITask(int sampleRate); + void updateCalibrationMotorRPM(); + void updateCalibrationMotorRotationDirection(); + void getCalibrationSamples(); + void startCalibration(); + void stopCalibration(); + void startContinuousCalibration(); + void stopContinuousCalibration(); + void startCalibrationStreamThread(); + void stopCalibrationStreamThread(); + void startWaitForVelocityReachedThread(int mode); + void stopWaitForVelocityReachedThread(); + void waitForVelocityReached(int mode, int sampleRate); + int calculateContinuousCalibrationSampleRate(double motorRPS, + int samplesPerCycle); + void configureConversionType(int mode); + void configureCalibrationSequenceSettings(); + void getStreamedCalibrationSamples(int microSampleRate); + void startOneShotCalibration(); + void postCalibrateData(); + void resetAllCalibrationState(); + void computeSineCosineOfAngles(QVector graphDataList); + void populateAngleErrorGraphs(); + void populateCorrectedAngleErrorGraphs(); + void clearHarmonicRegisters(); + void flashHarmonicValues(); + void calculateHarmonicValues(); + void updateCalculatedCoeffAngle(); + void updateCalculatedCoeffHex(); + void resetCalculatedCoeffAngle(); + void resetCalculatedCoeffHex(); + void displayCalculatedCoeff(); + void importCalibrationData(); + void extractCalibrationData(); + void toggleTabSwitching(bool value); + void toggleCalibrationButtonState(int state); + void canStartMotor(bool value); + void canCalibrate(bool); + void toggleCalibrationControls(bool value); + void clearCalibrationSamples(); + void clearCalibrationSineCosine(); + void clearPostCalibrationSamples(); + void clearAngleErrorGraphs(); + void clearCorrectedAngleErrorGraphs(); +#pragma endregion + +#pragma region Motor Methods + bool moveMotorToPosition(double &position, bool validate = true); + void moveMotorContinuous(); + bool resetCurrentPositionToZero(); + void stopMotor(); + int readMotorAttributeValue(ADMTController::MotorAttribute attribute, + double &value); + int writeMotorAttributeValue(ADMTController::MotorAttribute attribute, + double value); + int readMotorRegisterValue(uint32_t address, uint32_t *value); + void setRampMode(bool motorRotationClockwise); + void getRampMode(); + void startResetMotorToZero(); + void stopResetMotorToZero(); + void resetMotorToZero(); +#pragma endregion + +#pragma region Utility Methods + void startUtilityTask(); + void stopUtilityTask(); + void utilityTask(int sampleRate); + void toggleUtilityTask(bool run); + void getDIGIOENRegister(); + void updateDIGIOMonitorUI(); + void updateDIGIOControlUI(); + void getDIAG2Register(); + void getDIAG1Register(); + void getFAULTRegister(); + void toggleDIGIOEN(string DIGIOENName, bool value); + void toggleMTDiagnostics(int mode); + void toggleFaultRegisterMode(int mode); + bool resetDIGIO(); + void clearCommandLog(); +#pragma endregion + +#pragma region Register Methods + void readAllRegisters(); + void toggleRegisters(int mode); +#pragma endregion + +#pragma region UI Helper Methods + void updateLabelValue(QLabel *label, int channelIndex); + void updateLabelValue(QLabel *label, + ADMTController::MotorAttribute attribute); + bool updateChannelValue(int channelIndex); + void updateLineEditValue(QLineEdit *lineEdit, double value); + void toggleWidget(QPushButton *widget, bool value); + void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, + QString offLabel); + QCheckBox *createStatusLEDWidget(const QString &text, QVariant variant = true, + bool checked = false, + QWidget *parent = nullptr); + MenuControlButton *createChannelToggleWidget(const QString title, + QColor color, + QWidget *parent = nullptr); +#pragma endregion + +#pragma region Connect Methods + void connectLineEditToNumber(QLineEdit *lineEdit, int &variable, int min, + int max); + void connectLineEditToNumber(QLineEdit *lineEdit, double &variable, + QString unit = ""); + void connectLineEditToDouble(QLineEdit *lineEdit, double &variable); + void connectLineEditToNumberWrite(QLineEdit *lineEdit, double &variable, + ADMTController::MotorAttribute attribute); + void connectMenuComboToNumber(MenuCombo *menuCombo, double &variable); + void connectMenuComboToNumber(MenuCombo *menuCombo, int &variable); + void connectLineEditToRPSConversion(QLineEdit *lineEdit, double &vmax); + void connectLineEditToAMAXConversion(QLineEdit *lineEdit, double &amax); + void connectRegisterBlockToRegistry(RegisterBlockWidget *widget); + void connectLineEditToRPM(QLineEdit *lineEdit, double &variable); +#pragma endregion + +#pragma region Convert Methods + double convertRPStoVMAX(double rps); + double convertVMAXtoRPS(double vmax); + double convertAccelTimetoAMAX(double accelTime); + double convertAMAXtoAccelTime(double amax); + double convertRPMtoRPS(double rpm); + double convertRPStoRPM(double rps); +#pragma endregion + +#pragma region Debug Methods + QString readRegmapDumpAttributeValue(); +#pragma endregion }; } // namespace admt } // namespace scopy diff --git a/plugins/admt/include/admt/widgets/horizontalspinbox.h b/plugins/admt/include/admt/widgets/horizontalspinbox.h index ddeccadab2..2d148996e4 100644 --- a/plugins/admt/include/admt/widgets/horizontalspinbox.h +++ b/plugins/admt/include/admt/widgets/horizontalspinbox.h @@ -22,41 +22,44 @@ #ifndef HORIZONTALSPINBOX_H #define HORIZONTALSPINBOX_H -#include "scopy-admt_export.h" +#include "../scopy-admt_export.h" -#include -#include -#include +#include #include -#include #include +#include #include -#include +#include +#include namespace scopy::admt { - class SCOPY_ADMT_EXPORT HorizontalSpinBox : public QWidget - { - Q_OBJECT - public: - HorizontalSpinBox(QString header = "", double initialValue = 0.0, QString unit = "", QWidget *parent = nullptr); - QLineEdit *lineEdit(); - void setEnabled(double value); - public Q_SLOTS: - void setValue(double); - protected Q_SLOTS: - void onMinusButtonPressed(); - void onPlusButtonPressed(); - void onLineEditTextEdited(); - private: - double m_value = 0; - QString m_unit = ""; - QLineEdit *m_lineEdit; - QPushButton *m_minusButton, *m_plusButton; - QLabel *m_unitLabel; - void applyLineEditStyle(QLineEdit *widget); - void applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius = 0, int topRightBorderRadius = 0, int bottomLeftBorderRadius = 0, int bottomRightBorderRadius = 0); - void applyUnitLabelStyle(QLabel *widget, bool isEnabled = true); - }; +class SCOPY_ADMT_EXPORT HorizontalSpinBox : public QWidget { + Q_OBJECT +public: + HorizontalSpinBox(QString header = "", double initialValue = 0.0, + QString unit = "", QWidget *parent = nullptr); + QLineEdit *lineEdit(); + void setEnabled(double value); +public Q_SLOTS: + void setValue(double); +protected Q_SLOTS: + void onMinusButtonPressed(); + void onPlusButtonPressed(); + void onLineEditTextEdited(); + +private: + double m_value = 0; + QString m_unit = ""; + QLineEdit *m_lineEdit; + QPushButton *m_minusButton, *m_plusButton; + QLabel *m_unitLabel; + void applyLineEditStyle(QLineEdit *widget); + void applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius = 0, + int topRightBorderRadius = 0, + int bottomLeftBorderRadius = 0, + int bottomRightBorderRadius = 0); + void applyUnitLabelStyle(QLabel *widget, bool isEnabled = true); +}; } // namespace scopy::admt #endif // HORIZONTALSPINBOX_H \ No newline at end of file diff --git a/plugins/admt/include/admt/widgets/registerblockwidget.h b/plugins/admt/include/admt/widgets/registerblockwidget.h index 50171c7f4c..bcfd5d9c7d 100644 --- a/plugins/admt/include/admt/widgets/registerblockwidget.h +++ b/plugins/admt/include/admt/widgets/registerblockwidget.h @@ -22,60 +22,59 @@ #ifndef REGISTERBLOCKWIDGET_H #define REGISTERBLOCKWIDGET_H -#include "scopy-admt_export.h" +#include "../scopy-admt_export.h" -#include #include #include -#include #include +#include +#include -#include #include +#include namespace scopy::admt { - class SCOPY_ADMT_EXPORT RegisterBlockWidget : public QWidget - { - Q_OBJECT - public: - enum ACCESS_PERMISSION{ - READ, - WRITE, - READWRITE - }; +class SCOPY_ADMT_EXPORT RegisterBlockWidget : public QWidget { + Q_OBJECT +public: + enum ACCESS_PERMISSION { READ, WRITE, READWRITE }; + + QPushButton *m_readButton, *m_writeButton; + + RegisterBlockWidget(QString header, QString description, uint32_t address, + uint32_t cnvPage, + RegisterBlockWidget::ACCESS_PERMISSION accessPermission, + QWidget *parent = nullptr); + virtual ~RegisterBlockWidget(); + QPushButton *readButton(); + QPushButton *writeButton(); + uint32_t getAddress(); + uint32_t getCnvPage(); + uint32_t getValue(); + void setValue(uint32_t value); + RegisterBlockWidget::ACCESS_PERMISSION getAccessPermission(); +public Q_SLOTS: + void onValueChanged(int); - QPushButton *m_readButton, *m_writeButton; +private: + uint32_t m_address, m_value, m_cnvPage; + RegisterBlockWidget::ACCESS_PERMISSION m_accessPermission; - RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t cnvPage, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent = nullptr); - virtual ~RegisterBlockWidget(); - QPushButton *readButton(); - QPushButton *writeButton(); - uint32_t getAddress(); - uint32_t getCnvPage(); - uint32_t getValue(); - void setValue(uint32_t value); - RegisterBlockWidget::ACCESS_PERMISSION getAccessPermission(); - public Q_SLOTS: - void onValueChanged(int); - private: - uint32_t m_address, m_value, m_cnvPage; - RegisterBlockWidget::ACCESS_PERMISSION m_accessPermission; + QSpinBox *m_spinBox; - QSpinBox *m_spinBox; + void addReadButton(QWidget *parent); + void addWriteButton(QWidget *parent); +}; - void addReadButton(QWidget *parent); - void addWriteButton(QWidget *parent); - }; +class SCOPY_ADMT_EXPORT PaddedSpinBox : public QSpinBox { + Q_OBJECT +public: + PaddedSpinBox(QWidget *parent = nullptr); + virtual ~PaddedSpinBox(); - class SCOPY_ADMT_EXPORT PaddedSpinBox : public QSpinBox - { - Q_OBJECT - public: - PaddedSpinBox(QWidget *parent = nullptr); - virtual ~PaddedSpinBox(); - protected: - QString textFromValue(int value) const override; - }; +protected: + QString textFromValue(int value) const override; +}; } // namespace scopy::admt #endif // REGISTERBLOCKWIDGET_H \ No newline at end of file diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 7c7deaab09..68abd1341d 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -21,22 +21,22 @@ #include "admtcontroller.h" -#include -#include -#include #include +#include +#include +#include +#include #include -#include +#include +#include #include -#include -#include -#include +#include +#include #include #include -#include -#include -#include +#include #include +#include static const size_t maxAttrSize = 512; @@ -46,1724 +46,1887 @@ using namespace scopy::admt; using namespace std; ADMTController::ADMTController(QString uri, QObject *parent) - :QObject(parent) - , uri(uri) -{ - connect(this, &ADMTController::streamData, this, &ADMTController::handleStreamData); - connect(this, &ADMTController::streamBufferedData, this, &ADMTController::handleStreamBufferedData); - connect(this, &ADMTController::streamBufferedDataInterval, this, &ADMTController::handleStreamBufferedDataInterval); + : QObject(parent), uri(uri) { + connect(this, &ADMTController::streamData, this, + &ADMTController::handleStreamData); + connect(this, &ADMTController::streamBufferedData, this, + &ADMTController::handleStreamBufferedData); + connect(this, &ADMTController::streamBufferedDataInterval, this, + &ADMTController::handleStreamBufferedDataInterval); } ADMTController::~ADMTController() {} -void ADMTController::connectADMT() -{ - m_conn = ConnectionProvider::open(uri); - m_iioCtx = m_conn->context(); +void ADMTController::connectADMT() { + m_conn = ConnectionProvider::open(uri); + m_iioCtx = m_conn->context(); } -void ADMTController::disconnectADMT() -{ - if(!m_conn || !m_iioCtx){ - return; - } - - ConnectionProvider::close(uri); - m_conn = nullptr; - m_iioCtx = nullptr; +void ADMTController::disconnectADMT() { + if (!m_conn || !m_iioCtx) { + return; + } + + ConnectionProvider::close(uri); + m_conn = nullptr; + m_iioCtx = nullptr; } -const char* ADMTController::getChannelId(Channel channel) -{ - if(channel >= 0 && channel < CHANNEL_COUNT){ - return ChannelIds[channel]; - } - return "Unknown"; +const char *ADMTController::getChannelId(Channel channel) { + if (channel >= 0 && channel < CHANNEL_COUNT) { + return ChannelIds[channel]; + } + return "Unknown"; } -const char* ADMTController::getDeviceId(Device device) -{ - if(device >= 0 && device < DEVICE_COUNT){ - return DeviceIds[device]; - } - return "Unknown"; +const char *ADMTController::getDeviceId(Device device) { + if (device >= 0 && device < DEVICE_COUNT) { + return DeviceIds[device]; + } + return "Unknown"; } -const char* ADMTController::getDeviceAttribute(DeviceAttribute attribute) -{ - if(attribute >= 0 && attribute < DEVICE_ATTR_COUNT){ - return DeviceAttributes[attribute]; - } - return "Unknown"; +const char *ADMTController::getDeviceAttribute(DeviceAttribute attribute) { + if (attribute >= 0 && attribute < DEVICE_ATTR_COUNT) { + return DeviceAttributes[attribute]; + } + return "Unknown"; } -const char* ADMTController::getMotorAttribute(MotorAttribute attribute) -{ - if(attribute >= 0 && attribute < MOTOR_ATTR_COUNT){ - return MotorAttributes[attribute]; - } - return "Unknown"; +const char *ADMTController::getMotorAttribute(MotorAttribute attribute) { + if (attribute >= 0 && attribute < MOTOR_ATTR_COUNT) { + return MotorAttributes[attribute]; + } + return "Unknown"; } -const uint32_t ADMTController::getHarmonicRegister(HarmonicRegister registerID) -{ - if(registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT){ - return HarmonicRegisters[registerID]; - } - return UINT32_MAX; +const uint32_t +ADMTController::getHarmonicRegister(HarmonicRegister registerID) { + if (registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT) { + return HarmonicRegisters[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getHarmonicPage(HarmonicRegister registerID) -{ - if(registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT){ - return HarmonicPages[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getHarmonicPage(HarmonicRegister registerID) { + if (registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT) { + return HarmonicPages[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getConfigurationRegister(ConfigurationRegister registerID) -{ - if(registerID >= 0 && registerID < CONFIGURATION_REGISTER_COUNT){ - return ConfigurationRegisters[registerID]; - } - return UINT32_MAX; +const uint32_t +ADMTController::getConfigurationRegister(ConfigurationRegister registerID) { + if (registerID >= 0 && registerID < CONFIGURATION_REGISTER_COUNT) { + return ConfigurationRegisters[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getConfigurationPage(ConfigurationRegister registerID) -{ - if(registerID >= 0 && registerID < CONFIGURATION_REGISTER_COUNT){ - return ConfigurationPages[registerID]; - } - return UINT32_MAX; +const uint32_t +ADMTController::getConfigurationPage(ConfigurationRegister registerID) { + if (registerID >= 0 && registerID < CONFIGURATION_REGISTER_COUNT) { + return ConfigurationPages[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getSensorRegister(SensorRegister registerID) -{ - if(registerID >= 0 && registerID < SENSOR_REGISTER_COUNT){ - return SensorRegisters[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getSensorRegister(SensorRegister registerID) { + if (registerID >= 0 && registerID < SENSOR_REGISTER_COUNT) { + return SensorRegisters[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getSensorPage(SensorRegister registerID) -{ - if(registerID >= 0 && registerID < SENSOR_REGISTER_COUNT){ - return SensorPages[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getSensorPage(SensorRegister registerID) { + if (registerID >= 0 && registerID < SENSOR_REGISTER_COUNT) { + return SensorPages[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getUniqueIdRegister(UniqueIDRegister registerID) -{ - if(registerID >= 0 && registerID < UNIQID_REGISTER_COUNT){ - return UniqueIdRegisters[registerID]; - } - return UINT32_MAX; +const uint32_t +ADMTController::getUniqueIdRegister(UniqueIDRegister registerID) { + if (registerID >= 0 && registerID < UNIQID_REGISTER_COUNT) { + return UniqueIdRegisters[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getUniqueIdPage(UniqueIDRegister registerID) -{ - if(registerID >= 0 && registerID < UNIQID_REGISTER_COUNT){ - return UniqueIdPages[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getUniqueIdPage(UniqueIDRegister registerID) { + if (registerID >= 0 && registerID < UNIQID_REGISTER_COUNT) { + return UniqueIdPages[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getRampGeneratorDriverFeatureControlRegister(RampGeneratorDriverFeatureControlRegister registerID) -{ - if(registerID >= 0 && registerID < RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT){ - return RampGeneratorDriverFeatureControlRegisters[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getRampGeneratorDriverFeatureControlRegister( + RampGeneratorDriverFeatureControlRegister registerID) { + if (registerID >= 0 && + registerID < RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT) { + return RampGeneratorDriverFeatureControlRegisters[registerID]; + } + return UINT32_MAX; } -int ADMTController::getChannelIndex(const char *deviceName, const char *channelName) -{ - iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); - if(admtDevice == NULL) { return -1; } - int channelCount = iio_device_get_channels_count(admtDevice); - iio_channel *channel; - std::string message = ""; - for(int i = 0; i < channelCount; i++){ - channel = iio_device_get_channel(admtDevice, i); - const char *deviceChannel = iio_channel_get_id(channel); - - std::string strDeviceChannel = std::string(deviceChannel); - std::string strChannelName = std::string(channelName); - - if(deviceChannel != nullptr && strDeviceChannel == strChannelName){ - message = message + "[" + std::to_string(i) + "]" + std::string(deviceChannel) + ", "; - return iio_channel_get_index(channel); - } - else { - channel = NULL; - } - } - return -1; +int ADMTController::getChannelIndex(const char *deviceName, + const char *channelName) { + iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); + if (admtDevice == NULL) { + return -1; + } + int channelCount = iio_device_get_channels_count(admtDevice); + iio_channel *channel; + std::string message = ""; + for (int i = 0; i < channelCount; i++) { + channel = iio_device_get_channel(admtDevice, i); + const char *deviceChannel = iio_channel_get_id(channel); + + std::string strDeviceChannel = std::string(deviceChannel); + std::string strChannelName = std::string(channelName); + + if (deviceChannel != nullptr && strDeviceChannel == strChannelName) { + message = message + "[" + std::to_string(i) + "]" + + std::string(deviceChannel) + ", "; + return iio_channel_get_index(channel); + } else { + channel = NULL; + } + } + return -1; } -double ADMTController::getChannelValue(const char *deviceName, const char *channelName, int bufferSize) -{ - if(!m_iioCtx){ return static_cast(UINT64_MAX); } // return QString("No context available."); - double value; - - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if(deviceCount < 1) return static_cast(UINT64_MAX); // return QString("No devices found"); - - iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); - if(admtDevice == NULL) return static_cast(UINT64_MAX); // return QString("No ADMT4000 device"); - - int channelCount = iio_device_get_channels_count(admtDevice); - if(channelCount < 1) return static_cast(UINT64_MAX); // return QString("No channels found."); - - iio_channel *channel; - std::string message = ""; - for(int i = 0; i < channelCount; i++){ - channel = iio_device_get_channel(admtDevice, i); - const char *deviceChannel = iio_channel_get_id(channel); - - if(deviceChannel != nullptr && std::string(deviceChannel) == std::string(channelName)){ - message = message + "[" + std::to_string(i) + "]" + std::string(deviceChannel) + ", "; - break; - } - else { - channel = NULL; - } - } - if(channel == NULL) return static_cast(UINT64_MAX); // return QString("Channel not found."); - iio_channel_enable(channel); - - double scale = 1.0; - int offsetAttrVal = 0; - const char *scaleAttrName = "scale"; - const char *offsetAttrName = "offset"; - const char *scaleAttr = iio_channel_find_attr(channel, scaleAttrName); - if(scaleAttr == NULL) return static_cast(UINT64_MAX); // return QString("No scale attribute"); - const char *offsetAttr = iio_channel_find_attr(channel, offsetAttrName); - if(offsetAttr == NULL) return static_cast(UINT64_MAX); // return QString("No offset attribute"); - - double *scaleVal = new double(1); - int scaleRet = iio_channel_attr_read_double(channel, scaleAttr, scaleVal); - if(scaleRet != 0) return static_cast(UINT64_MAX); // return QString("Cannot read scale attribute"); - scale = *scaleVal; - - char *offsetDst = new char[maxAttrSize]; - iio_channel_attr_read(channel, offsetAttr, offsetDst, maxAttrSize); - offsetAttrVal = std::atoi(offsetDst); - - iio_buffer *iioBuffer = iio_device_create_buffer(admtDevice, bufferSize, false); - if(iioBuffer == NULL) return static_cast(UINT64_MAX); // return QString("Cannot create buffer."); - - ssize_t numBytesRead; - int8_t *pointerData, *pointerEnd; - void *buffer; - ptrdiff_t pointerIncrement; - - numBytesRead = iio_buffer_refill(iioBuffer); - if(numBytesRead < 0) return static_cast(UINT64_MAX); // return QString("Cannot refill buffer."); - - pointerIncrement = reinterpret_cast(iio_buffer_step(iioBuffer)); - pointerEnd = static_cast(iio_buffer_end(iioBuffer)); - - const struct iio_data_format *format = iio_channel_get_data_format(channel); - const struct iio_data_format channelFormat = *format; - unsigned int repeat = channelFormat.repeat; - uint8_t bitLength = static_cast(channelFormat.bits); - size_t offset = static_cast(channelFormat.shift); - - QString result; - std::list rawSamples; - // std::list unsignedSamples; - std::list castSamples; - - size_t sample, bytes; - - size_t sampleSize = channelFormat.length / 8 * repeat; - //if(sampleSize == 0) return QString("Sample size is zero."); - - buffer = malloc(sampleSize * bufferSize); - //if(!buffer) return QString("Cannot allocate memory for buffer."); - - bytes = iio_channel_read(channel, iioBuffer, buffer, sampleSize * bufferSize); - for(sample = 0; sample < bytes / sampleSize; ++sample) - { - for(int j = 0; j < repeat; ++j) - { - if(channelFormat.length / 8 == sizeof(int16_t)) - { - rawSamples.push_back(*((int8_t*)buffer)); - int16_t rawValue = ((int16_t*)buffer)[sample+j]; - castSamples.push_back(rawValue); - value = (rawValue - static_cast(offsetAttrVal)) * scale; - result = QString::number(value); - } - } - } - - message = message + result.toStdString(); - iio_buffer_destroy(iioBuffer); - return value; //QString::fromStdString(message); +double ADMTController::getChannelValue(const char *deviceName, + const char *channelName, + int bufferSize) { + if (!m_iioCtx) { + return static_cast(UINT64_MAX); + } // return QString("No context available."); + double value; + + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if (deviceCount < 1) + return static_cast( + UINT64_MAX); // return QString("No devices found"); + + iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); + if (admtDevice == NULL) + return static_cast( + UINT64_MAX); // return QString("No ADMT4000 device"); + + int channelCount = iio_device_get_channels_count(admtDevice); + if (channelCount < 1) + return static_cast( + UINT64_MAX); // return QString("No channels found."); + + iio_channel *channel; + std::string message = ""; + for (int i = 0; i < channelCount; i++) { + channel = iio_device_get_channel(admtDevice, i); + const char *deviceChannel = iio_channel_get_id(channel); + + if (deviceChannel != nullptr && + std::string(deviceChannel) == std::string(channelName)) { + message = message + "[" + std::to_string(i) + "]" + + std::string(deviceChannel) + ", "; + break; + } else { + channel = NULL; + } + } + if (channel == NULL) + return static_cast( + UINT64_MAX); // return QString("Channel not found."); + iio_channel_enable(channel); + + double scale = 1.0; + int offsetAttrVal = 0; + const char *scaleAttrName = "scale"; + const char *offsetAttrName = "offset"; + const char *scaleAttr = iio_channel_find_attr(channel, scaleAttrName); + if (scaleAttr == NULL) + return static_cast( + UINT64_MAX); // return QString("No scale attribute"); + const char *offsetAttr = iio_channel_find_attr(channel, offsetAttrName); + if (offsetAttr == NULL) + return static_cast( + UINT64_MAX); // return QString("No offset attribute"); + + double *scaleVal = new double(1); + int scaleRet = iio_channel_attr_read_double(channel, scaleAttr, scaleVal); + if (scaleRet != 0) + return static_cast( + UINT64_MAX); // return QString("Cannot read scale attribute"); + scale = *scaleVal; + + char *offsetDst = new char[maxAttrSize]; + iio_channel_attr_read(channel, offsetAttr, offsetDst, maxAttrSize); + offsetAttrVal = std::atoi(offsetDst); + + iio_buffer *iioBuffer = + iio_device_create_buffer(admtDevice, bufferSize, false); + if (iioBuffer == NULL) + return static_cast( + UINT64_MAX); // return QString("Cannot create buffer."); + + ssize_t numBytesRead; + int8_t *pointerData, *pointerEnd; + void *buffer; + ptrdiff_t pointerIncrement; + + numBytesRead = iio_buffer_refill(iioBuffer); + if (numBytesRead < 0) + return static_cast( + UINT64_MAX); // return QString("Cannot refill buffer."); + + pointerIncrement = reinterpret_cast(iio_buffer_step(iioBuffer)); + pointerEnd = static_cast(iio_buffer_end(iioBuffer)); + + const struct iio_data_format *format = iio_channel_get_data_format(channel); + const struct iio_data_format channelFormat = *format; + unsigned int repeat = channelFormat.repeat; + uint8_t bitLength = static_cast(channelFormat.bits); + size_t offset = static_cast(channelFormat.shift); + + QString result; + std::list rawSamples; + // std::list unsignedSamples; + std::list castSamples; + + size_t sample, bytes; + + size_t sampleSize = channelFormat.length / 8 * repeat; + // if(sampleSize == 0) return QString("Sample size is zero."); + + buffer = malloc(sampleSize * bufferSize); + // if(!buffer) return QString("Cannot allocate memory for buffer."); + + bytes = iio_channel_read(channel, iioBuffer, buffer, sampleSize * bufferSize); + for (sample = 0; sample < bytes / sampleSize; ++sample) { + for (int j = 0; j < repeat; ++j) { + if (channelFormat.length / 8 == sizeof(int16_t)) { + rawSamples.push_back(*((int8_t *)buffer)); + int16_t rawValue = ((int16_t *)buffer)[sample + j]; + castSamples.push_back(rawValue); + value = (rawValue - static_cast(offsetAttrVal)) * scale; + result = QString::number(value); + } + } + } + + message = message + result.toStdString(); + iio_buffer_destroy(iioBuffer); + return value; // QString::fromStdString(message); } /** @brief Get the attribute value of a device * @param deviceName A pointer to the device name - * @param attributeName A NULL-terminated string corresponding to the name of the - * attribute - * @param returnValue A pointer to a double variable where the value should be stored + * @param attributeName A NULL-terminated string corresponding to the name of + * the attribute + * @param returnValue A pointer to a double variable where the value should be + * stored * @return On success, 0 is returned. * @return On error, -1 is returned. */ -int ADMTController::getDeviceAttributeValue(const char *deviceName, const char *attributeName, double *returnValue) -{ - if(!m_iioCtx) { return -1; } - int result = -1; - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if(deviceCount == 0) { return result; } - iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); - if(iioDevice == NULL) { return result; } - const char* hasAttr = iio_device_find_attr(iioDevice, attributeName); - if(hasAttr == NULL) { return result; } - result = iio_device_attr_read_double(iioDevice, attributeName, returnValue); - +int ADMTController::getDeviceAttributeValue(const char *deviceName, + const char *attributeName, + double *returnValue) { + if (!m_iioCtx) { + return -1; + } + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if (deviceCount == 0) { return result; -} + } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if (iioDevice == NULL) { + return result; + } + const char *hasAttr = iio_device_find_attr(iioDevice, attributeName); + if (hasAttr == NULL) { + return result; + } + result = iio_device_attr_read_double(iioDevice, attributeName, returnValue); -int ADMTController::getDeviceAttributeValueString(const char *deviceName, const char *attributeName, char *returnValue, size_t byteLength) -{ - if(!m_iioCtx) { return -1; } - int result = -1; - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if(deviceCount == 0) { return result; } - iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); - if(iioDevice == NULL) { return result; } - const char* hasAttr = iio_device_find_attr(iioDevice, attributeName); - if(hasAttr == NULL) { return result; } - result = iio_device_attr_read(iioDevice, attributeName, returnValue, byteLength); + return result; +} +int ADMTController::getDeviceAttributeValueString(const char *deviceName, + const char *attributeName, + char *returnValue, + size_t byteLength) { + if (!m_iioCtx) { + return -1; + } + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if (deviceCount == 0) { return result; + } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if (iioDevice == NULL) { + return result; + } + const char *hasAttr = iio_device_find_attr(iioDevice, attributeName); + if (hasAttr == NULL) { + return result; + } + result = + iio_device_attr_read(iioDevice, attributeName, returnValue, byteLength); + + return result; } /** @brief Set the attribute value of a device * @param deviceName A pointer to the device name - * @param attributeName A NULL-terminated string corresponding to the name of the - * attribute + * @param attributeName A NULL-terminated string corresponding to the name of + * the attribute * @param writeValue A double variable of the value to be set * @return On success, 0 is returned. * @return On error, -1 is returned. */ -int ADMTController::setDeviceAttributeValue(const char *deviceName, const char *attributeName, double writeValue) -{ - if(!m_iioCtx) { return -1; } - int result = -1; - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if(deviceCount == 0) { return result; } - iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); - if(iioDevice == NULL) { return result; } - const char* hasAttr = iio_device_find_attr(iioDevice, attributeName); - if(hasAttr == NULL) { return result; } - result = iio_device_attr_write_double(iioDevice, attributeName, writeValue); - +int ADMTController::setDeviceAttributeValue(const char *deviceName, + const char *attributeName, + double writeValue) { + if (!m_iioCtx) { + return -1; + } + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if (deviceCount == 0) { return result; -} + } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if (iioDevice == NULL) { + return result; + } + const char *hasAttr = iio_device_find_attr(iioDevice, attributeName); + if (hasAttr == NULL) { + return result; + } + result = iio_device_attr_write_double(iioDevice, attributeName, writeValue); -int ADMTController::writeDeviceRegistry(const char *deviceName, uint32_t address, uint32_t value) -{ - if(!m_iioCtx) { return -1; } - int result = -1; - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if(deviceCount == 0) { return result; } - iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); - if(iioDevice == NULL) { return result; } - result = iio_device_reg_write(iioDevice, address, value); + return result; +} +int ADMTController::writeDeviceRegistry(const char *deviceName, + uint32_t address, uint32_t value) { + if (!m_iioCtx) { + return -1; + } + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if (deviceCount == 0) { return result; -} + } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if (iioDevice == NULL) { + return result; + } + result = iio_device_reg_write(iioDevice, address, value); -int ADMTController::readDeviceRegistry(const char *deviceName, uint32_t address, uint32_t *returnValue) -{ - if(!m_iioCtx) { return -1; } - if(address == UINT32_MAX) { return -1; } - int result = -1; - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if(deviceCount == 0) { return result; } - iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); - if(iioDevice == NULL) { return result; } - result = iio_device_reg_read(iioDevice, address, returnValue); + return result; +} +int ADMTController::readDeviceRegistry(const char *deviceName, uint32_t address, + uint32_t *returnValue) { + if (!m_iioCtx) { + return -1; + } + if (address == UINT32_MAX) { + return -1; + } + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if (deviceCount == 0) { + return result; + } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if (iioDevice == NULL) { return result; + } + result = iio_device_reg_read(iioDevice, address, returnValue); + + return result; } /* bit reversal from online example */ unsigned int ADMTController::bitReverse(unsigned int x, int log2n) { - int n = 0; - int mask = 0x1; - for (int i = 0; i < log2n; i++) { - n <<= 1; - n |= (x & 1); - x >>= 1; - } - return n; + int n = 0; + int mask = 0x1; + for (int i = 0; i < log2n; i++) { + n <<= 1; + n |= (x & 1); + x >>= 1; + } + return n; } -template -void ADMTController::fft(Iter_T a, Iter_T b, int log2n) -{ - typedef typename iterator_traits::value_type complex; - const complex J(0, 1); - int n = 1 << log2n; - for (unsigned int i = 0; i < n; ++i) { - b[bitReverse(i, log2n)] = a[i]; - } - for (int s = 1; s <= log2n; ++s) { - int m = 1 << s; - int m2 = m >> 1; - complex w(1, 0); - complex wm = exp(-J * (M_PI / m2)); - for (int j = 0; j < m2; ++j) { - for (int k = j; k < n; k += m) { - complex t = w * b[k + m2]; - complex u = b[k]; - b[k] = u + t; - b[k + m2] = u - t; - } - w *= wm; - } +template +void ADMTController::fft(Iter_T a, Iter_T b, int log2n) { + typedef typename iterator_traits::value_type complex; + const complex J(0, 1); + int n = 1 << log2n; + for (unsigned int i = 0; i < n; ++i) { + b[bitReverse(i, log2n)] = a[i]; + } + for (int s = 1; s <= log2n; ++s) { + int m = 1 << s; + int m2 = m >> 1; + complex w(1, 0); + complex wm = exp(-J * (M_PI / m2)); + for (int j = 0; j < m2; ++j) { + for (int k = j; k < n; k += m) { + complex t = w * b[k + m2]; + complex u = b[k]; + b[k] = u + t; + b[k + m2] = u - t; + } + w *= wm; } + } } -/* For linear fitting (hard-coded based on examples and formula for polynomial fitting) */ -int ADMTController::linear_fit(vector x, vector y, double* slope, double* intercept) -{ - /* x, y, x^2, y^2, xy, xy^2 */ - double sum_x = 0, sum_y = 0, sum_x2 = 0, sum_y2 = 0, sum_xy = 0; - int i; - - if (x.size() != y.size()) - return -22; - - for (i = 0; i < x.size(); i++) { - sum_x += x[i]; - sum_y += y[i]; - sum_x2 += (x[i] * x[i]); - sum_y2 += (y[i] * y[i]); - sum_xy += (x[i] * y[i]); - } +/* For linear fitting (hard-coded based on examples and formula for polynomial + * fitting) */ +int ADMTController::linear_fit(vector x, vector y, + double *slope, double *intercept) { + /* x, y, x^2, y^2, xy, xy^2 */ + double sum_x = 0, sum_y = 0, sum_x2 = 0, sum_y2 = 0, sum_xy = 0; + int i; - *slope = (x.size() * sum_xy - sum_x * sum_y) / (x.size() * sum_x2 - sum_x * sum_x); + if (x.size() != y.size()) + return -22; - *intercept = (sum_y * sum_x2 - sum_x * sum_xy) / (x.size() * sum_x2 - sum_x * sum_x); + for (i = 0; i < x.size(); i++) { + sum_x += x[i]; + sum_y += y[i]; + sum_x2 += (x[i] * x[i]); + sum_y2 += (y[i] * y[i]); + sum_xy += (x[i] * y[i]); + } - return 0; -} - -int ADMTController::calculate_angle_error(vector angle_meas, vector& angle_error_ret, double* max_angle_err) -{ - vector angle_meas_rad(angle_meas.size()); // radian converted input - vector angle_meas_rad_unwrap(angle_meas.size()); // unwrapped radian input - vector angle_fit(angle_meas.size()); // array for polynomial fitted data - vector x_data(angle_meas.size()); - double coeff_a, coeff_b; // coefficients generated by polynomial fitting - - // convert to radian - for (int i = 0; i < angle_meas_rad.size(); i++) - angle_meas_rad[i] = angle_meas[i] * M_PI / 180.0; - - // unwrap angle (extracted from decompiled Angle GSF Unit) - double num = 0.0; - angle_meas_rad_unwrap[0] = angle_meas_rad[0]; - for (int i = 1; i < angle_meas_rad.size(); i++) - { - double num2 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1]); - double num3 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] + M_PI * 2.0); - double num4 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] - M_PI * 2.0); - if (num3 < num2 && num3 < num4) - num += M_PI * 2.0; - - else if (num4 < num2 && num4 < num3) - num -= M_PI * 2.0; - - angle_meas_rad_unwrap[i] = angle_meas_rad[i] + num; - } + *slope = + (x.size() * sum_xy - sum_x * sum_y) / (x.size() * sum_x2 - sum_x * sum_x); - // set initial point to zero - double offset = angle_meas_rad_unwrap[0]; - for (int i = 0; i < angle_meas_rad_unwrap.size(); ++i) - angle_meas_rad_unwrap[i] -= offset; + *intercept = + (sum_y * sum_x2 - sum_x * sum_xy) / (x.size() * sum_x2 - sum_x * sum_x); - /* Generate xdata for polynomial fitting */ - iota(x_data.begin(), x_data.end(), 1); - - // linear angle fitting (generated coefficients not same with matlab and python) - // expecting 0.26 -0.26 - // getting ~0.27 ~-0.27 as of 4/2/2024 - /* input args: x, y, *slope, *intercept */ - linear_fit(x_data, angle_meas_rad_unwrap, &coeff_a, &coeff_b); - - // generate data using coefficients from polynomial fitting - for (int i = 0; i < angle_fit.size(); i++) { - angle_fit[i] = coeff_a * x_data[i]; - } - - // get angle error using pass by ref angle_error_ret - for (int i = 0; i < angle_error_ret.size(); i++) { - angle_error_ret[i] = angle_meas_rad_unwrap[i] - angle_fit[i]; - //cout << "angle_err_ret " << angle_error_ret[i] << "\n"; - } - - // Find the offset for error and subtract (using angle_error_ret) - auto minmax = minmax_element(angle_error_ret.begin(), angle_error_ret.end()); - double angle_err_offset = (*minmax.first + *minmax.second) / 2; - - for (int i = 0; i < angle_error_ret.size(); i++) - angle_error_ret[i] -= angle_err_offset; - - // Convert back to degrees (angle_error_ret) - for (int i = 0; i < angle_meas.size(); i++) - angle_error_ret[i] *= (180 / M_PI); - - // Find maximum absolute angle error - *max_angle_err = *minmax.second; + return 0; +} - return 0; +int ADMTController::calculate_angle_error(vector angle_meas, + vector &angle_error_ret, + double *max_angle_err) { + vector angle_meas_rad(angle_meas.size()); // radian converted input + vector angle_meas_rad_unwrap( + angle_meas.size()); // unwrapped radian input + vector angle_fit( + angle_meas.size()); // array for polynomial fitted data + vector x_data(angle_meas.size()); + double coeff_a, coeff_b; // coefficients generated by polynomial fitting + + // convert to radian + for (int i = 0; i < angle_meas_rad.size(); i++) + angle_meas_rad[i] = angle_meas[i] * M_PI / 180.0; + + // unwrap angle (extracted from decompiled Angle GSF Unit) + double num = 0.0; + angle_meas_rad_unwrap[0] = angle_meas_rad[0]; + for (int i = 1; i < angle_meas_rad.size(); i++) { + double num2 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1]); + double num3 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] + + M_PI * 2.0); + double num4 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] - + M_PI * 2.0); + if (num3 < num2 && num3 < num4) + num += M_PI * 2.0; + + else if (num4 < num2 && num4 < num3) + num -= M_PI * 2.0; + + angle_meas_rad_unwrap[i] = angle_meas_rad[i] + num; + } + + // set initial point to zero + double offset = angle_meas_rad_unwrap[0]; + for (int i = 0; i < angle_meas_rad_unwrap.size(); ++i) + angle_meas_rad_unwrap[i] -= offset; + + /* Generate xdata for polynomial fitting */ + iota(x_data.begin(), x_data.end(), 1); + + // linear angle fitting (generated coefficients not same with matlab and + // python) expecting 0.26 -0.26 getting ~0.27 ~-0.27 as of 4/2/2024 + /* input args: x, y, *slope, *intercept */ + linear_fit(x_data, angle_meas_rad_unwrap, &coeff_a, &coeff_b); + + // generate data using coefficients from polynomial fitting + for (int i = 0; i < angle_fit.size(); i++) { + angle_fit[i] = coeff_a * x_data[i]; + } + + // get angle error using pass by ref angle_error_ret + for (int i = 0; i < angle_error_ret.size(); i++) { + angle_error_ret[i] = angle_meas_rad_unwrap[i] - angle_fit[i]; + // cout << "angle_err_ret " << angle_error_ret[i] << "\n"; + } + + // Find the offset for error and subtract (using angle_error_ret) + auto minmax = minmax_element(angle_error_ret.begin(), angle_error_ret.end()); + double angle_err_offset = (*minmax.first + *minmax.second) / 2; + + for (int i = 0; i < angle_error_ret.size(); i++) + angle_error_ret[i] -= angle_err_offset; + + // Convert back to degrees (angle_error_ret) + for (int i = 0; i < angle_meas.size(); i++) + angle_error_ret[i] *= (180 / M_PI); + + // Find maximum absolute angle error + *max_angle_err = *minmax.second; + + return 0; } // Function to unwrap angles that can span multiple cycles -void ADMTController::unwrapAngles(vector& angles_rad) { - for (size_t i = 1; i < angles_rad.size(); ++i) { - // Calculate the difference between the current angle and the previous one - double diff = angles_rad[i] - angles_rad[i-1]; - - // If the difference is greater than pi, subtract 2*pi (unwrap backward) - if (diff > M_PI) { - angles_rad[i] -= 2 * M_PI; - } - // If the difference is less than -pi, add 2*pi (unwrap forward) - else if (diff < -M_PI) { - angles_rad[i] += 2 * M_PI; - } +void ADMTController::unwrapAngles(vector &angles_rad) { + for (size_t i = 1; i < angles_rad.size(); ++i) { + // Calculate the difference between the current angle and the previous one + double diff = angles_rad[i] - angles_rad[i - 1]; + + // If the difference is greater than pi, subtract 2*pi (unwrap backward) + if (diff > M_PI) { + angles_rad[i] -= 2 * M_PI; } -} - -QString ADMTController::calibrate(vector PANG, int cycleCount, int samplesPerCycle, bool CCW) { - int circshiftData = 0; - QString result = ""; - - /* Check CCW flag to know if array is to be reversed */ - if (CCW) - reverse(PANG.begin(), PANG.end()); - - /* Randomize starting point of array */ - if (circshiftData) { - int shift = rand() % PANG.size(); - rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); + // If the difference is less than -pi, add 2*pi (unwrap forward) + else if (diff < -M_PI) { + angles_rad[i] += 2 * M_PI; } - - // Declare vectors for pre-calibration FFT results - angle_errors_fft_pre = vector(PANG.size() / 2); - angle_errors_fft_phase_pre = vector(PANG.size() / 2); - - // Call the new function for pre-calibration FFT - getPreCalibrationFFT(PANG, angle_errors_fft_pre, angle_errors_fft_phase_pre, cycleCount, samplesPerCycle); - - // Extract HMag parameters - double H1Mag = angle_errors_fft_pre[cycleCount]; - double H2Mag = angle_errors_fft_pre[2 * cycleCount]; - double H3Mag = angle_errors_fft_pre[3 * cycleCount]; - double H8Mag = angle_errors_fft_pre[8 * cycleCount]; - - /* Display HMAG values */ - result.append("H1Mag = " + QString::number(H1Mag) + "\n"); - result.append("H2Mag = " + QString::number(H2Mag) + "\n"); - result.append("H3Mag = " + QString::number(H3Mag) + "\n"); - result.append("H8Mag = " + QString::number(H8Mag) + "\n"); - - // Extract HPhase parameters - double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycleCount]); - double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycleCount]); - double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycleCount]); - double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycleCount]); - - /* Display HPHASE values */ - result.append("H1Phase = " + QString::number(H1Phase) + "\n"); - result.append("H2Phase = " + QString::number(H2Phase) + "\n"); - result.append("H3Phase = " + QString::number(H3Phase) + "\n"); - result.append("H8Phase = " + QString::number(H8Phase) + "\n"); - - double H1 = H1Mag * cos(M_PI / 180 * (H1Phase)); - double H2 = H2Mag * cos(M_PI / 180 * (H2Phase)); - double H3 = H3Mag * cos(M_PI / 180 * (H3Phase)); - double H8 = H8Mag * cos(M_PI / 180 * (H8Phase)); - - double init_err = H1 + H2 + H3 + H8; - double init_angle = PANG[0] - init_err; - - double H1PHcor, H2PHcor, H3PHcor, H8PHcor; - - /* Counterclockwise, slope of error FIT is negative */ - if (CCW) { - H1Phase *= -1; - H2Phase *= -1; - H3Phase *= -1; - H8Phase *= -1; - } - - /* Clockwise */ - H1PHcor = H1Phase - (1 * init_angle - 90); - H2PHcor = H2Phase - (2 * init_angle - 90); - H3PHcor = H3Phase - (3 * init_angle - 90); - H8PHcor = H8Phase - (8 * init_angle - 90); - - /* Get modulo from 360 */ - H1PHcor = (int)H1PHcor % 360; - H2PHcor = (int)H2PHcor % 360; - H3PHcor = (int)H3PHcor % 360; - H8PHcor = (int)H8PHcor % 360; - - // HMag Scaling - H1Mag = H1Mag * 0.6072; - H2Mag = H2Mag * 0.6072; - H3Mag = H3Mag * 0.6072; - H8Mag = H8Mag * 0.6072; - - // Derive register compatible HMAG values - double mag_scale_factor_11bit = 11.2455 / (1 << 11); - double mag_scale_factor_8bit = 1.40076 / (1 << 8); - HAR_MAG_1 = (int)(H1Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit - HAR_MAG_2 = (int)(H2Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit - HAR_MAG_3 = (int)(H3Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit - HAR_MAG_8 = (int)(H8Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit - - // Derive register compatible HPHASE values - double pha_scale_factor_12bit = 360.0 / (1 << 12); // in Deg - HAR_PHASE_1 = (int)(H1PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - HAR_PHASE_2 = (int)(H2PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - HAR_PHASE_3 = (int)(H3PHcor / pha_scale_factor_12bit) & (0xFFF);// 12bit number - HAR_PHASE_8 = (int)(H8PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - - result.append("HMAG1: " + QString::number(HAR_MAG_1) + "\n"); - result.append("HMAG2: " + QString::number(HAR_MAG_2) + "\n"); - result.append("HMAG3: " + QString::number(HAR_MAG_3) + "\n"); - result.append("HMAG8: " + QString::number(HAR_MAG_8) + "\n"); - - result.append("HPHASE1: " + QString::number(HAR_PHASE_1) + "\n"); - result.append("HPHASE2: " + QString::number(HAR_PHASE_2) + "\n"); - result.append("HPHASE3: " + QString::number(HAR_PHASE_3) + "\n"); - result.append("HPHASE8: " + QString::number(HAR_PHASE_8) + "\n"); - - return result; + } } -void ADMTController::getPreCalibrationFFT(const vector& PANG, vector& angle_errors_fft_pre, vector& angle_errors_fft_phase_pre, int cycleCount, int samplesPerCycle) { - // Calculate the angle errors before calibration - double max_err_pre = 0; - vector angle_errors_pre(PANG.size()); - - // Calculate angle errors - calculate_angle_error(PANG, angle_errors_pre, &max_err_pre); - // Store the calculated angle errors (angle_errors_pre) - angleError = angle_errors_pre; - - // Perform FFT on pre-calibration angle errors - performFFT(angle_errors_pre, angle_errors_fft_pre, angle_errors_fft_phase_pre, cycleCount); - - // Store the FFT Angle Error Magnitude and Phase - FFTAngleErrorMagnitude = angle_errors_fft_pre; - FFTAngleErrorPhase = angle_errors_fft_phase_pre; +QString ADMTController::calibrate(vector PANG, int cycleCount, + int samplesPerCycle, bool CCW) { + int circshiftData = 0; + QString result = ""; + + /* Check CCW flag to know if array is to be reversed */ + if (CCW) + reverse(PANG.begin(), PANG.end()); + + /* Randomize starting point of array */ + if (circshiftData) { + int shift = rand() % PANG.size(); + rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); + } + + // Declare vectors for pre-calibration FFT results + angle_errors_fft_pre = vector(PANG.size() / 2); + angle_errors_fft_phase_pre = vector(PANG.size() / 2); + + // Call the new function for pre-calibration FFT + getPreCalibrationFFT(PANG, angle_errors_fft_pre, angle_errors_fft_phase_pre, + cycleCount, samplesPerCycle); + + // Extract HMag parameters + double H1Mag = angle_errors_fft_pre[cycleCount]; + double H2Mag = angle_errors_fft_pre[2 * cycleCount]; + double H3Mag = angle_errors_fft_pre[3 * cycleCount]; + double H8Mag = angle_errors_fft_pre[8 * cycleCount]; + + /* Display HMAG values */ + result.append("H1Mag = " + QString::number(H1Mag) + "\n"); + result.append("H2Mag = " + QString::number(H2Mag) + "\n"); + result.append("H3Mag = " + QString::number(H3Mag) + "\n"); + result.append("H8Mag = " + QString::number(H8Mag) + "\n"); + + // Extract HPhase parameters + double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycleCount]); + double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycleCount]); + double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycleCount]); + double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycleCount]); + + /* Display HPHASE values */ + result.append("H1Phase = " + QString::number(H1Phase) + "\n"); + result.append("H2Phase = " + QString::number(H2Phase) + "\n"); + result.append("H3Phase = " + QString::number(H3Phase) + "\n"); + result.append("H8Phase = " + QString::number(H8Phase) + "\n"); + + double H1 = H1Mag * cos(M_PI / 180 * (H1Phase)); + double H2 = H2Mag * cos(M_PI / 180 * (H2Phase)); + double H3 = H3Mag * cos(M_PI / 180 * (H3Phase)); + double H8 = H8Mag * cos(M_PI / 180 * (H8Phase)); + + double init_err = H1 + H2 + H3 + H8; + double init_angle = PANG[0] - init_err; + + double H1PHcor, H2PHcor, H3PHcor, H8PHcor; + + /* Counterclockwise, slope of error FIT is negative */ + if (CCW) { + H1Phase *= -1; + H2Phase *= -1; + H3Phase *= -1; + H8Phase *= -1; + } + + /* Clockwise */ + H1PHcor = H1Phase - (1 * init_angle - 90); + H2PHcor = H2Phase - (2 * init_angle - 90); + H3PHcor = H3Phase - (3 * init_angle - 90); + H8PHcor = H8Phase - (8 * init_angle - 90); + + /* Get modulo from 360 */ + H1PHcor = (int)H1PHcor % 360; + H2PHcor = (int)H2PHcor % 360; + H3PHcor = (int)H3PHcor % 360; + H8PHcor = (int)H8PHcor % 360; + + // HMag Scaling + H1Mag = H1Mag * 0.6072; + H2Mag = H2Mag * 0.6072; + H3Mag = H3Mag * 0.6072; + H8Mag = H8Mag * 0.6072; + + // Derive register compatible HMAG values + double mag_scale_factor_11bit = 11.2455 / (1 << 11); + double mag_scale_factor_8bit = 1.40076 / (1 << 8); + HAR_MAG_1 = (int)(H1Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit + HAR_MAG_2 = (int)(H2Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit + HAR_MAG_3 = (int)(H3Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit + HAR_MAG_8 = (int)(H8Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit + + // Derive register compatible HPHASE values + double pha_scale_factor_12bit = 360.0 / (1 << 12); // in Deg + HAR_PHASE_1 = + (int)(H1PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + HAR_PHASE_2 = + (int)(H2PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + HAR_PHASE_3 = + (int)(H3PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + HAR_PHASE_8 = + (int)(H8PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + + result.append("HMAG1: " + QString::number(HAR_MAG_1) + "\n"); + result.append("HMAG2: " + QString::number(HAR_MAG_2) + "\n"); + result.append("HMAG3: " + QString::number(HAR_MAG_3) + "\n"); + result.append("HMAG8: " + QString::number(HAR_MAG_8) + "\n"); + + result.append("HPHASE1: " + QString::number(HAR_PHASE_1) + "\n"); + result.append("HPHASE2: " + QString::number(HAR_PHASE_2) + "\n"); + result.append("HPHASE3: " + QString::number(HAR_PHASE_3) + "\n"); + result.append("HPHASE8: " + QString::number(HAR_PHASE_8) + "\n"); + + return result; } -void ADMTController::postcalibrate(vector PANG, int cycleCount, int samplesPerCycle, bool CCW){ - int circshiftData = 0; - QString result = ""; - - /* Check CCW flag to know if array is to be reversed */ - if (CCW) - reverse(PANG.begin(), PANG.end()); - - /* Randomize starting point of array */ - if (circshiftData) { - int shift = rand() % PANG.size(); - rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); - } - - // Declare vectors for pre-calibration FFT results - angle_errors_fft_post = vector(PANG.size() / 2); - angle_errors_fft_phase_post = vector(PANG.size() / 2); - - // Call the new function for post-calibration FFT - getPostCalibrationFFT(PANG, angle_errors_fft_post, angle_errors_fft_phase_post, cycleCount, samplesPerCycle); +void ADMTController::getPreCalibrationFFT( + const vector &PANG, vector &angle_errors_fft_pre, + vector &angle_errors_fft_phase_pre, int cycleCount, + int samplesPerCycle) { + // Calculate the angle errors before calibration + double max_err_pre = 0; + vector angle_errors_pre(PANG.size()); + + // Calculate angle errors + calculate_angle_error(PANG, angle_errors_pre, &max_err_pre); + // Store the calculated angle errors (angle_errors_pre) + angleError = angle_errors_pre; + + // Perform FFT on pre-calibration angle errors + performFFT(angle_errors_pre, angle_errors_fft_pre, angle_errors_fft_phase_pre, + cycleCount); + + // Store the FFT Angle Error Magnitude and Phase + FFTAngleErrorMagnitude = angle_errors_fft_pre; + FFTAngleErrorPhase = angle_errors_fft_phase_pre; } -void ADMTController::getPostCalibrationFFT(const vector& updated_PANG, vector& angle_errors_fft_post, vector& angle_errors_fft_phase_post, int cycleCount, int samplesPerCycle) { - // Calculate the angle errors after calibration - double max_err_post = 0; - vector angle_errors_post(updated_PANG.size()); - - // Calculate angle errors - calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post); - // Corrected Error (angle_errors_post) - correctedError = angle_errors_post; - - // Perform FFT on post-calibration angle errors - performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post, cycleCount); - // FFT Corrected Error (angle_errors_fft_post) - FFTCorrectedErrorMagnitude = angle_errors_fft_post; - // FFT Corrected Error Phase (angle_errors_fft_phase_post) - FFTCorrectedErrorPhase = angle_errors_fft_phase_post; +void ADMTController::postcalibrate(vector PANG, int cycleCount, + int samplesPerCycle, bool CCW) { + int circshiftData = 0; + QString result = ""; + + /* Check CCW flag to know if array is to be reversed */ + if (CCW) + reverse(PANG.begin(), PANG.end()); + + /* Randomize starting point of array */ + if (circshiftData) { + int shift = rand() % PANG.size(); + rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); + } + + // Declare vectors for pre-calibration FFT results + angle_errors_fft_post = vector(PANG.size() / 2); + angle_errors_fft_phase_post = vector(PANG.size() / 2); + + // Call the new function for post-calibration FFT + getPostCalibrationFFT(PANG, angle_errors_fft_post, + angle_errors_fft_phase_post, cycleCount, + samplesPerCycle); } -void ADMTController::performFFT(const vector& angle_errors, vector& angle_errors_fft, vector& angle_errors_fft_phase, int cycleCount) { - typedef complex cx; - - int L = angle_errors.size(); // Original signal length (L) - int N = pow(2, ceil(log2(L))); // Ensure size is a power of 2 (padding if necessary) - - vector fft_in(N, cx(0, 0)); // Input signal (zero-padded if necessary) - vector fft_out(N); // Output signal (complex) - - // Format angle errors into the fft_in vector - for (int i = 0; i < L; i++) { - fft_in[i] = cx(angle_errors[i], 0); - } - - // Perform FFT - fft(fft_in.data(), fft_out.data(), log2(N)); - - // Temporary vectors to store magnitude and phase - vector angle_errors_fft_temp(N); - vector angle_errors_fft_phase_temp(N); - - // Calculate magnitude and phase for all values - for (int i = 0; i < N; i++) { - // Magnitude: Normalize by L (original signal length) - angle_errors_fft_temp[i] = abs(fft_out[i]) * 2.0 / L; - angle_errors_fft_phase_temp[i] = atan2(fft_out[i].imag(), fft_out[i].real()); - } - - // Prepare vectors for upper half of FFT (positive frequencies) - vector angle_errors_fft_upper_half(N / 2); - vector angle_errors_fft_phase_upper_half(N / 2); - - // Get upper half only (due to symmetry in real-valued signal FFT) - for (int i = 0; i < N / 2; i++) { - angle_errors_fft_upper_half[i] = angle_errors_fft_temp[i]; - angle_errors_fft_phase_upper_half[i] = angle_errors_fft_phase_temp[i]; - } +void ADMTController::getPostCalibrationFFT( + const vector &updated_PANG, vector &angle_errors_fft_post, + vector &angle_errors_fft_phase_post, int cycleCount, + int samplesPerCycle) { + // Calculate the angle errors after calibration + double max_err_post = 0; + vector angle_errors_post(updated_PANG.size()); + + // Calculate angle errors + calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post); + // Corrected Error (angle_errors_post) + correctedError = angle_errors_post; + + // Perform FFT on post-calibration angle errors + performFFT(angle_errors_post, angle_errors_fft_post, + angle_errors_fft_phase_post, cycleCount); + // FFT Corrected Error (angle_errors_fft_post) + FFTCorrectedErrorMagnitude = angle_errors_fft_post; + // FFT Corrected Error Phase (angle_errors_fft_phase_post) + FFTCorrectedErrorPhase = angle_errors_fft_phase_post; +} - // Resize final vectors based on cycle count (if needed) - angle_errors_fft = angle_errors_fft_upper_half; - angle_errors_fft_phase = angle_errors_fft_phase_upper_half; +void ADMTController::performFFT(const vector &angle_errors, + vector &angle_errors_fft, + vector &angle_errors_fft_phase, + int cycleCount) { + typedef complex cx; + + int L = angle_errors.size(); // Original signal length (L) + int N = pow( + 2, ceil(log2(L))); // Ensure size is a power of 2 (padding if necessary) + + vector fft_in(N, cx(0, 0)); // Input signal (zero-padded if necessary) + vector fft_out(N); // Output signal (complex) + + // Format angle errors into the fft_in vector + for (int i = 0; i < L; i++) { + fft_in[i] = cx(angle_errors[i], 0); + } + + // Perform FFT + fft(fft_in.data(), fft_out.data(), log2(N)); + + // Temporary vectors to store magnitude and phase + vector angle_errors_fft_temp(N); + vector angle_errors_fft_phase_temp(N); + + // Calculate magnitude and phase for all values + for (int i = 0; i < N; i++) { + // Magnitude: Normalize by L (original signal length) + angle_errors_fft_temp[i] = abs(fft_out[i]) * 2.0 / L; + angle_errors_fft_phase_temp[i] = + atan2(fft_out[i].imag(), fft_out[i].real()); + } + + // Prepare vectors for upper half of FFT (positive frequencies) + vector angle_errors_fft_upper_half(N / 2); + vector angle_errors_fft_phase_upper_half(N / 2); + + // Get upper half only (due to symmetry in real-valued signal FFT) + for (int i = 0; i < N / 2; i++) { + angle_errors_fft_upper_half[i] = angle_errors_fft_temp[i]; + angle_errors_fft_phase_upper_half[i] = angle_errors_fft_phase_temp[i]; + } + + // Resize final vectors based on cycle count (if needed) + angle_errors_fft = angle_errors_fft_upper_half; + angle_errors_fft_phase = angle_errors_fft_phase_upper_half; } -void ADMTController::computeSineCosineOfAngles(const vector& angles) { - // Vectors to store sine and cosine values - calibration_samples_sine = vector(angles.size()); - calibration_samples_cosine = vector(angles.size()); - calibration_samples_sine_scaled = vector(angles.size()); - calibration_samples_cosine_scaled = vector(angles.size()); - - const double scaleMin = 0.0; - const double scaleMax = 360.0; - - // Convert angles to radians and compute sine, cosine, and their scaled versions - for (size_t i = 0; i < angles.size(); ++i) { - double radians = angles[i] * M_PI / 180.0; // Convert degrees to radians - calibration_samples_sine[i] = sin(radians); - calibration_samples_cosine[i] = cos(radians); - - // Scale sine and cosine to the range 0 to 360 - calibration_samples_sine_scaled[i] = ((calibration_samples_sine[i] + 1) / 2) * (scaleMax - scaleMin) + scaleMin; - calibration_samples_cosine_scaled[i] = ((calibration_samples_cosine[i] + 1) / 2) * (scaleMax - scaleMin) + scaleMin; - } +void ADMTController::computeSineCosineOfAngles(const vector &angles) { + // Vectors to store sine and cosine values + calibration_samples_sine = vector(angles.size()); + calibration_samples_cosine = vector(angles.size()); + calibration_samples_sine_scaled = vector(angles.size()); + calibration_samples_cosine_scaled = vector(angles.size()); + + const double scaleMin = 0.0; + const double scaleMax = 360.0; + + // Convert angles to radians and compute sine, cosine, and their scaled + // versions + for (size_t i = 0; i < angles.size(); ++i) { + double radians = angles[i] * M_PI / 180.0; // Convert degrees to radians + calibration_samples_sine[i] = sin(radians); + calibration_samples_cosine[i] = cos(radians); + + // Scale sine and cosine to the range 0 to 360 + calibration_samples_sine_scaled[i] = + ((calibration_samples_sine[i] + 1) / 2) * (scaleMax - scaleMin) + + scaleMin; + calibration_samples_cosine_scaled[i] = + ((calibration_samples_cosine[i] + 1) / 2) * (scaleMax - scaleMin) + + scaleMin; + } } -// Function to insert the harmonic coefficient magnitude directly into the register -uint16_t ADMTController::calculateHarmonicCoefficientMagnitude(uint16_t harmonicCoefficient, uint16_t originalValue, const string& key) { - uint16_t result = 0; - - // Switch case for different bitmapping based on the key - if (key == "h1" || key == "h2") { - // For h1 and h2: [15:11 reserved], [10:0 write] - result = harmonicCoefficient & 0x07FF; - originalValue = (originalValue & 0xF800) | result; - } - else if (key == "h3" || key == "h8") { - // For h3 and h8: [15:8 reserved], [7:0 write] - result = harmonicCoefficient & 0x00FF; - originalValue = (originalValue & 0xFF00) | result; - } - else { - // Handle invalid key, return the original value unchanged - return originalValue; - } - - return originalValue; // Return the updated original value +// Function to insert the harmonic coefficient magnitude directly into the +// register +uint16_t ADMTController::calculateHarmonicCoefficientMagnitude( + uint16_t harmonicCoefficient, uint16_t originalValue, const string &key) { + uint16_t result = 0; + + // Switch case for different bitmapping based on the key + if (key == "h1" || key == "h2") { + // For h1 and h2: [15:11 reserved], [10:0 write] + result = harmonicCoefficient & 0x07FF; + originalValue = (originalValue & 0xF800) | result; + } else if (key == "h3" || key == "h8") { + // For h3 and h8: [15:8 reserved], [7:0 write] + result = harmonicCoefficient & 0x00FF; + originalValue = (originalValue & 0xFF00) | result; + } else { + // Handle invalid key, return the original value unchanged + return originalValue; + } + + return originalValue; // Return the updated original value } // Function to insert the harmonic coefficient phase directly into the register -uint16_t ADMTController::calculateHarmonicCoefficientPhase(uint16_t harmonicPhase, uint16_t originalValue) { - uint16_t result = 0; +uint16_t +ADMTController::calculateHarmonicCoefficientPhase(uint16_t harmonicPhase, + uint16_t originalValue) { + uint16_t result = 0; - // Mask to keep only bits 11:0 (since phase is represented in 12 bits) - result = harmonicPhase & 0x0FFF; + // Mask to keep only bits 11:0 (since phase is represented in 12 bits) + result = harmonicPhase & 0x0FFF; - // Clear bits 11:0 of the original value, keeping bits 15:12 intact - uint16_t preservedValue = (originalValue & 0xF000) | result; + // Clear bits 11:0 of the original value, keeping bits 15:12 intact + uint16_t preservedValue = (originalValue & 0xF000) | result; - return preservedValue; + return preservedValue; } -double ADMTController::getActualHarmonicRegisterValue(uint16_t registerValue, const string key) { - double result = 0.0; - const double cordicScaler = 0.6072; - - // Switch case for different bitmapping based on the key - if (key == "h1mag" || key == "h2mag") { - // For h1h2mag: value is in bits [10:0], bits [15:12] are reserved - const double LSB = 0.005493; - - // Extract the value from bits [10:0] - uint16_t extractedValue = registerValue & 0x07FF; - - // Convert the extracted value by applying CORDIC scaler and LSB - result = extractedValue * LSB / cordicScaler; - } - else if (key == "h3mag" || key == "h8mag") { - // For h3h8mag: value is in bits [7:0], bits [15:8] are reserved - const double LSB = 0.005493; - - // Extract the value from bits [7:0] - uint16_t extractedValue = registerValue & 0x00FF; - - // Convert the extracted value by applying CORDIC scaler and LSB - result = extractedValue * LSB / cordicScaler; - } - else if (key == "h1phase" || key == "h2phase" || key == "h3phase" || key == "h8phase") { - // For Phase: value is in bits [11:0], bits [15:12] are reserved - const double LSB = 0.087891; - - // Extract the value from bits [11:0] - uint16_t extractedValue = registerValue & 0x0FFF; - - // Convert the extracted value by applying the LSB - result = extractedValue * LSB; - } - else { - // Indicating an error or invalid key - result = -404.0; - } - - return result; +double ADMTController::getActualHarmonicRegisterValue(uint16_t registerValue, + const string key) { + double result = 0.0; + const double cordicScaler = 0.6072; + + // Switch case for different bitmapping based on the key + if (key == "h1mag" || key == "h2mag") { + // For h1h2mag: value is in bits [10:0], bits [15:12] are reserved + const double LSB = 0.005493; + + // Extract the value from bits [10:0] + uint16_t extractedValue = registerValue & 0x07FF; + + // Convert the extracted value by applying CORDIC scaler and LSB + result = extractedValue * LSB / cordicScaler; + } else if (key == "h3mag" || key == "h8mag") { + // For h3h8mag: value is in bits [7:0], bits [15:8] are reserved + const double LSB = 0.005493; + + // Extract the value from bits [7:0] + uint16_t extractedValue = registerValue & 0x00FF; + + // Convert the extracted value by applying CORDIC scaler and LSB + result = extractedValue * LSB / cordicScaler; + } else if (key == "h1phase" || key == "h2phase" || key == "h3phase" || + key == "h8phase") { + // For Phase: value is in bits [11:0], bits [15:12] are reserved + const double LSB = 0.087891; + + // Extract the value from bits [11:0] + uint16_t extractedValue = registerValue & 0x0FFF; + + // Convert the extracted value by applying the LSB + result = extractedValue * LSB; + } else { + // Indicating an error or invalid key + result = -404.0; + } + + return result; } -map ADMTController::getFaultRegisterBitMapping(uint16_t registerValue) { - map result; - - // Extract each bit and store the result in the map - // Rain: Current returns it as value. - result["Sequencer Watchdog"] = (registerValue >> 15) & 0x01; - result["AMR Radius Check"] = (registerValue >> 14) & 0x01; - result["Turn Counter Cross Check"] = (registerValue >> 13) & 0x01; - result["MT Diagnostic"] = (registerValue >> 12) & 0x01; - result["Turn Count Sensor Levels"] = (registerValue >> 11) & 0x01; - result["Angle Cross Check"] = (registerValue >> 10) & 0x01; - result["Count Sensor False State"] = (registerValue >> 9) & 0x01; - result["Oscillator Drift"] = (registerValue >> 8) & 0x01; - result["ECC Double Bit Error"] = (registerValue >> 7) & 0x01; - result["Reserved"] = (registerValue >> 6) & 0x01; - result["NVM CRC Fault"] = (registerValue >> 5) & 0x01; - result["AFE Diagnostic"] = (registerValue >> 4) & 0x01; - result["VDRIVE Over Voltage"] = (registerValue >> 3) & 0x01; - result["VDRIVE Under Voltage"] = (registerValue >> 2) & 0x01; - result["VDD Over Voltage"] = (registerValue >> 1) & 0x01; - result["VDD Under Voltage"] = (registerValue >> 0) & 0x01; - - return result; +map +ADMTController::getFaultRegisterBitMapping(uint16_t registerValue) { + map result; + + // Extract each bit and store the result in the map + // Rain: Current returns it as value. + result["Sequencer Watchdog"] = (registerValue >> 15) & 0x01; + result["AMR Radius Check"] = (registerValue >> 14) & 0x01; + result["Turn Counter Cross Check"] = (registerValue >> 13) & 0x01; + result["MT Diagnostic"] = (registerValue >> 12) & 0x01; + result["Turn Count Sensor Levels"] = (registerValue >> 11) & 0x01; + result["Angle Cross Check"] = (registerValue >> 10) & 0x01; + result["Count Sensor False State"] = (registerValue >> 9) & 0x01; + result["Oscillator Drift"] = (registerValue >> 8) & 0x01; + result["ECC Double Bit Error"] = (registerValue >> 7) & 0x01; + result["Reserved"] = (registerValue >> 6) & 0x01; + result["NVM CRC Fault"] = (registerValue >> 5) & 0x01; + result["AFE Diagnostic"] = (registerValue >> 4) & 0x01; + result["VDRIVE Over Voltage"] = (registerValue >> 3) & 0x01; + result["VDRIVE Under Voltage"] = (registerValue >> 2) & 0x01; + result["VDD Over Voltage"] = (registerValue >> 1) & 0x01; + result["VDD Under Voltage"] = (registerValue >> 0) & 0x01; + + return result; } // // How to read each value sample // for (const auto& pair : result) { -// std::cout << pair.first << ": " << (pair.second ? "Set" : "Not Set") << std::endl; +// std::cout << pair.first << ": " << (pair.second ? "Set" : "Not Set") << +// std::endl; // } -map ADMTController::getGeneralRegisterBitMapping(uint16_t registerValue) { - map result; - - // Bit 15: STORAGE[7] - result["STORAGE[7]"] = ((registerValue >> 15) & 0x01) ? 1 : 0; // ? "Set" : "Not Set"; - - // Bits 14:13: Convert Synchronization - uint16_t convertSync = (registerValue >> 13) & 0x03; - switch (convertSync) { - case 0x00: - result["Convert Synchronization"] = 0; // "Disabled"; - break; - case 0x03: - result["Convert Synchronization"] = 1; // "Enabled"; - break; - default: - result["Convert Synchronization"] = -1; // "Reserved"; - break; - } - - // Bit 12: Angle Filter - result["Angle Filter"] = ((registerValue >> 12) & 0x01) ? 1 : 0; // ? "Enabled" : "Disabled"; - - // Bit 11: STORAGE[6] - result["STORAGE[6]"] = ((registerValue >> 11) & 0x01) ? 1 : 0; // ? "Set" : "Not Set"; - - // Bit 10: 8th Harmonic - result["8th Harmonic"] = ((registerValue >> 10) & 0x01) ? 1 : 0; // ? "User-Supplied Values" : "ADI Factory Values"; - - // // Bit 9: Reserved (skipped) - // result["Reserved"] = "Reserved"; - - // Bits 8:6: STORAGE[5:3] - // uint16_t storage_5_3 = (registerValue >> 6) & 0x07; - // result["STORAGE[5:3]"] = std::to_string(storage_5_3); - - // Bits 5:4: Sequence Type - uint16_t sequenceType = (registerValue >> 4) & 0x03; - switch (sequenceType) { - case 0x00: - result["Sequence Type"] = 1; // "Mode 2"; - break; - case 0x03: - result["Sequence Type"] = 0; // "Mode 1"; - break; - default: - result["Sequence Type"] = -1; // "Reserved"; - break; - } - - // Bits 3:1: STORAGE[2:0] - // uint16_t storage_2_0 = (registerValue >> 1) & 0x07; - // result["STORAGE[2:0]"] = std::to_string(storage_2_0); - - // Bit 0: Conversion Type - result["Conversion Type"] = (registerValue & 0x01) ? 1 : 0; // ? "One-shot conversion" : "Continuous conversions"; - - return result; +map +ADMTController::getGeneralRegisterBitMapping(uint16_t registerValue) { + map result; + + // Bit 15: STORAGE[7] + result["STORAGE[7]"] = + ((registerValue >> 15) & 0x01) ? 1 : 0; // ? "Set" : "Not Set"; + + // Bits 14:13: Convert Synchronization + uint16_t convertSync = (registerValue >> 13) & 0x03; + switch (convertSync) { + case 0x00: + result["Convert Synchronization"] = 0; // "Disabled"; + break; + case 0x03: + result["Convert Synchronization"] = 1; // "Enabled"; + break; + default: + result["Convert Synchronization"] = -1; // "Reserved"; + break; + } + + // Bit 12: Angle Filter + result["Angle Filter"] = + ((registerValue >> 12) & 0x01) ? 1 : 0; // ? "Enabled" : "Disabled"; + + // Bit 11: STORAGE[6] + result["STORAGE[6]"] = + ((registerValue >> 11) & 0x01) ? 1 : 0; // ? "Set" : "Not Set"; + + // Bit 10: 8th Harmonic + result["8th Harmonic"] = + ((registerValue >> 10) & 0x01) + ? 1 + : 0; // ? "User-Supplied Values" : "ADI Factory Values"; + + // // Bit 9: Reserved (skipped) + // result["Reserved"] = "Reserved"; + + // Bits 8:6: STORAGE[5:3] + // uint16_t storage_5_3 = (registerValue >> 6) & 0x07; + // result["STORAGE[5:3]"] = std::to_string(storage_5_3); + + // Bits 5:4: Sequence Type + uint16_t sequenceType = (registerValue >> 4) & 0x03; + switch (sequenceType) { + case 0x00: + result["Sequence Type"] = 1; // "Mode 2"; + break; + case 0x03: + result["Sequence Type"] = 0; // "Mode 1"; + break; + default: + result["Sequence Type"] = -1; // "Reserved"; + break; + } + + // Bits 3:1: STORAGE[2:0] + // uint16_t storage_2_0 = (registerValue >> 1) & 0x07; + // result["STORAGE[2:0]"] = std::to_string(storage_2_0); + + // Bit 0: Conversion Type + result["Conversion Type"] = + (registerValue & 0x01) + ? 1 + : 0; // ? "One-shot conversion" : "Continuous conversions"; + + return result; } // // How to read each value sample // for (const auto& pair : result) { // std::cout << pair.first << ": " << pair.second << std::endl; // } -map ADMTController::getDIGIOENRegisterBitMapping(uint16_t registerValue) { - map result; - - // // Bits 15:14: Reserved (skipped) - // result["Reserved (15:14)"] = "Reserved"; - - // Bit 13: DIGIO5EN - result["DIGIO5EN"] = ((registerValue >> 13) & 0x01) ? true : false; // ? "GPIO5 output enable" : "GPIO5 output disable"; - - // Bit 12: DIGIO4EN - result["DIGIO4EN"] = ((registerValue >> 12) & 0x01) ? true : false; // ? "GPIO4 output enable" : "GPIO4 output disable"; - - // Bit 11: DIGIO3EN - result["DIGIO3EN"] = ((registerValue >> 11) & 0x01) ? true : false; // ? "GPIO3 output enable" : "GPIO3 output disable"; - - // Bit 10: DIGIO2EN - result["DIGIO2EN"] = ((registerValue >> 10) & 0x01) ? true : false; // ? "GPIO2 output enable" : "GPIO2 output disable"; - - // Bit 9: DIGIO1EN - result["DIGIO1EN"] = ((registerValue >> 9) & 0x01) ? true : false; // ? "GPIO1 output enable" : "GPIO1 output disable"; - - // Bit 8: DIGIO0EN - result["DIGIO0EN"] = ((registerValue >> 8) & 0x01) ? true : false; // ? "GPIO0 output enable" : "GPIO0 output disable"; - - // // Bits 7:6: Reserved (skipped) - // result["Reserved (7:6)"] = "Reserved"; - - // Bit 5: Bootload - result["BOOTLOAD"] = ((registerValue >> 5) & 0x01) ? true : false; // ? "GPIO5" : "Bootload (Output only)"; - - // Bit 4: Fault - result["FAULT"] = ((registerValue >> 4) & 0x01) ? true : false; // ? "GPIO4" : "Fault (Output only)"; - - // Bit 3: Acalc - result["ACALC"] = ((registerValue >> 3) & 0x01) ? true : false; // ? "GPIO3" : "Acalc (Output only)"; - - // Bit 2: Sent - result["SENT"] = ((registerValue >> 2) & 0x01) ? true : false; // ? "GPIO2" : "Sent (Output only)"; - - // Bit 1: Cnv - result["CNV"] = ((registerValue >> 1) & 0x01) ? true : false; // ? "GPIO1" : "Cnv (Output only)"; - - // Bit 0: Busy - result["BUSY"] = (registerValue & 0x01) ? true : false; // ? "GPIO0" : "Busy (Output only)"; - - return result; +map +ADMTController::getDIGIOENRegisterBitMapping(uint16_t registerValue) { + map result; + + // // Bits 15:14: Reserved (skipped) + // result["Reserved (15:14)"] = "Reserved"; + + // Bit 13: DIGIO5EN + result["DIGIO5EN"] = + ((registerValue >> 13) & 0x01) + ? true + : false; // ? "GPIO5 output enable" : "GPIO5 output disable"; + + // Bit 12: DIGIO4EN + result["DIGIO4EN"] = + ((registerValue >> 12) & 0x01) + ? true + : false; // ? "GPIO4 output enable" : "GPIO4 output disable"; + + // Bit 11: DIGIO3EN + result["DIGIO3EN"] = + ((registerValue >> 11) & 0x01) + ? true + : false; // ? "GPIO3 output enable" : "GPIO3 output disable"; + + // Bit 10: DIGIO2EN + result["DIGIO2EN"] = + ((registerValue >> 10) & 0x01) + ? true + : false; // ? "GPIO2 output enable" : "GPIO2 output disable"; + + // Bit 9: DIGIO1EN + result["DIGIO1EN"] = + ((registerValue >> 9) & 0x01) + ? true + : false; // ? "GPIO1 output enable" : "GPIO1 output disable"; + + // Bit 8: DIGIO0EN + result["DIGIO0EN"] = + ((registerValue >> 8) & 0x01) + ? true + : false; // ? "GPIO0 output enable" : "GPIO0 output disable"; + + // // Bits 7:6: Reserved (skipped) + // result["Reserved (7:6)"] = "Reserved"; + + // Bit 5: Bootload + result["BOOTLOAD"] = ((registerValue >> 5) & 0x01) + ? true + : false; // ? "GPIO5" : "Bootload (Output only)"; + + // Bit 4: Fault + result["FAULT"] = ((registerValue >> 4) & 0x01) + ? true + : false; // ? "GPIO4" : "Fault (Output only)"; + + // Bit 3: Acalc + result["ACALC"] = ((registerValue >> 3) & 0x01) + ? true + : false; // ? "GPIO3" : "Acalc (Output only)"; + + // Bit 2: Sent + result["SENT"] = ((registerValue >> 2) & 0x01) + ? true + : false; // ? "GPIO2" : "Sent (Output only)"; + + // Bit 1: Cnv + result["CNV"] = ((registerValue >> 1) & 0x01) + ? true + : false; // ? "GPIO1" : "Cnv (Output only)"; + + // Bit 0: Busy + result["BUSY"] = (registerValue & 0x01) + ? true + : false; // ? "GPIO0" : "Busy (Output only)"; + + return result; } -map ADMTController::getDIGIORegisterBitMapping(uint16_t registerValue) { - map result; +map +ADMTController::getDIGIORegisterBitMapping(uint16_t registerValue) { + map result; - // Bits 15:6: Reserved (skipped) + // Bits 15:6: Reserved (skipped) - // Bit 5: GPIO5 - result["GPIO5"] = ((registerValue >> 5) & 0x01) ? true : false; + // Bit 5: GPIO5 + result["GPIO5"] = ((registerValue >> 5) & 0x01) ? true : false; - // Bit 4: GPIO4 - result["GPIO4"] = ((registerValue >> 4) & 0x01) ? true : false; + // Bit 4: GPIO4 + result["GPIO4"] = ((registerValue >> 4) & 0x01) ? true : false; - // Bit 3: GPIO3 - result["GPIO3"] = ((registerValue >> 3) & 0x01) ? true : false; + // Bit 3: GPIO3 + result["GPIO3"] = ((registerValue >> 3) & 0x01) ? true : false; - // Bit 2: GPIO2 - result["GPIO2"] = ((registerValue >> 2) & 0x01) ? true : false; + // Bit 2: GPIO2 + result["GPIO2"] = ((registerValue >> 2) & 0x01) ? true : false; - // Bit 1: GPIO1 - result["GPIO1"] = ((registerValue >> 1) & 0x01) ? true : false; + // Bit 1: GPIO1 + result["GPIO1"] = ((registerValue >> 1) & 0x01) ? true : false; - // Bit 0: GPIO0 - result["GPIO0"] = (registerValue & 0x01) ? true : false; + // Bit 0: GPIO0 + result["GPIO0"] = (registerValue & 0x01) ? true : false; - return result; + return result; } -map ADMTController::getDiag1RegisterBitMapping_Register(uint16_t registerValue) { - map result; - - // Bits 15 to 8: R7 to R0 (Enabled or Disabled) - result["R7"] = ((registerValue >> 15) & 0x01) ? true : false; - result["R6"] = ((registerValue >> 14) & 0x01) ? true : false; - result["R5"] = ((registerValue >> 13) & 0x01) ? true : false; - result["R4"] = ((registerValue >> 12) & 0x01) ? true : false; - result["R3"] = ((registerValue >> 11) & 0x01) ? true : false; - result["R2"] = ((registerValue >> 10) & 0x01) ? true : false; - result["R1"] = ((registerValue >> 9) & 0x01) ? true : false; - result["R0"] = ((registerValue >> 8) & 0x01) ? true : false; - - return result; +map +ADMTController::getDiag1RegisterBitMapping_Register(uint16_t registerValue) { + map result; + + // Bits 15 to 8: R7 to R0 (Enabled or Disabled) + result["R7"] = ((registerValue >> 15) & 0x01) ? true : false; + result["R6"] = ((registerValue >> 14) & 0x01) ? true : false; + result["R5"] = ((registerValue >> 13) & 0x01) ? true : false; + result["R4"] = ((registerValue >> 12) & 0x01) ? true : false; + result["R3"] = ((registerValue >> 11) & 0x01) ? true : false; + result["R2"] = ((registerValue >> 10) & 0x01) ? true : false; + result["R1"] = ((registerValue >> 9) & 0x01) ? true : false; + result["R0"] = ((registerValue >> 8) & 0x01) ? true : false; + + return result; } -map ADMTController::getDiag1RegisterBitMapping_Afe(uint16_t registerValue, bool is5V) { - map result; - - // Bits 7:0: AFE Diagnostic 2 - Measurement of Fixed voltage (stored in 2's complement) - int8_t afeDiagnostic = static_cast(registerValue & 0x00FF); // Interpret as signed 8-bit - - // Choose the correct resolution based on the voltage level (5V or 3.3V part) - double resolution = is5V ? 0.0048828 : 0.003222; // 0.0048828 for 5V, 0.003222 for 3.3V +map +ADMTController::getDiag1RegisterBitMapping_Afe(uint16_t registerValue, + bool is5V) { + map result; - // Convert the AFE Diagnostic value to a voltage - double diagnosticVoltage = static_cast(afeDiagnostic) * resolution; - result["AFE Diagnostic 2"] = diagnosticVoltage; + // Bits 7:0: AFE Diagnostic 2 - Measurement of Fixed voltage (stored in 2's + // complement) + int8_t afeDiagnostic = + static_cast(registerValue & 0x00FF); // Interpret as signed 8-bit - return result; -} + // Choose the correct resolution based on the voltage level (5V or 3.3V part) + double resolution = + is5V ? 0.0048828 : 0.003222; // 0.0048828 for 5V, 0.003222 for 3.3V -map ADMTController::getDiag2RegisterBitMapping(uint16_t registerValue) { - map result; - - // Bits 15:8: AFE Diagnostic 1 - Measurement of AFE +57% diagnostic resistor - uint16_t afeDiagnostic1 = (registerValue >> 8) & 0x00FF; - - // Convert AFE Diagnostic 1 value to double - // Rain: adjust scaling factor as needed with actual method. - double diagnostic1Voltage = static_cast(afeDiagnostic1) * 0.01; // what I found (to be confirmed) - - // Store the result with fixed precision - result["AFE Diagnostic 1 (+57%)"] = diagnostic1Voltage; - - // Bits 7:0: AFE Diagnostic 0 - Measurement of AFE -57% diagnostic resistor - uint16_t afeDiagnostic0 = registerValue & 0x00FF; - - // Convert AFE Diagnostic 0 value to double - // Rain: adjust scaling factor as needed with actual method. - double diagnostic0Voltage = static_cast(afeDiagnostic0) * 0.01; // what I found (to be confirmed) - - // Store the result with fixed precision - result["AFE Diagnostic 0 (-57%)"] = diagnostic0Voltage; + // Convert the AFE Diagnostic value to a voltage + double diagnosticVoltage = static_cast(afeDiagnostic) * resolution; + result["AFE Diagnostic 2"] = diagnosticVoltage; - return result; + return result; } -uint16_t ADMTController::setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings) { - uint16_t registerValue = currentRegisterValue; // Start with the current register value +map +ADMTController::getDiag2RegisterBitMapping(uint16_t registerValue) { + map result; - // Bit 15: STORAGE[7] (preserve original value) - // Do nothing, as STORAGE[7] is preserved. + // Bits 15:8: AFE Diagnostic 1 - Measurement of AFE +57% diagnostic resistor + uint16_t afeDiagnostic1 = (registerValue >> 8) & 0x00FF; - // Bits 14:13: Convert Synchronization - if (settings["Convert Synchronization"] == 1) { // Enabled - registerValue |= (0x03 << 13); // Set bits 14:13 to 0b11 - } else if (settings["Convert Synchronization"] == 0) { // Disabled - registerValue &= ~(0x03 << 13); // Clear bits 14:13 (set to 0b00) - } - - // Bit 12: Angle Filter - if (settings["Angle Filter"] == 1) { // Enabled - registerValue |= (1 << 12); // Set bit 12 - } else if (settings["Angle Filter"] == 0) { // Disabled - registerValue &= ~(1 << 12); // Clear bit 12 - } + // Convert AFE Diagnostic 1 value to double + // Rain: adjust scaling factor as needed with actual method. + double diagnostic1Voltage = static_cast(afeDiagnostic1) * + 0.01; // what I found (to be confirmed) - // Bit 11: STORAGE[6] (preserve original value) - // Do nothing, as STORAGE[6] is preserved. + // Store the result with fixed precision + result["AFE Diagnostic 1 (+57%)"] = diagnostic1Voltage; - // Bit 10: 8th Harmonic - if (settings["8th Harmonic"] == 1) { // User-Supplied Values - registerValue |= (1 << 10); // Set bit 10 - } else if (settings["8th Harmonic"] == 0) { // ADI Factory Values - registerValue &= ~(1 << 10); // Clear bit 10 - } + // Bits 7:0: AFE Diagnostic 0 - Measurement of AFE -57% diagnostic resistor + uint16_t afeDiagnostic0 = registerValue & 0x00FF; - // Bit 9: Reserved (no change) - - // Bits 8:6: STORAGE[5:3] (preserve original value) - // Do nothing, as STORAGE[5:3] is preserved. - - // Bits 5:4: Sequence Type - if (settings["Sequence Type"] == 0) { // Mode 1 - registerValue |= (0x03 << 4); // Set bits 5:4 to 0b11 - } else if (settings["Sequence Type"] == 1) { // Mode 2 - registerValue &= ~(0x03 << 4); // Clear bits 5:4 (set to 0b00) - } + // Convert AFE Diagnostic 0 value to double + // Rain: adjust scaling factor as needed with actual method. + double diagnostic0Voltage = static_cast(afeDiagnostic0) * + 0.01; // what I found (to be confirmed) - // Bits 3:1: STORAGE[2:0] (preserve original value) - // Do nothing, as STORAGE[2:0] is preserved. + // Store the result with fixed precision + result["AFE Diagnostic 0 (-57%)"] = diagnostic0Voltage; - // Bit 0: Conversion Type - if (settings["Conversion Type"] == 1) { // One-shot conversion - registerValue |= (1 << 0); // Set bit 0 - } else if (settings["Conversion Type"] == 0) { // Continuous conversions - registerValue &= ~(1 << 0); // Clear bit 0 - } + return result; +} - return registerValue; +uint16_t +ADMTController::setGeneralRegisterBitMapping(uint16_t currentRegisterValue, + map settings) { + uint16_t registerValue = + currentRegisterValue; // Start with the current register value + + // Bit 15: STORAGE[7] (preserve original value) + // Do nothing, as STORAGE[7] is preserved. + + // Bits 14:13: Convert Synchronization + if (settings["Convert Synchronization"] == 1) { // Enabled + registerValue |= (0x03 << 13); // Set bits 14:13 to 0b11 + } else if (settings["Convert Synchronization"] == 0) { // Disabled + registerValue &= ~(0x03 << 13); // Clear bits 14:13 (set to 0b00) + } + + // Bit 12: Angle Filter + if (settings["Angle Filter"] == 1) { // Enabled + registerValue |= (1 << 12); // Set bit 12 + } else if (settings["Angle Filter"] == 0) { // Disabled + registerValue &= ~(1 << 12); // Clear bit 12 + } + + // Bit 11: STORAGE[6] (preserve original value) + // Do nothing, as STORAGE[6] is preserved. + + // Bit 10: 8th Harmonic + if (settings["8th Harmonic"] == 1) { // User-Supplied Values + registerValue |= (1 << 10); // Set bit 10 + } else if (settings["8th Harmonic"] == 0) { // ADI Factory Values + registerValue &= ~(1 << 10); // Clear bit 10 + } + + // Bit 9: Reserved (no change) + + // Bits 8:6: STORAGE[5:3] (preserve original value) + // Do nothing, as STORAGE[5:3] is preserved. + + // Bits 5:4: Sequence Type + if (settings["Sequence Type"] == 0) { // Mode 1 + registerValue |= (0x03 << 4); // Set bits 5:4 to 0b11 + } else if (settings["Sequence Type"] == 1) { // Mode 2 + registerValue &= ~(0x03 << 4); // Clear bits 5:4 (set to 0b00) + } + + // Bits 3:1: STORAGE[2:0] (preserve original value) + // Do nothing, as STORAGE[2:0] is preserved. + + // Bit 0: Conversion Type + if (settings["Conversion Type"] == 1) { // One-shot conversion + registerValue |= (1 << 0); // Set bit 0 + } else if (settings["Conversion Type"] == 0) { // Continuous conversions + registerValue &= ~(1 << 0); // Clear bit 0 + } + + return registerValue; } int ADMTController::getAbsAngleTurnCount(uint16_t registerValue) { - // Bits 15:8: Turn count in quarter turns - uint8_t turnCount = (registerValue & 0xFF00) >> 8; - - if (turnCount <= 0xD5) { - // Straight binary turn count - return turnCount / 4; // Convert from quarter turns to whole turns - } else if (turnCount == 0xD6) { - // Invalid turn count - return -1; - } else { - // 2's complement turn count - int8_t signedTurnCount = static_cast(turnCount); // Handle as signed value - return signedTurnCount / 4; // Convert from quarter turns to whole turns - } + // Bits 15:8: Turn count in quarter turns + uint8_t turnCount = (registerValue & 0xFF00) >> 8; + + if (turnCount <= 0xD5) { + // Straight binary turn count + return turnCount / 4; // Convert from quarter turns to whole turns + } else if (turnCount == 0xD6) { + // Invalid turn count + return -1; + } else { + // 2's complement turn count + int8_t signedTurnCount = + static_cast(turnCount); // Handle as signed value + return signedTurnCount / 4; // Convert from quarter turns to whole turns + } } -uint16_t ADMTController::setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings) { - uint16_t registerValue = currentRegisterValue; // Start with the current register value - - // Bits 15:14: (preserve original value) - - // Bit 13: DIGIO5EN - if (settings["DIGIO5EN"]) // "Enabled" - { - registerValue |= (1 << 13); // Set bit 13 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 13); // Clear bit 13 (Disabled) - } - - // Bit 12: DIGIO4EN - if (settings["DIGIO4EN"]) // "Enabled" - { - registerValue |= (1 << 12); // Set bit 12 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 12); // Clear bit 12 (Disabled) - } - - // Bit 11: DIGIO3EN - if (settings["DIGIO3EN"]) // "Enabled" - { - registerValue |= (1 << 11); // Set bit 11 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 11); // Clear bit 11 (Disabled) - } - - // Bit 10: DIGIO2EN - if (settings["DIGIO2EN"]) // "Enabled" - { - registerValue |= (1 << 10); // Set bit 10 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 10); // Clear bit 10 (Disabled) - } - - // Bit 9: DIGIO1EN - if (settings["DIGIO1EN"]) // "Enabled" - { - registerValue |= (1 << 9); // Set bit 9 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 9); // Clear bit 9 (Disabled) - } - - // Bit 8: DIGIO0EN - if (settings["DIGIO0EN"]) // "Enabled" - { - registerValue |= (1 << 8); // Set bit 8 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 8); // Clear bit 8 (Disabled) - } - - // Bits 7:6: (preserve original value) - - // Bit 5: Bootload - if (settings["BOOTLOAD"]) // "Enabled" - { - registerValue |= (1 << 5); // Set bit 5 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 5); // Clear bit 5 (Disabled) - } - - // Bit 4: Fault - if (settings["FAULT"]) // "Enabled" - { - registerValue |= (1 << 4); // Set bit 4 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 4); // Clear bit 4 (Disabled) - } - - // Bit 3: Acalc - if (settings["ACALC"]) // "Enabled" - { - registerValue |= (1 << 3); // Set bit 3 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 3); // Clear bit 3 (Disabled) - } - - // Bit 2: Sent - if (settings["SENT"]) // "Enabled" - { - registerValue |= (1 << 2); // Set bit 2 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 2); // Clear bit 2 (Disabled) - } - - // Bit 1: Cnv - if (settings["CNV"]) // "Enabled" - { - registerValue |= (1 << 1); // Set bit 1 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 1); // Clear bit 1 (Disabled) - } - - // Bit 0: Sent - if (settings["BUSY"]) // "Enabled" - { - registerValue |= (1 << 0); // Set bit 0 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 0); // Clear bit 0 (Disabled) - } - - return registerValue; +uint16_t +ADMTController::setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, + map settings) { + uint16_t registerValue = + currentRegisterValue; // Start with the current register value + + // Bits 15:14: (preserve original value) + + // Bit 13: DIGIO5EN + if (settings["DIGIO5EN"]) // "Enabled" + { + registerValue |= (1 << 13); // Set bit 13 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 13); // Clear bit 13 (Disabled) + } + + // Bit 12: DIGIO4EN + if (settings["DIGIO4EN"]) // "Enabled" + { + registerValue |= (1 << 12); // Set bit 12 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 12); // Clear bit 12 (Disabled) + } + + // Bit 11: DIGIO3EN + if (settings["DIGIO3EN"]) // "Enabled" + { + registerValue |= (1 << 11); // Set bit 11 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 11); // Clear bit 11 (Disabled) + } + + // Bit 10: DIGIO2EN + if (settings["DIGIO2EN"]) // "Enabled" + { + registerValue |= (1 << 10); // Set bit 10 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 10); // Clear bit 10 (Disabled) + } + + // Bit 9: DIGIO1EN + if (settings["DIGIO1EN"]) // "Enabled" + { + registerValue |= (1 << 9); // Set bit 9 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 9); // Clear bit 9 (Disabled) + } + + // Bit 8: DIGIO0EN + if (settings["DIGIO0EN"]) // "Enabled" + { + registerValue |= (1 << 8); // Set bit 8 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 8); // Clear bit 8 (Disabled) + } + + // Bits 7:6: (preserve original value) + + // Bit 5: Bootload + if (settings["BOOTLOAD"]) // "Enabled" + { + registerValue |= (1 << 5); // Set bit 5 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 5); // Clear bit 5 (Disabled) + } + + // Bit 4: Fault + if (settings["FAULT"]) // "Enabled" + { + registerValue |= (1 << 4); // Set bit 4 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 4); // Clear bit 4 (Disabled) + } + + // Bit 3: Acalc + if (settings["ACALC"]) // "Enabled" + { + registerValue |= (1 << 3); // Set bit 3 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 3); // Clear bit 3 (Disabled) + } + + // Bit 2: Sent + if (settings["SENT"]) // "Enabled" + { + registerValue |= (1 << 2); // Set bit 2 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 2); // Clear bit 2 (Disabled) + } + + // Bit 1: Cnv + if (settings["CNV"]) // "Enabled" + { + registerValue |= (1 << 1); // Set bit 1 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 1); // Clear bit 1 (Disabled) + } + + // Bit 0: Sent + if (settings["BUSY"]) // "Enabled" + { + registerValue |= (1 << 0); // Set bit 0 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 0); // Clear bit 0 (Disabled) + } + + return registerValue; } -uint16_t ADMTController::setDIGIORegisterBitMapping(uint16_t currentRegisterValue, map settings) { - uint16_t registerValue = currentRegisterValue; // Start with the current register value - - // Bits 15:6: (preserve original value) - - // Bit 5: GPIO5 - if (settings["GPIO5"]) // "Enabled" - { - registerValue |= (1 << 5); // Set bit 5 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 5); // Clear bit 5 (Disabled) - } - - // Bit 4: GPIO4 - if (settings["GPIO4"]) // "Enabled" - { - registerValue |= (1 << 4); // Set bit 4 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 4); // Clear bit 4 (Disabled) - } - - // Bit 3: GPIO3 - if (settings["GPIO3"]) // "Enabled" - { - registerValue |= (1 << 3); // Set bit 3 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 3); // Clear bit 3 (Disabled) - } - - // Bit 2: GPIO2 - if (settings["GPIO2"]) // "Enabled" - { - registerValue |= (1 << 2); // Set bit 2 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 2); // Clear bit 2 (Disabled) - } - - // Bit 1: GPIO1 - if (settings["GPIO1"]) // "Enabled" - { - registerValue |= (1 << 1); // Set bit 1 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 1); // Clear bit 1 (Disabled) - } - - // Bit 0: GPIO0 - if (settings["GPIO0"]) // "Enabled" - { - registerValue |= (1 << 0); // Set bit 0 to 1 (Enabled) - } - else // "Disabled" - { - registerValue &= ~(1 << 0); // Clear bit 0 (Disabled) - } - - return registerValue; +uint16_t +ADMTController::setDIGIORegisterBitMapping(uint16_t currentRegisterValue, + map settings) { + uint16_t registerValue = + currentRegisterValue; // Start with the current register value + + // Bits 15:6: (preserve original value) + + // Bit 5: GPIO5 + if (settings["GPIO5"]) // "Enabled" + { + registerValue |= (1 << 5); // Set bit 5 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 5); // Clear bit 5 (Disabled) + } + + // Bit 4: GPIO4 + if (settings["GPIO4"]) // "Enabled" + { + registerValue |= (1 << 4); // Set bit 4 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 4); // Clear bit 4 (Disabled) + } + + // Bit 3: GPIO3 + if (settings["GPIO3"]) // "Enabled" + { + registerValue |= (1 << 3); // Set bit 3 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 3); // Clear bit 3 (Disabled) + } + + // Bit 2: GPIO2 + if (settings["GPIO2"]) // "Enabled" + { + registerValue |= (1 << 2); // Set bit 2 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 2); // Clear bit 2 (Disabled) + } + + // Bit 1: GPIO1 + if (settings["GPIO1"]) // "Enabled" + { + registerValue |= (1 << 1); // Set bit 1 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 1); // Clear bit 1 (Disabled) + } + + // Bit 0: GPIO0 + if (settings["GPIO0"]) // "Enabled" + { + registerValue |= (1 << 0); // Set bit 0 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 0); // Clear bit 0 (Disabled) + } + + return registerValue; } -map ADMTController::getUNIQID3RegisterMapping(uint16_t registerValue) { - map result; - - // Bits 15:11 - Reserved (ignore) - - // Bits 10:08 - Product ID (3 bits) - uint8_t productID = (registerValue >> 8) & 0x07; - switch (productID) { - case 0x00: - result["Product ID"] = "ADMT4000"; - break; - case 0x01: - result["Product ID"] = "ADMT4001"; - break; - default: - result["Product ID"] = "Unidentified"; - break; - } - - // Bits 7:06 - Supply ID (2 bits) - uint8_t supplyID = (registerValue >> 6) & 0x03; - switch (supplyID) { - case 0x00: - result["Supply ID"] = "3.3V"; - break; - case 0x02: - result["Supply ID"] = "5V"; - break; - default: - result["Supply ID"] = "Unknown"; - break; - } - - // Bits 5:03 - ASIL ID (3 bits) - uint8_t asilID = (registerValue >> 3) & 0x07; // Show both Seq 1 & 2 if unknown - switch (asilID) { - case 0x00: - result["ASIL ID"] = "ASIL QM"; - break; - case 0x01: - result["ASIL ID"] = "ASIL A"; - break; - case 0x02: - result["ASIL ID"] = "ASIL B"; - break; - case 0x03: - result["ASIL ID"] = "ASIL C"; - break; - case 0x04: - result["ASIL ID"] = "ASIL D"; - break; - default: - result["ASIL ID"] = "Unidentified ASIL"; - break; - } - - // Bits 2:00 - Revision ID (3 bits) - uint8_t revisionID = registerValue & 0x07; - switch (revisionID) { - case 0x01: - result["Revision ID"] = "S1"; - break; - case 0x02: - result["Revision ID"] = "S2"; - break; - default: - result["Revision ID"] = "Unknown"; - break; - } - - return result; +map +ADMTController::getUNIQID3RegisterMapping(uint16_t registerValue) { + map result; + + // Bits 15:11 - Reserved (ignore) + + // Bits 10:08 - Product ID (3 bits) + uint8_t productID = (registerValue >> 8) & 0x07; + switch (productID) { + case 0x00: + result["Product ID"] = "ADMT4000"; + break; + case 0x01: + result["Product ID"] = "ADMT4001"; + break; + default: + result["Product ID"] = "Unidentified"; + break; + } + + // Bits 7:06 - Supply ID (2 bits) + uint8_t supplyID = (registerValue >> 6) & 0x03; + switch (supplyID) { + case 0x00: + result["Supply ID"] = "3.3V"; + break; + case 0x02: + result["Supply ID"] = "5V"; + break; + default: + result["Supply ID"] = "Unknown"; + break; + } + + // Bits 5:03 - ASIL ID (3 bits) + uint8_t asilID = + (registerValue >> 3) & 0x07; // Show both Seq 1 & 2 if unknown + switch (asilID) { + case 0x00: + result["ASIL ID"] = "ASIL QM"; + break; + case 0x01: + result["ASIL ID"] = "ASIL A"; + break; + case 0x02: + result["ASIL ID"] = "ASIL B"; + break; + case 0x03: + result["ASIL ID"] = "ASIL C"; + break; + case 0x04: + result["ASIL ID"] = "ASIL D"; + break; + default: + result["ASIL ID"] = "Unidentified ASIL"; + break; + } + + // Bits 2:00 - Revision ID (3 bits) + uint8_t revisionID = registerValue & 0x07; + switch (revisionID) { + case 0x01: + result["Revision ID"] = "S1"; + break; + case 0x02: + result["Revision ID"] = "S2"; + break; + default: + result["Revision ID"] = "Unknown"; + break; + } + + return result; } -map ADMTController::getSineRegisterBitMapping(uint16_t registerValue) { - map result; +map +ADMTController::getSineRegisterBitMapping(uint16_t registerValue) { + map result; - // Bit 0 - Extract the status - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the status + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bit 1 - Reserved (ignore) + // Bit 1 - Reserved (ignore) - // Bits 15:2 - Extract the sine value - int16_t sineValueRaw = (registerValue >> 2); // Shift right by 2 to discard Bits [1:0] + // Bits 15:2 - Extract the sine value + int16_t sineValueRaw = + (registerValue >> 2); // Shift right by 2 to discard Bits [1:0] - // Check if the value is negative (2's complement format) - if (sineValueRaw & 0x2000) { - sineValueRaw |= 0xC000; - } + // Check if the value is negative (2's complement format) + if (sineValueRaw & 0x2000) { + sineValueRaw |= 0xC000; + } - // Convert the raw uncorrected sine value to a double - result["SINE"] = static_cast(sineValueRaw); + // Convert the raw uncorrected sine value to a double + result["SINE"] = static_cast(sineValueRaw); - return result; + return result; } -map ADMTController::getCosineRegisterBitMapping(uint16_t registerValue) { - map result; +map +ADMTController::getCosineRegisterBitMapping(uint16_t registerValue) { + map result; - // Bit 0 - Extract the status - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the status + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bit 1 - Reserved (ignore) + // Bit 1 - Reserved (ignore) - // Bits 15:2 - Extract the cosine value - int16_t cosineValueRaw = (registerValue >> 2); // Shift right by 2 to discard Bits [1:0] + // Bits 15:2 - Extract the cosine value + int16_t cosineValueRaw = + (registerValue >> 2); // Shift right by 2 to discard Bits [1:0] - // Check if the value is negative (2's complement format) - if (cosineValueRaw & 0x2000) { - cosineValueRaw |= 0xC000; - } + // Check if the value is negative (2's complement format) + if (cosineValueRaw & 0x2000) { + cosineValueRaw |= 0xC000; + } - // Convert the raw uncorrected cosine value to a double - result["COSINE"] = static_cast(cosineValueRaw); + // Convert the raw uncorrected cosine value to a double + result["COSINE"] = static_cast(cosineValueRaw); - return result; + return result; } -map ADMTController::getRadiusRegisterBitMapping(uint16_t registerValue) { - map result; +map +ADMTController::getRadiusRegisterBitMapping(uint16_t registerValue) { + map result; - // Bit 0 - Extract the STATUS - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the STATUS + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bits 15:1 - Extract the RADIUS value - uint16_t radiusRaw = (registerValue >> 1); // Shift right by 1 to discard Bit 0 + // Bits 15:1 - Extract the RADIUS value + uint16_t radiusRaw = + (registerValue >> 1); // Shift right by 1 to discard Bit 0 - // Apply the resolution to convert the raw value - constexpr double resolution = 0.000924; // mV/V - result["RADIUS"] = static_cast(radiusRaw) * resolution; + // Apply the resolution to convert the raw value + constexpr double resolution = 0.000924; // mV/V + result["RADIUS"] = static_cast(radiusRaw) * resolution; - return result; + return result; } -map ADMTController::getAngleSecRegisterBitMapping(uint16_t registerValue) { - map result; +map +ADMTController::getAngleSecRegisterBitMapping(uint16_t registerValue) { + map result; - // Bit 0 - Extract the STATUS - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the STATUS + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bits 15:4 - Extract the ANGLESEC value - uint16_t angleSecRaw = (registerValue >> 4); // Right-shift by 4 to discard Bits [3:0] + // Bits 15:4 - Extract the ANGLESEC value + uint16_t angleSecRaw = + (registerValue >> 4); // Right-shift by 4 to discard Bits [3:0] - // Calculate the actual angle using the given resolution (360° / 4096) - constexpr double resolution = 360.0 / 4096.0; // 0.087890625 degrees per LSB - result["ANGLESEC"] = angleSecRaw * resolution; + // Calculate the actual angle using the given resolution (360° / 4096) + constexpr double resolution = 360.0 / 4096.0; // 0.087890625 degrees per LSB + result["ANGLESEC"] = angleSecRaw * resolution; - return result; + return result; } -map ADMTController::getSecAnglQRegisterBitMapping(uint16_t registerValue) { - map result; +map +ADMTController::getSecAnglQRegisterBitMapping(uint16_t registerValue) { + map result; - // Bit 0 - Extract the STATUS - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the STATUS + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bits 15:2 - Extract the SECANGLQ raw value - int16_t secAnglQRaw = static_cast((registerValue & 0xFFFC) >> 2); // Mask Bits [1:0] and shift right by 2 + // Bits 15:2 - Extract the SECANGLQ raw value + int16_t secAnglQRaw = static_cast( + (registerValue & 0xFFFC) >> 2); // Mask Bits [1:0] and shift right by 2 - // Convert the 2's complement raw value to the actual signed value - if (secAnglQRaw & 0x2000) { // Check the sign bit (Bit 13) - secAnglQRaw |= 0xC000; // Sign extend to preserve the 16-bit signed value - } + // Convert the 2's complement raw value to the actual signed value + if (secAnglQRaw & 0x2000) { // Check the sign bit (Bit 13) + secAnglQRaw |= 0xC000; // Sign extend to preserve the 16-bit signed value + } - // Store the SECANGLQ raw uncorrected value - result["SECANGLQ"] = static_cast(secAnglQRaw); + // Store the SECANGLQ raw uncorrected value + result["SECANGLQ"] = static_cast(secAnglQRaw); - return result; + return result; } -map ADMTController::getSecAnglIRegisterBitMapping(uint16_t registerValue) { - map result; +map +ADMTController::getSecAnglIRegisterBitMapping(uint16_t registerValue) { + map result; - // Bit 0 - Extract the STATUS bit - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the STATUS bit + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bits 15:2 - Extract the SECANGLI raw value - int16_t secAnglIRaw = static_cast((registerValue & 0xFFFC) >> 2); // Mask Bits [1:0] and shift right by 2 + // Bits 15:2 - Extract the SECANGLI raw value + int16_t secAnglIRaw = static_cast( + (registerValue & 0xFFFC) >> 2); // Mask Bits [1:0] and shift right by 2 - // Convert the 2's complement raw value to the actual signed value - if (secAnglIRaw & 0x2000) { // Check the sign bit (Bit 13) - secAnglIRaw |= 0xC000; // Sign extend to preserve the 16-bit signed value - } + // Convert the 2's complement raw value to the actual signed value + if (secAnglIRaw & 0x2000) { // Check the sign bit (Bit 13) + secAnglIRaw |= 0xC000; // Sign extend to preserve the 16-bit signed value + } - // Store the SECANGLI raw value (optional, for debugging or diagnostic purposes) - result["SECANGLI"] = static_cast(secAnglIRaw); + // Store the SECANGLI raw value (optional, for debugging or diagnostic + // purposes) + result["SECANGLI"] = static_cast(secAnglIRaw); - return result; + return result; } -map ADMTController::getTmp1RegisterBitMapping(uint16_t registerValue, bool is5V) { - map result; +map +ADMTController::getTmp1RegisterBitMapping(uint16_t registerValue, bool is5V) { + map result; - // Bits 15:4 - Extract the TMP1 raw value - uint16_t tmp1Raw = (registerValue & 0xFFF0) >> 4; + // Bits 15:4 - Extract the TMP1 raw value + uint16_t tmp1Raw = (registerValue & 0xFFF0) >> 4; - // Store the raw TMP1 value (for diagnostics) - result["TMP1Raw"] = static_cast(tmp1Raw); + // Store the raw TMP1 value (for diagnostics) + result["TMP1Raw"] = static_cast(tmp1Raw); - // Calculate TMP1 temperature in degrees Celsius based on VDD - double tmp1DegC = 0.0; - if (is5V == true) { - tmp1DegC = (tmp1Raw - 1238.0) / 13.45; - } else { - tmp1DegC = (tmp1Raw - 1208.0) / 13.61; - } + // Calculate TMP1 temperature in degrees Celsius based on VDD + double tmp1DegC = 0.0; + if (is5V == true) { + tmp1DegC = (tmp1Raw - 1238.0) / 13.45; + } else { + tmp1DegC = (tmp1Raw - 1208.0) / 13.61; + } - // Store the calculated temperature in degrees Celsius - result["TMP1"] = tmp1DegC; + // Store the calculated temperature in degrees Celsius + result["TMP1"] = tmp1DegC; - return result; + return result; } bool ADMTController::checkRegisterFault(uint16_t registerValue, bool isMode1) { - // Mode-specific checks - if (isMode1) { - return ((registerValue >> 14) & 0x01) || // AMR Radius Check - ((registerValue >> 13) & 0x01) || // Turn Counter Cross Check - ((registerValue >> 9) & 0x01) || // Count Sensor False State - ((registerValue >> 7) & 0x01) || // ECC Double Bit Error - ((registerValue >> 5) & 0x01) || // NVM CRC Fault - ((registerValue >> 3) & 0x01) || // VDRIVE Over Voltage - ((registerValue >> 2) & 0x01) || // VDRIVE Under Voltage - ((registerValue >> 1) & 0x01) || // VDD Over Voltage - ((registerValue >> 0) & 0x01); // VDD Under Voltage - } else { - // Check all bits if not in Mode 1 - return ((registerValue >> 15) & 0x01) || // Sequencer Watchdog - ((registerValue >> 14) & 0x01) || // AMR Radius Check - ((registerValue >> 13) & 0x01) || // Turn Counter Cross Check - ((registerValue >> 12) & 0x01) || // MT Diagnostic - ((registerValue >> 11) & 0x01) || // Turn Count Sensor Levels - ((registerValue >> 10) & 0x01) || // Angle Cross Check - ((registerValue >> 9) & 0x01) || // Count Sensor False State - ((registerValue >> 8) & 0x01) || // Oscillator Drift - ((registerValue >> 7) & 0x01) || // ECC Double Bit Error - ((registerValue >> 6) & 0x01) || // Reserved - ((registerValue >> 5) & 0x01) || // NVM CRC Fault - ((registerValue >> 4) & 0x01) || // AFE Diagnostic - ((registerValue >> 3) & 0x01) || // VDRIVE Over Voltage - ((registerValue >> 2) & 0x01) || // VDRIVE Under Voltage - ((registerValue >> 1) & 0x01) || // VDD Over Voltage - ((registerValue >> 0) & 0x01); // VDD Under Voltage - } + // Mode-specific checks + if (isMode1) { + return ((registerValue >> 14) & 0x01) || // AMR Radius Check + ((registerValue >> 13) & 0x01) || // Turn Counter Cross Check + ((registerValue >> 9) & 0x01) || // Count Sensor False State + ((registerValue >> 7) & 0x01) || // ECC Double Bit Error + ((registerValue >> 5) & 0x01) || // NVM CRC Fault + ((registerValue >> 3) & 0x01) || // VDRIVE Over Voltage + ((registerValue >> 2) & 0x01) || // VDRIVE Under Voltage + ((registerValue >> 1) & 0x01) || // VDD Over Voltage + ((registerValue >> 0) & 0x01); // VDD Under Voltage + } else { + // Check all bits if not in Mode 1 + return ((registerValue >> 15) & 0x01) || // Sequencer Watchdog + ((registerValue >> 14) & 0x01) || // AMR Radius Check + ((registerValue >> 13) & 0x01) || // Turn Counter Cross Check + ((registerValue >> 12) & 0x01) || // MT Diagnostic + ((registerValue >> 11) & 0x01) || // Turn Count Sensor Levels + ((registerValue >> 10) & 0x01) || // Angle Cross Check + ((registerValue >> 9) & 0x01) || // Count Sensor False State + ((registerValue >> 8) & 0x01) || // Oscillator Drift + ((registerValue >> 7) & 0x01) || // ECC Double Bit Error + ((registerValue >> 6) & 0x01) || // Reserved + ((registerValue >> 5) & 0x01) || // NVM CRC Fault + ((registerValue >> 4) & 0x01) || // AFE Diagnostic + ((registerValue >> 3) & 0x01) || // VDRIVE Over Voltage + ((registerValue >> 2) & 0x01) || // VDRIVE Under Voltage + ((registerValue >> 1) & 0x01) || // VDD Over Voltage + ((registerValue >> 0) & 0x01); // VDD Under Voltage + } } -int ADMTController::streamIO() -{ - int result = -1; - const char *deviceName = "admt4000"; - const char *channelName = "rot"; - const char *scaleAttrName = "scale"; - const char *offsetAttrName = "offset"; - size_t samples = 1; - bool isOutput = false; - bool isCyclic = false; - - unsigned int i, j, major, minor; - char git_tag[8]; - iio_library_get_version(&major, &minor, git_tag); - bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; - - double *scaleAttrValue = new double(1); - int offsetAttrValue = 0; - char *offsetDst = new char[maxAttrSize]; - - if(!m_iioCtx) return result; // Check if the context is valid - if(iio_context_get_devices_count(m_iioCtx) < 1) return result; // Check if there are devices in the context - struct iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); // Find the ADMT device - if(admtDevice == NULL) return result; - struct iio_channel *channel = iio_device_find_channel(admtDevice, channelName, isOutput); // Find the rotation channel - if(channel == NULL) return result; - iio_channel_enable(channel); // Enable the channel - int scaleRet = iio_channel_attr_read_double(channel, scaleAttrName, scaleAttrValue); // Read the scale attribute - if(scaleRet != 0) return scaleRet; - iio_channel_attr_read(channel, offsetAttrName, offsetDst, maxAttrSize); // Read the offset attribute - offsetAttrValue = atoi(offsetDst); - struct iio_buffer *buffer = iio_device_create_buffer(admtDevice, samples, isCyclic); // Create a buffer - - while(!stopStream) - { - ssize_t numBytesRead; - char *pointerData, *pointerEnd; - ptrdiff_t pointerIncrement; - - numBytesRead = iio_buffer_refill(buffer); - if(numBytesRead < 0) break; - - pointerIncrement = iio_buffer_step(buffer); - pointerEnd = static_cast(iio_buffer_end(buffer)); - - const struct iio_data_format *format = iio_channel_get_data_format(channel); - unsigned int repeat = has_repeat ? format->repeat : 1; - - for(pointerData = static_cast(iio_buffer_first(buffer, channel)); pointerData < pointerEnd; pointerData += pointerIncrement) - { - for(int j = 0; j < repeat; j++) - { - if(format->length / 8 == sizeof(int16_t)) - { - int16_t rawValue = (reinterpret_cast(pointerData))[j]; - double scaledValue = (rawValue - offsetAttrValue) * *scaleAttrValue; - Q_EMIT streamData(scaledValue); - } - } +int ADMTController::streamIO() { + int result = -1; + const char *deviceName = "admt4000"; + const char *channelName = "rot"; + const char *scaleAttrName = "scale"; + const char *offsetAttrName = "offset"; + size_t samples = 1; + bool isOutput = false; + bool isCyclic = false; + + unsigned int i, j, major, minor; + char git_tag[8]; + iio_library_get_version(&major, &minor, git_tag); + bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; + + double *scaleAttrValue = new double(1); + int offsetAttrValue = 0; + char *offsetDst = new char[maxAttrSize]; + + if (!m_iioCtx) + return result; // Check if the context is valid + if (iio_context_get_devices_count(m_iioCtx) < 1) + return result; // Check if there are devices in the context + struct iio_device *admtDevice = + iio_context_find_device(m_iioCtx, deviceName); // Find the ADMT device + if (admtDevice == NULL) + return result; + struct iio_channel *channel = iio_device_find_channel( + admtDevice, channelName, isOutput); // Find the rotation channel + if (channel == NULL) + return result; + iio_channel_enable(channel); // Enable the channel + int scaleRet = iio_channel_attr_read_double( + channel, scaleAttrName, scaleAttrValue); // Read the scale attribute + if (scaleRet != 0) + return scaleRet; + iio_channel_attr_read(channel, offsetAttrName, offsetDst, + maxAttrSize); // Read the offset attribute + offsetAttrValue = atoi(offsetDst); + struct iio_buffer *buffer = iio_device_create_buffer( + admtDevice, samples, isCyclic); // Create a buffer + + while (!stopStream) { + ssize_t numBytesRead; + char *pointerData, *pointerEnd; + ptrdiff_t pointerIncrement; + + numBytesRead = iio_buffer_refill(buffer); + if (numBytesRead < 0) + break; + + pointerIncrement = iio_buffer_step(buffer); + pointerEnd = static_cast(iio_buffer_end(buffer)); + + const struct iio_data_format *format = iio_channel_get_data_format(channel); + unsigned int repeat = has_repeat ? format->repeat : 1; + + for (pointerData = static_cast(iio_buffer_first(buffer, channel)); + pointerData < pointerEnd; pointerData += pointerIncrement) { + for (int j = 0; j < repeat; j++) { + if (format->length / 8 == sizeof(int16_t)) { + int16_t rawValue = (reinterpret_cast(pointerData))[j]; + double scaledValue = (rawValue - offsetAttrValue) * *scaleAttrValue; + Q_EMIT streamData(scaledValue); } + } } + } - iio_buffer_destroy(buffer); - return 0; + iio_buffer_destroy(buffer); + return 0; } -void ADMTController::handleStreamData(double value) -{ - streamedValue = value; -} - -void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) -{ - streamBufferedIntervals.clear(); - QVector bufferedValues; - vector rawBufferedValues; - sampleCount = 0; - - int result = -1; - const char *deviceName = "admt4000"; - const char *channelName = "rot"; - const char *scaleAttrName = "scale"; - const char *offsetAttrName = "offset"; - size_t samples = 1; - bool isOutput = false; - bool isCyclic = true; - - unsigned int i, j, major, minor; - char git_tag[8]; - iio_library_get_version(&major, &minor, git_tag); - bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; - - double *scaleAttrValue = new double(1); - int offsetAttrValue = 0; - char *offsetDst = new char[maxAttrSize]; - - if(!m_iioCtx) return; // result; // Check if the context is valid - if(iio_context_get_devices_count(m_iioCtx) < 1) return; // result; // Check if there are devices in the context - struct iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); // Find the ADMT device - if(admtDevice == NULL) return; // result; - struct iio_channel *channel = iio_device_find_channel(admtDevice, channelName, isOutput); // Find the rotation channel - if(channel == NULL) return; // result; - iio_channel_enable(channel); // Enable the channel - int scaleRet = iio_channel_attr_read_double(channel, scaleAttrName, scaleAttrValue); // Read the scale attribute - if(scaleRet != 0) return; // scaleRet; - iio_channel_attr_read(channel, offsetAttrName, offsetDst, maxAttrSize); // Read the offset attribute - offsetAttrValue = atoi(offsetDst); - struct iio_buffer *buffer = iio_device_create_buffer(admtDevice, samples, isCyclic); // Create a buffer - - while(!stopStream && sampleCount < totalSamples) - { - elapsedStreamTimer.start(); - - ssize_t numBytesRead; - char *pointerData, *pointerEnd; - ptrdiff_t pointerIncrement; - - numBytesRead = iio_buffer_refill(buffer); - if(numBytesRead < 0) break; - - pointerIncrement = iio_buffer_step(buffer); - pointerEnd = static_cast(iio_buffer_end(buffer)); - - const struct iio_data_format *format = iio_channel_get_data_format(channel); - unsigned int repeat = has_repeat ? format->repeat : 1; - int j = 0; - - for(pointerData = static_cast(iio_buffer_first(buffer, channel)); pointerData < pointerEnd; pointerData += pointerIncrement) - { - for(j = 0; j < repeat; j++) - { - if(format->length / 8 == sizeof(int16_t)) - { - rawBufferedValues.push_back((reinterpret_cast(pointerData))[j]); - sampleCount++; - continue; - } - } - } - - qint64 elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); - while(elapsedNanoseconds < targetSampleRate) - { - elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); +void ADMTController::handleStreamData(double value) { streamedValue = value; } + +void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) { + streamBufferedIntervals.clear(); + QVector bufferedValues; + vector rawBufferedValues; + sampleCount = 0; + + int result = -1; + const char *deviceName = "admt4000"; + const char *channelName = "rot"; + const char *scaleAttrName = "scale"; + const char *offsetAttrName = "offset"; + size_t samples = 1; + bool isOutput = false; + bool isCyclic = true; + + unsigned int i, j, major, minor; + char git_tag[8]; + iio_library_get_version(&major, &minor, git_tag); + bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; + + double *scaleAttrValue = new double(1); + int offsetAttrValue = 0; + char *offsetDst = new char[maxAttrSize]; + + if (!m_iioCtx) + return; // result; // Check if the context is valid + if (iio_context_get_devices_count(m_iioCtx) < 1) + return; // result; // Check if there are devices in the context + struct iio_device *admtDevice = + iio_context_find_device(m_iioCtx, deviceName); // Find the ADMT device + if (admtDevice == NULL) + return; // result; + struct iio_channel *channel = iio_device_find_channel( + admtDevice, channelName, isOutput); // Find the rotation channel + if (channel == NULL) + return; // result; + iio_channel_enable(channel); // Enable the channel + int scaleRet = iio_channel_attr_read_double( + channel, scaleAttrName, scaleAttrValue); // Read the scale attribute + if (scaleRet != 0) + return; // scaleRet; + iio_channel_attr_read(channel, offsetAttrName, offsetDst, + maxAttrSize); // Read the offset attribute + offsetAttrValue = atoi(offsetDst); + struct iio_buffer *buffer = iio_device_create_buffer( + admtDevice, samples, isCyclic); // Create a buffer + + while (!stopStream && sampleCount < totalSamples) { + elapsedStreamTimer.start(); + + ssize_t numBytesRead; + char *pointerData, *pointerEnd; + ptrdiff_t pointerIncrement; + + numBytesRead = iio_buffer_refill(buffer); + if (numBytesRead < 0) + break; + + pointerIncrement = iio_buffer_step(buffer); + pointerEnd = static_cast(iio_buffer_end(buffer)); + + const struct iio_data_format *format = iio_channel_get_data_format(channel); + unsigned int repeat = has_repeat ? format->repeat : 1; + int j = 0; + + for (pointerData = static_cast(iio_buffer_first(buffer, channel)); + pointerData < pointerEnd; pointerData += pointerIncrement) { + for (j = 0; j < repeat; j++) { + if (format->length / 8 == sizeof(int16_t)) { + rawBufferedValues.push_back( + (reinterpret_cast(pointerData))[j]); + sampleCount++; + continue; } - streamBufferedIntervals.append(elapsedNanoseconds); + } } - iio_buffer_destroy(buffer); - for(int i = 0; i < rawBufferedValues.size(); i++) - { - double scaledValue = (rawBufferedValues[i] - offsetAttrValue) * *scaleAttrValue; - bufferedValues.append(scaledValue); + qint64 elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); + while (elapsedNanoseconds < targetSampleRate) { + elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); } - - Q_EMIT streamBufferedData(bufferedValues); - Q_EMIT streamBufferedDataInterval(streamBufferedIntervals); + streamBufferedIntervals.append(elapsedNanoseconds); + } + iio_buffer_destroy(buffer); + + for (int i = 0; i < rawBufferedValues.size(); i++) { + double scaledValue = + (rawBufferedValues[i] - offsetAttrValue) * *scaleAttrValue; + bufferedValues.append(scaledValue); + } + + Q_EMIT streamBufferedData(bufferedValues); + Q_EMIT streamBufferedDataInterval(streamBufferedIntervals); } -void ADMTController::handleStreamBufferedData(const QVector &value) -{ - streamBufferedValues = value; +void ADMTController::handleStreamBufferedData(const QVector &value) { + streamBufferedValues = value; } -bool ADMTController::checkVelocityReachedFlag(uint16_t registerValue) -{ - // Bit 8 - 1: Signals that the target velocity is reached. This flag becomes set while VACTUAL and VMAX match. - return ((registerValue >> 8) & 0x01) ? true : false; +bool ADMTController::checkVelocityReachedFlag(uint16_t registerValue) { + // Bit 8 - 1: Signals that the target velocity is reached. This flag becomes + // set while VACTUAL and VMAX match. + return ((registerValue >> 8) & 0x01) ? true : false; } -void ADMTController::handleStreamBufferedDataInterval(const QVector &value) -{ - streamBufferedIntervals = value; -} \ No newline at end of file +void ADMTController::handleStreamBufferedDataInterval( + const QVector &value) { + streamBufferedIntervals = value; +} +#include "moc_admtcontroller.cpp" diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index c030a8e027..2749880fda 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -23,8 +23,8 @@ #include "admtcontroller.h" #include "harmoniccalibration.h" -#include #include +#include #include @@ -34,121 +34,120 @@ using namespace scopy::admt; const bool isDebug = false; -bool ADMTPlugin::compatible(QString m_param, QString category) -{ - m_name = "ADMT4000"; - bool ret = false; - Connection *conn = ConnectionProvider::GetInstance()->open(m_param); - - if(!conn) { - qWarning(CAT_ADMTPLUGIN) << "No context available for ADMT"; - return false; - } - - iio_device *admtDevice = iio_context_find_device(conn->context(), "admt4000"); - if(admtDevice) { - ret = true; - } +bool ADMTPlugin::compatible(QString m_param, QString category) { + m_name = "ADMT4000"; + bool ret = false; + Connection *conn = ConnectionProvider::GetInstance()->open(m_param); + + if (!conn) { + qWarning(CAT_ADMTPLUGIN) << "No context available for ADMT"; + return false; + } + + iio_device *admtDevice = iio_context_find_device(conn->context(), "admt4000"); + if (admtDevice) { + ret = true; + } + + ConnectionProvider::close(m_param); + if (isDebug) + return true; + return ret; +} - ConnectionProvider::close(m_param); - if(isDebug) return true; - return ret; +bool ADMTPlugin::loadPage() { + // Here you must write the code for the plugin info page + // Below is an example for an iio device + /*m_page = new QWidget(); + m_page->setLayout(new QVBoxLayout(m_page)); + m_page->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_infoPage = new InfoPage(m_page); + m_infoPage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + m_page->layout()->addWidget(m_infoPage); + m_page->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Preferred, + QSizePolicy::Expanding)); + + auto cp = ContextProvider::GetInstance(); + struct iio_context *context = cp->open(m_param); + ssize_t attributeCount = iio_context_get_attrs_count(context); + for(int i = 0; i < attributeCount; ++i) { + const char *name; + const char *value; + int ret = iio_context_get_attr(context, i, &name, &value); + if(ret < 0) { + qWarning(CAT_ADMTPLUGIN) << "Could not read attribute with + index:" << i; continue; + } + + m_infoPage->update(name, value); + } + cp->close(m_param); + m_page->ensurePolished();*/ + return true; } -bool ADMTPlugin::loadPage() -{ - // Here you must write the code for the plugin info page - // Below is an example for an iio device - /*m_page = new QWidget(); - m_page->setLayout(new QVBoxLayout(m_page)); - m_page->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_infoPage = new InfoPage(m_page); - m_infoPage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - m_page->layout()->addWidget(m_infoPage); - m_page->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding)); - - auto cp = ContextProvider::GetInstance(); - struct iio_context *context = cp->open(m_param); - ssize_t attributeCount = iio_context_get_attrs_count(context); - for(int i = 0; i < attributeCount; ++i) { - const char *name; - const char *value; - int ret = iio_context_get_attr(context, i, &name, &value); - if(ret < 0) { - qWarning(CAT_ADMTPLUGIN) << "Could not read attribute with index:" << i; - continue; - } - - m_infoPage->update(name, value); - } - cp->close(m_param); - m_page->ensurePolished();*/ - return true; +bool ADMTPlugin::loadIcon() { + SCOPY_PLUGIN_ICON(":/gui/icons/adalm.svg"); + return true; } -bool ADMTPlugin::loadIcon() -{ - SCOPY_PLUGIN_ICON(":/gui/icons/adalm.svg"); - return true; +void ADMTPlugin::loadToolList() { + m_toolList.append(SCOPY_NEW_TOOLMENUENTRY( + "harmoniccalibration", "Harmonic Calibration", + ":/gui/icons/scopy-default/icons/tool_oscilloscope.svg")); } -void ADMTPlugin::loadToolList() -{ - m_toolList.append( - SCOPY_NEW_TOOLMENUENTRY("harmoniccalibration", "Harmonic Calibration", ":/gui/icons/scopy-default/icons/tool_oscilloscope.svg")); +void ADMTPlugin::unload() { /*delete m_infoPage;*/ } -void ADMTPlugin::unload() { /*delete m_infoPage;*/ } - -QString ADMTPlugin::description() { return "Plugin for ADMT Harmonic Calibration"; } - -bool ADMTPlugin::onConnect() -{ - // This method is called when you try to connect to a device and the plugin is - // compatible to that device - // In case of success the function must return true and false otherwise - - Connection *conn = ConnectionProvider::GetInstance()->open(m_param); - if(conn == nullptr) - return false; - m_ctx = conn->context(); - m_toolList[0]->setEnabled(true); - m_toolList[0]->setRunBtnVisible(false); - - m_admtController = new ADMTController(m_param, this); - m_admtController->connectADMT(); - harmonicCalibration = new HarmonicCalibration(m_admtController, isDebug); - m_toolList[0]->setTool(harmonicCalibration); - - return true; +QString ADMTPlugin::description() { + return "Plugin for ADMT Harmonic Calibration"; } -bool ADMTPlugin::onDisconnect() -{ - // This method is called when the disconnect button is pressed - // It must remove all connections that were established on the connection - - dynamic_cast(harmonicCalibration)->requestDisconnect(); - - for(auto &tool : m_toolList) { - tool->setEnabled(false); - tool->setRunning(false); - tool->setRunBtnVisible(false); - QWidget *w = tool->tool(); - if(w) { - tool->setTool(nullptr); - delete(w); - } - } +bool ADMTPlugin::onConnect() { + // This method is called when you try to connect to a device and the plugin is + // compatible to that device + // In case of success the function must return true and false otherwise + + Connection *conn = ConnectionProvider::GetInstance()->open(m_param); + if (conn == nullptr) + return false; + m_ctx = conn->context(); + m_toolList[0]->setEnabled(true); + m_toolList[0]->setRunBtnVisible(false); + + m_admtController = new ADMTController(m_param, this); + m_admtController->connectADMT(); + harmonicCalibration = new HarmonicCalibration(m_admtController, isDebug); + m_toolList[0]->setTool(harmonicCalibration); - m_admtController->disconnectADMT(); - return true; + return true; } -void ADMTPlugin::initMetadata() -{ - loadMetadata( - R"plugin( +bool ADMTPlugin::onDisconnect() { + // This method is called when the disconnect button is pressed + // It must remove all connections that were established on the connection + + dynamic_cast(harmonicCalibration)->requestDisconnect(); + + for (auto &tool : m_toolList) { + tool->setEnabled(false); + tool->setRunning(false); + tool->setRunBtnVisible(false); + QWidget *w = tool->tool(); + if (w) { + tool->setTool(nullptr); + delete (w); + } + } + + m_admtController->disconnectADMT(); + return true; +} + +void ADMTPlugin::initMetadata() { + loadMetadata( + R"plugin( { "priority":102, "category":[ @@ -158,3 +157,5 @@ void ADMTPlugin::initMetadata() } )plugin"); } + +#include "moc_admtplugin.cpp" diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp index a6e77831b9..c979a2b97f 100644 --- a/plugins/admt/src/admtstylehelper.cpp +++ b/plugins/admt/src/admtstylehelper.cpp @@ -27,46 +27,44 @@ using namespace scopy::admt; ADMTStyleHelper *ADMTStyleHelper::pinstance_{nullptr}; -ADMTStyleHelper:: ADMTStyleHelper(QObject *parent) {} - -ADMTStyleHelper *ADMTStyleHelper::GetInstance() -{ - if(pinstance_ == nullptr) { - pinstance_ = new ADMTStyleHelper(QApplication::instance()); // singleton has the app as parent - } - return pinstance_; +ADMTStyleHelper::ADMTStyleHelper(QObject *parent) {} + +ADMTStyleHelper *ADMTStyleHelper::GetInstance() { + if (pinstance_ == nullptr) { + pinstance_ = new ADMTStyleHelper( + QApplication::instance()); // singleton has the app as parent + } + return pinstance_; } ADMTStyleHelper::~ADMTStyleHelper() {} -void ADMTStyleHelper::initColorMap() -{ - auto sh = ADMTStyleHelper::GetInstance(); - sh->colorMap.insert("CH0", "#FF7200"); - sh->colorMap.insert("CH1", "#9013FE"); - sh->colorMap.insert("CH2", "#27B34F"); - sh->colorMap.insert("CH3", "#F8E71C"); - sh->colorMap.insert("CH4", "#4A64FF"); - sh->colorMap.insert("CH5", "#02BCD4"); - sh->colorMap.insert("CH6", "#F44336"); - sh->colorMap.insert("CH7", "#F5A623"); - sh->colorMap.insert("CH8", "#1981AE"); - sh->colorMap.insert("CH9", "#6FCEA6"); - sh->colorMap.insert("CH10", "#F7A1DA"); - sh->colorMap.insert("CH11", "#E3F5FC"); +void ADMTStyleHelper::initColorMap() { + auto sh = ADMTStyleHelper::GetInstance(); + sh->colorMap.insert("CH0", "#FF7200"); + sh->colorMap.insert("CH1", "#9013FE"); + sh->colorMap.insert("CH2", "#27B34F"); + sh->colorMap.insert("CH3", "#F8E71C"); + sh->colorMap.insert("CH4", "#4A64FF"); + sh->colorMap.insert("CH5", "#02BCD4"); + sh->colorMap.insert("CH6", "#F44336"); + sh->colorMap.insert("CH7", "#F5A623"); + sh->colorMap.insert("CH8", "#1981AE"); + sh->colorMap.insert("CH9", "#6FCEA6"); + sh->colorMap.insert("CH10", "#F7A1DA"); + sh->colorMap.insert("CH11", "#E3F5FC"); } -QString ADMTStyleHelper::getColor(QString id) -{ - auto sh = ADMTStyleHelper::GetInstance(); - return sh->colorMap[id]; +QString ADMTStyleHelper::getColor(QString id) { + auto sh = ADMTStyleHelper::GetInstance(); + return sh->colorMap[id]; } -void ADMTStyleHelper::TopContainerButtonStyle(QPushButton *btn, QString objectName) -{ - if(!objectName.isEmpty()) - btn->setObjectName(objectName); - QString style = QString(R"css( +void ADMTStyleHelper::TopContainerButtonStyle(QPushButton *btn, + QString objectName) { + if (!objectName.isEmpty()) + btn->setObjectName(objectName); + QString style = QString(R"css( QPushButton { width: 88px; height: 48px; @@ -90,23 +88,22 @@ void ADMTStyleHelper::TopContainerButtonStyle(QPushButton *btn, QString objectNa background-color:#272730; } })css"); - style.replace("&&ScopyBlue&&", Style::getAttribute(json::theme::interactive_primary_idle)); - btn->setStyleSheet(style); + style.replace("&&ScopyBlue&&", + Style::getAttribute(json::theme::interactive_primary_idle)); + btn->setStyleSheet(style); } -void ADMTStyleHelper::PlotWidgetStyle(PlotWidget *widget, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - widget->setContentsMargins(10, 10, 10, 6); - widget->plot()->canvas()->setStyleSheet("background-color: black;"); +void ADMTStyleHelper::PlotWidgetStyle(PlotWidget *widget, QString objectName) { + if (!objectName.isEmpty()) + widget->setObjectName(objectName); + widget->setContentsMargins(10, 10, 10, 6); + widget->plot()->canvas()->setStyleSheet("background-color: black;"); } -void ADMTStyleHelper::ComboBoxStyle(QComboBox *widget, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - QString style = QString(R"css( +void ADMTStyleHelper::ComboBoxStyle(QComboBox *widget, QString objectName) { + if (!objectName.isEmpty()) + widget->setObjectName(objectName); + QString style = QString(R"css( QWidget { } QComboBox { @@ -158,14 +155,14 @@ void ADMTStyleHelper::ComboBoxStyle(QComboBox *widget, QString objectName) selection-color: transparent; } )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); + style = style.replace(QString("&&colorname&&"), + Style::getAttribute(json::global::ch0)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); } -void ADMTStyleHelper::LineEditStyle(QLineEdit *widget, QString objectName) -{ - QString style = QString(R"css( +void ADMTStyleHelper::LineEditStyle(QLineEdit *widget, QString objectName) { + QString style = QString(R"css( QLineEdit { font-family: Open Sans; font-size: 16px; @@ -183,19 +180,20 @@ void ADMTStyleHelper::LineEditStyle(QLineEdit *widget, QString objectName) color: #9c4600; } )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setContentsMargins(0, 0, 0, 0); - widget->setTextMargins(12, 4, 12, 4); - widget->setAlignment(Qt::AlignRight); + style = style.replace(QString("&&colorname&&"), + Style::getAttribute(json::global::ch0)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setContentsMargins(0, 0, 0, 0); + widget->setTextMargins(12, 4, 12, 4); + widget->setAlignment(Qt::AlignRight); } -void ADMTStyleHelper::ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName) -{ - if(!objectName.isEmpty()) - chk->setObjectName(objectName); - QString style = QString(R"css( +void ADMTStyleHelper::ColoredSquareCheckbox(QCheckBox *chk, QColor color, + QString objectName) { + if (!objectName.isEmpty()) + chk->setObjectName(objectName); + QString style = QString(R"css( QCheckBox { width:16px; height:16px; @@ -211,16 +209,16 @@ void ADMTStyleHelper::ColoredSquareCheckbox(QCheckBox *chk, QColor color, QStrin QCheckBox::indicator:unchecked { background-color: &&UIElementBackground&&; } QCheckBox::indicator:checked { background-color: &&colorname&&; } )css"); - style.replace("&&colorname&&", color.name()); - style.replace("&&UIElementBackground&&", Style::getAttribute(json::theme::background_primary)); - chk->setStyleSheet(style); + style.replace("&&colorname&&", color.name()); + style.replace("&&UIElementBackground&&", + Style::getAttribute(json::theme::background_primary)); + chk->setStyleSheet(style); } -void ADMTStyleHelper::StartButtonStyle(QPushButton *btn, QString objectName) -{ - if(!objectName.isEmpty()) - btn->setObjectName(objectName); - QString style = QString(R"css( +void ADMTStyleHelper::StartButtonStyle(QPushButton *btn, QString objectName) { + if (!objectName.isEmpty()) + btn->setObjectName(objectName); + QString style = QString(R"css( QPushButton { border-radius: 2px; padding-left: 20px; @@ -241,46 +239,49 @@ void ADMTStyleHelper::StartButtonStyle(QPushButton *btn, QString objectName) QPushButton:disabled { background-color: grey; })css"); - btn->setCheckable(true); - btn->setChecked(false); - btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - btn->setFixedHeight(36); - btn->setStyleSheet(style); - QIcon playIcon; - playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/play.svg", "white", 1), QIcon::Normal, QIcon::Off); - playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/scopy-default/icons/play_stop.svg", "white", 1), - QIcon::Normal, QIcon::On); - btn->setIcon(playIcon); - btn->setIconSize(QSize(64, 64)); + btn->setCheckable(true); + btn->setChecked(false); + btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + btn->setFixedHeight(36); + btn->setStyleSheet(style); + QIcon playIcon; + playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/play.svg", "white", 1), + QIcon::Normal, QIcon::Off); + playIcon.addPixmap( + Util::ChangeSVGColor(":/gui/icons/scopy-default/icons/play_stop.svg", + "white", 1), + QIcon::Normal, QIcon::On); + btn->setIcon(playIcon); + btn->setIconSize(QSize(64, 64)); } -void ADMTStyleHelper::TextStyle(QWidget *widget, const char *styleHelperColor, bool isBold, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - QString existingStyle = widget->styleSheet(); - QString style = QString(R"css( +void ADMTStyleHelper::TextStyle(QWidget *widget, const char *styleHelperColor, + bool isBold, QString objectName) { + if (!objectName.isEmpty()) + widget->setObjectName(objectName); + QString existingStyle = widget->styleSheet(); + QString style = QString(R"css( font-size: 16px; font-weight: &&fontweight&&; text-align: right; color: &&colorname&&; )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(styleHelperColor)); - QString fontWeight = QString("normal"); - if(isBold){ - fontWeight = QString("bold"); - } - style = style.replace(QString("&&fontweight&&"), fontWeight); - widget->setStyleSheet(existingStyle + style); + style = style.replace(QString("&&colorname&&"), + Style::getAttribute(styleHelperColor)); + QString fontWeight = QString("normal"); + if (isBold) { + fontWeight = QString("bold"); + } + style = style.replace(QString("&&fontweight&&"), fontWeight); + widget->setStyleSheet(existingStyle + style); } -void ADMTStyleHelper::MenuSmallLabel(QLabel *label, QString objectName) -{ - if(!objectName.isEmpty()) - label->setObjectName(objectName); - label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); +void ADMTStyleHelper::MenuSmallLabel(QLabel *label, QString objectName) { + if (!objectName.isEmpty()) + label->setObjectName(objectName); + label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - QString style = QString(R"css( + QString style = QString(R"css( QLabel { color: white; background-color: rgba(255,255,255,0); @@ -293,72 +294,73 @@ void ADMTStyleHelper::MenuSmallLabel(QLabel *label, QString objectName) color: grey; } )css"); - label->setStyleSheet(style); + label->setStyleSheet(style); } -void ADMTStyleHelper::LineStyle(QFrame *line, QString objectName) -{ - if(!objectName.isEmpty()) - line->setObjectName(objectName); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Plain); - line->setFixedHeight(1); - QString lineStyle = QString(R"css( +void ADMTStyleHelper::LineStyle(QFrame *line, QString objectName) { + if (!objectName.isEmpty()) + line->setObjectName(objectName); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Plain); + line->setFixedHeight(1); + QString lineStyle = QString(R"css( QFrame { border: 1px solid #808085; } )css"); - line->setStyleSheet(lineStyle); + line->setStyleSheet(lineStyle); } -void ADMTStyleHelper::UIBackgroundStyle(QWidget *widget, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - QString style = QString(R"css( +void ADMTStyleHelper::UIBackgroundStyle(QWidget *widget, QString objectName) { + if (!objectName.isEmpty()) + widget->setObjectName(objectName); + QString style = QString(R"css( background-color: &&colorname&&; )css"); - style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::background_primary)); - widget->setStyleSheet(style); + style.replace(QString("&&colorname&&"), + Style::getAttribute(json::theme::background_primary)); + widget->setStyleSheet(style); } -void ADMTStyleHelper::GraphChannelStyle(QWidget *widget, QLayout *layout, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - widget->setLayout(layout); - ADMTStyleHelper::UIBackgroundStyle(widget); - layout->setContentsMargins(20, 13, 20, 5); - layout->setSpacing(20); +void ADMTStyleHelper::GraphChannelStyle(QWidget *widget, QLayout *layout, + QString objectName) { + if (!objectName.isEmpty()) + widget->setObjectName(objectName); + widget->setLayout(layout); + ADMTStyleHelper::UIBackgroundStyle(widget); + layout->setContentsMargins(20, 13, 20, 5); + layout->setSpacing(20); } -void ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(QWidget *widget, QHBoxLayout *layout, QLabel *hLabel, QLabel *hMagLabel, QLabel *hPhaseLabel, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); +void ADMTStyleHelper::CalculatedCoeffWidgetRowStyle( + QWidget *widget, QHBoxLayout *layout, QLabel *hLabel, QLabel *hMagLabel, + QLabel *hPhaseLabel, QString objectName) { + if (!objectName.isEmpty()) + widget->setObjectName(objectName); - widget->setLayout(layout); - QString style = QString(R"css( + widget->setLayout(layout); + QString style = QString(R"css( background-color: &&colorname&&; border-radius: 4px; )css"); - style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::background_subtle)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - layout->setContentsMargins(12, 4, 12, 4); - - ADMTStyleHelper::TextStyle(hLabel, json::global::white, true); - ADMTStyleHelper::TextStyle(hMagLabel, json::global::ch0); - ADMTStyleHelper::TextStyle(hPhaseLabel, json::global::ch1); - - hLabel->setFixedWidth(24); - hMagLabel->setContentsMargins(0, 0, 32, 0); - hPhaseLabel->setFixedWidth(72); - - layout->addWidget(hLabel); - layout->addWidget(hMagLabel, 0, Qt::AlignRight); - layout->addWidget(hPhaseLabel); + style.replace(QString("&&colorname&&"), + Style::getAttribute(json::theme::background_subtle)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + layout->setContentsMargins(12, 4, 12, 4); + + ADMTStyleHelper::TextStyle(hLabel, json::global::white, true); + ADMTStyleHelper::TextStyle(hMagLabel, json::global::ch0); + ADMTStyleHelper::TextStyle(hPhaseLabel, json::global::ch1); + + hLabel->setFixedWidth(24); + hMagLabel->setContentsMargins(0, 0, 32, 0); + hPhaseLabel->setFixedWidth(72); + + layout->addWidget(hLabel); + layout->addWidget(hMagLabel, 0, Qt::AlignRight); + layout->addWidget(hPhaseLabel); } #include "moc_admtstylehelper.cpp" \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 6fed3edefb..599d7ca563 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -24,15 +24,15 @@ #include "style.h" #include "style_properties.h" -#include -#include #include +#include +#include using namespace scopy; using namespace scopy::admt; static int acquisitionUITimerRate = 500; // In ms -static int acquisitionSampleRate = 20; +static int acquisitionSampleRate = 20; static int acquisitionGraphSampleRate = 100; static int motorWaitVelocityReachedSampleRate = 50; @@ -57,25 +57,30 @@ static bool hasMTDiagnostics = false; static bool isMotorRotationClockwise = true; static double fast_motor_rpm = 300; -static double motorFullStepAngle = 0.9; // TODO input as configuration +static double motorFullStepAngle = 0.9; // TODO input as configuration static double microStepResolution = 256; // TODO input as configuration -static int motorfCLK = 12500000; // 12.5 Mhz, TODO input as configuration +static int motorfCLK = 12500000; // 12.5 Mhz, TODO input as configuration static double motorAccelTime = 1; // In seconds static double motorFullStepPerRevolution = 360 / motorFullStepAngle; -static double motorMicrostepPerRevolution = motorFullStepPerRevolution * microStepResolution; -static double motorTimeUnit = static_cast(1 << 24) / motorfCLK; // t = 2^24/16Mhz +static double motorMicrostepPerRevolution = + motorFullStepPerRevolution * microStepResolution; +static double motorTimeUnit = + static_cast(1 << 24) / motorfCLK; // t = 2^24/16Mhz static int acquisitionDisplayLength = 200; -static QVector acquisitionAngleList, acquisitionABSAngleList, acquisitionTurnCountList, acquisitionTmp0List, - acquisitionTmp1List, acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, - graphDataList, graphPostDataList; +static QVector acquisitionAngleList, acquisitionABSAngleList, + acquisitionTurnCountList, acquisitionTmp0List, acquisitionTmp1List, + acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, + graphDataList, graphPostDataList; -static const QColor scopyBlueColor = Style::getColor(json::theme::interactive_primary_idle); +static const QColor scopyBlueColor = + Style::getColor(json::theme::interactive_primary_idle); static const QColor sineColor = QColor("#85e94c"); static const QColor cosineColor = QColor("#91e6cf"); static const QColor faultLEDColor = QColor("#c81a28"); -static const QColor gpioLEDColor = Style::getColor(json::theme::interactive_secondary_idle); +static const QColor gpioLEDColor = + Style::getColor(json::theme::interactive_secondary_idle); static const QColor statusLEDColor = QColor("#2e9e6f"); static const QPen scopyBluePen(scopyBlueColor); @@ -102,8 +107,10 @@ static QString deviceName = ""; static QString deviceType = ""; static bool is5V = false; -static double H1_MAG_ANGLE, H2_MAG_ANGLE, H3_MAG_ANGLE, H8_MAG_ANGLE, H1_PHASE_ANGLE, H2_PHASE_ANGLE, H3_PHASE_ANGLE, H8_PHASE_ANGLE; -static uint32_t H1_MAG_HEX, H2_MAG_HEX, H3_MAG_HEX, H8_MAG_HEX, H1_PHASE_HEX, H2_PHASE_HEX, H3_PHASE_HEX, H8_PHASE_HEX; +static double H1_MAG_ANGLE, H2_MAG_ANGLE, H3_MAG_ANGLE, H8_MAG_ANGLE, + H1_PHASE_ANGLE, H2_PHASE_ANGLE, H3_PHASE_ANGLE, H8_PHASE_ANGLE; +static uint32_t H1_MAG_HEX, H2_MAG_HEX, H3_MAG_HEX, H8_MAG_HEX, H1_PHASE_HEX, + H2_PHASE_HEX, H3_PHASE_HEX, H8_PHASE_HEX; static int acquisitionGraphYMin = 0; static int acquisitionGraphYMax = 360; @@ -129,4171 +136,5219 @@ static int globalSpacingSmall = Style::getDimension(json::global::unit_0_5); static int globalSpacingMedium = Style::getDimension(json::global::unit_1); static map acquisitionDataMap = { - {RADIUS, false}, - {ANGLE, false}, - {TURNCOUNT, false}, - {ABSANGLE, false}, - {SINE, false}, - {COSINE, false}, - {SECANGLI, false}, - {SECANGLQ, false}, - {ANGLESEC, false}, - {DIAG1, false}, - {DIAG2, false}, - {TMP0, false}, - {TMP1, false}, - {CNVCNT, false}, - {SCRADIUS, false}, - {SPIFAULT, false} -}; - -HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool isDebug, QWidget *parent) - : QWidget(parent) - , isDebug(isDebug) - , m_admtController(m_admtController) -{ - ADMTStyleHelper::GetInstance()->initColorMap(); - readDeviceProperties(); - initializeADMT(); - initializeMotor(); - readSequence(); - - rotationChannelName = m_admtController->getChannelId(ADMTController::Channel::ROTATION); - angleChannelName = m_admtController->getChannelId(ADMTController::Channel::ANGLE); - countChannelName = m_admtController->getChannelId(ADMTController::Channel::COUNT); - temperatureChannelName = m_admtController->getChannelId(ADMTController::Channel::TEMPERATURE); - - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - QHBoxLayout *lay = new QHBoxLayout(this); - tabWidget = new QTabWidget(this); - - setLayout(lay); - lay->setMargin(0); - lay->insertWidget(1, tabWidget); - tabWidget->setStyleSheet(""); - tabWidget->tabBar()->setStyleSheet(""); - Style::setStyle(tabWidget, style::properties::admt::tabWidget); - Style::setStyle(tabWidget->tabBar(), style::properties::admt::tabBar); - - tabWidget->addTab(createAcquisitionWidget(), "Acquisition"); - tabWidget->addTab(createCalibrationWidget(), "Calibration"); - tabWidget->addTab(createUtilityWidget(), "Utility"); - tabWidget->addTab(createRegistersWidget(), "Registers"); - - connect(tabWidget, &QTabWidget::currentChanged, [=](int index){ - tabWidget->setCurrentIndex(index); - - if(index == 0 || index == 1) - { - startDeviceStatusMonitor(); - startCurrentMotorPositionMonitor(); - } - else{ - stopDeviceStatusMonitor(); - stopCurrentMotorPositionMonitor(); - } - - if(index == 0) // Acquisition Tab - { - startAcquisitionUITask(); - readSequence(); - updateSequenceWidget(); - updateAcquisitionMotorRPM(); - updateAcquisitionMotorRotationDirection(); - } - else - { - stopAcquisitionUITask(); - stop(); - } - - if(index == 1) // Calibration Tab - { - startCalibrationUITask(); - updateCalibrationMotorRPM(); - updateCalibrationMotorRotationDirection(); - } - else - { - stopCalibrationUITask(); - } - - if(index == 2) // Utility Tab - { - readSequence(); - toggleFaultRegisterMode(GENERALRegisterMap.at("Sequence Type")); - toggleMTDiagnostics(GENERALRegisterMap.at("Sequence Type")); - toggleUtilityTask(true); - } - else - { - toggleUtilityTask(false); - } - - if(index == 3) // Registers Tab - { - readSequence(); - toggleRegisters(GENERALRegisterMap.at("Sequence Type")); - } - }); - - connect(this, &HarmonicCalibration::updateFaultStatusSignal, this, &HarmonicCalibration::updateFaultStatus); - connect(this, &HarmonicCalibration::motorPositionChanged, this, &HarmonicCalibration::updateMotorPosition); - - connect(this, &HarmonicCalibration::calibrationLogWriteSignal, this, &HarmonicCalibration::calibrationLogWrite); - connect(this, &HarmonicCalibration::commandLogWriteSignal, this, &HarmonicCalibration::commandLogWrite); - connect(this, &HarmonicCalibration::DIGIORegisterChanged, this, &HarmonicCalibration::updateDIGIOUI); - connect(this, &HarmonicCalibration::FaultRegisterChanged, this, &HarmonicCalibration::updateFaultRegisterUI); - connect(this, &HarmonicCalibration::DIAG1RegisterChanged, this, &HarmonicCalibration::updateMTDiagnosticRegisterUI); - connect(this, &HarmonicCalibration::DIAG2RegisterChanged, this, &HarmonicCalibration::updateMTDiagnosticsUI); - - startAcquisitionUITask(); - startDeviceStatusMonitor(); - startCurrentMotorPositionMonitor(); -} - -HarmonicCalibration::~HarmonicCalibration() -{ - requestDisconnect(); -} - -ToolTemplate* HarmonicCalibration::createAcquisitionWidget() -{ - tool = new ToolTemplate(this); - openLastMenuButton = new OpenLastMenuBtn(dynamic_cast(tool->rightContainer()), true, this); - rightMenuButtonGroup = dynamic_cast(openLastMenuButton)->getButtonGroup(); - - settingsButton = new GearBtn(this); - runButton = new RunBtn(this); - - QPushButton *resetGMRButton = new QPushButton(this); - resetGMRButton->setText("GMR Reset"); - Style::setStyle(resetGMRButton, style::properties::button::singleButton); - connect(resetGMRButton, &QPushButton::clicked, this, &HarmonicCalibration::GMRReset); - - rightMenuButtonGroup->addButton(settingsButton); - - #pragma region Raw Data Widget - QScrollArea *rawDataScroll = new QScrollArea(this); - rawDataScroll->setWidgetResizable(true); - QWidget *rawDataWidget = new QWidget(rawDataScroll); - rawDataScroll->setWidget(rawDataWidget); - QVBoxLayout *rawDataLayout = new QVBoxLayout(rawDataWidget); - rawDataLayout->setMargin(0); - rawDataWidget->setLayout(rawDataLayout); - - MenuSectionWidget *rotationWidget = new MenuSectionWidget(rawDataWidget); - MenuSectionWidget *angleWidget = new MenuSectionWidget(rawDataWidget); - MenuSectionWidget *countWidget = new MenuSectionWidget(rawDataWidget); - MenuSectionWidget *tempWidget = new MenuSectionWidget(rawDataWidget); - Style::setStyle(rotationWidget, style::properties::widget::basicComponent); - Style::setStyle(angleWidget, style::properties::widget::basicComponent); - Style::setStyle(countWidget, style::properties::widget::basicComponent); - Style::setStyle(tempWidget, style::properties::widget::basicComponent); - MenuCollapseSection *rotationSection = new MenuCollapseSection("ABS Angle", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, rotationWidget); - MenuCollapseSection *angleSection = new MenuCollapseSection("Angle", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, angleWidget); - MenuCollapseSection *countSection = new MenuCollapseSection("Count", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, countWidget); - MenuCollapseSection *tempSection = new MenuCollapseSection("Temp 0", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, tempWidget); - rotationSection->contentLayout()->setSpacing(globalSpacingSmall); - angleSection->contentLayout()->setSpacing(globalSpacingSmall); - countSection->contentLayout()->setSpacing(globalSpacingSmall); - tempSection->contentLayout()->setSpacing(globalSpacingSmall); - - rotationWidget->contentLayout()->addWidget(rotationSection); - angleWidget->contentLayout()->addWidget(angleSection); - countWidget->contentLayout()->addWidget(countSection); - tempWidget->contentLayout()->addWidget(tempSection); - - rotationValueLabel = new QLabel("--.--°", rotationSection); - angleValueLabel = new QLabel("--.--°", angleSection); - countValueLabel = new QLabel("--", countSection); - tempValueLabel = new QLabel("--.-- °C", tempSection); - - rotationSection->contentLayout()->addWidget(rotationValueLabel); - angleSection->contentLayout()->addWidget(angleValueLabel); - countSection->contentLayout()->addWidget(countValueLabel); - tempSection->contentLayout()->addWidget(tempValueLabel); - - #pragma region Acquisition Motor Control Section Widget - MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(rawDataWidget); - Style::setStyle(motorControlSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection("Motor Control", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorControlSectionWidget); - motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); - - QWidget *motorRPMWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); - motorRPMWidget->setLayout(motorRPMLayout); - motorRPMLayout->setMargin(0); - motorRPMLayout->setSpacing(0); - QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); - acquisitionMotorRPMLineEdit = new QLineEdit(QString::number(motor_rpm), motorRPMWidget); - connectLineEditToRPM(acquisitionMotorRPMLineEdit, motor_rpm); - motorRPMLayout->addWidget(motorRPMLabel); - motorRPMLayout->addWidget(acquisitionMotorRPMLineEdit); - - QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); - currentPositionWidget->setLayout(currentPositionLayout); - currentPositionLayout->setMargin(0); - currentPositionLayout->setSpacing(0); - QLabel *currentPositionLabel = new QLabel("Current Position", currentPositionWidget); - acquisitionMotorCurrentPositionLineEdit = new QLineEdit("--.--", currentPositionWidget); - acquisitionMotorCurrentPositionLineEdit->setReadOnly(true); - connectLineEditToDouble(acquisitionMotorCurrentPositionLineEdit, current_pos); - currentPositionLayout->addWidget(currentPositionLabel); - currentPositionLayout->addWidget(acquisitionMotorCurrentPositionLineEdit); - - QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); - targetPositionWidget->setLayout(targetPositionLayout); - targetPositionLayout->setMargin(0); - targetPositionLayout->setSpacing(0); - QLabel *targetPositionLabel = new QLabel("Target Position", targetPositionWidget); - motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), targetPositionWidget); - connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, ADMTController::MotorAttribute::TARGET_POS); - targetPositionLayout->addWidget(targetPositionLabel); - targetPositionLayout->addWidget(motorTargetPositionLineEdit); - - QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); - motorDirectionWidget->setLayout(motorDirectionLayout); - motorDirectionLayout->setMargin(0); - motorDirectionLayout->setSpacing(0); - QLabel *motorDirectionLabel = new QLabel("Rotation Direction", motorDirectionWidget); - acquisitionMotorDirectionSwitch = new CustomSwitch("CW", "CCW", motorControlSectionWidget); - acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); - connect(acquisitionMotorDirectionSwitch, &CustomSwitch::toggled, this, [=](bool b){ - isMotorRotationClockwise = b; - }); - motorDirectionLayout->addWidget(motorDirectionLabel); - motorDirectionLayout->addWidget(acquisitionMotorDirectionSwitch); - - QPushButton *continuousRotationButton = new QPushButton("Continuous Rotation", motorControlSectionWidget); - StyleHelper::BasicButton(continuousRotationButton); - connect(continuousRotationButton, &QPushButton::clicked, this, &HarmonicCalibration::moveMotorContinuous); - - QPushButton *stopMotorButton = new QPushButton("Stop Motor", motorControlSectionWidget); - StyleHelper::BasicButton(stopMotorButton); - connect(stopMotorButton, &QPushButton::clicked, this, &HarmonicCalibration::stopMotor); - - motorControlCollapseSection->contentLayout()->setSpacing(globalSpacingSmall); - motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); - motorControlCollapseSection->contentLayout()->addWidget(currentPositionWidget); - motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); - motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); - motorControlCollapseSection->contentLayout()->addWidget(continuousRotationButton); - motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); - #pragma endregion - - rawDataLayout->setSpacing(globalSpacingSmall); - rawDataLayout->addWidget(angleWidget); - rawDataLayout->addWidget(rotationWidget); - rawDataLayout->addWidget(countWidget); - rawDataLayout->addWidget(tempWidget); - rawDataLayout->addWidget(motorControlSectionWidget); - rawDataLayout->addStretch(); - #pragma endregion - - #pragma region Acquisition Graph Section Widget - MenuSectionWidget *acquisitionGraphSectionWidget = new MenuSectionWidget(this); - Style::setStyle(acquisitionGraphSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *acquisitionGraphCollapseSection = new MenuCollapseSection("Captured Data", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, acquisitionGraphSectionWidget); - acquisitionGraphSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - acquisitionGraphSectionWidget->contentLayout()->addWidget(acquisitionGraphCollapseSection); - acquisitionGraphCollapseSection->contentLayout()->setSpacing(8); - - acquisitionGraphPlotWidget = new PlotWidget(); - acquisitionGraphPlotWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - - acquisitionXPlotAxis = new PlotAxis(QwtAxis::XBottom, acquisitionGraphPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); - acquisitionYPlotAxis = new PlotAxis(QwtAxis::YLeft, acquisitionGraphPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - acquisitionYPlotAxis->setInterval(0, 360); - - acquisitionAnglePlotChannel = new PlotChannel("Angle", channel0Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionABSAnglePlotChannel = new PlotChannel("ABS Angle", channel1Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionTurnCountPlotChannel = new PlotChannel("Turn Count", channel2Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionTmp0PlotChannel = new PlotChannel("TMP 0", channel3Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionTmp1PlotChannel = new PlotChannel("TMP 1", channel4Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionSinePlotChannel = new PlotChannel("Sine", sinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionCosinePlotChannel = new PlotChannel("Cosine", cosinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionRadiusPlotChannel = new PlotChannel("Radius", channel5Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionSecAnglQPlotChannel = new PlotChannel("SECANGLQ", channel6Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionSecAnglIPlotChannel = new PlotChannel("SECANGLI", channel7Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - - acquisitionGraphPlotWidget->addPlotChannel(acquisitionAnglePlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionABSAnglePlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionTurnCountPlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp0PlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp1PlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionSinePlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionCosinePlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionRadiusPlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglQPlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglIPlotChannel); - acquisitionAnglePlotChannel->setEnabled(true); - acquisitionABSAnglePlotChannel->setEnabled(true); - acquisitionTurnCountPlotChannel->setEnabled(true); - acquisitionTmp0PlotChannel->setEnabled(true); - acquisitionTmp1PlotChannel->setEnabled(true); - acquisitionSinePlotChannel->setEnabled(true); - acquisitionCosinePlotChannel->setEnabled(true); - acquisitionRadiusPlotChannel->setEnabled(true); - acquisitionSecAnglQPlotChannel->setEnabled(true); - acquisitionSecAnglIPlotChannel->setEnabled(true); - acquisitionGraphPlotWidget->selectChannel(acquisitionAnglePlotChannel); - - acquisitionGraphPlotWidget->setShowXAxisLabels(true); - acquisitionGraphPlotWidget->setShowYAxisLabels(true); - acquisitionGraphPlotWidget->showAxisLabels(); - acquisitionGraphPlotWidget->replot(); - - #pragma region Channel Selection - QWidget *acquisitionGraphChannelWidget = new QWidget(acquisitionGraphSectionWidget); - QGridLayout *acquisitionGraphChannelGridLayout = new QGridLayout(acquisitionGraphChannelWidget); - acquisitionGraphChannelGridLayout->setContentsMargins(16, 8, 8, 16); - acquisitionGraphChannelGridLayout->setSpacing(8); - - QCheckBox *angleCheckBox = new QCheckBox("Angle", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(angleCheckBox, channel0Pen.color()); - connectCheckBoxToAcquisitionGraph(angleCheckBox, acquisitionAnglePlotChannel, ANGLE); - angleCheckBox->setChecked(true); - - QCheckBox *absAngleCheckBox = new QCheckBox("ABS Angle", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(absAngleCheckBox, channel1Pen.color()); - connectCheckBoxToAcquisitionGraph(absAngleCheckBox, acquisitionABSAnglePlotChannel, ABSANGLE); - - QCheckBox *temp0CheckBox = new QCheckBox("Temp 0", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(temp0CheckBox, channel3Pen.color()); - connectCheckBoxToAcquisitionGraph(temp0CheckBox, acquisitionTmp0PlotChannel, TMP0); - - QCheckBox *sineCheckBox = new QCheckBox("Sine", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(sineCheckBox, sineColor); - connectCheckBoxToAcquisitionGraph(sineCheckBox, acquisitionSinePlotChannel, SINE); - - QCheckBox *cosineCheckBox = new QCheckBox("Cosine", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(cosineCheckBox, cosineColor); - connectCheckBoxToAcquisitionGraph(cosineCheckBox, acquisitionCosinePlotChannel, COSINE); - - QCheckBox *radiusCheckBox = new QCheckBox("Radius", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(radiusCheckBox, channel5Pen.color()); - connectCheckBoxToAcquisitionGraph(radiusCheckBox, acquisitionRadiusPlotChannel, RADIUS); - - if(GENERALRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 - { - acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); - acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); - acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); - acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); - acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); - acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); - } - else if(GENERALRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 - { - acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); - acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); - acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); - acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); - acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); - acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); - } - #pragma endregion - - acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphPlotWidget); - acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphChannelWidget); - #pragma endregion - - #pragma region General Setting - QScrollArea *generalSettingScroll = new QScrollArea(this); - generalSettingScroll->setWidgetResizable(true); - QWidget *generalSettingWidget = new QWidget(generalSettingScroll); - generalSettingScroll->setWidget(generalSettingWidget); - QVBoxLayout *generalSettingLayout = new QVBoxLayout(generalSettingWidget); - generalSettingLayout->setMargin(0); - generalSettingWidget->setLayout(generalSettingLayout); - - header = new MenuHeaderWidget(deviceName + " " + deviceType, scopyBluePen, this); - Style::setStyle(header, style::properties::widget::basicComponent); - - // General Setting Widget - MenuSectionWidget *generalWidget = new MenuSectionWidget(generalSettingWidget); - Style::setStyle(generalWidget, style::properties::widget::basicComponent); - MenuCollapseSection *generalSection = new MenuCollapseSection("Data Acquisition", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); - generalSection->header()->toggle(); - generalSection->contentLayout()->setSpacing(globalSpacingSmall); - generalWidget->contentLayout()->addWidget(generalSection); - - // Graph Update Interval - QWidget *graphUpdateIntervalWidget = new QWidget(generalSection); - QVBoxLayout *graphUpdateIntervalLayout = new QVBoxLayout(graphUpdateIntervalWidget); - graphUpdateIntervalWidget->setLayout(graphUpdateIntervalLayout); - graphUpdateIntervalLayout->setMargin(0); - graphUpdateIntervalLayout->setSpacing(0); - QLabel *graphUpdateIntervalLabel = new QLabel(graphUpdateIntervalWidget); - graphUpdateIntervalLabel->setText("Graph Update Interval (ms)"); - graphUpdateIntervalLineEdit = new QLineEdit(graphUpdateIntervalWidget); - graphUpdateIntervalLineEdit->setText(QString::number(acquisitionGraphSampleRate)); - connectLineEditToNumber(graphUpdateIntervalLineEdit, acquisitionGraphSampleRate, 1, 5000); - graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLabel); - graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLineEdit); - - // Data Sample Size - QWidget *displayLengthWidget = new QWidget(generalSection); - QVBoxLayout *displayLengthLayout = new QVBoxLayout(displayLengthWidget); - displayLengthWidget->setLayout(displayLengthLayout); - displayLengthLayout->setMargin(0); - displayLengthLayout->setSpacing(0); - QLabel *displayLengthLabel = new QLabel("Display Length", displayLengthWidget); - displayLengthLineEdit = new QLineEdit(displayLengthWidget); - displayLengthLineEdit->setText(QString::number(acquisitionDisplayLength)); - connectLineEditToNumber(displayLengthLineEdit, acquisitionDisplayLength, 1, 2048); - displayLengthLayout->addWidget(displayLengthLabel); - displayLengthLayout->addWidget(displayLengthLineEdit); - - QPushButton *resetYAxisButton = new QPushButton("Reset Y-Axis Scale", generalSection); - StyleHelper::BasicButton(resetYAxisButton); - connect(resetYAxisButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAcquisitionYAxisScale); - - generalSection->contentLayout()->addWidget(graphUpdateIntervalWidget); - generalSection->contentLayout()->addWidget(displayLengthWidget); - generalSection->contentLayout()->addWidget(resetYAxisButton); - - MenuSectionWidget *sequenceWidget = new MenuSectionWidget(generalSettingWidget); - Style::setStyle(sequenceWidget, style::properties::widget::basicComponent); - MenuCollapseSection *sequenceSection = new MenuCollapseSection("Sequence", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, sequenceWidget); - sequenceWidget->contentLayout()->addWidget(sequenceSection); - sequenceSection->contentLayout()->setSpacing(globalSpacingSmall); - - sequenceTypeMenuCombo = new MenuCombo("Sequence Type", sequenceSection); - QComboBox *sequenceTypeComboBox = sequenceTypeMenuCombo->combo(); - sequenceTypeComboBox->addItem("Mode 1", QVariant(0)); - if(deviceType.toStdString() == "Automotive") - { - sequenceTypeComboBox->addItem("Mode 2", QVariant(1)); - } - - conversionTypeMenuCombo = new MenuCombo("Conversion Type", sequenceSection); - QComboBox *conversionTypeComboBox = conversionTypeMenuCombo->combo(); - conversionTypeComboBox->addItem("Continuous conversions", QVariant(0)); - conversionTypeComboBox->addItem("One-shot conversion", QVariant(1)); - - convertSynchronizationMenuCombo = new MenuCombo("Convert Synchronization", sequenceSection); - QComboBox *convertSynchronizationComboBox = convertSynchronizationMenuCombo->combo(); - convertSynchronizationComboBox->addItem("Enabled", QVariant(1)); - convertSynchronizationComboBox->addItem("Disabled", QVariant(0)); - - angleFilterMenuCombo = new MenuCombo("Angle Filter", sequenceSection); - QComboBox *angleFilterComboBox = angleFilterMenuCombo->combo(); - angleFilterComboBox->addItem("Enabled", QVariant(1)); - angleFilterComboBox->addItem("Disabled", QVariant(0)); - - eighthHarmonicMenuCombo = new MenuCombo("8th Harmonic", sequenceSection); - QComboBox *eighthHarmonicComboBox = eighthHarmonicMenuCombo->combo(); - eighthHarmonicComboBox->addItem("User-Supplied Values", QVariant(1)); - eighthHarmonicComboBox->addItem("ADI Factory Values", QVariant(0)); - - updateSequenceWidget(); - - applySequenceButton = new QPushButton("Apply", sequenceSection); - StyleHelper::BasicButton(applySequenceButton); - connect(applySequenceButton, &QPushButton::clicked, this, &HarmonicCalibration::applySequenceAndUpdate); - - sequenceSection->contentLayout()->addWidget(sequenceTypeMenuCombo); - sequenceSection->contentLayout()->addWidget(conversionTypeMenuCombo); - sequenceSection->contentLayout()->addWidget(convertSynchronizationMenuCombo); - sequenceSection->contentLayout()->addWidget(angleFilterMenuCombo); - sequenceSection->contentLayout()->addWidget(eighthHarmonicMenuCombo); - sequenceSection->contentLayout()->addWidget(applySequenceButton); - - #pragma region Device Status Widget - MenuSectionWidget *acquisitionDeviceStatusWidget = new MenuSectionWidget(generalSettingWidget); - Style::setStyle(acquisitionDeviceStatusWidget, style::properties::widget::basicComponent); - MenuCollapseSection *acquisitionDeviceStatusSection = new MenuCollapseSection("Device Status", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); - acquisitionDeviceStatusSection->contentLayout()->setSpacing(globalSpacingSmall); - acquisitionDeviceStatusWidget->contentLayout()->addWidget(acquisitionDeviceStatusSection); - - acquisitionFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", "status", false, acquisitionDeviceStatusSection); - acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionFaultRegisterLEDWidget); - - if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 - { - QCheckBox *acquisitionSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", "status", false, acquisitionDeviceStatusSection); - QCheckBox *acquisitionSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", "status", false, acquisitionDeviceStatusSection); - acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPICRCLEDWidget); - acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPIFlagLEDWidget); - } - #pragma endregion - - generalSettingLayout->setSpacing(globalSpacingSmall); - generalSettingLayout->addWidget(acquisitionDeviceStatusWidget); - generalSettingLayout->addWidget(header); - generalSettingLayout->addWidget(sequenceWidget); - generalSettingLayout->addWidget(generalWidget); - generalSettingLayout->addStretch(); - #pragma endregion - - tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - tool->topContainer()->setVisible(true); - tool->leftContainer()->setVisible(true); - tool->rightContainer()->setVisible(true); - tool->bottomContainer()->setVisible(false); - tool->setLeftContainerWidth(210); - tool->setRightContainerWidth(300); - tool->setTopContainerHeight(100); - tool->openBottomContainerHelper(false); - tool->openTopContainerHelper(false); - tool->addWidgetToTopContainerMenuControlHelper(openLastMenuButton, TTA_RIGHT); - tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); - tool->addWidgetToTopContainerHelper(resetGMRButton, TTA_RIGHT); - tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); - tool->leftStack()->add("rawDataScroll", rawDataScroll); - tool->rightStack()->add("generalSettingScroll", generalSettingScroll); - tool->addWidgetToCentralContainerHelper(acquisitionGraphSectionWidget); - - connect(runButton, &QPushButton::toggled, this, &HarmonicCalibration::setRunning); - connect(this, &HarmonicCalibration::runningChanged, this, &HarmonicCalibration::run); - connect(this, &HarmonicCalibration::runningChanged, runButton, &QAbstractButton::setChecked); - - return tool; -} - -ToolTemplate* HarmonicCalibration::createCalibrationWidget() -{ - ToolTemplate *tool = new ToolTemplate(this); - - #pragma region Calibration Data Graph Widget - QWidget *calibrationDataGraphWidget = new QWidget(); - QGridLayout *calibrationDataGraphLayout = new QGridLayout(calibrationDataGraphWidget); - calibrationDataGraphWidget->setLayout(calibrationDataGraphLayout); - calibrationDataGraphLayout->setMargin(0); - calibrationDataGraphLayout->setSpacing(5); - - MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); - Style::setStyle(calibrationDataGraphSectionWidget, style::properties::widget::basicComponent); - calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); - calibrationDataGraphTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 176px; }"); - calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); - calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); - - #pragma region Calibration Samples - QWidget *calibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); - Style::setStyle(calibrationSamplesWidget, style::properties::widget::basicBackground); - QVBoxLayout *calibrationSamplesLayout = new QVBoxLayout(calibrationSamplesWidget); - calibrationSamplesWidget->setLayout(calibrationSamplesLayout); - calibrationSamplesLayout->setMargin(0); - calibrationSamplesLayout->setSpacing(0); - - calibrationRawDataPlotWidget = new PlotWidget(); - calibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); - - calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - calibrationRawDataXPlotAxis->setMin(0); - calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - calibrationRawDataYPlotAxis->setInterval(0, 360); - - calibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - calibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - calibrationCosineDataPlotChannel = new PlotChannel("Cosine", cosinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); - - calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); - calibrationRawDataPlotWidget->addPlotChannel(calibrationSineDataPlotChannel); - calibrationRawDataPlotWidget->addPlotChannel(calibrationCosineDataPlotChannel); - calibrationSineDataPlotChannel->setEnabled(true); - calibrationCosineDataPlotChannel->setEnabled(true); - calibrationRawDataPlotChannel->setEnabled(true); - calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); - - calibrationRawDataPlotWidget->setShowXAxisLabels(true); - calibrationRawDataPlotWidget->setShowYAxisLabels(true); - calibrationRawDataPlotWidget->showAxisLabels(); - calibrationRawDataPlotWidget->replot(); - - QWidget *calibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); - ADMTStyleHelper::UIBackgroundStyle(calibrationDataGraphChannelsWidget); - QHBoxLayout *calibrationDataGraphChannelsLayout = new QHBoxLayout(calibrationDataGraphChannelsWidget); - calibrationDataGraphChannelsWidget->setLayout(calibrationDataGraphChannelsLayout); - calibrationDataGraphChannelsLayout->setContentsMargins(20, 13, 20, 5); - calibrationDataGraphChannelsLayout->setSpacing(20); - - MenuControlButton *toggleAngleButton = createChannelToggleWidget("Angle", scopyBlueColor, calibrationDataGraphChannelsWidget); - MenuControlButton *toggleSineButton = createChannelToggleWidget("Sine", sineColor, calibrationDataGraphChannelsWidget); - MenuControlButton *toggleCosineButton = createChannelToggleWidget("Cosine", cosineColor, calibrationDataGraphChannelsWidget); - - calibrationDataGraphChannelsLayout->addWidget(toggleAngleButton); - calibrationDataGraphChannelsLayout->addWidget(toggleSineButton); - calibrationDataGraphChannelsLayout->addWidget(toggleCosineButton); - calibrationDataGraphChannelsLayout->addStretch(); - - calibrationSamplesLayout->addWidget(calibrationRawDataPlotWidget); - calibrationSamplesLayout->addWidget(calibrationDataGraphChannelsWidget); - #pragma endregion - - #pragma region Post Calibration Samples - QWidget *postCalibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); - Style::setStyle(postCalibrationSamplesWidget, style::properties::widget::basicBackground); - QVBoxLayout *postCalibrationSamplesLayout = new QVBoxLayout(postCalibrationSamplesWidget); - postCalibrationSamplesWidget->setLayout(postCalibrationSamplesLayout); - postCalibrationSamplesLayout->setMargin(0); - postCalibrationSamplesLayout->setSpacing(0); - - postCalibrationRawDataPlotWidget = new PlotWidget(); - postCalibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); - - postCalibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, postCalibrationRawDataPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - postCalibrationRawDataXPlotAxis->setMin(0); - postCalibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, postCalibrationRawDataPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - postCalibrationRawDataYPlotAxis->setInterval(0, 360); - - postCalibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); - postCalibrationSineDataPlotChannel = new PlotChannel("Sine", sinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); - postCalibrationCosineDataPlotChannel = new PlotChannel("Cosine", cosinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); - - postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationRawDataPlotChannel); - postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationSineDataPlotChannel); - postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationCosineDataPlotChannel); - - postCalibrationSineDataPlotChannel->setEnabled(true); - postCalibrationCosineDataPlotChannel->setEnabled(true); - postCalibrationRawDataPlotChannel->setEnabled(true); - postCalibrationRawDataPlotWidget->selectChannel(postCalibrationRawDataPlotChannel); - - postCalibrationRawDataPlotWidget->setShowXAxisLabels(true); - postCalibrationRawDataPlotWidget->setShowYAxisLabels(true); - postCalibrationRawDataPlotWidget->showAxisLabels(); - postCalibrationRawDataPlotWidget->replot(); - - QWidget *postCalibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); - QHBoxLayout *postCalibrationDataGraphChannelsLayout = new QHBoxLayout(postCalibrationDataGraphChannelsWidget); - ADMTStyleHelper::GraphChannelStyle(postCalibrationDataGraphChannelsWidget, postCalibrationDataGraphChannelsLayout); - - MenuControlButton *togglePostAngleButton = createChannelToggleWidget("Angle", scopyBlueColor, postCalibrationDataGraphChannelsWidget); - MenuControlButton *togglePostSineButton = createChannelToggleWidget("Sine", sineColor, postCalibrationDataGraphChannelsWidget); - MenuControlButton *togglePostCosineButton = createChannelToggleWidget("Cosine", cosineColor, postCalibrationDataGraphChannelsWidget); - - postCalibrationDataGraphChannelsLayout->addWidget(togglePostAngleButton); - postCalibrationDataGraphChannelsLayout->addWidget(togglePostSineButton); - postCalibrationDataGraphChannelsLayout->addWidget(togglePostCosineButton); - postCalibrationDataGraphChannelsLayout->addStretch(); - - postCalibrationSamplesLayout->addWidget(postCalibrationRawDataPlotWidget); - postCalibrationSamplesLayout->addWidget(postCalibrationDataGraphChannelsWidget); - #pragma endregion - - calibrationDataGraphTabWidget->addTab(calibrationSamplesWidget, "Calibration Samples"); - calibrationDataGraphTabWidget->addTab(postCalibrationSamplesWidget, "Post Calibration Samples"); - - MenuSectionWidget *resultDataSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); - Style::setStyle(resultDataSectionWidget, style::properties::widget::basicComponent); - resultDataTabWidget = new QTabWidget(resultDataSectionWidget); - resultDataTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 160px; }"); - resultDataSectionWidget->contentLayout()->setSpacing(8); - resultDataSectionWidget->contentLayout()->addWidget(resultDataTabWidget); - - QColor magnitudeColor = Style::getColor(json::global::ch0); - QColor phaseColor = Style::getColor(json::global::ch1); - QPen magnitudePen = QPen(magnitudeColor); - QPen phasePen = QPen(phaseColor); - - #pragma region Angle Error Widget - QWidget *angleErrorWidget = new QWidget(); - Style::setStyle(angleErrorWidget, style::properties::widget::basicBackground); - QVBoxLayout *angleErrorLayout = new QVBoxLayout(angleErrorWidget); - angleErrorWidget->setLayout(angleErrorLayout); - angleErrorLayout->setMargin(0); - angleErrorLayout->setSpacing(0); - - angleErrorPlotWidget = new PlotWidget(); - angleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - angleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, angleErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - angleErrorXPlotAxis->setMin(0); - angleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, angleErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - angleErrorYPlotAxis->setInterval(-4, 4); - - angleErrorPlotChannel = new PlotChannel("Angle Error", scopyBluePen, angleErrorXPlotAxis, angleErrorYPlotAxis); - - angleErrorPlotWidget->addPlotChannel(angleErrorPlotChannel); - angleErrorPlotChannel->setEnabled(true); - angleErrorPlotWidget->selectChannel(angleErrorPlotChannel); - - angleErrorPlotWidget->setShowXAxisLabels(true); - angleErrorPlotWidget->setShowYAxisLabels(true); - angleErrorPlotWidget->showAxisLabels(); - angleErrorPlotWidget->replot(); - - angleErrorLayout->addWidget(angleErrorPlotWidget); - #pragma endregion - - #pragma region FFT Angle Error Widget - QWidget *FFTAngleErrorWidget = new QWidget(); - Style::setStyle(FFTAngleErrorWidget, style::properties::widget::basicBackground); - QVBoxLayout *FFTAngleErrorLayout = new QVBoxLayout(FFTAngleErrorWidget); - FFTAngleErrorWidget->setLayout(FFTAngleErrorLayout); - FFTAngleErrorLayout->setMargin(0); - FFTAngleErrorLayout->setSpacing(0); - - FFTAngleErrorPlotWidget = new PlotWidget(); - FFTAngleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - - FFTAngleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTAngleErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTAngleErrorXPlotAxis->setMin(0); - FFTAngleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTAngleErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTAngleErrorYPlotAxis->setInterval(-4, 4); - - FFTAngleErrorMagnitudeChannel = new PlotChannel("FFT Angle Error Magnitude", magnitudePen, FFTAngleErrorXPlotAxis, FFTAngleErrorYPlotAxis); - FFTAngleErrorPhaseChannel = new PlotChannel("FFT Angle Error Phase", phasePen, FFTAngleErrorXPlotAxis, FFTAngleErrorYPlotAxis); - FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorMagnitudeChannel); - FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorPhaseChannel); - - FFTAngleErrorPhaseChannel->setEnabled(true); - FFTAngleErrorMagnitudeChannel->setEnabled(true); - FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); - - FFTAngleErrorPlotWidget->setShowXAxisLabels(true); - FFTAngleErrorPlotWidget->setShowYAxisLabels(true); - FFTAngleErrorPlotWidget->showAxisLabels(); - FFTAngleErrorPlotWidget->replot(); - - QWidget *FFTAngleErrorChannelsWidget = new QWidget(); - QHBoxLayout *FFTAngleErrorChannelsLayout = new QHBoxLayout(FFTAngleErrorChannelsWidget); - ADMTStyleHelper::GraphChannelStyle(FFTAngleErrorChannelsWidget, FFTAngleErrorChannelsLayout); - - MenuControlButton *toggleFFTAngleErrorMagnitudeButton = createChannelToggleWidget("Magnitude", magnitudeColor, FFTAngleErrorChannelsWidget); - MenuControlButton *toggleFFTAngleErrorPhaseButton = createChannelToggleWidget("Phase", phaseColor, FFTAngleErrorChannelsWidget); - - FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorMagnitudeButton); - FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorPhaseButton); - FFTAngleErrorChannelsLayout->addStretch(); - - FFTAngleErrorLayout->addWidget(FFTAngleErrorPlotWidget); - FFTAngleErrorLayout->addWidget(FFTAngleErrorChannelsWidget); - #pragma endregion - - #pragma region Corrected Error Widget - QWidget *correctedErrorWidget = new QWidget(); - Style::setStyle(correctedErrorWidget, style::properties::widget::basicBackground); - QVBoxLayout *correctedErrorLayout = new QVBoxLayout(correctedErrorWidget); - correctedErrorWidget->setLayout(correctedErrorLayout); - correctedErrorLayout->setMargin(0); - correctedErrorLayout->setSpacing(0); - - correctedErrorPlotWidget = new PlotWidget(); - correctedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - - correctedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, correctedErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - correctedErrorXPlotAxis->setMin(0); - correctedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, correctedErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - correctedErrorYPlotAxis->setInterval(-4, 4); - - correctedErrorPlotChannel = new PlotChannel("Corrected Error", scopyBluePen, correctedErrorXPlotAxis, correctedErrorYPlotAxis); - correctedErrorPlotWidget->addPlotChannel(correctedErrorPlotChannel); - - correctedErrorPlotChannel->setEnabled(true); - correctedErrorPlotWidget->selectChannel(correctedErrorPlotChannel); - - correctedErrorPlotWidget->setShowXAxisLabels(true); - correctedErrorPlotWidget->setShowYAxisLabels(true); - correctedErrorPlotWidget->showAxisLabels(); - correctedErrorPlotWidget->replot(); - - correctedErrorLayout->addWidget(correctedErrorPlotWidget); - #pragma endregion - - #pragma region FFT Corrected Error Widget - QWidget *FFTCorrectedErrorWidget = new QWidget(); - Style::setStyle(FFTCorrectedErrorWidget, style::properties::widget::basicBackground); - QVBoxLayout *FFTCorrectedErrorLayout = new QVBoxLayout(FFTCorrectedErrorWidget); - FFTCorrectedErrorWidget->setLayout(FFTCorrectedErrorLayout); - FFTCorrectedErrorLayout->setMargin(0); - FFTCorrectedErrorLayout->setSpacing(0); - - FFTCorrectedErrorPlotWidget = new PlotWidget(); - FFTCorrectedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - - FFTCorrectedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTCorrectedErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTCorrectedErrorXPlotAxis->setMin(0); - FFTCorrectedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTCorrectedErrorPlotWidget, QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTCorrectedErrorYPlotAxis->setInterval(-4, 4); - - FFTCorrectedErrorMagnitudeChannel = new PlotChannel("FFT Corrected Error Magnitude", magnitudePen, FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); - FFTCorrectedErrorPhaseChannel = new PlotChannel("FFT Corrected Error Phase", phasePen, FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); - FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorMagnitudeChannel); - FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorPhaseChannel); - - FFTCorrectedErrorPhaseChannel->setEnabled(true); - FFTCorrectedErrorMagnitudeChannel->setEnabled(true); - FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); - - FFTCorrectedErrorPlotWidget->setShowXAxisLabels(true); - FFTCorrectedErrorPlotWidget->setShowYAxisLabels(true); - FFTCorrectedErrorPlotWidget->showAxisLabels(); - FFTCorrectedErrorPlotWidget->replot(); - - QWidget *FFTCorrectedErrorChannelsWidget = new QWidget(); - QHBoxLayout *FFTCorrectedErrorChannelsLayout = new QHBoxLayout(FFTCorrectedErrorChannelsWidget); - ADMTStyleHelper::GraphChannelStyle(FFTCorrectedErrorChannelsWidget, FFTCorrectedErrorChannelsLayout); - - MenuControlButton *toggleFFTCorrectedErrorMagnitudeButton = createChannelToggleWidget("Magnitude", magnitudeColor, FFTCorrectedErrorChannelsWidget); - MenuControlButton *toggleFFTCorrectedErrorPhaseButton = createChannelToggleWidget("Phase", phaseColor, FFTCorrectedErrorChannelsWidget); - - FFTCorrectedErrorChannelsLayout->addWidget(toggleFFTCorrectedErrorMagnitudeButton); - FFTCorrectedErrorChannelsLayout->addWidget(toggleFFTCorrectedErrorPhaseButton); - FFTCorrectedErrorChannelsLayout->addStretch(); - - FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorPlotWidget); - FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorChannelsWidget); - #pragma endregion - - resultDataTabWidget->addTab(angleErrorWidget, "Angle Error"); - resultDataTabWidget->addTab(FFTAngleErrorWidget, "FFT Angle Error"); - resultDataTabWidget->addTab(correctedErrorWidget, "Corrected Error"); - resultDataTabWidget->addTab(FFTCorrectedErrorWidget, "FFT Corrected Error"); - - calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget, 0, 0); - calibrationDataGraphLayout->addWidget(resultDataSectionWidget, 1, 0); - - calibrationDataGraphLayout->setColumnStretch(0, 1); - calibrationDataGraphLayout->setRowStretch(0, 1); - calibrationDataGraphLayout->setRowStretch(1, 1); - #pragma endregion - - #pragma region Calibration Settings Widget - QWidget *calibrationSettingsGroupWidget = new QWidget(); - QVBoxLayout *calibrationSettingsGroupLayout = new QVBoxLayout(calibrationSettingsGroupWidget); - calibrationSettingsGroupWidget->setLayout(calibrationSettingsGroupLayout); - calibrationSettingsGroupLayout->setMargin(0); - calibrationSettingsGroupLayout->setSpacing(8); - - #pragma region Device Status Widget - MenuSectionWidget *calibrationDeviceStatusWidget = new MenuSectionWidget(calibrationSettingsGroupWidget); - Style::setStyle(calibrationDeviceStatusWidget, style::properties::widget::basicComponent); - calibrationDeviceStatusWidget->contentLayout()->setSpacing(8); - MenuCollapseSection *calibrationDeviceStatusSection = new MenuCollapseSection("Device Status", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationSettingsGroupWidget); - calibrationDeviceStatusSection->contentLayout()->setSpacing(8); - calibrationDeviceStatusWidget->contentLayout()->addWidget(calibrationDeviceStatusSection); - - calibrationFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", "status", false, calibrationDeviceStatusSection); - calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationFaultRegisterLEDWidget); - - if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 - { - QCheckBox *calibrationSPICRCLEDWidget = createStatusLEDWidget("SPI CRC", "status", false, calibrationDeviceStatusSection); - QCheckBox *calibrationSPIFlagLEDWidget = createStatusLEDWidget("SPI Flag", "status", false, calibrationDeviceStatusSection); - calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPICRCLEDWidget); - calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPIFlagLEDWidget); - } - #pragma endregion - - #pragma region Acquire Calibration Samples Button - calibrationStartMotorButton = new QPushButton(" Acquire Samples", calibrationSettingsGroupWidget); - Style::setStyle(calibrationStartMotorButton, style::properties::admt::fullWidthRunButton); - calibrationStartMotorButton->setCheckable(true); - calibrationStartMotorButton->setChecked(false); - QIcon icon1; - icon1.addPixmap(Style::getPixmap(":/gui/icons/play.svg", Style::getColor(json::theme::content_inverse)), - QIcon::Normal, QIcon::Off); - icon1.addPixmap(Style::getPixmap(":/gui/icons/" + Style::getAttribute(json::theme::icon_theme_folder) + - "/icons/play_stop.svg", - Style::getColor(json::theme::content_inverse)), - QIcon::Normal, QIcon::On); - calibrationStartMotorButton->setIcon(icon1); - - connect(calibrationStartMotorButton, &QPushButton::toggled, this, [=](bool toggled) { - calibrationStartMotorButton->setText(toggled ? " Stop Acquisition" : " Acquire Samples"); - isStartMotor = toggled; - if(toggled){ - isPostCalibration = false; - startCalibration(); - } - else{ - stopCalibration(); - } - }); - #pragma endregion - - #pragma region Start Calibration Button - calibrateDataButton = new QPushButton(" Calibrate", calibrationSettingsGroupWidget); - Style::setStyle(calibrateDataButton, style::properties::admt::fullWidthRunButton); - calibrateDataButton->setCheckable(true); - calibrateDataButton->setChecked(false); - calibrateDataButton->setEnabled(false); - calibrateDataButton->setIcon(icon1); - - connect(calibrateDataButton, &QPushButton::toggled, this, [=](bool toggled) { - calibrateDataButton->setText(toggled ? " Stop Calibration" : " Calibrate"); - if(toggled) postCalibrateData(); - else stopCalibration(); - }); - #pragma endregion - - #pragma region Reset Calibration Button - clearCalibrateDataButton = new QPushButton("Reset Calibration", calibrationSettingsGroupWidget); - StyleHelper::BasicButton(clearCalibrateDataButton); - QIcon resetIcon; - // resetIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/refresh.svg", "white", 1), QIcon::Normal, QIcon::Off); - resetIcon.addPixmap(Style::getPixmap(":/gui/icons/refresh.svg", Style::getColor(json::theme::content_inverse)), - QIcon::Normal, QIcon::Off); - clearCalibrateDataButton->setIcon(resetIcon); - clearCalibrateDataButton->setIconSize(QSize(26, 26)); - #pragma endregion - - QScrollArea *calibrationSettingsScrollArea = new QScrollArea(); - QWidget *calibrationSettingsWidget = new QWidget(calibrationSettingsScrollArea); - QVBoxLayout *calibrationSettingsLayout = new QVBoxLayout(calibrationSettingsWidget); - calibrationSettingsScrollArea->setWidgetResizable(true); - calibrationSettingsScrollArea->setWidget(calibrationSettingsWidget); - calibrationSettingsWidget->setFixedWidth(260); - calibrationSettingsWidget->setLayout(calibrationSettingsLayout); - - calibrationSettingsGroupLayout->addWidget(calibrationDeviceStatusWidget); - calibrationSettingsGroupLayout->addWidget(calibrationStartMotorButton); - calibrationSettingsGroupLayout->addWidget(calibrateDataButton); - calibrationSettingsGroupLayout->addWidget(clearCalibrateDataButton); - calibrationSettingsGroupLayout->addWidget(calibrationSettingsScrollArea); - - #pragma region Calibration Coefficient Section Widget - MenuSectionWidget *calibrationCoeffSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(calibrationCoeffSectionWidget, style::properties::widget::basicComponent); - QLabel *calibrationDisplayFormatLabel = new QLabel(calibrationCoeffSectionWidget); - calibrationDisplayFormatLabel->setText("Display Format"); - Style::setStyle(calibrationDisplayFormatLabel, style::properties::label::menuMedium); - QLabel *calibrationCalculatedCoeffLabel = new QLabel(calibrationCoeffSectionWidget); - calibrationCalculatedCoeffLabel->setText("Calculated Coefficients"); - Style::setStyle(calibrationCalculatedCoeffLabel, style::properties::label::menuMedium); - - calibrationDisplayFormatSwitch = new CustomSwitch(); - calibrationDisplayFormatSwitch->setOffText("Hex"); - calibrationDisplayFormatSwitch->setOnText("Angle"); - calibrationDisplayFormatSwitch->setProperty("bigBtn", true); - - QWidget *calibrationCalculatedCoeffWidget = new QWidget(calibrationCoeffSectionWidget); - QGridLayout *calibrationCalculatedCoeffLayout = new QGridLayout(calibrationCalculatedCoeffWidget); - - calibrationCalculatedCoeffWidget->setLayout(calibrationCalculatedCoeffLayout); - calibrationCalculatedCoeffLayout->setMargin(0); - calibrationCalculatedCoeffLayout->setVerticalSpacing(4); - Style::setStyle(calibrationCalculatedCoeffWidget, style::properties::widget::basicBackground); - - QWidget *h1RowContainer = new QWidget(calibrationCalculatedCoeffWidget); - QHBoxLayout *h1RowLayout = new QHBoxLayout(h1RowContainer); - QLabel *calibrationH1Label = new QLabel("H1", calibrationCalculatedCoeffWidget); - calibrationH1MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - calibrationH1PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h1RowContainer, h1RowLayout, calibrationH1Label, calibrationH1MagLabel, calibrationH1PhaseLabel); - - QWidget *h2RowContainer = new QWidget(calibrationCalculatedCoeffWidget); - QHBoxLayout *h2RowLayout = new QHBoxLayout(h2RowContainer); - QLabel *calibrationH2Label = new QLabel("H2", calibrationCalculatedCoeffWidget); - calibrationH2MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - calibrationH2PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h2RowContainer, h2RowLayout, calibrationH2Label, calibrationH2MagLabel, calibrationH2PhaseLabel); - - QWidget *h3RowContainer = new QWidget(calibrationCalculatedCoeffWidget); - QHBoxLayout *h3RowLayout = new QHBoxLayout(h3RowContainer); - QLabel *calibrationH3Label = new QLabel("H3", calibrationCalculatedCoeffWidget); - calibrationH3MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - calibrationH3PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h3RowContainer, h3RowLayout, calibrationH3Label, calibrationH3MagLabel, calibrationH3PhaseLabel); - - QWidget *h8RowContainer = new QWidget(calibrationCalculatedCoeffWidget); - QHBoxLayout *h8RowLayout = new QHBoxLayout(h8RowContainer); - QLabel *calibrationH8Label = new QLabel("H8", calibrationCalculatedCoeffWidget); - calibrationH8MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - calibrationH8PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h8RowContainer, h8RowLayout, calibrationH8Label, calibrationH8MagLabel, calibrationH8PhaseLabel); - - calibrationCalculatedCoeffLayout->addWidget(h1RowContainer, 0, 0); - calibrationCalculatedCoeffLayout->addWidget(h2RowContainer, 1, 0); - calibrationCalculatedCoeffLayout->addWidget(h3RowContainer, 2, 0); - calibrationCalculatedCoeffLayout->addWidget(h8RowContainer, 3, 0); - - calibrationCoeffSectionWidget->contentLayout()->setSpacing(8); - calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatLabel); - calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatSwitch); - calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffLabel); - calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffWidget); - #pragma endregion - - #pragma region Calibration Dataset Configuration - MenuSectionWidget *calibrationDatasetConfigSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(calibrationDatasetConfigSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *calibrationDatasetConfigCollapseSection = new MenuCollapseSection("Dataset Configuration", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationDatasetConfigSectionWidget); - calibrationDatasetConfigSectionWidget->contentLayout()->setSpacing(8); - calibrationDatasetConfigSectionWidget->contentLayout()->addWidget(calibrationDatasetConfigCollapseSection); - - #pragma region Continuous Calibration Toggle - calibrationModeMenuCombo = new MenuCombo("Calibration Mode", calibrationDatasetConfigCollapseSection); - auto calibrationModeCombo = calibrationModeMenuCombo->combo(); - calibrationModeCombo->addItem("Continuous", QVariant(0)); - calibrationModeCombo->addItem("One Shot", QVariant(1)); - connectMenuComboToNumber(calibrationModeMenuCombo, calibrationMode); - #pragma endregion - - QWidget *calibrationCycleCountWidget = new QWidget(calibrationDatasetConfigCollapseSection); - QVBoxLayout *calibrationCycleCountLayout = new QVBoxLayout(calibrationCycleCountWidget); - calibrationCycleCountWidget->setLayout(calibrationCycleCountLayout); - calibrationCycleCountLayout->setMargin(0); - calibrationCycleCountLayout->setSpacing(0); - QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", calibrationCycleCountWidget); - QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(calibrationCycleCountWidget); - calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); - connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 1000); - calibrationCycleCountLayout->addWidget(calibrationCycleCountLabel); - calibrationCycleCountLayout->addWidget(calibrationCycleCountLineEdit); - - QWidget *calibrationSamplesPerCycleWidget = new QWidget(calibrationDatasetConfigCollapseSection); - QVBoxLayout *calibrationSamplesPerCycleLayout = new QVBoxLayout(calibrationSamplesPerCycleWidget); - calibrationSamplesPerCycleWidget->setLayout(calibrationSamplesPerCycleLayout); - calibrationSamplesPerCycleLayout->setMargin(0); - calibrationSamplesPerCycleLayout->setSpacing(0); - QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", calibrationSamplesPerCycleWidget); - QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationSamplesPerCycleWidget); - calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); - connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, 1, 5000); - calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLabel); - calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLineEdit); - - calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(8); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationModeMenuCombo); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountWidget); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleWidget); - - #pragma endregion - - #pragma region Calibration Data Section Widget - MenuSectionWidget *calibrationDataSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(calibrationDataSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection("Calibration Data", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationDataSectionWidget); - calibrationDataSectionWidget->contentLayout()->setSpacing(8); - calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); - - QPushButton *importSamplesButton = new QPushButton("Import Samples", calibrationDataCollapseSection); - QPushButton *extractDataButton = new QPushButton("Save to CSV", calibrationDataCollapseSection); - StyleHelper::BasicButton(importSamplesButton); - StyleHelper::BasicButton(extractDataButton); - - calibrationDataCollapseSection->contentLayout()->setSpacing(8); - calibrationDataCollapseSection->contentLayout()->addWidget(importSamplesButton); - calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); - #pragma endregion - - #pragma region Motor Control Section Widget - MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(motorControlSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection("Motor Control", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorControlSectionWidget); - motorControlSectionWidget->contentLayout()->setSpacing(8); - motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); - - QWidget *motorRPMWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); - motorRPMWidget->setLayout(motorRPMLayout); - motorRPMLayout->setMargin(0); - motorRPMLayout->setSpacing(0); - QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); - calibrationMotorRPMLineEdit = new QLineEdit(QString::number(motor_rpm), motorRPMWidget); - connectLineEditToRPM(calibrationMotorRPMLineEdit, motor_rpm); - motorRPMLayout->addWidget(motorRPMLabel); - motorRPMLayout->addWidget(calibrationMotorRPMLineEdit); - - QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); - currentPositionWidget->setLayout(currentPositionLayout); - currentPositionLayout->setMargin(0); - currentPositionLayout->setSpacing(0); - QLabel *currentPositionLabel = new QLabel("Current Position", currentPositionWidget); - calibrationMotorCurrentPositionLineEdit = new QLineEdit("--.--", currentPositionWidget); - calibrationMotorCurrentPositionLineEdit->setReadOnly(true); - connectLineEditToDouble(calibrationMotorCurrentPositionLineEdit, current_pos); - currentPositionLayout->addWidget(currentPositionLabel); - currentPositionLayout->addWidget(calibrationMotorCurrentPositionLineEdit); - - QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); - targetPositionWidget->setLayout(targetPositionLayout); - targetPositionLayout->setMargin(0); - targetPositionLayout->setSpacing(0); - QLabel *targetPositionLabel = new QLabel("Target Position", targetPositionWidget); - motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), targetPositionWidget); - connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, ADMTController::MotorAttribute::TARGET_POS); - targetPositionLayout->addWidget(targetPositionLabel); - targetPositionLayout->addWidget(motorTargetPositionLineEdit); - - QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); - motorDirectionWidget->setLayout(motorDirectionLayout); - motorDirectionLayout->setMargin(0); - motorDirectionLayout->setSpacing(0); - QLabel *motorDirectionLabel = new QLabel("Rotation Direction", motorDirectionWidget); - calibrationMotorDirectionSwitch = new CustomSwitch("CW", "CCW", motorControlSectionWidget); - calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); - connect(calibrationMotorDirectionSwitch, &CustomSwitch::toggled, this, [=](bool b){ - isMotorRotationClockwise = b; - }); - motorDirectionLayout->addWidget(motorDirectionLabel); - motorDirectionLayout->addWidget(calibrationMotorDirectionSwitch); - - QPushButton *continuousRotationButton = new QPushButton("Continuous Rotation", motorControlSectionWidget); - StyleHelper::BasicButton(continuousRotationButton); - connect(continuousRotationButton, &QPushButton::clicked, this, &HarmonicCalibration::moveMotorContinuous); - - QPushButton *stopMotorButton = new QPushButton("Stop Motor", motorControlSectionWidget); - StyleHelper::BasicButton(stopMotorButton); - connect(stopMotorButton, &QPushButton::clicked, this, &HarmonicCalibration::stopMotor); - - motorControlCollapseSection->contentLayout()->setSpacing(8); - motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); - motorControlCollapseSection->contentLayout()->addWidget(currentPositionWidget); - motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); - motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); - motorControlCollapseSection->contentLayout()->addWidget(continuousRotationButton); - motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); - #pragma endregion - - #pragma region Logs Section Widget - MenuSectionWidget *logsSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(logsSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *logsCollapseSection = new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, logsSectionWidget); - logsCollapseSection->header()->toggle(); - logsSectionWidget->contentLayout()->setSpacing(8); - logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); - - logsPlainTextEdit = new QPlainTextEdit(logsSectionWidget); - logsPlainTextEdit->setReadOnly(true); - logsPlainTextEdit->setFixedHeight(320); - logsPlainTextEdit->setStyleSheet("QPlainTextEdit { border: none; }"); - - logsCollapseSection->contentLayout()->setSpacing(8); - logsCollapseSection->contentLayout()->addWidget(logsPlainTextEdit); - #pragma endregion - - calibrationSettingsLayout->setMargin(0); - calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); - calibrationSettingsLayout->addWidget(motorControlSectionWidget); - calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); - // calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); - calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); - calibrationSettingsLayout->addWidget(logsSectionWidget); - calibrationSettingsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); - #pragma endregion - - tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - tool->topContainer()->setVisible(false); - tool->topContainerMenuControl()->setVisible(false); - tool->leftContainer()->setVisible(false); - tool->rightContainer()->setVisible(true); - tool->bottomContainer()->setVisible(false); - tool->setLeftContainerWidth(270); - tool->setRightContainerWidth(270); - tool->openBottomContainerHelper(false); - tool->openTopContainerHelper(false); - - tool->addWidgetToCentralContainerHelper(calibrationDataGraphWidget); - tool->rightStack()->add("calibrationSettingsGroupWidget", calibrationSettingsGroupWidget); - - connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); - connect(importSamplesButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); - connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAllCalibrationState); - connect(toggleAngleButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); - calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleSineButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - calibrationRawDataPlotWidget->selectChannel(calibrationSineDataPlotChannel); - calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleCosineButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - calibrationRawDataPlotWidget->selectChannel(calibrationCosineDataPlotChannel); - calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(togglePostAngleButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - postCalibrationRawDataPlotWidget->selectChannel(postCalibrationRawDataPlotChannel); - postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(togglePostSineButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - postCalibrationRawDataPlotWidget->selectChannel(postCalibrationSineDataPlotChannel); - postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(togglePostCosineButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - postCalibrationRawDataPlotWidget->selectChannel(postCalibrationCosineDataPlotChannel); - postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleFFTAngleErrorMagnitudeButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); - FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleFFTAngleErrorPhaseButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorPhaseChannel); - FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleFFTCorrectedErrorMagnitudeButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); - FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleFFTCorrectedErrorPhaseButton->checkBox(), &QCheckBox::toggled, this, [=](bool b){ - FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorPhaseChannel); - FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(calibrationDisplayFormatSwitch, &CustomSwitch::toggled, this, [=](bool b){ - isAngleDisplayFormat = b; - displayCalculatedCoeff(); - }); - - connect(&m_calibrationWaitVelocityWatcher, &QFutureWatcher::finished, this, [=]() { - if(isMotorVelocityReached) - { - startCalibrationStreamThread(); - } - else - { - startCurrentMotorPositionMonitor(); - startDeviceStatusMonitor(); - } - }); - - connect(&m_resetMotorToZeroWatcher, &QFutureWatcher::finished, this, [=]() { - startWaitForVelocityReachedThread(1); - }); - - connect(&m_calibrationStreamWatcher, &QFutureWatcher::started, [=]() { - QThread *thread = QThread::currentThread(); - thread->setPriority(QThread::TimeCriticalPriority); - }); - - connect(&m_calibrationStreamWatcher, &QFutureWatcher::finished, this, [=]() { - stopMotor(); - isStartMotor = false; - toggleTabSwitching(true); - toggleCalibrationControls(true); - - QString log = "Calibration Stream Timing: \n"; - for(auto& value : m_admtController->streamBufferedIntervals) { log += QString::number(value) + "\n"; } - Q_EMIT calibrationLogWriteSignal(log); - - if(isPostCalibration) - { - graphPostDataList = m_admtController->streamBufferedValues; - postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); - postCalibrationRawDataPlotWidget->replot(); - if(static_cast(graphPostDataList.size()) == totalSamplesCount) - { - computeSineCosineOfAngles(graphPostDataList); - m_admtController->postcalibrate(vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, samplesPerCycle, !isMotorRotationClockwise); - populateCorrectedAngleErrorGraphs(); - isPostCalibration = false; - isStartMotor = false; - resetToZero = true; - toggleCalibrationButtonState(4); - } - } - else - { - graphDataList = m_admtController->streamBufferedValues; - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotWidget->replot(); - if(static_cast(graphDataList.size()) >= totalSamplesCount) - { - computeSineCosineOfAngles(graphDataList); - calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle, !isMotorRotationClockwise)); - populateAngleErrorGraphs(); - calculateHarmonicValues(); - toggleCalibrationButtonState(2); - } - else - { - resetToZero = true; - toggleCalibrationButtonState(0); - } - } - - startCurrentMotorPositionMonitor(); - startDeviceStatusMonitor(); - }); - - - - return tool; -} - -ToolTemplate* HarmonicCalibration::createRegistersWidget() -{ - ToolTemplate *tool = new ToolTemplate(this); - - QScrollArea *registerScrollArea = new QScrollArea(); - QWidget *registerWidget = new QWidget(registerScrollArea); - registerWidget->setContentsMargins(0, 0, Style::getDimension(json::global::unit_0_5), 0); - QVBoxLayout *registerLayout = new QVBoxLayout(registerWidget); - registerScrollArea->setWidgetResizable(true); - registerScrollArea->setWidget(registerWidget); - registerWidget->setLayout(registerLayout); - registerLayout->setMargin(0); - registerLayout->setSpacing(globalSpacingSmall); - - MenuCollapseSection *registerConfigurationCollapseSection = new MenuCollapseSection("Configuration", MenuCollapseSection::MHCW_ARROW, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); - QWidget *registerConfigurationGridWidget = new QWidget(registerWidget); - QGridLayout *registerConfigurationGridLayout = new QGridLayout(registerConfigurationGridWidget); - registerConfigurationGridWidget->setLayout(registerConfigurationGridLayout); - registerConfigurationGridLayout->setMargin(0); - registerConfigurationGridLayout->setSpacing(globalSpacingSmall); - registerConfigurationCollapseSection->contentLayout()->addWidget(registerConfigurationGridWidget); - - MenuCollapseSection *registerSensorDataCollapseSection = new MenuCollapseSection("Sensor Data", MenuCollapseSection::MHCW_ARROW, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); - QWidget *registerSensorDataGridWidget = new QWidget(registerWidget); - QGridLayout *registerSensorDataGridLayout = new QGridLayout(registerSensorDataGridWidget); - registerSensorDataGridWidget->setLayout(registerSensorDataGridLayout); - registerSensorDataGridLayout->setMargin(0); - registerSensorDataGridLayout->setSpacing(globalSpacingSmall); - registerSensorDataCollapseSection->contentLayout()->addWidget(registerSensorDataGridWidget); - - MenuCollapseSection *registerDeviceIDCollapseSection = new MenuCollapseSection("Device ID", MenuCollapseSection::MHCW_ARROW, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); - QWidget *registerDeviceIDGridWidget = new QWidget(registerWidget); - QGridLayout *registerDeviceIDGridLayout = new QGridLayout(registerDeviceIDGridWidget); - registerDeviceIDGridWidget->setLayout(registerDeviceIDGridLayout); - registerDeviceIDGridLayout->setMargin(0); - registerDeviceIDGridLayout->setSpacing(globalSpacingSmall); - registerDeviceIDCollapseSection->contentLayout()->addWidget(registerDeviceIDGridWidget); - - MenuCollapseSection *registerHarmonicsCollapseSection = new MenuCollapseSection("Harmonics", MenuCollapseSection::MHCW_ARROW, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); - QWidget *registerHarmonicsGridWidget = new QWidget(registerWidget); - QGridLayout *registerHarmonicsGridLayout = new QGridLayout(registerHarmonicsGridWidget); - registerHarmonicsGridWidget->setLayout(registerHarmonicsGridLayout); - registerHarmonicsGridLayout->setMargin(0); - registerHarmonicsGridLayout->setSpacing(globalSpacingSmall); - registerHarmonicsCollapseSection->contentLayout()->addWidget(registerHarmonicsGridWidget); - - cnvPageRegisterBlock = new RegisterBlockWidget("CNVPAGE", "Convert Start and Page Select", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::CNVPAGE), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - digIORegisterBlock = new RegisterBlockWidget("DIGIO", "Digital Input Output", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIO), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIO), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - faultRegisterBlock = new RegisterBlockWidget("FAULT", "Fault Register", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::FAULT), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - generalRegisterBlock = new RegisterBlockWidget("GENERAL", "General Device Configuration", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - digIOEnRegisterBlock = new RegisterBlockWidget("DIGIOEN", "Enable Digital Input/Outputs", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - angleCkRegisterBlock = new RegisterBlockWidget("ANGLECK", "Primary vs Secondary Angle Check", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ANGLECK), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ANGLECK), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - eccDcdeRegisterBlock = new RegisterBlockWidget("ECCDCDE", "Error Correction Codes", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ECCDCDE), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCDCDE), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - eccDisRegisterBlock = new RegisterBlockWidget("ECCDIS", "Error Correction Code disable", m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ECCDIS), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCDIS), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - - absAngleRegisterBlock = new RegisterBlockWidget("ABSANGLE", "Absolute Angle", m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), m_admtController->getSensorPage(ADMTController::SensorRegister::ABSANGLE), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - angleRegisterBlock = new RegisterBlockWidget("ANGLE", "Angle Register", m_admtController->getSensorRegister(ADMTController::SensorRegister::ANGLEREG), m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLEREG), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - angleSecRegisterBlock = new RegisterBlockWidget("ANGLESEC", "Secondary Angle", m_admtController->getSensorRegister(ADMTController::SensorRegister::ANGLESEC), m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLESEC), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - sineRegisterBlock = new RegisterBlockWidget("SINE", "Sine Measurement", m_admtController->getSensorRegister(ADMTController::SensorRegister::SINE), m_admtController->getSensorPage(ADMTController::SensorRegister::SINE), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - cosineRegisterBlock = new RegisterBlockWidget("COSINE", "Cosine Measurement", m_admtController->getSensorRegister(ADMTController::SensorRegister::COSINE), m_admtController->getSensorPage(ADMTController::SensorRegister::COSINE), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - secAnglIRegisterBlock = new RegisterBlockWidget("SECANGLI", "In-phase secondary angle measurement", m_admtController->getSensorRegister(ADMTController::SensorRegister::SECANGLI), m_admtController->getSensorPage(ADMTController::SensorRegister::SECANGLI), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - secAnglQRegisterBlock = new RegisterBlockWidget("SECANGLQ", "Quadrature phase secondary angle measurement", m_admtController->getSensorRegister(ADMTController::SensorRegister::SECANGLQ), m_admtController->getSensorPage(ADMTController::SensorRegister::SECANGLQ), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - radiusRegisterBlock = new RegisterBlockWidget("RADIUS", "Angle measurement radius", m_admtController->getSensorRegister(ADMTController::SensorRegister::RADIUS), m_admtController->getSensorPage(ADMTController::SensorRegister::RADIUS), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - diag1RegisterBlock = new RegisterBlockWidget("DIAG1", "State of the MT reference resistors and AFE fixed input voltage", m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1), m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - diag2RegisterBlock = new RegisterBlockWidget("DIAG2", "Measurements of two diagnostics resistors of fixed value", m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG2), m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - tmp0RegisterBlock = new RegisterBlockWidget("TMP0", "Primary Temperature Sensor", m_admtController->getSensorRegister(ADMTController::SensorRegister::TMP0), m_admtController->getSensorPage(ADMTController::SensorRegister::TMP0), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - tmp1RegisterBlock = new RegisterBlockWidget("TMP1", "Secondary Temperature Sensor", m_admtController->getSensorRegister(ADMTController::SensorRegister::TMP1), m_admtController->getSensorPage(ADMTController::SensorRegister::TMP1), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - cnvCntRegisterBlock = new RegisterBlockWidget("CNVCNT", "Conversion Count", m_admtController->getSensorRegister(ADMTController::SensorRegister::CNVCNT), m_admtController->getSensorPage(ADMTController::SensorRegister::CNVCNT), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - - uniqID0RegisterBlock = new RegisterBlockWidget("UNIQID0", "Unique ID Register 0", m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID0), m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID0), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - uniqID1RegisterBlock = new RegisterBlockWidget("UNIQID1", "Unique ID Register 1", m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID1), m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID1), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - uniqID2RegisterBlock = new RegisterBlockWidget("UNIQID2", "Unique ID Register 2", m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID2), m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID2), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - uniqID3RegisterBlock = new RegisterBlockWidget("UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID3), m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - - h1MagRegisterBlock = new RegisterBlockWidget("H1MAG", "1st Harmonic error magnitude", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1MAG), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h1PhRegisterBlock = new RegisterBlockWidget("H1PH", "1st Harmonic error phase", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1PH), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h2MagRegisterBlock = new RegisterBlockWidget("H2MAG", "2nd Harmonic error magnitude", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H2MAG), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h2PhRegisterBlock = new RegisterBlockWidget("H2PH", "2nd Harmonic error phase", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H2PH), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h3MagRegisterBlock = new RegisterBlockWidget("H3MAG", "3rd Harmonic error magnitude", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H3MAG), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h3PhRegisterBlock = new RegisterBlockWidget("H3PH", "3rd Harmonic error phase", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H3PH), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h8MagRegisterBlock = new RegisterBlockWidget("H8MAG", "8th Harmonic error magnitude", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H8MAG), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h8PhRegisterBlock = new RegisterBlockWidget("H8PH", "8th Harmonic error phase", m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H8PH), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - - registerConfigurationGridLayout->addWidget(cnvPageRegisterBlock, 0, 0); - registerConfigurationGridLayout->addWidget(digIORegisterBlock, 0, 1); - registerConfigurationGridLayout->addWidget(faultRegisterBlock, 0, 2); - registerConfigurationGridLayout->addWidget(generalRegisterBlock, 0, 3); - registerConfigurationGridLayout->addWidget(digIOEnRegisterBlock, 0, 4); - registerConfigurationGridLayout->addWidget(eccDcdeRegisterBlock, 1, 0); - registerConfigurationGridLayout->addWidget(eccDisRegisterBlock, 1, 1); - registerConfigurationGridLayout->addWidget(angleCkRegisterBlock, 1, 2); - - registerSensorDataGridLayout->addWidget(absAngleRegisterBlock, 0, 0); - registerSensorDataGridLayout->addWidget(angleRegisterBlock, 0, 1); - registerSensorDataGridLayout->addWidget(sineRegisterBlock, 0, 2); - registerSensorDataGridLayout->addWidget(cosineRegisterBlock, 0, 3); - registerSensorDataGridLayout->addWidget(cnvCntRegisterBlock, 0, 4); - registerSensorDataGridLayout->addWidget(tmp0RegisterBlock, 1, 0); - registerSensorDataGridLayout->addWidget(tmp1RegisterBlock, 1, 1); - registerSensorDataGridLayout->addWidget(diag1RegisterBlock, 1, 2); - registerSensorDataGridLayout->addWidget(diag2RegisterBlock, 1, 3); - registerSensorDataGridLayout->addWidget(radiusRegisterBlock, 1, 4); - registerSensorDataGridLayout->addWidget(angleSecRegisterBlock, 2, 0); - registerSensorDataGridLayout->addWidget(secAnglIRegisterBlock, 2, 1); - registerSensorDataGridLayout->addWidget(secAnglQRegisterBlock, 2, 2); - - registerDeviceIDGridLayout->addWidget(uniqID0RegisterBlock, 0, 0); - registerDeviceIDGridLayout->addWidget(uniqID1RegisterBlock, 0, 1); - registerDeviceIDGridLayout->addWidget(uniqID2RegisterBlock, 0, 2); - registerDeviceIDGridLayout->addWidget(uniqID3RegisterBlock, 0, 3); - QSpacerItem *registerDeviceSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred); - registerDeviceIDGridLayout->addItem(registerDeviceSpacer, 0, 4); - - registerHarmonicsGridLayout->addWidget(h1MagRegisterBlock, 0, 0); - registerHarmonicsGridLayout->addWidget(h1PhRegisterBlock, 0, 1); - registerHarmonicsGridLayout->addWidget(h2MagRegisterBlock, 0, 2); - registerHarmonicsGridLayout->addWidget(h2PhRegisterBlock, 0, 3); - registerHarmonicsGridLayout->addWidget(h3MagRegisterBlock, 0, 4); - registerHarmonicsGridLayout->addWidget(h3PhRegisterBlock, 1, 0); - registerHarmonicsGridLayout->addWidget(h8MagRegisterBlock, 1, 1); - registerHarmonicsGridLayout->addWidget(h8PhRegisterBlock, 1, 2); - - for(int c=0; c < registerConfigurationGridLayout->columnCount(); ++c) registerConfigurationGridLayout->setColumnStretch(c,1); - for(int c=0; c < registerDeviceIDGridLayout->columnCount(); ++c) registerDeviceIDGridLayout->setColumnStretch(c,1); - for(int c=0; c < registerHarmonicsGridLayout->columnCount(); ++c) registerHarmonicsGridLayout->setColumnStretch(c,1); - for(int c=0; c < registerSensorDataGridLayout->columnCount(); ++c) registerSensorDataGridLayout->setColumnStretch(c,1); - - QWidget *registerActionsWidget = new QWidget(registerWidget); - QHBoxLayout *registerActionsLayout = new QHBoxLayout(registerActionsWidget); - registerActionsWidget->setLayout(registerActionsLayout); - registerActionsLayout->setMargin(0); - registerActionsLayout->setSpacing(globalSpacingSmall); - readAllRegistersButton = new QPushButton("Read All Registers", registerWidget); - StyleHelper::BasicButton(readAllRegistersButton); - readAllRegistersButton->setFixedWidth(270); - connect(readAllRegistersButton, &QPushButton::clicked, this, &HarmonicCalibration::readAllRegisters); - registerActionsLayout->addWidget(readAllRegistersButton); - - registerLayout->addWidget(registerConfigurationCollapseSection); - registerLayout->addWidget(registerSensorDataCollapseSection); - registerLayout->addWidget(registerDeviceIDCollapseSection); - registerLayout->addWidget(registerHarmonicsCollapseSection); - registerLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); - - tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - tool->topContainer()->setVisible(true); - tool->topContainerMenuControl()->setVisible(false); - tool->leftContainer()->setVisible(false); - tool->rightContainer()->setVisible(false); - tool->bottomContainer()->setVisible(false); - tool->openBottomContainerHelper(false); - tool->openTopContainerHelper(false); - - tool->addWidgetToTopContainerHelper(registerActionsWidget, ToolTemplateAlignment::TTA_LEFT); - tool->addWidgetToCentralContainerHelper(registerScrollArea); - - tool->layout()->setMargin(0); - tool->layout()->setContentsMargins(globalSpacingSmall, globalSpacingSmall, Style::getDimension(json::global::unit_0_5), globalSpacingSmall); - - connectRegisterBlockToRegistry(cnvPageRegisterBlock); - connectRegisterBlockToRegistry(digIORegisterBlock); - connectRegisterBlockToRegistry(faultRegisterBlock); - connectRegisterBlockToRegistry(generalRegisterBlock); - connectRegisterBlockToRegistry(digIOEnRegisterBlock); - connectRegisterBlockToRegistry(angleCkRegisterBlock); - connectRegisterBlockToRegistry(eccDcdeRegisterBlock); - connectRegisterBlockToRegistry(eccDisRegisterBlock); - - connectRegisterBlockToRegistry(absAngleRegisterBlock); - connectRegisterBlockToRegistry(angleRegisterBlock); - connectRegisterBlockToRegistry(angleSecRegisterBlock); - connectRegisterBlockToRegistry(sineRegisterBlock); - connectRegisterBlockToRegistry(cosineRegisterBlock); - connectRegisterBlockToRegistry(secAnglIRegisterBlock); - connectRegisterBlockToRegistry(secAnglQRegisterBlock); - connectRegisterBlockToRegistry(radiusRegisterBlock); - connectRegisterBlockToRegistry(diag1RegisterBlock); - connectRegisterBlockToRegistry(diag2RegisterBlock); - connectRegisterBlockToRegistry(tmp0RegisterBlock); - connectRegisterBlockToRegistry(tmp1RegisterBlock); - connectRegisterBlockToRegistry(cnvCntRegisterBlock); - - connectRegisterBlockToRegistry(uniqID0RegisterBlock); - connectRegisterBlockToRegistry(uniqID1RegisterBlock); - connectRegisterBlockToRegistry(uniqID2RegisterBlock); - connectRegisterBlockToRegistry(uniqID3RegisterBlock); - - connectRegisterBlockToRegistry(h1MagRegisterBlock); - connectRegisterBlockToRegistry(h1PhRegisterBlock); - connectRegisterBlockToRegistry(h2MagRegisterBlock); - connectRegisterBlockToRegistry(h2PhRegisterBlock); - connectRegisterBlockToRegistry(h3MagRegisterBlock); - connectRegisterBlockToRegistry(h3PhRegisterBlock); - connectRegisterBlockToRegistry(h8MagRegisterBlock); - connectRegisterBlockToRegistry(h8PhRegisterBlock); - - return tool; -} - -ToolTemplate* HarmonicCalibration::createUtilityWidget() -{ - ToolTemplate *tool = new ToolTemplate(this); - - #pragma region Left Utility Widget - QWidget *leftUtilityWidget = new QWidget(this); - QVBoxLayout *leftUtilityLayout = new QVBoxLayout(leftUtilityWidget); - leftUtilityWidget->setLayout(leftUtilityLayout); - leftUtilityLayout->setMargin(0); - leftUtilityLayout->setSpacing(8); - #pragma region Command Log Widget - MenuSectionWidget *commandLogSectionWidget = new MenuSectionWidget(leftUtilityWidget); - Style::setStyle(commandLogSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *commandLogCollapseSection = new MenuCollapseSection("Command Log", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, commandLogSectionWidget); - commandLogSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - commandLogSectionWidget->contentLayout()->addWidget(commandLogCollapseSection); - commandLogCollapseSection->contentLayout()->setSpacing(8); - - commandLogPlainTextEdit = new QPlainTextEdit(commandLogSectionWidget); - commandLogPlainTextEdit->setReadOnly(true); - commandLogPlainTextEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - commandLogPlainTextEdit->setStyleSheet("QPlainTextEdit { border: none; }"); - - clearCommandLogButton = new QPushButton("Clear Command Logs", commandLogSectionWidget); - StyleHelper::BasicButton(clearCommandLogButton); - connect(clearCommandLogButton, &QPushButton::clicked, this, &HarmonicCalibration::clearCommandLog); - - commandLogCollapseSection->contentLayout()->addWidget(commandLogPlainTextEdit); - commandLogCollapseSection->contentLayout()->addWidget(clearCommandLogButton); - - leftUtilityLayout->addWidget(commandLogSectionWidget, 1); - leftUtilityLayout->addStretch(); - #pragma endregion - #pragma endregion - - #pragma region Center Utility Widget - QWidget *centerUtilityWidget = new QWidget(this); - QHBoxLayout *centerUtilityLayout = new QHBoxLayout(centerUtilityWidget); - centerUtilityWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - centerUtilityWidget->setContentsMargins(2, 0, 2, 0); - centerUtilityWidget->setLayout(centerUtilityLayout); - centerUtilityLayout->setMargin(0); - centerUtilityLayout->setSpacing(8); - - QScrollArea *DIGIOScrollArea = new QScrollArea(centerUtilityWidget); - QWidget *DIGIOWidget = new QWidget(DIGIOScrollArea); - DIGIOScrollArea->setWidget(DIGIOWidget); - DIGIOScrollArea->setWidgetResizable(true); - QVBoxLayout *DIGIOLayout = new QVBoxLayout(DIGIOWidget); - DIGIOWidget->setLayout(DIGIOLayout); - DIGIOLayout->setMargin(0); - DIGIOLayout->setSpacing(8); - - #pragma region DIGIO Monitor - MenuSectionWidget *DIGIOMonitorSectionWidget = new MenuSectionWidget(DIGIOWidget); - Style::setStyle(DIGIOMonitorSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection("DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOMonitorSectionWidget); - DIGIOMonitorSectionWidget->contentLayout()->addWidget(DIGIOMonitorCollapseSection); - DIGIOMonitorCollapseSection->contentLayout()->setSpacing(8); - - DIGIOBusyStatusLED = createStatusLEDWidget("BUSY (Output)", "digio", false, DIGIOMonitorCollapseSection); - DIGIOCNVStatusLED = createStatusLEDWidget("CNV (Input)", "digio", false, DIGIOMonitorCollapseSection); - DIGIOSENTStatusLED = createStatusLEDWidget("SENT (Output)", "digio", false, DIGIOMonitorCollapseSection); - DIGIOACALCStatusLED = createStatusLEDWidget("ACALC (Output)", "digio", false, DIGIOMonitorCollapseSection); - DIGIOFaultStatusLED = createStatusLEDWidget("FAULT (Output)", "digio", false, DIGIOMonitorCollapseSection); - DIGIOBootloaderStatusLED = createStatusLEDWidget("BOOTLOADER (Output)", "digio", false, DIGIOMonitorCollapseSection); - - DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBusyStatusLED); - DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOCNVStatusLED); - DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOSENTStatusLED); - DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOACALCStatusLED); - DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOFaultStatusLED); - DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBootloaderStatusLED); - #pragma endregion - - #pragma region DIGIO Control - MenuSectionWidget *DIGIOControlSectionWidget = new MenuSectionWidget(DIGIOWidget); - Style::setStyle(DIGIOControlSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *DIGIOControlCollapseSection = new MenuCollapseSection("DIGIO Control", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOControlSectionWidget); - DIGIOControlCollapseSection->contentLayout()->setSpacing(8); - DIGIOControlSectionWidget->contentLayout()->addWidget(DIGIOControlCollapseSection); - - QWidget *DIGIOControlGridWidget = new QWidget(DIGIOControlCollapseSection); - QGridLayout *DIGIOControlGridLayout = new QGridLayout(DIGIOControlGridWidget); - DIGIOControlGridWidget->setLayout(DIGIOControlGridLayout); - DIGIOControlGridLayout->setMargin(0); - DIGIOControlGridLayout->setSpacing(8); - - QLabel *DIGIO0Label = new QLabel("DIGIO0", DIGIOControlGridWidget); - QLabel *DIGIO1Label = new QLabel("DIGIO1", DIGIOControlGridWidget); - QLabel *DIGIO2Label = new QLabel("DIGIO2", DIGIOControlGridWidget); - QLabel *DIGIO3Label = new QLabel("DIGIO3", DIGIOControlGridWidget); - QLabel *DIGIO4Label = new QLabel("DIGIO4", DIGIOControlGridWidget); - QLabel *DIGIO5Label = new QLabel("DIGIO5", DIGIOControlGridWidget); - QLabel *DIGIOFunctionLabel = new QLabel("DIGIO Function", DIGIOControlGridWidget); - QLabel *GPIOModeLabel = new QLabel("GPIO Mode", DIGIOControlGridWidget); - - DIGIO0ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Output", "Input"); - connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("DIGIO0EN", value); - }); - - DIGIO0FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO0FNCToggleSwitch, "GPIO0", "BUSY"); - connect(DIGIO0FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("BUSY", value); - }); - - DIGIO1ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO1ENToggleSwitch, "Output", "Input"); - connect(DIGIO1ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("DIGIO1EN", value); - }); - - DIGIO1FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO1FNCToggleSwitch, "GPIO1", "CNV"); - connect(DIGIO1FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("CNV", value); - }); - - DIGIO2ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO2ENToggleSwitch, "Output", "Input"); - connect(DIGIO2ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("DIGIO2EN", value); - }); - - DIGIO2FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO2FNCToggleSwitch, "GPIO2", "SENT"); - connect(DIGIO2FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("SENT", value); - }); - - DIGIO3ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO3ENToggleSwitch, "Output", "Input"); - connect(DIGIO3ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("DIGIO3EN", value); - }); - - DIGIO3FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO3FNCToggleSwitch, "GPIO3", "ACALC"); - connect(DIGIO3FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("ACALC", value); - }); - - DIGIO4ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO4ENToggleSwitch, "Output", "Input"); - connect(DIGIO4ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("DIGIO4EN", value); - }); - - DIGIO4FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO4FNCToggleSwitch, "GPIO4", "FAULT"); - connect(DIGIO4FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("FAULT", value); - }); - - DIGIO5ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO5ENToggleSwitch, "Output", "Input"); - connect(DIGIO5ENToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("DIGIO5EN", value); - }); - - DIGIO5FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO5FNCToggleSwitch, "GPIO5", "BOOT"); - connect(DIGIO5FNCToggleSwitch, &CustomSwitch::clicked, [=](bool value){ - toggleDIGIOEN("BOOTLOAD", value); - }); - - QPushButton *DIGIOResetButton = new QPushButton("Reset DIGIO", DIGIOControlGridWidget); - DIGIOResetButton->setFixedWidth(100); - StyleHelper::BasicButton(DIGIOResetButton); - connect(DIGIOResetButton, &QPushButton::clicked, [=]{ - toggleUtilityTask(false); - resetDIGIO(); - toggleUtilityTask(true); - }); - - DIGIOControlGridLayout->addWidget(DIGIOFunctionLabel, 0, 1); - DIGIOControlGridLayout->addWidget(GPIOModeLabel, 0, 2); - - DIGIOControlGridLayout->addWidget(DIGIO0Label, 1, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO0FNCToggleSwitch, 1, 1); - DIGIOControlGridLayout->addWidget(DIGIO0ENToggleSwitch, 1, 2); - - DIGIOControlGridLayout->addWidget(DIGIO1Label, 2, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO1FNCToggleSwitch, 2, 1); - DIGIOControlGridLayout->addWidget(DIGIO1ENToggleSwitch, 2, 2); - - DIGIOControlGridLayout->addWidget(DIGIO2Label, 3, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO2FNCToggleSwitch, 3, 1); - DIGIOControlGridLayout->addWidget(DIGIO2ENToggleSwitch, 3, 2); - - DIGIOControlGridLayout->addWidget(DIGIO3Label, 4, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO3FNCToggleSwitch, 4, 1); - DIGIOControlGridLayout->addWidget(DIGIO3ENToggleSwitch, 4, 2); - - DIGIOControlGridLayout->addWidget(DIGIO4Label, 5, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO4FNCToggleSwitch, 5, 1); - DIGIOControlGridLayout->addWidget(DIGIO4ENToggleSwitch, 5, 2); - - DIGIOControlGridLayout->addWidget(DIGIO5Label, 6, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO5FNCToggleSwitch, 6, 1); - DIGIOControlGridLayout->addWidget(DIGIO5ENToggleSwitch, 6, 2); - - DIGIOControlGridLayout->setColumnStretch(0, 1); - - DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOControlGridWidget); - DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOResetButton); - - if(GENERALRegisterMap.at("Sequence Type") == 0) - { - DIGIO2FNCToggleSwitch->setVisible(false); - DIGIO4FNCToggleSwitch->setVisible(false); - } - - #pragma endregion - - DIGIOLayout->addWidget(DIGIOMonitorSectionWidget); - DIGIOLayout->addWidget(DIGIOControlSectionWidget); - DIGIOLayout->addStretch(); - - #pragma region MTDIAG1 Widget - MenuSectionWidget *MTDIAG1SectionWidget = new MenuSectionWidget(centerUtilityWidget); - Style::setStyle(MTDIAG1SectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *MTDIAG1CollapseSection = new MenuCollapseSection("MT Diagnostic Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, MTDIAG1SectionWidget); - MTDIAG1SectionWidget->contentLayout()->addWidget(MTDIAG1CollapseSection); - MTDIAG1CollapseSection->contentLayout()->setSpacing(8); - - R0StatusLED = createStatusLEDWidget("R0", "mtdiag", false, MTDIAG1SectionWidget); - R1StatusLED = createStatusLEDWidget("R1", "mtdiag", false, MTDIAG1SectionWidget); - R2StatusLED = createStatusLEDWidget("R2", "mtdiag", false, MTDIAG1SectionWidget); - R3StatusLED = createStatusLEDWidget("R3", "mtdiag", false, MTDIAG1SectionWidget); - R4StatusLED = createStatusLEDWidget("R4", "mtdiag", false, MTDIAG1SectionWidget); - R5StatusLED = createStatusLEDWidget("R5", "mtdiag", false, MTDIAG1SectionWidget); - R6StatusLED = createStatusLEDWidget("R6", "mtdiag", false, MTDIAG1SectionWidget); - R7StatusLED = createStatusLEDWidget("R7", "mtdiag", false, MTDIAG1SectionWidget); - - MTDIAG1CollapseSection->contentLayout()->addWidget(R0StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R1StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R2StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R3StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R4StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R5StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R6StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R7StatusLED); - #pragma endregion - - #pragma region MT Diagnostics - MTDiagnosticsScrollArea = new QScrollArea(centerUtilityWidget); - QWidget *MTDiagnosticsWidget = new QWidget(MTDiagnosticsScrollArea); - MTDiagnosticsScrollArea->setWidget(MTDiagnosticsWidget); - MTDiagnosticsScrollArea->setWidgetResizable(true); - QVBoxLayout *MTDiagnosticsLayout = new QVBoxLayout(MTDiagnosticsWidget); - MTDiagnosticsWidget->setLayout(MTDiagnosticsLayout); - MTDiagnosticsLayout->setMargin(0); - MTDiagnosticsLayout->setSpacing(8); - - MenuSectionWidget *MTDiagnosticsSectionWidget = new MenuSectionWidget(centerUtilityWidget); - Style::setStyle(MTDiagnosticsSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *MTDiagnosticsCollapseSection = new MenuCollapseSection("MT Diagnostics", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, MTDiagnosticsSectionWidget); - MTDiagnosticsSectionWidget->contentLayout()->addWidget(MTDiagnosticsCollapseSection); - MTDiagnosticsCollapseSection->contentLayout()->setSpacing(8); - - QLabel *AFEDIAG0Label = new QLabel("AFEDIAG0 (%)"); - Style::setStyle(AFEDIAG0Label, style::properties::label::menuSmall); - QLabel *AFEDIAG1Label = new QLabel("AFEDIAG1 (%)"); - Style::setStyle(AFEDIAG1Label, style::properties::label::menuSmall); - QLabel *AFEDIAG2Label = new QLabel("AFEDIAG2 (V)"); - Style::setStyle(AFEDIAG2Label, style::properties::label::menuSmall); - - AFEDIAG0LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); - AFEDIAG1LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); - AFEDIAG2LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); - AFEDIAG0LineEdit->setReadOnly(true); - AFEDIAG1LineEdit->setReadOnly(true); - AFEDIAG2LineEdit->setReadOnly(true); - connectLineEditToNumber(AFEDIAG0LineEdit, afeDiag0, "V"); - connectLineEditToNumber(AFEDIAG1LineEdit, afeDiag1, "V"); - connectLineEditToNumber(AFEDIAG2LineEdit, afeDiag2, "V"); - - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0Label); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0LineEdit); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1Label); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1LineEdit); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2Label); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2LineEdit); - - MTDiagnosticsLayout->addWidget(MTDiagnosticsSectionWidget); - MTDiagnosticsLayout->addWidget(MTDIAG1SectionWidget); - MTDiagnosticsLayout->addStretch(); - #pragma endregion - - centerUtilityLayout->addWidget(DIGIOScrollArea); - centerUtilityLayout->addWidget(MTDiagnosticsScrollArea); - - #pragma endregion - - #pragma region Right Utility Widget - QScrollArea *rightUtilityScrollArea = new QScrollArea(this); - QWidget *rightUtilityWidget = new QWidget(rightUtilityScrollArea); - rightUtilityScrollArea->setWidget(rightUtilityWidget); - rightUtilityScrollArea->setWidgetResizable(true); - QVBoxLayout *rightUtilityLayout = new QVBoxLayout(rightUtilityWidget); - rightUtilityWidget->setLayout(rightUtilityLayout); - rightUtilityLayout->setMargin(0); - rightUtilityLayout->setSpacing(8); - - MenuSectionWidget *faultRegisterSectionWidget = new MenuSectionWidget(rightUtilityWidget); - Style::setStyle(faultRegisterSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection("Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, faultRegisterSectionWidget); - faultRegisterSectionWidget->contentLayout()->addWidget(faultRegisterCollapseSection); - faultRegisterCollapseSection->contentLayout()->setSpacing(8); - - VDDUnderVoltageStatusLED = createStatusLEDWidget("VDD Under Voltage", "fault", false, faultRegisterCollapseSection); - VDDOverVoltageStatusLED = createStatusLEDWidget("VDD Over Voltage", "fault", false, faultRegisterCollapseSection); - VDRIVEUnderVoltageStatusLED = createStatusLEDWidget("VDRIVE Under Voltage", "fault", false, faultRegisterCollapseSection); - VDRIVEOverVoltageStatusLED = createStatusLEDWidget("VDRIVE Over Voltage", "fault", false, faultRegisterCollapseSection); - AFEDIAGStatusLED = createStatusLEDWidget("AFEDIAG", "fault", false, faultRegisterCollapseSection); - NVMCRCFaultStatusLED = createStatusLEDWidget("NVM CRC Fault", "fault", false, faultRegisterCollapseSection); - ECCDoubleBitErrorStatusLED = createStatusLEDWidget("ECC Double Bit Error", "fault", false, faultRegisterCollapseSection); - OscillatorDriftStatusLED = createStatusLEDWidget("Oscillator Drift", "fault", false, faultRegisterCollapseSection); - CountSensorFalseStateStatusLED = createStatusLEDWidget("Count Sensor False State", "fault", false, faultRegisterCollapseSection); - AngleCrossCheckStatusLED = createStatusLEDWidget("Angle Cross Check", "fault", false, faultRegisterCollapseSection); - TurnCountSensorLevelsStatusLED = createStatusLEDWidget("Turn Count Sensor Levels", "fault", false, faultRegisterCollapseSection); - MTDIAGStatusLED = createStatusLEDWidget("MTDIAG", "fault", false, faultRegisterCollapseSection); - TurnCounterCrossCheckStatusLED = createStatusLEDWidget("Turn Counter Cross Check", "fault", false, faultRegisterCollapseSection); - RadiusCheckStatusLED = createStatusLEDWidget("Radius Check", "fault", false, faultRegisterCollapseSection); - SequencerWatchdogStatusLED = createStatusLEDWidget("Sequencer Watchdog", "fault", false, faultRegisterCollapseSection); - - faultRegisterCollapseSection->contentLayout()->addWidget(VDDUnderVoltageStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(VDDOverVoltageStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(VDRIVEUnderVoltageStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(VDRIVEOverVoltageStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(AFEDIAGStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(NVMCRCFaultStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(ECCDoubleBitErrorStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(OscillatorDriftStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(CountSensorFalseStateStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(AngleCrossCheckStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(TurnCountSensorLevelsStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(MTDIAGStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(TurnCounterCrossCheckStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(RadiusCheckStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(SequencerWatchdogStatusLED); - - rightUtilityLayout->addWidget(faultRegisterSectionWidget); - rightUtilityLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); - #pragma endregion - - tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - tool->topContainer()->setVisible(false); - tool->topContainerMenuControl()->setVisible(false); - tool->leftContainer()->setVisible(true); - tool->rightContainer()->setVisible(true); - tool->bottomContainer()->setVisible(false); - tool->setLeftContainerWidth(240); - tool->setRightContainerWidth(224); - tool->openBottomContainerHelper(false); - tool->openTopContainerHelper(false); - - tool->leftStack()->addWidget(leftUtilityWidget); - tool->addWidgetToCentralContainerHelper(centerUtilityWidget); - tool->rightStack()->addWidget(rightUtilityScrollArea); - - return tool; -} - -void HarmonicCalibration::readDeviceProperties() -{ - uint32_t *uniqId3RegisterValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t page = m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3); - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); - - bool success = false; - - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, page) != -1){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ - if(*cnvPageRegValue == page){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID3), uniqId3RegisterValue) != -1){ - deviceRegisterMap = m_admtController->getUNIQID3RegisterMapping(static_cast(*uniqId3RegisterValue)); - - if(deviceRegisterMap.at("Supply ID") == "5V") { is5V = true; } - else if(deviceRegisterMap.at("Supply ID") == "3.3V") { is5V = false; } - else { is5V = false; } - - deviceName = QString::fromStdString(deviceRegisterMap.at("Product ID")); - - if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { deviceType = QString::fromStdString("Industrial"); } - else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { deviceType = QString::fromStdString("Automotive"); } - else { deviceType = QString::fromStdString(deviceRegisterMap.at("ASIL ID")); } - - success = true; - } - } - } - } - - if(!success) { StatusBarManager::pushMessage("Failed to read device properties"); } -} - -void HarmonicCalibration::initializeADMT() -{ - bool success = resetDIGIO(); - success = resetGENERAL(); - - if(!success){ StatusBarManager::pushMessage("Failed initialize ADMT"); } -} - -bool HarmonicCalibration::readSequence(){ - uint32_t *generalRegValue = new uint32_t; - uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); - uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); - - bool success = false; - - if(changeCNVPage(generalRegisterPage)){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ - if(*generalRegValue != UINT32_MAX){ - GENERALRegisterMap = m_admtController->getGeneralRegisterBitMapping(static_cast(*generalRegValue)); - success = true; - } - } - } - - return success; -} - -bool HarmonicCalibration::writeSequence(const map &settings) -{ - uint32_t *generalRegValue = new uint32_t; - uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); - - bool success = false; - - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, generalRegValue) != -1){ - - uint32_t newGeneralRegValue = m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings); - uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); - - if(changeCNVPage(generalRegisterPage)){ - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, newGeneralRegValue) != -1){ - if(readSequence()){ - if(settings.at("Convert Synchronization") == GENERALRegisterMap.at("Convert Synchronization") && - settings.at("Angle Filter") == GENERALRegisterMap.at("Angle Filter") && - settings.at("8th Harmonic") == GENERALRegisterMap.at("8th Harmonic") && - settings.at("Sequence Type") == GENERALRegisterMap.at("Sequence Type") && - settings.at("Conversion Type") == GENERALRegisterMap.at("Conversion Type")) - { - success = true; - } - } - } - } - } - - return success; -} - -void HarmonicCalibration::applySequence(){ - toggleWidget(applySequenceButton, false); - applySequenceButton->setText("Writing..."); - QTimer::singleShot(1000, this, [this](){ - this->toggleWidget(applySequenceButton, true); - applySequenceButton->setText("Apply"); - }); - uint32_t *generalRegValue = new uint32_t; - uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); - map settings; - - bool success = false; - - settings["Sequence Type"] = qvariant_cast(sequenceTypeMenuCombo->combo()->currentData()); // sequenceType; - settings["Conversion Type"] = qvariant_cast(conversionTypeMenuCombo->combo()->currentData()); // conversionType; - settings["Convert Synchronization"] = qvariant_cast(convertSynchronizationMenuCombo->combo()->currentData()); // convertSync; - settings["Angle Filter"] = qvariant_cast(angleFilterMenuCombo->combo()->currentData()); // angleFilter; - settings["8th Harmonic"] = qvariant_cast(eighthHarmonicMenuCombo->combo()->currentData()); // eighthHarmonic; - - success = writeSequence(settings); - if(!success) StatusBarManager::pushMessage("Failed to apply sequence settings"); - else StatusBarManager::pushMessage("Sequence settings applied successfully"); -} - -bool HarmonicCalibration::changeCNVPage(uint32_t page){ - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); - - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, page) != -1){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ - if(*cnvPageRegValue == page){ - return true; - } - } - } - - return false; -} - -void HarmonicCalibration::initializeMotor() -{ - motor_rpm = 60; - rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(motor_rpm)); - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - - amax = convertAccelTimetoAMAX(motorAccelTime); - writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - - dmax = 3000; - writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - - ramp_mode = 0; - writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - - target_pos = 0; - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - - current_pos = 0; - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); -} - -void HarmonicCalibration::startDeviceStatusMonitor() -{ - if(!m_deviceStatusThread.isRunning()) - { - isDeviceStatusMonitor = true; - m_deviceStatusThread = QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); - m_deviceStatusWatcher.setFuture(m_deviceStatusThread); - } -} - -void HarmonicCalibration::stopDeviceStatusMonitor() -{ - isDeviceStatusMonitor = false; - if(m_deviceStatusThread.isRunning()) - { - m_deviceStatusThread.cancel(); - m_deviceStatusWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) -{ - uint32_t *readValue = new uint32_t; - bool registerFault = false; - while(isDeviceStatusMonitor) - { - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), 0) == 0) - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), readValue) == 0) - { - registerFault = m_admtController->checkRegisterFault(static_cast(*readValue), GENERALRegisterMap.at("Sequence Type") == 0 ? true : false); - Q_EMIT updateFaultStatusSignal(registerFault); - } - else - { - Q_EMIT updateFaultStatusSignal(true); - } - } - else - { - Q_EMIT updateFaultStatusSignal(true); - } - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::requestDisconnect() -{ - stopAcquisition(); - - stopAcquisitionUITask(); - stopCalibrationUITask(); - stopUtilityTask(); - - stopCalibrationStreamThread(); - - stopDeviceStatusMonitor(); - stopCurrentMotorPositionMonitor(); -} - -void HarmonicCalibration::startCurrentMotorPositionMonitor() -{ - if(!m_currentMotorPositionThread.isRunning()) - { - isMotorPositionMonitor = true; - m_currentMotorPositionThread = QtConcurrent::run(this, &HarmonicCalibration::currentMotorPositionTask, motorPositionMonitorRate); - m_currentMotorPositionWatcher.setFuture(m_currentMotorPositionThread); - } -} - -void HarmonicCalibration::stopCurrentMotorPositionMonitor() -{ - isMotorPositionMonitor = false; - if(m_currentMotorPositionThread.isRunning()) - { - m_currentMotorPositionThread.cancel(); - m_currentMotorPositionWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::currentMotorPositionTask(int sampleRate) -{ - double motorPosition = 0; - while(isMotorPositionMonitor) - { - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, motorPosition); - - Q_EMIT motorPositionChanged(motorPosition); - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::updateMotorPosition(double position) -{ - current_pos = position; - if(isAcquisitionTab) updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); - else if(isCalibrationTab) updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); -} - -bool HarmonicCalibration::resetGENERAL() -{ - bool success = false; - - uint32_t resetValue = 0x0000; - if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { resetValue = 0x1231; } // Industrial or ASIL QM - else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { resetValue = 0x1200; } // Automotive or ASIL B - - if(resetValue != 0x0000){ - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL), resetValue) == 0) { success = true; } - } - - return success; + {RADIUS, false}, {ANGLE, false}, {TURNCOUNT, false}, {ABSANGLE, false}, + {SINE, false}, {COSINE, false}, {SECANGLI, false}, {SECANGLQ, false}, + {ANGLESEC, false}, {DIAG1, false}, {DIAG2, false}, {TMP0, false}, + {TMP1, false}, {CNVCNT, false}, {SCRADIUS, false}, {SPIFAULT, false}}; + +HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, + bool isDebug, QWidget *parent) + : QWidget(parent), isDebug(isDebug), m_admtController(m_admtController) { + ADMTStyleHelper::GetInstance()->initColorMap(); + readDeviceProperties(); + initializeADMT(); + initializeMotor(); + readSequence(); + + rotationChannelName = + m_admtController->getChannelId(ADMTController::Channel::ROTATION); + angleChannelName = + m_admtController->getChannelId(ADMTController::Channel::ANGLE); + countChannelName = + m_admtController->getChannelId(ADMTController::Channel::COUNT); + temperatureChannelName = + m_admtController->getChannelId(ADMTController::Channel::TEMPERATURE); + + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + QHBoxLayout *lay = new QHBoxLayout(this); + tabWidget = new QTabWidget(this); + + setLayout(lay); + lay->setMargin(0); + lay->insertWidget(1, tabWidget); + tabWidget->setStyleSheet(""); + tabWidget->tabBar()->setStyleSheet(""); + Style::setStyle(tabWidget, style::properties::admt::tabWidget); + Style::setStyle(tabWidget->tabBar(), style::properties::admt::tabBar); + + tabWidget->addTab(createAcquisitionWidget(), "Acquisition"); + tabWidget->addTab(createCalibrationWidget(), "Calibration"); + tabWidget->addTab(createUtilityWidget(), "Utility"); + tabWidget->addTab(createRegistersWidget(), "Registers"); + + connect(tabWidget, &QTabWidget::currentChanged, [this](int index) { + tabWidget->setCurrentIndex(index); + + if (index == 0 || index == 1) { + startDeviceStatusMonitor(); + startCurrentMotorPositionMonitor(); + } else { + stopDeviceStatusMonitor(); + stopCurrentMotorPositionMonitor(); + } + + if (index == 0) // Acquisition Tab + { + startAcquisitionUITask(); + readSequence(); + updateSequenceWidget(); + updateAcquisitionMotorRPM(); + updateAcquisitionMotorRotationDirection(); + } else { + stopAcquisitionUITask(); + stop(); + } + + if (index == 1) // Calibration Tab + { + startCalibrationUITask(); + updateCalibrationMotorRPM(); + updateCalibrationMotorRotationDirection(); + } else { + stopCalibrationUITask(); + } + + if (index == 2) // Utility Tab + { + readSequence(); + toggleFaultRegisterMode(GENERALRegisterMap.at("Sequence Type")); + toggleMTDiagnostics(GENERALRegisterMap.at("Sequence Type")); + toggleUtilityTask(true); + } else { + toggleUtilityTask(false); + } + + if (index == 3) // Registers Tab + { + readSequence(); + toggleRegisters(GENERALRegisterMap.at("Sequence Type")); + } + }); + + connect(this, &HarmonicCalibration::updateFaultStatusSignal, this, + &HarmonicCalibration::updateFaultStatus); + connect(this, &HarmonicCalibration::motorPositionChanged, this, + &HarmonicCalibration::updateMotorPosition); + + connect(this, &HarmonicCalibration::calibrationLogWriteSignal, this, + &HarmonicCalibration::calibrationLogWrite); + connect(this, &HarmonicCalibration::commandLogWriteSignal, this, + &HarmonicCalibration::commandLogWrite); + connect(this, &HarmonicCalibration::DIGIORegisterChanged, this, + &HarmonicCalibration::updateDIGIOUI); + connect(this, &HarmonicCalibration::FaultRegisterChanged, this, + &HarmonicCalibration::updateFaultRegisterUI); + connect(this, &HarmonicCalibration::DIAG1RegisterChanged, this, + &HarmonicCalibration::updateMTDiagnosticRegisterUI); + connect(this, &HarmonicCalibration::DIAG2RegisterChanged, this, + &HarmonicCalibration::updateMTDiagnosticsUI); + + startAcquisitionUITask(); + startDeviceStatusMonitor(); + startCurrentMotorPositionMonitor(); +} + +HarmonicCalibration::~HarmonicCalibration() { requestDisconnect(); } + +ToolTemplate *HarmonicCalibration::createAcquisitionWidget() { + tool = new ToolTemplate(this); + openLastMenuButton = new OpenLastMenuBtn( + dynamic_cast(tool->rightContainer()), true, this); + rightMenuButtonGroup = + dynamic_cast(openLastMenuButton)->getButtonGroup(); + + settingsButton = new GearBtn(this); + runButton = new RunBtn(this); + + QPushButton *resetGMRButton = new QPushButton(this); + resetGMRButton->setText("GMR Reset"); + Style::setStyle(resetGMRButton, style::properties::button::singleButton); + connect(resetGMRButton, &QPushButton::clicked, this, + &HarmonicCalibration::GMRReset); + + rightMenuButtonGroup->addButton(settingsButton); + +#pragma region Raw Data Widget + QScrollArea *rawDataScroll = new QScrollArea(this); + rawDataScroll->setWidgetResizable(true); + QWidget *rawDataWidget = new QWidget(rawDataScroll); + rawDataScroll->setWidget(rawDataWidget); + QVBoxLayout *rawDataLayout = new QVBoxLayout(rawDataWidget); + rawDataLayout->setMargin(0); + rawDataWidget->setLayout(rawDataLayout); + + MenuSectionWidget *rotationWidget = new MenuSectionWidget(rawDataWidget); + MenuSectionWidget *angleWidget = new MenuSectionWidget(rawDataWidget); + MenuSectionWidget *countWidget = new MenuSectionWidget(rawDataWidget); + MenuSectionWidget *tempWidget = new MenuSectionWidget(rawDataWidget); + Style::setStyle(rotationWidget, style::properties::widget::basicComponent); + Style::setStyle(angleWidget, style::properties::widget::basicComponent); + Style::setStyle(countWidget, style::properties::widget::basicComponent); + Style::setStyle(tempWidget, style::properties::widget::basicComponent); + MenuCollapseSection *rotationSection = new MenuCollapseSection( + "ABS Angle", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + rotationWidget); + MenuCollapseSection *angleSection = new MenuCollapseSection( + "Angle", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, angleWidget); + MenuCollapseSection *countSection = new MenuCollapseSection( + "Count", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, countWidget); + MenuCollapseSection *tempSection = new MenuCollapseSection( + "Temp 0", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, tempWidget); + rotationSection->contentLayout()->setSpacing(globalSpacingSmall); + angleSection->contentLayout()->setSpacing(globalSpacingSmall); + countSection->contentLayout()->setSpacing(globalSpacingSmall); + tempSection->contentLayout()->setSpacing(globalSpacingSmall); + + rotationWidget->contentLayout()->addWidget(rotationSection); + angleWidget->contentLayout()->addWidget(angleSection); + countWidget->contentLayout()->addWidget(countSection); + tempWidget->contentLayout()->addWidget(tempSection); + + rotationValueLabel = new QLabel("--.--°", rotationSection); + angleValueLabel = new QLabel("--.--°", angleSection); + countValueLabel = new QLabel("--", countSection); + tempValueLabel = new QLabel("--.-- °C", tempSection); + + rotationSection->contentLayout()->addWidget(rotationValueLabel); + angleSection->contentLayout()->addWidget(angleValueLabel); + countSection->contentLayout()->addWidget(countValueLabel); + tempSection->contentLayout()->addWidget(tempValueLabel); + +#pragma region Acquisition Motor Control Section Widget + MenuSectionWidget *motorControlSectionWidget = + new MenuSectionWidget(rawDataWidget); + Style::setStyle(motorControlSectionWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection( + "Motor Control", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + motorControlSectionWidget); + motorControlSectionWidget->contentLayout()->addWidget( + motorControlCollapseSection); + + QWidget *motorRPMWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); + motorRPMWidget->setLayout(motorRPMLayout); + motorRPMLayout->setMargin(0); + motorRPMLayout->setSpacing(0); + QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); + acquisitionMotorRPMLineEdit = + new QLineEdit(QString::number(motor_rpm), motorRPMWidget); + connectLineEditToRPM(acquisitionMotorRPMLineEdit, motor_rpm); + motorRPMLayout->addWidget(motorRPMLabel); + motorRPMLayout->addWidget(acquisitionMotorRPMLineEdit); + + QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); + currentPositionWidget->setLayout(currentPositionLayout); + currentPositionLayout->setMargin(0); + currentPositionLayout->setSpacing(0); + QLabel *currentPositionLabel = + new QLabel("Current Position", currentPositionWidget); + acquisitionMotorCurrentPositionLineEdit = + new QLineEdit("--.--", currentPositionWidget); + acquisitionMotorCurrentPositionLineEdit->setReadOnly(true); + connectLineEditToDouble(acquisitionMotorCurrentPositionLineEdit, current_pos); + currentPositionLayout->addWidget(currentPositionLabel); + currentPositionLayout->addWidget(acquisitionMotorCurrentPositionLineEdit); + + QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); + targetPositionWidget->setLayout(targetPositionLayout); + targetPositionLayout->setMargin(0); + targetPositionLayout->setSpacing(0); + QLabel *targetPositionLabel = + new QLabel("Target Position", targetPositionWidget); + motorTargetPositionLineEdit = + new QLineEdit(QString::number(target_pos), targetPositionWidget); + connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, + ADMTController::MotorAttribute::TARGET_POS); + targetPositionLayout->addWidget(targetPositionLabel); + targetPositionLayout->addWidget(motorTargetPositionLineEdit); + + QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); + motorDirectionWidget->setLayout(motorDirectionLayout); + motorDirectionLayout->setMargin(0); + motorDirectionLayout->setSpacing(0); + QLabel *motorDirectionLabel = + new QLabel("Rotation Direction", motorDirectionWidget); + acquisitionMotorDirectionSwitch = + new CustomSwitch("CW", "CCW", motorControlSectionWidget); + acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); + connect(acquisitionMotorDirectionSwitch, &CustomSwitch::toggled, this, + [this](bool b) { isMotorRotationClockwise = b; }); + motorDirectionLayout->addWidget(motorDirectionLabel); + motorDirectionLayout->addWidget(acquisitionMotorDirectionSwitch); + + QPushButton *continuousRotationButton = + new QPushButton("Continuous Rotation", motorControlSectionWidget); + StyleHelper::BasicButton(continuousRotationButton); + connect(continuousRotationButton, &QPushButton::clicked, this, + &HarmonicCalibration::moveMotorContinuous); + + QPushButton *stopMotorButton = + new QPushButton("Stop Motor", motorControlSectionWidget); + StyleHelper::BasicButton(stopMotorButton); + connect(stopMotorButton, &QPushButton::clicked, this, + &HarmonicCalibration::stopMotor); + + motorControlCollapseSection->contentLayout()->setSpacing(globalSpacingSmall); + motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); + motorControlCollapseSection->contentLayout()->addWidget( + currentPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); + motorControlCollapseSection->contentLayout()->addWidget( + continuousRotationButton); + motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); +#pragma endregion + + rawDataLayout->setSpacing(globalSpacingSmall); + rawDataLayout->addWidget(angleWidget); + rawDataLayout->addWidget(rotationWidget); + rawDataLayout->addWidget(countWidget); + rawDataLayout->addWidget(tempWidget); + rawDataLayout->addWidget(motorControlSectionWidget); + rawDataLayout->addStretch(); +#pragma endregion + +#pragma region Acquisition Graph Section Widget + MenuSectionWidget *acquisitionGraphSectionWidget = + new MenuSectionWidget(this); + Style::setStyle(acquisitionGraphSectionWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *acquisitionGraphCollapseSection = + new MenuCollapseSection( + "Captured Data", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + acquisitionGraphSectionWidget); + acquisitionGraphSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding); + acquisitionGraphSectionWidget->contentLayout()->addWidget( + acquisitionGraphCollapseSection); + acquisitionGraphCollapseSection->contentLayout()->setSpacing(8); + + acquisitionGraphPlotWidget = new PlotWidget(); + acquisitionGraphPlotWidget->setSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding); + + acquisitionXPlotAxis = new PlotAxis( + QwtAxis::XBottom, acquisitionGraphPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); + acquisitionYPlotAxis = new PlotAxis( + QwtAxis::YLeft, acquisitionGraphPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + acquisitionYPlotAxis->setInterval(0, 360); + + acquisitionAnglePlotChannel = new PlotChannel( + "Angle", channel0Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionABSAnglePlotChannel = new PlotChannel( + "ABS Angle", channel1Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTurnCountPlotChannel = new PlotChannel( + "Turn Count", channel2Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTmp0PlotChannel = new PlotChannel( + "TMP 0", channel3Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTmp1PlotChannel = new PlotChannel( + "TMP 1", channel4Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionSinePlotChannel = new PlotChannel( + "Sine", sinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionCosinePlotChannel = new PlotChannel( + "Cosine", cosinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionRadiusPlotChannel = new PlotChannel( + "Radius", channel5Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionSecAnglQPlotChannel = new PlotChannel( + "SECANGLQ", channel6Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionSecAnglIPlotChannel = new PlotChannel( + "SECANGLI", channel7Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + + acquisitionGraphPlotWidget->addPlotChannel(acquisitionAnglePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionABSAnglePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionTurnCountPlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp0PlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp1PlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionSinePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionCosinePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionRadiusPlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglQPlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglIPlotChannel); + acquisitionAnglePlotChannel->setEnabled(true); + acquisitionABSAnglePlotChannel->setEnabled(true); + acquisitionTurnCountPlotChannel->setEnabled(true); + acquisitionTmp0PlotChannel->setEnabled(true); + acquisitionTmp1PlotChannel->setEnabled(true); + acquisitionSinePlotChannel->setEnabled(true); + acquisitionCosinePlotChannel->setEnabled(true); + acquisitionRadiusPlotChannel->setEnabled(true); + acquisitionSecAnglQPlotChannel->setEnabled(true); + acquisitionSecAnglIPlotChannel->setEnabled(true); + acquisitionGraphPlotWidget->selectChannel(acquisitionAnglePlotChannel); + + acquisitionGraphPlotWidget->setShowXAxisLabels(true); + acquisitionGraphPlotWidget->setShowYAxisLabels(true); + acquisitionGraphPlotWidget->showAxisLabels(); + acquisitionGraphPlotWidget->replot(); + +#pragma region Channel Selection + QWidget *acquisitionGraphChannelWidget = + new QWidget(acquisitionGraphSectionWidget); + QGridLayout *acquisitionGraphChannelGridLayout = + new QGridLayout(acquisitionGraphChannelWidget); + acquisitionGraphChannelGridLayout->setContentsMargins(16, 8, 8, 16); + acquisitionGraphChannelGridLayout->setSpacing(8); + + QCheckBox *angleCheckBox = + new QCheckBox("Angle", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(angleCheckBox, channel0Pen.color()); + connectCheckBoxToAcquisitionGraph(angleCheckBox, acquisitionAnglePlotChannel, + ANGLE); + angleCheckBox->setChecked(true); + + QCheckBox *absAngleCheckBox = + new QCheckBox("ABS Angle", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(absAngleCheckBox, channel1Pen.color()); + connectCheckBoxToAcquisitionGraph(absAngleCheckBox, + acquisitionABSAnglePlotChannel, ABSANGLE); + + QCheckBox *temp0CheckBox = + new QCheckBox("Temp 0", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(temp0CheckBox, channel3Pen.color()); + connectCheckBoxToAcquisitionGraph(temp0CheckBox, acquisitionTmp0PlotChannel, + TMP0); + + QCheckBox *sineCheckBox = + new QCheckBox("Sine", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(sineCheckBox, sineColor); + connectCheckBoxToAcquisitionGraph(sineCheckBox, acquisitionSinePlotChannel, + SINE); + + QCheckBox *cosineCheckBox = + new QCheckBox("Cosine", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(cosineCheckBox, cosineColor); + connectCheckBoxToAcquisitionGraph(cosineCheckBox, + acquisitionCosinePlotChannel, COSINE); + + QCheckBox *radiusCheckBox = + new QCheckBox("Radius", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(radiusCheckBox, channel5Pen.color()); + connectCheckBoxToAcquisitionGraph(radiusCheckBox, + acquisitionRadiusPlotChannel, RADIUS); + + if (GENERALRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 + { + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); + } else if (GENERALRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 + { + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); + } +#pragma endregion + + acquisitionGraphCollapseSection->contentLayout()->addWidget( + acquisitionGraphPlotWidget); + acquisitionGraphCollapseSection->contentLayout()->addWidget( + acquisitionGraphChannelWidget); +#pragma endregion + +#pragma region General Setting + QScrollArea *generalSettingScroll = new QScrollArea(this); + generalSettingScroll->setWidgetResizable(true); + QWidget *generalSettingWidget = new QWidget(generalSettingScroll); + generalSettingScroll->setWidget(generalSettingWidget); + QVBoxLayout *generalSettingLayout = new QVBoxLayout(generalSettingWidget); + generalSettingLayout->setMargin(0); + generalSettingWidget->setLayout(generalSettingLayout); + + header = + new MenuHeaderWidget(deviceName + " " + deviceType, scopyBluePen, this); + Style::setStyle(header, style::properties::widget::basicComponent); + + // General Setting Widget + MenuSectionWidget *generalWidget = + new MenuSectionWidget(generalSettingWidget); + Style::setStyle(generalWidget, style::properties::widget::basicComponent); + MenuCollapseSection *generalSection = new MenuCollapseSection( + "Data Acquisition", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); + generalSection->header()->toggle(); + generalSection->contentLayout()->setSpacing(globalSpacingSmall); + generalWidget->contentLayout()->addWidget(generalSection); + + // Graph Update Interval + QWidget *graphUpdateIntervalWidget = new QWidget(generalSection); + QVBoxLayout *graphUpdateIntervalLayout = + new QVBoxLayout(graphUpdateIntervalWidget); + graphUpdateIntervalWidget->setLayout(graphUpdateIntervalLayout); + graphUpdateIntervalLayout->setMargin(0); + graphUpdateIntervalLayout->setSpacing(0); + QLabel *graphUpdateIntervalLabel = new QLabel(graphUpdateIntervalWidget); + graphUpdateIntervalLabel->setText("Graph Update Interval (ms)"); + graphUpdateIntervalLineEdit = new QLineEdit(graphUpdateIntervalWidget); + graphUpdateIntervalLineEdit->setText( + QString::number(acquisitionGraphSampleRate)); + connectLineEditToNumber(graphUpdateIntervalLineEdit, + acquisitionGraphSampleRate, 1, 5000); + graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLabel); + graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLineEdit); + + // Data Sample Size + QWidget *displayLengthWidget = new QWidget(generalSection); + QVBoxLayout *displayLengthLayout = new QVBoxLayout(displayLengthWidget); + displayLengthWidget->setLayout(displayLengthLayout); + displayLengthLayout->setMargin(0); + displayLengthLayout->setSpacing(0); + QLabel *displayLengthLabel = + new QLabel("Display Length", displayLengthWidget); + displayLengthLineEdit = new QLineEdit(displayLengthWidget); + displayLengthLineEdit->setText(QString::number(acquisitionDisplayLength)); + connectLineEditToNumber(displayLengthLineEdit, acquisitionDisplayLength, 1, + 2048); + displayLengthLayout->addWidget(displayLengthLabel); + displayLengthLayout->addWidget(displayLengthLineEdit); + + QPushButton *resetYAxisButton = + new QPushButton("Reset Y-Axis Scale", generalSection); + StyleHelper::BasicButton(resetYAxisButton); + connect(resetYAxisButton, &QPushButton::clicked, this, + &HarmonicCalibration::resetAcquisitionYAxisScale); + + generalSection->contentLayout()->addWidget(graphUpdateIntervalWidget); + generalSection->contentLayout()->addWidget(displayLengthWidget); + generalSection->contentLayout()->addWidget(resetYAxisButton); + + MenuSectionWidget *sequenceWidget = + new MenuSectionWidget(generalSettingWidget); + Style::setStyle(sequenceWidget, style::properties::widget::basicComponent); + MenuCollapseSection *sequenceSection = new MenuCollapseSection( + "Sequence", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + sequenceWidget); + sequenceWidget->contentLayout()->addWidget(sequenceSection); + sequenceSection->contentLayout()->setSpacing(globalSpacingSmall); + + sequenceTypeMenuCombo = new MenuCombo("Sequence Type", sequenceSection); + QComboBox *sequenceTypeComboBox = sequenceTypeMenuCombo->combo(); + sequenceTypeComboBox->addItem("Mode 1", QVariant(0)); + if (deviceType.toStdString() == "Automotive") { + sequenceTypeComboBox->addItem("Mode 2", QVariant(1)); + } + + conversionTypeMenuCombo = new MenuCombo("Conversion Type", sequenceSection); + QComboBox *conversionTypeComboBox = conversionTypeMenuCombo->combo(); + conversionTypeComboBox->addItem("Continuous conversions", QVariant(0)); + conversionTypeComboBox->addItem("One-shot conversion", QVariant(1)); + + convertSynchronizationMenuCombo = + new MenuCombo("Convert Synchronization", sequenceSection); + QComboBox *convertSynchronizationComboBox = + convertSynchronizationMenuCombo->combo(); + convertSynchronizationComboBox->addItem("Enabled", QVariant(1)); + convertSynchronizationComboBox->addItem("Disabled", QVariant(0)); + + angleFilterMenuCombo = new MenuCombo("Angle Filter", sequenceSection); + QComboBox *angleFilterComboBox = angleFilterMenuCombo->combo(); + angleFilterComboBox->addItem("Enabled", QVariant(1)); + angleFilterComboBox->addItem("Disabled", QVariant(0)); + + eighthHarmonicMenuCombo = new MenuCombo("8th Harmonic", sequenceSection); + QComboBox *eighthHarmonicComboBox = eighthHarmonicMenuCombo->combo(); + eighthHarmonicComboBox->addItem("User-Supplied Values", QVariant(1)); + eighthHarmonicComboBox->addItem("ADI Factory Values", QVariant(0)); + + updateSequenceWidget(); + + applySequenceButton = new QPushButton("Apply", sequenceSection); + StyleHelper::BasicButton(applySequenceButton); + connect(applySequenceButton, &QPushButton::clicked, this, + &HarmonicCalibration::applySequenceAndUpdate); + + sequenceSection->contentLayout()->addWidget(sequenceTypeMenuCombo); + sequenceSection->contentLayout()->addWidget(conversionTypeMenuCombo); + sequenceSection->contentLayout()->addWidget(convertSynchronizationMenuCombo); + sequenceSection->contentLayout()->addWidget(angleFilterMenuCombo); + sequenceSection->contentLayout()->addWidget(eighthHarmonicMenuCombo); + sequenceSection->contentLayout()->addWidget(applySequenceButton); + +#pragma region Device Status Widget + MenuSectionWidget *acquisitionDeviceStatusWidget = + new MenuSectionWidget(generalSettingWidget); + Style::setStyle(acquisitionDeviceStatusWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *acquisitionDeviceStatusSection = new MenuCollapseSection( + "Device Status", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); + acquisitionDeviceStatusSection->contentLayout()->setSpacing( + globalSpacingSmall); + acquisitionDeviceStatusWidget->contentLayout()->addWidget( + acquisitionDeviceStatusSection); + + acquisitionFaultRegisterLEDWidget = createStatusLEDWidget( + "Fault Register", "status", false, acquisitionDeviceStatusSection); + acquisitionDeviceStatusSection->contentLayout()->addWidget( + acquisitionFaultRegisterLEDWidget); + + if (deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == + 1) // Automotive & Sequence Mode 2 + { + QCheckBox *acquisitionSPICRCLEDWidget = createStatusLEDWidget( + "SPI CRC", "status", false, acquisitionDeviceStatusSection); + QCheckBox *acquisitionSPIFlagLEDWidget = createStatusLEDWidget( + "SPI Flag", "status", false, acquisitionDeviceStatusSection); + acquisitionDeviceStatusSection->contentLayout()->addWidget( + acquisitionSPICRCLEDWidget); + acquisitionDeviceStatusSection->contentLayout()->addWidget( + acquisitionSPIFlagLEDWidget); + } +#pragma endregion + + generalSettingLayout->setSpacing(globalSpacingSmall); + generalSettingLayout->addWidget(acquisitionDeviceStatusWidget); + generalSettingLayout->addWidget(header); + generalSettingLayout->addWidget(sequenceWidget); + generalSettingLayout->addWidget(generalWidget); + generalSettingLayout->addStretch(); +#pragma endregion + + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(true); + tool->leftContainer()->setVisible(true); + tool->rightContainer()->setVisible(true); + tool->bottomContainer()->setVisible(false); + tool->setLeftContainerWidth(210); + tool->setRightContainerWidth(300); + tool->setTopContainerHeight(100); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + tool->addWidgetToTopContainerMenuControlHelper(openLastMenuButton, TTA_RIGHT); + tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); + tool->addWidgetToTopContainerHelper(resetGMRButton, TTA_RIGHT); + tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); + tool->leftStack()->add("rawDataScroll", rawDataScroll); + tool->rightStack()->add("generalSettingScroll", generalSettingScroll); + tool->addWidgetToCentralContainerHelper(acquisitionGraphSectionWidget); + + connect(runButton, &QPushButton::toggled, this, + &HarmonicCalibration::setRunning); + connect(this, &HarmonicCalibration::runningChanged, this, + &HarmonicCalibration::run); + connect(this, &HarmonicCalibration::runningChanged, runButton, + &QAbstractButton::setChecked); + + return tool; +} + +ToolTemplate *HarmonicCalibration::createCalibrationWidget() { + ToolTemplate *tool = new ToolTemplate(this); + +#pragma region Calibration Data Graph Widget + QWidget *calibrationDataGraphWidget = new QWidget(); + QGridLayout *calibrationDataGraphLayout = + new QGridLayout(calibrationDataGraphWidget); + calibrationDataGraphWidget->setLayout(calibrationDataGraphLayout); + calibrationDataGraphLayout->setMargin(0); + calibrationDataGraphLayout->setSpacing(5); + + MenuSectionWidget *calibrationDataGraphSectionWidget = + new MenuSectionWidget(calibrationDataGraphWidget); + Style::setStyle(calibrationDataGraphSectionWidget, + style::properties::widget::basicComponent); + calibrationDataGraphTabWidget = + new QTabWidget(calibrationDataGraphSectionWidget); + calibrationDataGraphTabWidget->tabBar()->setStyleSheet( + "QTabBar::tab { width: 176px; }"); + calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); + calibrationDataGraphSectionWidget->contentLayout()->addWidget( + calibrationDataGraphTabWidget); + +#pragma region Calibration Samples + QWidget *calibrationSamplesWidget = + new QWidget(calibrationDataGraphTabWidget); + Style::setStyle(calibrationSamplesWidget, + style::properties::widget::basicBackground); + QVBoxLayout *calibrationSamplesLayout = + new QVBoxLayout(calibrationSamplesWidget); + calibrationSamplesWidget->setLayout(calibrationSamplesLayout); + calibrationSamplesLayout->setMargin(0); + calibrationSamplesLayout->setSpacing(0); + + calibrationRawDataPlotWidget = new PlotWidget(); + calibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); + + calibrationRawDataXPlotAxis = new PlotAxis( + QwtAxis::XBottom, calibrationRawDataPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + calibrationRawDataXPlotAxis->setMin(0); + calibrationRawDataYPlotAxis = new PlotAxis( + QwtAxis::YLeft, calibrationRawDataPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + calibrationRawDataYPlotAxis->setInterval(0, 360); + + calibrationRawDataPlotChannel = + new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, + calibrationRawDataYPlotAxis); + calibrationSineDataPlotChannel = + new PlotChannel("Sine", sinePen, calibrationRawDataXPlotAxis, + calibrationRawDataYPlotAxis); + calibrationCosineDataPlotChannel = + new PlotChannel("Cosine", cosinePen, calibrationRawDataXPlotAxis, + calibrationRawDataYPlotAxis); + + calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); + calibrationRawDataPlotWidget->addPlotChannel(calibrationSineDataPlotChannel); + calibrationRawDataPlotWidget->addPlotChannel( + calibrationCosineDataPlotChannel); + calibrationSineDataPlotChannel->setEnabled(true); + calibrationCosineDataPlotChannel->setEnabled(true); + calibrationRawDataPlotChannel->setEnabled(true); + calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); + + calibrationRawDataPlotWidget->setShowXAxisLabels(true); + calibrationRawDataPlotWidget->setShowYAxisLabels(true); + calibrationRawDataPlotWidget->showAxisLabels(); + calibrationRawDataPlotWidget->replot(); + + QWidget *calibrationDataGraphChannelsWidget = + new QWidget(calibrationDataGraphTabWidget); + ADMTStyleHelper::UIBackgroundStyle(calibrationDataGraphChannelsWidget); + QHBoxLayout *calibrationDataGraphChannelsLayout = + new QHBoxLayout(calibrationDataGraphChannelsWidget); + calibrationDataGraphChannelsWidget->setLayout( + calibrationDataGraphChannelsLayout); + calibrationDataGraphChannelsLayout->setContentsMargins(20, 13, 20, 5); + calibrationDataGraphChannelsLayout->setSpacing(20); + + MenuControlButton *toggleAngleButton = createChannelToggleWidget( + "Angle", scopyBlueColor, calibrationDataGraphChannelsWidget); + MenuControlButton *toggleSineButton = createChannelToggleWidget( + "Sine", sineColor, calibrationDataGraphChannelsWidget); + MenuControlButton *toggleCosineButton = createChannelToggleWidget( + "Cosine", cosineColor, calibrationDataGraphChannelsWidget); + + calibrationDataGraphChannelsLayout->addWidget(toggleAngleButton); + calibrationDataGraphChannelsLayout->addWidget(toggleSineButton); + calibrationDataGraphChannelsLayout->addWidget(toggleCosineButton); + calibrationDataGraphChannelsLayout->addStretch(); + + calibrationSamplesLayout->addWidget(calibrationRawDataPlotWidget); + calibrationSamplesLayout->addWidget(calibrationDataGraphChannelsWidget); +#pragma endregion + +#pragma region Post Calibration Samples + QWidget *postCalibrationSamplesWidget = + new QWidget(calibrationDataGraphTabWidget); + Style::setStyle(postCalibrationSamplesWidget, + style::properties::widget::basicBackground); + QVBoxLayout *postCalibrationSamplesLayout = + new QVBoxLayout(postCalibrationSamplesWidget); + postCalibrationSamplesWidget->setLayout(postCalibrationSamplesLayout); + postCalibrationSamplesLayout->setMargin(0); + postCalibrationSamplesLayout->setSpacing(0); + + postCalibrationRawDataPlotWidget = new PlotWidget(); + postCalibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); + + postCalibrationRawDataXPlotAxis = new PlotAxis( + QwtAxis::XBottom, postCalibrationRawDataPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + postCalibrationRawDataXPlotAxis->setMin(0); + postCalibrationRawDataYPlotAxis = new PlotAxis( + QwtAxis::YLeft, postCalibrationRawDataPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + postCalibrationRawDataYPlotAxis->setInterval(0, 360); + + postCalibrationRawDataPlotChannel = + new PlotChannel("Samples", scopyBluePen, postCalibrationRawDataXPlotAxis, + postCalibrationRawDataYPlotAxis); + postCalibrationSineDataPlotChannel = + new PlotChannel("Sine", sinePen, postCalibrationRawDataXPlotAxis, + postCalibrationRawDataYPlotAxis); + postCalibrationCosineDataPlotChannel = + new PlotChannel("Cosine", cosinePen, postCalibrationRawDataXPlotAxis, + postCalibrationRawDataYPlotAxis); + + postCalibrationRawDataPlotWidget->addPlotChannel( + postCalibrationRawDataPlotChannel); + postCalibrationRawDataPlotWidget->addPlotChannel( + postCalibrationSineDataPlotChannel); + postCalibrationRawDataPlotWidget->addPlotChannel( + postCalibrationCosineDataPlotChannel); + + postCalibrationSineDataPlotChannel->setEnabled(true); + postCalibrationCosineDataPlotChannel->setEnabled(true); + postCalibrationRawDataPlotChannel->setEnabled(true); + postCalibrationRawDataPlotWidget->selectChannel( + postCalibrationRawDataPlotChannel); + + postCalibrationRawDataPlotWidget->setShowXAxisLabels(true); + postCalibrationRawDataPlotWidget->setShowYAxisLabels(true); + postCalibrationRawDataPlotWidget->showAxisLabels(); + postCalibrationRawDataPlotWidget->replot(); + + QWidget *postCalibrationDataGraphChannelsWidget = + new QWidget(calibrationDataGraphTabWidget); + QHBoxLayout *postCalibrationDataGraphChannelsLayout = + new QHBoxLayout(postCalibrationDataGraphChannelsWidget); + ADMTStyleHelper::GraphChannelStyle(postCalibrationDataGraphChannelsWidget, + postCalibrationDataGraphChannelsLayout); + + MenuControlButton *togglePostAngleButton = createChannelToggleWidget( + "Angle", scopyBlueColor, postCalibrationDataGraphChannelsWidget); + MenuControlButton *togglePostSineButton = createChannelToggleWidget( + "Sine", sineColor, postCalibrationDataGraphChannelsWidget); + MenuControlButton *togglePostCosineButton = createChannelToggleWidget( + "Cosine", cosineColor, postCalibrationDataGraphChannelsWidget); + + postCalibrationDataGraphChannelsLayout->addWidget(togglePostAngleButton); + postCalibrationDataGraphChannelsLayout->addWidget(togglePostSineButton); + postCalibrationDataGraphChannelsLayout->addWidget(togglePostCosineButton); + postCalibrationDataGraphChannelsLayout->addStretch(); + + postCalibrationSamplesLayout->addWidget(postCalibrationRawDataPlotWidget); + postCalibrationSamplesLayout->addWidget( + postCalibrationDataGraphChannelsWidget); +#pragma endregion + + calibrationDataGraphTabWidget->addTab(calibrationSamplesWidget, + "Calibration Samples"); + calibrationDataGraphTabWidget->addTab(postCalibrationSamplesWidget, + "Post Calibration Samples"); + + MenuSectionWidget *resultDataSectionWidget = + new MenuSectionWidget(calibrationDataGraphWidget); + Style::setStyle(resultDataSectionWidget, + style::properties::widget::basicComponent); + resultDataTabWidget = new QTabWidget(resultDataSectionWidget); + resultDataTabWidget->tabBar()->setStyleSheet( + "QTabBar::tab { width: 160px; }"); + resultDataSectionWidget->contentLayout()->setSpacing(8); + resultDataSectionWidget->contentLayout()->addWidget(resultDataTabWidget); + + QColor magnitudeColor = Style::getColor(json::global::ch0); + QColor phaseColor = Style::getColor(json::global::ch1); + QPen magnitudePen = QPen(magnitudeColor); + QPen phasePen = QPen(phaseColor); + +#pragma region Angle Error Widget + QWidget *angleErrorWidget = new QWidget(); + Style::setStyle(angleErrorWidget, style::properties::widget::basicBackground); + QVBoxLayout *angleErrorLayout = new QVBoxLayout(angleErrorWidget); + angleErrorWidget->setLayout(angleErrorLayout); + angleErrorLayout->setMargin(0); + angleErrorLayout->setSpacing(0); + + angleErrorPlotWidget = new PlotWidget(); + angleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + angleErrorXPlotAxis = new PlotAxis( + QwtAxis::XBottom, angleErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + angleErrorXPlotAxis->setMin(0); + angleErrorYPlotAxis = new PlotAxis( + QwtAxis::YLeft, angleErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + angleErrorYPlotAxis->setInterval(-4, 4); + + angleErrorPlotChannel = new PlotChannel( + "Angle Error", scopyBluePen, angleErrorXPlotAxis, angleErrorYPlotAxis); + + angleErrorPlotWidget->addPlotChannel(angleErrorPlotChannel); + angleErrorPlotChannel->setEnabled(true); + angleErrorPlotWidget->selectChannel(angleErrorPlotChannel); + + angleErrorPlotWidget->setShowXAxisLabels(true); + angleErrorPlotWidget->setShowYAxisLabels(true); + angleErrorPlotWidget->showAxisLabels(); + angleErrorPlotWidget->replot(); + + angleErrorLayout->addWidget(angleErrorPlotWidget); +#pragma endregion + +#pragma region FFT Angle Error Widget + QWidget *FFTAngleErrorWidget = new QWidget(); + Style::setStyle(FFTAngleErrorWidget, + style::properties::widget::basicBackground); + QVBoxLayout *FFTAngleErrorLayout = new QVBoxLayout(FFTAngleErrorWidget); + FFTAngleErrorWidget->setLayout(FFTAngleErrorLayout); + FFTAngleErrorLayout->setMargin(0); + FFTAngleErrorLayout->setSpacing(0); + + FFTAngleErrorPlotWidget = new PlotWidget(); + FFTAngleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + + FFTAngleErrorXPlotAxis = new PlotAxis( + QwtAxis::XBottom, FFTAngleErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + FFTAngleErrorXPlotAxis->setMin(0); + FFTAngleErrorYPlotAxis = new PlotAxis( + QwtAxis::YLeft, FFTAngleErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + FFTAngleErrorYPlotAxis->setInterval(-4, 4); + + FFTAngleErrorMagnitudeChannel = + new PlotChannel("FFT Angle Error Magnitude", magnitudePen, + FFTAngleErrorXPlotAxis, FFTAngleErrorYPlotAxis); + FFTAngleErrorPhaseChannel = + new PlotChannel("FFT Angle Error Phase", phasePen, FFTAngleErrorXPlotAxis, + FFTAngleErrorYPlotAxis); + FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorMagnitudeChannel); + FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorPhaseChannel); + + FFTAngleErrorPhaseChannel->setEnabled(true); + FFTAngleErrorMagnitudeChannel->setEnabled(true); + FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); + + FFTAngleErrorPlotWidget->setShowXAxisLabels(true); + FFTAngleErrorPlotWidget->setShowYAxisLabels(true); + FFTAngleErrorPlotWidget->showAxisLabels(); + FFTAngleErrorPlotWidget->replot(); + + QWidget *FFTAngleErrorChannelsWidget = new QWidget(); + QHBoxLayout *FFTAngleErrorChannelsLayout = + new QHBoxLayout(FFTAngleErrorChannelsWidget); + ADMTStyleHelper::GraphChannelStyle(FFTAngleErrorChannelsWidget, + FFTAngleErrorChannelsLayout); + + MenuControlButton *toggleFFTAngleErrorMagnitudeButton = + createChannelToggleWidget("Magnitude", magnitudeColor, + FFTAngleErrorChannelsWidget); + MenuControlButton *toggleFFTAngleErrorPhaseButton = createChannelToggleWidget( + "Phase", phaseColor, FFTAngleErrorChannelsWidget); + + FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorMagnitudeButton); + FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorPhaseButton); + FFTAngleErrorChannelsLayout->addStretch(); + + FFTAngleErrorLayout->addWidget(FFTAngleErrorPlotWidget); + FFTAngleErrorLayout->addWidget(FFTAngleErrorChannelsWidget); +#pragma endregion + +#pragma region Corrected Error Widget + QWidget *correctedErrorWidget = new QWidget(); + Style::setStyle(correctedErrorWidget, + style::properties::widget::basicBackground); + QVBoxLayout *correctedErrorLayout = new QVBoxLayout(correctedErrorWidget); + correctedErrorWidget->setLayout(correctedErrorLayout); + correctedErrorLayout->setMargin(0); + correctedErrorLayout->setSpacing(0); + + correctedErrorPlotWidget = new PlotWidget(); + correctedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + + correctedErrorXPlotAxis = new PlotAxis( + QwtAxis::XBottom, correctedErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + correctedErrorXPlotAxis->setMin(0); + correctedErrorYPlotAxis = new PlotAxis( + QwtAxis::YLeft, correctedErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + correctedErrorYPlotAxis->setInterval(-4, 4); + + correctedErrorPlotChannel = + new PlotChannel("Corrected Error", scopyBluePen, correctedErrorXPlotAxis, + correctedErrorYPlotAxis); + correctedErrorPlotWidget->addPlotChannel(correctedErrorPlotChannel); + + correctedErrorPlotChannel->setEnabled(true); + correctedErrorPlotWidget->selectChannel(correctedErrorPlotChannel); + + correctedErrorPlotWidget->setShowXAxisLabels(true); + correctedErrorPlotWidget->setShowYAxisLabels(true); + correctedErrorPlotWidget->showAxisLabels(); + correctedErrorPlotWidget->replot(); + + correctedErrorLayout->addWidget(correctedErrorPlotWidget); +#pragma endregion + +#pragma region FFT Corrected Error Widget + QWidget *FFTCorrectedErrorWidget = new QWidget(); + Style::setStyle(FFTCorrectedErrorWidget, + style::properties::widget::basicBackground); + QVBoxLayout *FFTCorrectedErrorLayout = + new QVBoxLayout(FFTCorrectedErrorWidget); + FFTCorrectedErrorWidget->setLayout(FFTCorrectedErrorLayout); + FFTCorrectedErrorLayout->setMargin(0); + FFTCorrectedErrorLayout->setSpacing(0); + + FFTCorrectedErrorPlotWidget = new PlotWidget(); + FFTCorrectedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + + FFTCorrectedErrorXPlotAxis = new PlotAxis( + QwtAxis::XBottom, FFTCorrectedErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + FFTCorrectedErrorXPlotAxis->setMin(0); + FFTCorrectedErrorYPlotAxis = new PlotAxis( + QwtAxis::YLeft, FFTCorrectedErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + FFTCorrectedErrorYPlotAxis->setInterval(-4, 4); + + FFTCorrectedErrorMagnitudeChannel = + new PlotChannel("FFT Corrected Error Magnitude", magnitudePen, + FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); + FFTCorrectedErrorPhaseChannel = + new PlotChannel("FFT Corrected Error Phase", phasePen, + FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); + FFTCorrectedErrorPlotWidget->addPlotChannel( + FFTCorrectedErrorMagnitudeChannel); + FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorPhaseChannel); + + FFTCorrectedErrorPhaseChannel->setEnabled(true); + FFTCorrectedErrorMagnitudeChannel->setEnabled(true); + FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); + + FFTCorrectedErrorPlotWidget->setShowXAxisLabels(true); + FFTCorrectedErrorPlotWidget->setShowYAxisLabels(true); + FFTCorrectedErrorPlotWidget->showAxisLabels(); + FFTCorrectedErrorPlotWidget->replot(); + + QWidget *FFTCorrectedErrorChannelsWidget = new QWidget(); + QHBoxLayout *FFTCorrectedErrorChannelsLayout = + new QHBoxLayout(FFTCorrectedErrorChannelsWidget); + ADMTStyleHelper::GraphChannelStyle(FFTCorrectedErrorChannelsWidget, + FFTCorrectedErrorChannelsLayout); + + MenuControlButton *toggleFFTCorrectedErrorMagnitudeButton = + createChannelToggleWidget("Magnitude", magnitudeColor, + FFTCorrectedErrorChannelsWidget); + MenuControlButton *toggleFFTCorrectedErrorPhaseButton = + createChannelToggleWidget("Phase", phaseColor, + FFTCorrectedErrorChannelsWidget); + + FFTCorrectedErrorChannelsLayout->addWidget( + toggleFFTCorrectedErrorMagnitudeButton); + FFTCorrectedErrorChannelsLayout->addWidget( + toggleFFTCorrectedErrorPhaseButton); + FFTCorrectedErrorChannelsLayout->addStretch(); + + FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorPlotWidget); + FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorChannelsWidget); +#pragma endregion + + resultDataTabWidget->addTab(angleErrorWidget, "Angle Error"); + resultDataTabWidget->addTab(FFTAngleErrorWidget, "FFT Angle Error"); + resultDataTabWidget->addTab(correctedErrorWidget, "Corrected Error"); + resultDataTabWidget->addTab(FFTCorrectedErrorWidget, "FFT Corrected Error"); + + calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget, 0, + 0); + calibrationDataGraphLayout->addWidget(resultDataSectionWidget, 1, 0); + + calibrationDataGraphLayout->setColumnStretch(0, 1); + calibrationDataGraphLayout->setRowStretch(0, 1); + calibrationDataGraphLayout->setRowStretch(1, 1); +#pragma endregion + +#pragma region Calibration Settings Widget + QWidget *calibrationSettingsGroupWidget = new QWidget(); + QVBoxLayout *calibrationSettingsGroupLayout = + new QVBoxLayout(calibrationSettingsGroupWidget); + calibrationSettingsGroupWidget->setLayout(calibrationSettingsGroupLayout); + calibrationSettingsGroupLayout->setMargin(0); + calibrationSettingsGroupLayout->setSpacing(8); + +#pragma region Device Status Widget + MenuSectionWidget *calibrationDeviceStatusWidget = + new MenuSectionWidget(calibrationSettingsGroupWidget); + Style::setStyle(calibrationDeviceStatusWidget, + style::properties::widget::basicComponent); + calibrationDeviceStatusWidget->contentLayout()->setSpacing(8); + MenuCollapseSection *calibrationDeviceStatusSection = new MenuCollapseSection( + "Device Status", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + calibrationSettingsGroupWidget); + calibrationDeviceStatusSection->contentLayout()->setSpacing(8); + calibrationDeviceStatusWidget->contentLayout()->addWidget( + calibrationDeviceStatusSection); + + calibrationFaultRegisterLEDWidget = createStatusLEDWidget( + "Fault Register", "status", false, calibrationDeviceStatusSection); + calibrationDeviceStatusSection->contentLayout()->addWidget( + calibrationFaultRegisterLEDWidget); + + if (deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == + 1) // Automotive & Sequence Mode 2 + { + QCheckBox *calibrationSPICRCLEDWidget = createStatusLEDWidget( + "SPI CRC", "status", false, calibrationDeviceStatusSection); + QCheckBox *calibrationSPIFlagLEDWidget = createStatusLEDWidget( + "SPI Flag", "status", false, calibrationDeviceStatusSection); + calibrationDeviceStatusSection->contentLayout()->addWidget( + calibrationSPICRCLEDWidget); + calibrationDeviceStatusSection->contentLayout()->addWidget( + calibrationSPIFlagLEDWidget); + } +#pragma endregion + +#pragma region Acquire Calibration Samples Button + calibrationStartMotorButton = + new QPushButton(" Acquire Samples", calibrationSettingsGroupWidget); + Style::setStyle(calibrationStartMotorButton, + style::properties::admt::fullWidthRunButton); + calibrationStartMotorButton->setCheckable(true); + calibrationStartMotorButton->setChecked(false); + QIcon icon1; + icon1.addPixmap( + Style::getPixmap(":/gui/icons/play.svg", + Style::getColor(json::theme::content_inverse)), + QIcon::Normal, QIcon::Off); + icon1.addPixmap( + Style::getPixmap(":/gui/icons/" + + Style::getAttribute(json::theme::icon_theme_folder) + + "/icons/play_stop.svg", + Style::getColor(json::theme::content_inverse)), + QIcon::Normal, QIcon::On); + calibrationStartMotorButton->setIcon(icon1); + + connect(calibrationStartMotorButton, &QPushButton::toggled, this, + [this](bool toggled) { + calibrationStartMotorButton->setText(toggled ? " Stop Acquisition" + : " Acquire Samples"); + isStartMotor = toggled; + if (toggled) { + isPostCalibration = false; + startCalibration(); + } else { + stopCalibration(); + } + }); +#pragma endregion + +#pragma region Start Calibration Button + calibrateDataButton = + new QPushButton(" Calibrate", calibrationSettingsGroupWidget); + Style::setStyle(calibrateDataButton, + style::properties::admt::fullWidthRunButton); + calibrateDataButton->setCheckable(true); + calibrateDataButton->setChecked(false); + calibrateDataButton->setEnabled(false); + calibrateDataButton->setIcon(icon1); + + connect(calibrateDataButton, &QPushButton::toggled, this, [this](bool toggled) { + calibrateDataButton->setText(toggled ? " Stop Calibration" : " Calibrate"); + if (toggled) + postCalibrateData(); + else + stopCalibration(); + }); +#pragma endregion + +#pragma region Reset Calibration Button + clearCalibrateDataButton = + new QPushButton("Reset Calibration", calibrationSettingsGroupWidget); + StyleHelper::BasicButton(clearCalibrateDataButton); + QIcon resetIcon; + // resetIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/refresh.svg", + // "white", 1), QIcon::Normal, QIcon::Off); + resetIcon.addPixmap( + Style::getPixmap(":/gui/icons/refresh.svg", + Style::getColor(json::theme::content_inverse)), + QIcon::Normal, QIcon::Off); + clearCalibrateDataButton->setIcon(resetIcon); + clearCalibrateDataButton->setIconSize(QSize(26, 26)); +#pragma endregion + + QScrollArea *calibrationSettingsScrollArea = new QScrollArea(); + QWidget *calibrationSettingsWidget = + new QWidget(calibrationSettingsScrollArea); + QVBoxLayout *calibrationSettingsLayout = + new QVBoxLayout(calibrationSettingsWidget); + calibrationSettingsScrollArea->setWidgetResizable(true); + calibrationSettingsScrollArea->setWidget(calibrationSettingsWidget); + calibrationSettingsWidget->setFixedWidth(260); + calibrationSettingsWidget->setLayout(calibrationSettingsLayout); + + calibrationSettingsGroupLayout->addWidget(calibrationDeviceStatusWidget); + calibrationSettingsGroupLayout->addWidget(calibrationStartMotorButton); + calibrationSettingsGroupLayout->addWidget(calibrateDataButton); + calibrationSettingsGroupLayout->addWidget(clearCalibrateDataButton); + calibrationSettingsGroupLayout->addWidget(calibrationSettingsScrollArea); + +#pragma region Calibration Coefficient Section Widget + MenuSectionWidget *calibrationCoeffSectionWidget = + new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(calibrationCoeffSectionWidget, + style::properties::widget::basicComponent); + QLabel *calibrationDisplayFormatLabel = + new QLabel(calibrationCoeffSectionWidget); + calibrationDisplayFormatLabel->setText("Display Format"); + Style::setStyle(calibrationDisplayFormatLabel, + style::properties::label::menuMedium); + QLabel *calibrationCalculatedCoeffLabel = + new QLabel(calibrationCoeffSectionWidget); + calibrationCalculatedCoeffLabel->setText("Calculated Coefficients"); + Style::setStyle(calibrationCalculatedCoeffLabel, + style::properties::label::menuMedium); + + calibrationDisplayFormatSwitch = new CustomSwitch(); + calibrationDisplayFormatSwitch->setOffText("Hex"); + calibrationDisplayFormatSwitch->setOnText("Angle"); + calibrationDisplayFormatSwitch->setProperty("bigBtn", true); + + QWidget *calibrationCalculatedCoeffWidget = + new QWidget(calibrationCoeffSectionWidget); + QGridLayout *calibrationCalculatedCoeffLayout = + new QGridLayout(calibrationCalculatedCoeffWidget); + + calibrationCalculatedCoeffWidget->setLayout(calibrationCalculatedCoeffLayout); + calibrationCalculatedCoeffLayout->setMargin(0); + calibrationCalculatedCoeffLayout->setVerticalSpacing(4); + Style::setStyle(calibrationCalculatedCoeffWidget, + style::properties::widget::basicBackground); + + QWidget *h1RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h1RowLayout = new QHBoxLayout(h1RowContainer); + QLabel *calibrationH1Label = + new QLabel("H1", calibrationCalculatedCoeffWidget); + calibrationH1MagLabel = + new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH1PhaseLabel = + new QLabel("0x----", calibrationCalculatedCoeffWidget); + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle( + h1RowContainer, h1RowLayout, calibrationH1Label, calibrationH1MagLabel, + calibrationH1PhaseLabel); + + QWidget *h2RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h2RowLayout = new QHBoxLayout(h2RowContainer); + QLabel *calibrationH2Label = + new QLabel("H2", calibrationCalculatedCoeffWidget); + calibrationH2MagLabel = + new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH2PhaseLabel = + new QLabel("0x----", calibrationCalculatedCoeffWidget); + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle( + h2RowContainer, h2RowLayout, calibrationH2Label, calibrationH2MagLabel, + calibrationH2PhaseLabel); + + QWidget *h3RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h3RowLayout = new QHBoxLayout(h3RowContainer); + QLabel *calibrationH3Label = + new QLabel("H3", calibrationCalculatedCoeffWidget); + calibrationH3MagLabel = + new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH3PhaseLabel = + new QLabel("0x----", calibrationCalculatedCoeffWidget); + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle( + h3RowContainer, h3RowLayout, calibrationH3Label, calibrationH3MagLabel, + calibrationH3PhaseLabel); + + QWidget *h8RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h8RowLayout = new QHBoxLayout(h8RowContainer); + QLabel *calibrationH8Label = + new QLabel("H8", calibrationCalculatedCoeffWidget); + calibrationH8MagLabel = + new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH8PhaseLabel = + new QLabel("0x----", calibrationCalculatedCoeffWidget); + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle( + h8RowContainer, h8RowLayout, calibrationH8Label, calibrationH8MagLabel, + calibrationH8PhaseLabel); + + calibrationCalculatedCoeffLayout->addWidget(h1RowContainer, 0, 0); + calibrationCalculatedCoeffLayout->addWidget(h2RowContainer, 1, 0); + calibrationCalculatedCoeffLayout->addWidget(h3RowContainer, 2, 0); + calibrationCalculatedCoeffLayout->addWidget(h8RowContainer, 3, 0); + + calibrationCoeffSectionWidget->contentLayout()->setSpacing(8); + calibrationCoeffSectionWidget->contentLayout()->addWidget( + calibrationDisplayFormatLabel); + calibrationCoeffSectionWidget->contentLayout()->addWidget( + calibrationDisplayFormatSwitch); + calibrationCoeffSectionWidget->contentLayout()->addWidget( + calibrationCalculatedCoeffLabel); + calibrationCoeffSectionWidget->contentLayout()->addWidget( + calibrationCalculatedCoeffWidget); +#pragma endregion + +#pragma region Calibration Dataset Configuration + MenuSectionWidget *calibrationDatasetConfigSectionWidget = + new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(calibrationDatasetConfigSectionWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *calibrationDatasetConfigCollapseSection = + new MenuCollapseSection( + "Dataset Configuration", + MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + calibrationDatasetConfigSectionWidget); + calibrationDatasetConfigSectionWidget->contentLayout()->setSpacing(8); + calibrationDatasetConfigSectionWidget->contentLayout()->addWidget( + calibrationDatasetConfigCollapseSection); + +#pragma region Continuous Calibration Toggle + calibrationModeMenuCombo = new MenuCombo( + "Calibration Mode", calibrationDatasetConfigCollapseSection); + auto calibrationModeCombo = calibrationModeMenuCombo->combo(); + calibrationModeCombo->addItem("Continuous", QVariant(0)); + calibrationModeCombo->addItem("One Shot", QVariant(1)); + connectMenuComboToNumber(calibrationModeMenuCombo, calibrationMode); +#pragma endregion + + QWidget *calibrationCycleCountWidget = + new QWidget(calibrationDatasetConfigCollapseSection); + QVBoxLayout *calibrationCycleCountLayout = + new QVBoxLayout(calibrationCycleCountWidget); + calibrationCycleCountWidget->setLayout(calibrationCycleCountLayout); + calibrationCycleCountLayout->setMargin(0); + calibrationCycleCountLayout->setSpacing(0); + QLabel *calibrationCycleCountLabel = + new QLabel("Cycle Count", calibrationCycleCountWidget); + QLineEdit *calibrationCycleCountLineEdit = + new QLineEdit(calibrationCycleCountWidget); + calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); + connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 1000); + calibrationCycleCountLayout->addWidget(calibrationCycleCountLabel); + calibrationCycleCountLayout->addWidget(calibrationCycleCountLineEdit); + + QWidget *calibrationSamplesPerCycleWidget = + new QWidget(calibrationDatasetConfigCollapseSection); + QVBoxLayout *calibrationSamplesPerCycleLayout = + new QVBoxLayout(calibrationSamplesPerCycleWidget); + calibrationSamplesPerCycleWidget->setLayout(calibrationSamplesPerCycleLayout); + calibrationSamplesPerCycleLayout->setMargin(0); + calibrationSamplesPerCycleLayout->setSpacing(0); + QLabel *calibrationSamplesPerCycleLabel = + new QLabel("Samples Per Cycle", calibrationSamplesPerCycleWidget); + QLineEdit *calibrationSamplesPerCycleLineEdit = + new QLineEdit(calibrationSamplesPerCycleWidget); + calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); + connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, + 1, 5000); + calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLabel); + calibrationSamplesPerCycleLayout->addWidget( + calibrationSamplesPerCycleLineEdit); + + calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(8); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget( + calibrationModeMenuCombo); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget( + calibrationCycleCountWidget); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget( + calibrationSamplesPerCycleWidget); + +#pragma endregion + +#pragma region Calibration Data Section Widget + MenuSectionWidget *calibrationDataSectionWidget = + new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(calibrationDataSectionWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection( + "Calibration Data", + MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + calibrationDataSectionWidget); + calibrationDataSectionWidget->contentLayout()->setSpacing(8); + calibrationDataSectionWidget->contentLayout()->addWidget( + calibrationDataCollapseSection); + + QPushButton *importSamplesButton = + new QPushButton("Import Samples", calibrationDataCollapseSection); + QPushButton *extractDataButton = + new QPushButton("Save to CSV", calibrationDataCollapseSection); + StyleHelper::BasicButton(importSamplesButton); + StyleHelper::BasicButton(extractDataButton); + + calibrationDataCollapseSection->contentLayout()->setSpacing(8); + calibrationDataCollapseSection->contentLayout()->addWidget( + importSamplesButton); + calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); +#pragma endregion + +#pragma region Motor Control Section Widget + MenuSectionWidget *motorControlSectionWidget = + new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(motorControlSectionWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection( + "Motor Control", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + motorControlSectionWidget); + motorControlSectionWidget->contentLayout()->setSpacing(8); + motorControlSectionWidget->contentLayout()->addWidget( + motorControlCollapseSection); + + QWidget *motorRPMWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); + motorRPMWidget->setLayout(motorRPMLayout); + motorRPMLayout->setMargin(0); + motorRPMLayout->setSpacing(0); + QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); + calibrationMotorRPMLineEdit = + new QLineEdit(QString::number(motor_rpm), motorRPMWidget); + connectLineEditToRPM(calibrationMotorRPMLineEdit, motor_rpm); + motorRPMLayout->addWidget(motorRPMLabel); + motorRPMLayout->addWidget(calibrationMotorRPMLineEdit); + + QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); + currentPositionWidget->setLayout(currentPositionLayout); + currentPositionLayout->setMargin(0); + currentPositionLayout->setSpacing(0); + QLabel *currentPositionLabel = + new QLabel("Current Position", currentPositionWidget); + calibrationMotorCurrentPositionLineEdit = + new QLineEdit("--.--", currentPositionWidget); + calibrationMotorCurrentPositionLineEdit->setReadOnly(true); + connectLineEditToDouble(calibrationMotorCurrentPositionLineEdit, current_pos); + currentPositionLayout->addWidget(currentPositionLabel); + currentPositionLayout->addWidget(calibrationMotorCurrentPositionLineEdit); + + QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); + targetPositionWidget->setLayout(targetPositionLayout); + targetPositionLayout->setMargin(0); + targetPositionLayout->setSpacing(0); + QLabel *targetPositionLabel = + new QLabel("Target Position", targetPositionWidget); + motorTargetPositionLineEdit = + new QLineEdit(QString::number(target_pos), targetPositionWidget); + connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, + ADMTController::MotorAttribute::TARGET_POS); + targetPositionLayout->addWidget(targetPositionLabel); + targetPositionLayout->addWidget(motorTargetPositionLineEdit); + + QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); + motorDirectionWidget->setLayout(motorDirectionLayout); + motorDirectionLayout->setMargin(0); + motorDirectionLayout->setSpacing(0); + QLabel *motorDirectionLabel = + new QLabel("Rotation Direction", motorDirectionWidget); + calibrationMotorDirectionSwitch = + new CustomSwitch("CW", "CCW", motorControlSectionWidget); + calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); + connect(calibrationMotorDirectionSwitch, &CustomSwitch::toggled, this, + [this](bool b) { isMotorRotationClockwise = b; }); + motorDirectionLayout->addWidget(motorDirectionLabel); + motorDirectionLayout->addWidget(calibrationMotorDirectionSwitch); + + QPushButton *continuousRotationButton = + new QPushButton("Continuous Rotation", motorControlSectionWidget); + StyleHelper::BasicButton(continuousRotationButton); + connect(continuousRotationButton, &QPushButton::clicked, this, + &HarmonicCalibration::moveMotorContinuous); + + QPushButton *stopMotorButton = + new QPushButton("Stop Motor", motorControlSectionWidget); + StyleHelper::BasicButton(stopMotorButton); + connect(stopMotorButton, &QPushButton::clicked, this, + &HarmonicCalibration::stopMotor); + + motorControlCollapseSection->contentLayout()->setSpacing(8); + motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); + motorControlCollapseSection->contentLayout()->addWidget( + currentPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); + motorControlCollapseSection->contentLayout()->addWidget( + continuousRotationButton); + motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); +#pragma endregion + +#pragma region Logs Section Widget + MenuSectionWidget *logsSectionWidget = + new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(logsSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *logsCollapseSection = new MenuCollapseSection( + "Logs", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + logsSectionWidget); + logsCollapseSection->header()->toggle(); + logsSectionWidget->contentLayout()->setSpacing(8); + logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); + + logsPlainTextEdit = new QPlainTextEdit(logsSectionWidget); + logsPlainTextEdit->setReadOnly(true); + logsPlainTextEdit->setFixedHeight(320); + logsPlainTextEdit->setStyleSheet("QPlainTextEdit { border: none; }"); + + logsCollapseSection->contentLayout()->setSpacing(8); + logsCollapseSection->contentLayout()->addWidget(logsPlainTextEdit); +#pragma endregion + + calibrationSettingsLayout->setMargin(0); + calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); + calibrationSettingsLayout->addWidget(motorControlSectionWidget); + calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); + // calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); + calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); + calibrationSettingsLayout->addWidget(logsSectionWidget); + calibrationSettingsLayout->addSpacerItem( + new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); +#pragma endregion + + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(false); + tool->topContainerMenuControl()->setVisible(false); + tool->leftContainer()->setVisible(false); + tool->rightContainer()->setVisible(true); + tool->bottomContainer()->setVisible(false); + tool->setLeftContainerWidth(270); + tool->setRightContainerWidth(270); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + + tool->addWidgetToCentralContainerHelper(calibrationDataGraphWidget); + tool->rightStack()->add("calibrationSettingsGroupWidget", + calibrationSettingsGroupWidget); + + connect(extractDataButton, &QPushButton::clicked, this, + &HarmonicCalibration::extractCalibrationData); + connect(importSamplesButton, &QPushButton::clicked, this, + &HarmonicCalibration::importCalibrationData); + connect(clearCalibrateDataButton, &QPushButton::clicked, this, + &HarmonicCalibration::resetAllCalibrationState); + connect(toggleAngleButton->checkBox(), &QCheckBox::toggled, this, + [this](bool b) { + calibrationRawDataPlotWidget->selectChannel( + calibrationRawDataPlotChannel); + calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleSineButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + calibrationRawDataPlotWidget->selectChannel(calibrationSineDataPlotChannel); + calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleCosineButton->checkBox(), &QCheckBox::toggled, this, + [this](bool b) { + calibrationRawDataPlotWidget->selectChannel( + calibrationCosineDataPlotChannel); + calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(togglePostAngleButton->checkBox(), &QCheckBox::toggled, this, + [this](bool b) { + postCalibrationRawDataPlotWidget->selectChannel( + postCalibrationRawDataPlotChannel); + postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(togglePostSineButton->checkBox(), &QCheckBox::toggled, this, + [this](bool b) { + postCalibrationRawDataPlotWidget->selectChannel( + postCalibrationSineDataPlotChannel); + postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(togglePostCosineButton->checkBox(), &QCheckBox::toggled, this, + [this](bool b) { + postCalibrationRawDataPlotWidget->selectChannel( + postCalibrationCosineDataPlotChannel); + postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleFFTAngleErrorMagnitudeButton->checkBox(), &QCheckBox::toggled, + this, [this](bool b) { + FFTAngleErrorPlotWidget->selectChannel( + FFTAngleErrorMagnitudeChannel); + FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleFFTAngleErrorPhaseButton->checkBox(), &QCheckBox::toggled, this, + [this](bool b) { + FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorPhaseChannel); + FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleFFTCorrectedErrorMagnitudeButton->checkBox(), + &QCheckBox::toggled, this, [this](bool b) { + FFTCorrectedErrorPlotWidget->selectChannel( + FFTCorrectedErrorMagnitudeChannel); + FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleFFTCorrectedErrorPhaseButton->checkBox(), &QCheckBox::toggled, + this, [this](bool b) { + FFTCorrectedErrorPlotWidget->selectChannel( + FFTCorrectedErrorPhaseChannel); + FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(calibrationDisplayFormatSwitch, &CustomSwitch::toggled, this, + [this](bool b) { + isAngleDisplayFormat = b; + displayCalculatedCoeff(); + }); + + connect(&m_calibrationWaitVelocityWatcher, &QFutureWatcher::finished, + this, [this]() { + if (isMotorVelocityReached) { + startCalibrationStreamThread(); + } else { + startCurrentMotorPositionMonitor(); + startDeviceStatusMonitor(); + } + }); + + connect(&m_resetMotorToZeroWatcher, &QFutureWatcher::finished, this, + [this]() { startWaitForVelocityReachedThread(1); }); + + connect(&m_calibrationStreamWatcher, &QFutureWatcher::started, [this]() { + QThread *thread = QThread::currentThread(); + thread->setPriority(QThread::TimeCriticalPriority); + }); + + connect(&m_calibrationStreamWatcher, &QFutureWatcher::finished, this, + [this]() { + stopMotor(); + isStartMotor = false; + toggleTabSwitching(true); + toggleCalibrationControls(true); + + QString log = "Calibration Stream Timing: \n"; + for (auto &value : m_admtController->streamBufferedIntervals) { + log += QString::number(value) + "\n"; + } + Q_EMIT calibrationLogWriteSignal(log); + + if (isPostCalibration) { + graphPostDataList = m_admtController->streamBufferedValues; + postCalibrationRawDataPlotChannel->curve()->setSamples( + graphPostDataList); + postCalibrationRawDataPlotWidget->replot(); + if (static_cast(graphPostDataList.size()) == + totalSamplesCount) { + computeSineCosineOfAngles(graphPostDataList); + m_admtController->postcalibrate( + vector(graphPostDataList.begin(), + graphPostDataList.end()), + cycleCount, samplesPerCycle, !isMotorRotationClockwise); + populateCorrectedAngleErrorGraphs(); + isPostCalibration = false; + isStartMotor = false; + resetToZero = true; + toggleCalibrationButtonState(4); + } + } else { + graphDataList = m_admtController->streamBufferedValues; + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotWidget->replot(); + if (static_cast(graphDataList.size()) >= totalSamplesCount) { + computeSineCosineOfAngles(graphDataList); + calibrationLogWrite(m_admtController->calibrate( + vector(graphDataList.begin(), graphDataList.end()), + cycleCount, samplesPerCycle, !isMotorRotationClockwise)); + populateAngleErrorGraphs(); + calculateHarmonicValues(); + toggleCalibrationButtonState(2); + } else { + resetToZero = true; + toggleCalibrationButtonState(0); + } + } + + startCurrentMotorPositionMonitor(); + startDeviceStatusMonitor(); + }); + + return tool; +} + +ToolTemplate *HarmonicCalibration::createRegistersWidget() { + ToolTemplate *tool = new ToolTemplate(this); + + QScrollArea *registerScrollArea = new QScrollArea(); + QWidget *registerWidget = new QWidget(registerScrollArea); + registerWidget->setContentsMargins( + 0, 0, Style::getDimension(json::global::unit_0_5), 0); + QVBoxLayout *registerLayout = new QVBoxLayout(registerWidget); + registerScrollArea->setWidgetResizable(true); + registerScrollArea->setWidget(registerWidget); + registerWidget->setLayout(registerLayout); + registerLayout->setMargin(0); + registerLayout->setSpacing(globalSpacingSmall); + + MenuCollapseSection *registerConfigurationCollapseSection = + new MenuCollapseSection( + "Configuration", MenuCollapseSection::MHCW_ARROW, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + registerWidget); + QWidget *registerConfigurationGridWidget = new QWidget(registerWidget); + QGridLayout *registerConfigurationGridLayout = + new QGridLayout(registerConfigurationGridWidget); + registerConfigurationGridWidget->setLayout(registerConfigurationGridLayout); + registerConfigurationGridLayout->setMargin(0); + registerConfigurationGridLayout->setSpacing(globalSpacingSmall); + registerConfigurationCollapseSection->contentLayout()->addWidget( + registerConfigurationGridWidget); + + MenuCollapseSection *registerSensorDataCollapseSection = + new MenuCollapseSection( + "Sensor Data", MenuCollapseSection::MHCW_ARROW, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + registerWidget); + QWidget *registerSensorDataGridWidget = new QWidget(registerWidget); + QGridLayout *registerSensorDataGridLayout = + new QGridLayout(registerSensorDataGridWidget); + registerSensorDataGridWidget->setLayout(registerSensorDataGridLayout); + registerSensorDataGridLayout->setMargin(0); + registerSensorDataGridLayout->setSpacing(globalSpacingSmall); + registerSensorDataCollapseSection->contentLayout()->addWidget( + registerSensorDataGridWidget); + + MenuCollapseSection *registerDeviceIDCollapseSection = + new MenuCollapseSection( + "Device ID", MenuCollapseSection::MHCW_ARROW, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + registerWidget); + QWidget *registerDeviceIDGridWidget = new QWidget(registerWidget); + QGridLayout *registerDeviceIDGridLayout = + new QGridLayout(registerDeviceIDGridWidget); + registerDeviceIDGridWidget->setLayout(registerDeviceIDGridLayout); + registerDeviceIDGridLayout->setMargin(0); + registerDeviceIDGridLayout->setSpacing(globalSpacingSmall); + registerDeviceIDCollapseSection->contentLayout()->addWidget( + registerDeviceIDGridWidget); + + MenuCollapseSection *registerHarmonicsCollapseSection = + new MenuCollapseSection( + "Harmonics", MenuCollapseSection::MHCW_ARROW, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + registerWidget); + QWidget *registerHarmonicsGridWidget = new QWidget(registerWidget); + QGridLayout *registerHarmonicsGridLayout = + new QGridLayout(registerHarmonicsGridWidget); + registerHarmonicsGridWidget->setLayout(registerHarmonicsGridLayout); + registerHarmonicsGridLayout->setMargin(0); + registerHarmonicsGridLayout->setSpacing(globalSpacingSmall); + registerHarmonicsCollapseSection->contentLayout()->addWidget( + registerHarmonicsGridWidget); + + cnvPageRegisterBlock = new RegisterBlockWidget( + "CNVPAGE", "Convert Start and Page Select", + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::CNVPAGE), + m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::CNVPAGE), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + digIORegisterBlock = new RegisterBlockWidget( + "DIGIO", "Digital Input Output", + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::DIGIO), + m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::DIGIO), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + faultRegisterBlock = new RegisterBlockWidget( + "FAULT", "Fault Register", + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::FAULT), + m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::FAULT), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + generalRegisterBlock = new RegisterBlockWidget( + "GENERAL", "General Device Configuration", + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::GENERAL), + m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::GENERAL), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + digIOEnRegisterBlock = new RegisterBlockWidget( + "DIGIOEN", "Enable Digital Input/Outputs", + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::DIGIOEN), + m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::DIGIOEN), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + angleCkRegisterBlock = new RegisterBlockWidget( + "ANGLECK", "Primary vs Secondary Angle Check", + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::ANGLECK), + m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::ANGLECK), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + eccDcdeRegisterBlock = new RegisterBlockWidget( + "ECCDCDE", "Error Correction Codes", + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::ECCDCDE), + m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::ECCDCDE), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + eccDisRegisterBlock = new RegisterBlockWidget( + "ECCDIS", "Error Correction Code disable", + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::ECCDIS), + m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::ECCDIS), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + + absAngleRegisterBlock = new RegisterBlockWidget( + "ABSANGLE", "Absolute Angle", + m_admtController->getSensorRegister( + ADMTController::SensorRegister::ABSANGLE), + m_admtController->getSensorPage(ADMTController::SensorRegister::ABSANGLE), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + angleRegisterBlock = new RegisterBlockWidget( + "ANGLE", "Angle Register", + m_admtController->getSensorRegister( + ADMTController::SensorRegister::ANGLEREG), + m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLEREG), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + angleSecRegisterBlock = new RegisterBlockWidget( + "ANGLESEC", "Secondary Angle", + m_admtController->getSensorRegister( + ADMTController::SensorRegister::ANGLESEC), + m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLESEC), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + sineRegisterBlock = new RegisterBlockWidget( + "SINE", "Sine Measurement", + m_admtController->getSensorRegister(ADMTController::SensorRegister::SINE), + m_admtController->getSensorPage(ADMTController::SensorRegister::SINE), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + cosineRegisterBlock = new RegisterBlockWidget( + "COSINE", "Cosine Measurement", + m_admtController->getSensorRegister( + ADMTController::SensorRegister::COSINE), + m_admtController->getSensorPage(ADMTController::SensorRegister::COSINE), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + secAnglIRegisterBlock = new RegisterBlockWidget( + "SECANGLI", "In-phase secondary angle measurement", + m_admtController->getSensorRegister( + ADMTController::SensorRegister::SECANGLI), + m_admtController->getSensorPage(ADMTController::SensorRegister::SECANGLI), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + secAnglQRegisterBlock = new RegisterBlockWidget( + "SECANGLQ", "Quadrature phase secondary angle measurement", + m_admtController->getSensorRegister( + ADMTController::SensorRegister::SECANGLQ), + m_admtController->getSensorPage(ADMTController::SensorRegister::SECANGLQ), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + radiusRegisterBlock = new RegisterBlockWidget( + "RADIUS", "Angle measurement radius", + m_admtController->getSensorRegister( + ADMTController::SensorRegister::RADIUS), + m_admtController->getSensorPage(ADMTController::SensorRegister::RADIUS), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + diag1RegisterBlock = new RegisterBlockWidget( + "DIAG1", + "State of the MT reference resistors and AFE fixed input voltage", + m_admtController->getSensorRegister( + ADMTController::SensorRegister::DIAG1), + m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + diag2RegisterBlock = new RegisterBlockWidget( + "DIAG2", "Measurements of two diagnostics resistors of fixed value", + m_admtController->getSensorRegister( + ADMTController::SensorRegister::DIAG2), + m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + tmp0RegisterBlock = new RegisterBlockWidget( + "TMP0", "Primary Temperature Sensor", + m_admtController->getSensorRegister(ADMTController::SensorRegister::TMP0), + m_admtController->getSensorPage(ADMTController::SensorRegister::TMP0), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + tmp1RegisterBlock = new RegisterBlockWidget( + "TMP1", "Secondary Temperature Sensor", + m_admtController->getSensorRegister(ADMTController::SensorRegister::TMP1), + m_admtController->getSensorPage(ADMTController::SensorRegister::TMP1), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + cnvCntRegisterBlock = new RegisterBlockWidget( + "CNVCNT", "Conversion Count", + m_admtController->getSensorRegister( + ADMTController::SensorRegister::CNVCNT), + m_admtController->getSensorPage(ADMTController::SensorRegister::CNVCNT), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + + uniqID0RegisterBlock = new RegisterBlockWidget( + "UNIQID0", "Unique ID Register 0", + m_admtController->getUniqueIdRegister( + ADMTController::UniqueIDRegister::UNIQID0), + m_admtController->getUniqueIdPage( + ADMTController::UniqueIDRegister::UNIQID0), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID1RegisterBlock = new RegisterBlockWidget( + "UNIQID1", "Unique ID Register 1", + m_admtController->getUniqueIdRegister( + ADMTController::UniqueIDRegister::UNIQID1), + m_admtController->getUniqueIdPage( + ADMTController::UniqueIDRegister::UNIQID1), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID2RegisterBlock = new RegisterBlockWidget( + "UNIQID2", "Unique ID Register 2", + m_admtController->getUniqueIdRegister( + ADMTController::UniqueIDRegister::UNIQID2), + m_admtController->getUniqueIdPage( + ADMTController::UniqueIDRegister::UNIQID2), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID3RegisterBlock = new RegisterBlockWidget( + "UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", + m_admtController->getUniqueIdRegister( + ADMTController::UniqueIDRegister::UNIQID3), + m_admtController->getUniqueIdPage( + ADMTController::UniqueIDRegister::UNIQID3), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + + h1MagRegisterBlock = new RegisterBlockWidget( + "H1MAG", "1st Harmonic error magnitude", + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H1MAG), + m_admtController->getHarmonicPage( + ADMTController::HarmonicRegister::H1MAG), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h1PhRegisterBlock = new RegisterBlockWidget( + "H1PH", "1st Harmonic error phase", + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H1PH), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1PH), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h2MagRegisterBlock = new RegisterBlockWidget( + "H2MAG", "2nd Harmonic error magnitude", + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H2MAG), + m_admtController->getHarmonicPage( + ADMTController::HarmonicRegister::H2MAG), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h2PhRegisterBlock = new RegisterBlockWidget( + "H2PH", "2nd Harmonic error phase", + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H2PH), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H2PH), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h3MagRegisterBlock = new RegisterBlockWidget( + "H3MAG", "3rd Harmonic error magnitude", + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H3MAG), + m_admtController->getHarmonicPage( + ADMTController::HarmonicRegister::H3MAG), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h3PhRegisterBlock = new RegisterBlockWidget( + "H3PH", "3rd Harmonic error phase", + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H3PH), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H3PH), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h8MagRegisterBlock = new RegisterBlockWidget( + "H8MAG", "8th Harmonic error magnitude", + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H8MAG), + m_admtController->getHarmonicPage( + ADMTController::HarmonicRegister::H8MAG), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h8PhRegisterBlock = new RegisterBlockWidget( + "H8PH", "8th Harmonic error phase", + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H8PH), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H8PH), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + + registerConfigurationGridLayout->addWidget(cnvPageRegisterBlock, 0, 0); + registerConfigurationGridLayout->addWidget(digIORegisterBlock, 0, 1); + registerConfigurationGridLayout->addWidget(faultRegisterBlock, 0, 2); + registerConfigurationGridLayout->addWidget(generalRegisterBlock, 0, 3); + registerConfigurationGridLayout->addWidget(digIOEnRegisterBlock, 0, 4); + registerConfigurationGridLayout->addWidget(eccDcdeRegisterBlock, 1, 0); + registerConfigurationGridLayout->addWidget(eccDisRegisterBlock, 1, 1); + registerConfigurationGridLayout->addWidget(angleCkRegisterBlock, 1, 2); + + registerSensorDataGridLayout->addWidget(absAngleRegisterBlock, 0, 0); + registerSensorDataGridLayout->addWidget(angleRegisterBlock, 0, 1); + registerSensorDataGridLayout->addWidget(sineRegisterBlock, 0, 2); + registerSensorDataGridLayout->addWidget(cosineRegisterBlock, 0, 3); + registerSensorDataGridLayout->addWidget(cnvCntRegisterBlock, 0, 4); + registerSensorDataGridLayout->addWidget(tmp0RegisterBlock, 1, 0); + registerSensorDataGridLayout->addWidget(tmp1RegisterBlock, 1, 1); + registerSensorDataGridLayout->addWidget(diag1RegisterBlock, 1, 2); + registerSensorDataGridLayout->addWidget(diag2RegisterBlock, 1, 3); + registerSensorDataGridLayout->addWidget(radiusRegisterBlock, 1, 4); + registerSensorDataGridLayout->addWidget(angleSecRegisterBlock, 2, 0); + registerSensorDataGridLayout->addWidget(secAnglIRegisterBlock, 2, 1); + registerSensorDataGridLayout->addWidget(secAnglQRegisterBlock, 2, 2); + + registerDeviceIDGridLayout->addWidget(uniqID0RegisterBlock, 0, 0); + registerDeviceIDGridLayout->addWidget(uniqID1RegisterBlock, 0, 1); + registerDeviceIDGridLayout->addWidget(uniqID2RegisterBlock, 0, 2); + registerDeviceIDGridLayout->addWidget(uniqID3RegisterBlock, 0, 3); + QSpacerItem *registerDeviceSpacer = + new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred); + registerDeviceIDGridLayout->addItem(registerDeviceSpacer, 0, 4); + + registerHarmonicsGridLayout->addWidget(h1MagRegisterBlock, 0, 0); + registerHarmonicsGridLayout->addWidget(h1PhRegisterBlock, 0, 1); + registerHarmonicsGridLayout->addWidget(h2MagRegisterBlock, 0, 2); + registerHarmonicsGridLayout->addWidget(h2PhRegisterBlock, 0, 3); + registerHarmonicsGridLayout->addWidget(h3MagRegisterBlock, 0, 4); + registerHarmonicsGridLayout->addWidget(h3PhRegisterBlock, 1, 0); + registerHarmonicsGridLayout->addWidget(h8MagRegisterBlock, 1, 1); + registerHarmonicsGridLayout->addWidget(h8PhRegisterBlock, 1, 2); + + for (int c = 0; c < registerConfigurationGridLayout->columnCount(); ++c) + registerConfigurationGridLayout->setColumnStretch(c, 1); + for (int c = 0; c < registerDeviceIDGridLayout->columnCount(); ++c) + registerDeviceIDGridLayout->setColumnStretch(c, 1); + for (int c = 0; c < registerHarmonicsGridLayout->columnCount(); ++c) + registerHarmonicsGridLayout->setColumnStretch(c, 1); + for (int c = 0; c < registerSensorDataGridLayout->columnCount(); ++c) + registerSensorDataGridLayout->setColumnStretch(c, 1); + + QWidget *registerActionsWidget = new QWidget(registerWidget); + QHBoxLayout *registerActionsLayout = new QHBoxLayout(registerActionsWidget); + registerActionsWidget->setLayout(registerActionsLayout); + registerActionsLayout->setMargin(0); + registerActionsLayout->setSpacing(globalSpacingSmall); + readAllRegistersButton = + new QPushButton("Read All Registers", registerWidget); + StyleHelper::BasicButton(readAllRegistersButton); + readAllRegistersButton->setFixedWidth(270); + connect(readAllRegistersButton, &QPushButton::clicked, this, + &HarmonicCalibration::readAllRegisters); + registerActionsLayout->addWidget(readAllRegistersButton); + + registerLayout->addWidget(registerConfigurationCollapseSection); + registerLayout->addWidget(registerSensorDataCollapseSection); + registerLayout->addWidget(registerDeviceIDCollapseSection); + registerLayout->addWidget(registerHarmonicsCollapseSection); + registerLayout->addSpacerItem( + new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(true); + tool->topContainerMenuControl()->setVisible(false); + tool->leftContainer()->setVisible(false); + tool->rightContainer()->setVisible(false); + tool->bottomContainer()->setVisible(false); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + + tool->addWidgetToTopContainerHelper(registerActionsWidget, + ToolTemplateAlignment::TTA_LEFT); + tool->addWidgetToCentralContainerHelper(registerScrollArea); + + tool->layout()->setMargin(0); + tool->layout()->setContentsMargins( + globalSpacingSmall, globalSpacingSmall, + Style::getDimension(json::global::unit_0_5), globalSpacingSmall); + + connectRegisterBlockToRegistry(cnvPageRegisterBlock); + connectRegisterBlockToRegistry(digIORegisterBlock); + connectRegisterBlockToRegistry(faultRegisterBlock); + connectRegisterBlockToRegistry(generalRegisterBlock); + connectRegisterBlockToRegistry(digIOEnRegisterBlock); + connectRegisterBlockToRegistry(angleCkRegisterBlock); + connectRegisterBlockToRegistry(eccDcdeRegisterBlock); + connectRegisterBlockToRegistry(eccDisRegisterBlock); + + connectRegisterBlockToRegistry(absAngleRegisterBlock); + connectRegisterBlockToRegistry(angleRegisterBlock); + connectRegisterBlockToRegistry(angleSecRegisterBlock); + connectRegisterBlockToRegistry(sineRegisterBlock); + connectRegisterBlockToRegistry(cosineRegisterBlock); + connectRegisterBlockToRegistry(secAnglIRegisterBlock); + connectRegisterBlockToRegistry(secAnglQRegisterBlock); + connectRegisterBlockToRegistry(radiusRegisterBlock); + connectRegisterBlockToRegistry(diag1RegisterBlock); + connectRegisterBlockToRegistry(diag2RegisterBlock); + connectRegisterBlockToRegistry(tmp0RegisterBlock); + connectRegisterBlockToRegistry(tmp1RegisterBlock); + connectRegisterBlockToRegistry(cnvCntRegisterBlock); + + connectRegisterBlockToRegistry(uniqID0RegisterBlock); + connectRegisterBlockToRegistry(uniqID1RegisterBlock); + connectRegisterBlockToRegistry(uniqID2RegisterBlock); + connectRegisterBlockToRegistry(uniqID3RegisterBlock); + + connectRegisterBlockToRegistry(h1MagRegisterBlock); + connectRegisterBlockToRegistry(h1PhRegisterBlock); + connectRegisterBlockToRegistry(h2MagRegisterBlock); + connectRegisterBlockToRegistry(h2PhRegisterBlock); + connectRegisterBlockToRegistry(h3MagRegisterBlock); + connectRegisterBlockToRegistry(h3PhRegisterBlock); + connectRegisterBlockToRegistry(h8MagRegisterBlock); + connectRegisterBlockToRegistry(h8PhRegisterBlock); + + return tool; +} + +ToolTemplate *HarmonicCalibration::createUtilityWidget() { + ToolTemplate *tool = new ToolTemplate(this); + +#pragma region Left Utility Widget + QWidget *leftUtilityWidget = new QWidget(this); + QVBoxLayout *leftUtilityLayout = new QVBoxLayout(leftUtilityWidget); + leftUtilityWidget->setLayout(leftUtilityLayout); + leftUtilityLayout->setMargin(0); + leftUtilityLayout->setSpacing(8); +#pragma region Command Log Widget + MenuSectionWidget *commandLogSectionWidget = + new MenuSectionWidget(leftUtilityWidget); + Style::setStyle(commandLogSectionWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *commandLogCollapseSection = new MenuCollapseSection( + "Command Log", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + commandLogSectionWidget); + commandLogSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding); + commandLogSectionWidget->contentLayout()->addWidget( + commandLogCollapseSection); + commandLogCollapseSection->contentLayout()->setSpacing(8); + + commandLogPlainTextEdit = new QPlainTextEdit(commandLogSectionWidget); + commandLogPlainTextEdit->setReadOnly(true); + commandLogPlainTextEdit->setSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding); + commandLogPlainTextEdit->setStyleSheet("QPlainTextEdit { border: none; }"); + + clearCommandLogButton = + new QPushButton("Clear Command Logs", commandLogSectionWidget); + StyleHelper::BasicButton(clearCommandLogButton); + connect(clearCommandLogButton, &QPushButton::clicked, this, + &HarmonicCalibration::clearCommandLog); + + commandLogCollapseSection->contentLayout()->addWidget( + commandLogPlainTextEdit); + commandLogCollapseSection->contentLayout()->addWidget(clearCommandLogButton); + + leftUtilityLayout->addWidget(commandLogSectionWidget, 1); + leftUtilityLayout->addStretch(); +#pragma endregion +#pragma endregion + +#pragma region Center Utility Widget + QWidget *centerUtilityWidget = new QWidget(this); + QHBoxLayout *centerUtilityLayout = new QHBoxLayout(centerUtilityWidget); + centerUtilityWidget->setSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding); + centerUtilityWidget->setContentsMargins(2, 0, 2, 0); + centerUtilityWidget->setLayout(centerUtilityLayout); + centerUtilityLayout->setMargin(0); + centerUtilityLayout->setSpacing(8); + + QScrollArea *DIGIOScrollArea = new QScrollArea(centerUtilityWidget); + QWidget *DIGIOWidget = new QWidget(DIGIOScrollArea); + DIGIOScrollArea->setWidget(DIGIOWidget); + DIGIOScrollArea->setWidgetResizable(true); + QVBoxLayout *DIGIOLayout = new QVBoxLayout(DIGIOWidget); + DIGIOWidget->setLayout(DIGIOLayout); + DIGIOLayout->setMargin(0); + DIGIOLayout->setSpacing(8); + +#pragma region DIGIO Monitor + MenuSectionWidget *DIGIOMonitorSectionWidget = + new MenuSectionWidget(DIGIOWidget); + Style::setStyle(DIGIOMonitorSectionWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection( + "DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + DIGIOMonitorSectionWidget); + DIGIOMonitorSectionWidget->contentLayout()->addWidget( + DIGIOMonitorCollapseSection); + DIGIOMonitorCollapseSection->contentLayout()->setSpacing(8); + + DIGIOBusyStatusLED = createStatusLEDWidget("BUSY (Output)", "digio", false, + DIGIOMonitorCollapseSection); + DIGIOCNVStatusLED = createStatusLEDWidget("CNV (Input)", "digio", false, + DIGIOMonitorCollapseSection); + DIGIOSENTStatusLED = createStatusLEDWidget("SENT (Output)", "digio", false, + DIGIOMonitorCollapseSection); + DIGIOACALCStatusLED = createStatusLEDWidget("ACALC (Output)", "digio", false, + DIGIOMonitorCollapseSection); + DIGIOFaultStatusLED = createStatusLEDWidget("FAULT (Output)", "digio", false, + DIGIOMonitorCollapseSection); + DIGIOBootloaderStatusLED = createStatusLEDWidget( + "BOOTLOADER (Output)", "digio", false, DIGIOMonitorCollapseSection); + + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBusyStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOCNVStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOSENTStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOACALCStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOFaultStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget( + DIGIOBootloaderStatusLED); +#pragma endregion + +#pragma region DIGIO Control + MenuSectionWidget *DIGIOControlSectionWidget = + new MenuSectionWidget(DIGIOWidget); + Style::setStyle(DIGIOControlSectionWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *DIGIOControlCollapseSection = new MenuCollapseSection( + "DIGIO Control", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + DIGIOControlSectionWidget); + DIGIOControlCollapseSection->contentLayout()->setSpacing(8); + DIGIOControlSectionWidget->contentLayout()->addWidget( + DIGIOControlCollapseSection); + + QWidget *DIGIOControlGridWidget = new QWidget(DIGIOControlCollapseSection); + QGridLayout *DIGIOControlGridLayout = new QGridLayout(DIGIOControlGridWidget); + DIGIOControlGridWidget->setLayout(DIGIOControlGridLayout); + DIGIOControlGridLayout->setMargin(0); + DIGIOControlGridLayout->setSpacing(8); + + QLabel *DIGIO0Label = new QLabel("DIGIO0", DIGIOControlGridWidget); + QLabel *DIGIO1Label = new QLabel("DIGIO1", DIGIOControlGridWidget); + QLabel *DIGIO2Label = new QLabel("DIGIO2", DIGIOControlGridWidget); + QLabel *DIGIO3Label = new QLabel("DIGIO3", DIGIOControlGridWidget); + QLabel *DIGIO4Label = new QLabel("DIGIO4", DIGIOControlGridWidget); + QLabel *DIGIO5Label = new QLabel("DIGIO5", DIGIOControlGridWidget); + QLabel *DIGIOFunctionLabel = + new QLabel("DIGIO Function", DIGIOControlGridWidget); + QLabel *GPIOModeLabel = new QLabel("GPIO Mode", DIGIOControlGridWidget); + + DIGIO0ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Output", "Input"); + connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("DIGIO0EN", value); }); + + DIGIO0FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO0FNCToggleSwitch, "GPIO0", "BUSY"); + connect(DIGIO0FNCToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("BUSY", value); }); + + DIGIO1ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO1ENToggleSwitch, "Output", "Input"); + connect(DIGIO1ENToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("DIGIO1EN", value); }); + + DIGIO1FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO1FNCToggleSwitch, "GPIO1", "CNV"); + connect(DIGIO1FNCToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("CNV", value); }); + + DIGIO2ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO2ENToggleSwitch, "Output", "Input"); + connect(DIGIO2ENToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("DIGIO2EN", value); }); + + DIGIO2FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO2FNCToggleSwitch, "GPIO2", "SENT"); + connect(DIGIO2FNCToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("SENT", value); }); + + DIGIO3ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO3ENToggleSwitch, "Output", "Input"); + connect(DIGIO3ENToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("DIGIO3EN", value); }); + + DIGIO3FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO3FNCToggleSwitch, "GPIO3", "ACALC"); + connect(DIGIO3FNCToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("ACALC", value); }); + + DIGIO4ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO4ENToggleSwitch, "Output", "Input"); + connect(DIGIO4ENToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("DIGIO4EN", value); }); + + DIGIO4FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO4FNCToggleSwitch, "GPIO4", "FAULT"); + connect(DIGIO4FNCToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("FAULT", value); }); + + DIGIO5ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO5ENToggleSwitch, "Output", "Input"); + connect(DIGIO5ENToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("DIGIO5EN", value); }); + + DIGIO5FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO5FNCToggleSwitch, "GPIO5", "BOOT"); + connect(DIGIO5FNCToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("BOOTLOAD", value); }); + + QPushButton *DIGIOResetButton = + new QPushButton("Reset DIGIO", DIGIOControlGridWidget); + DIGIOResetButton->setFixedWidth(100); + StyleHelper::BasicButton(DIGIOResetButton); + connect(DIGIOResetButton, &QPushButton::clicked, [this] { + toggleUtilityTask(false); + resetDIGIO(); + toggleUtilityTask(true); + }); + + DIGIOControlGridLayout->addWidget(DIGIOFunctionLabel, 0, 1); + DIGIOControlGridLayout->addWidget(GPIOModeLabel, 0, 2); + + DIGIOControlGridLayout->addWidget(DIGIO0Label, 1, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO0FNCToggleSwitch, 1, 1); + DIGIOControlGridLayout->addWidget(DIGIO0ENToggleSwitch, 1, 2); + + DIGIOControlGridLayout->addWidget(DIGIO1Label, 2, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO1FNCToggleSwitch, 2, 1); + DIGIOControlGridLayout->addWidget(DIGIO1ENToggleSwitch, 2, 2); + + DIGIOControlGridLayout->addWidget(DIGIO2Label, 3, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO2FNCToggleSwitch, 3, 1); + DIGIOControlGridLayout->addWidget(DIGIO2ENToggleSwitch, 3, 2); + + DIGIOControlGridLayout->addWidget(DIGIO3Label, 4, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO3FNCToggleSwitch, 4, 1); + DIGIOControlGridLayout->addWidget(DIGIO3ENToggleSwitch, 4, 2); + + DIGIOControlGridLayout->addWidget(DIGIO4Label, 5, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO4FNCToggleSwitch, 5, 1); + DIGIOControlGridLayout->addWidget(DIGIO4ENToggleSwitch, 5, 2); + + DIGIOControlGridLayout->addWidget(DIGIO5Label, 6, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO5FNCToggleSwitch, 6, 1); + DIGIOControlGridLayout->addWidget(DIGIO5ENToggleSwitch, 6, 2); + + DIGIOControlGridLayout->setColumnStretch(0, 1); + + DIGIOControlCollapseSection->contentLayout()->addWidget( + DIGIOControlGridWidget); + DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOResetButton); + + if (GENERALRegisterMap.at("Sequence Type") == 0) { + DIGIO2FNCToggleSwitch->setVisible(false); + DIGIO4FNCToggleSwitch->setVisible(false); + } + +#pragma endregion + + DIGIOLayout->addWidget(DIGIOMonitorSectionWidget); + DIGIOLayout->addWidget(DIGIOControlSectionWidget); + DIGIOLayout->addStretch(); + +#pragma region MTDIAG1 Widget + MenuSectionWidget *MTDIAG1SectionWidget = + new MenuSectionWidget(centerUtilityWidget); + Style::setStyle(MTDIAG1SectionWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *MTDIAG1CollapseSection = new MenuCollapseSection( + "MT Diagnostic Register", + MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + MTDIAG1SectionWidget); + MTDIAG1SectionWidget->contentLayout()->addWidget(MTDIAG1CollapseSection); + MTDIAG1CollapseSection->contentLayout()->setSpacing(8); + + R0StatusLED = + createStatusLEDWidget("R0", "mtdiag", false, MTDIAG1SectionWidget); + R1StatusLED = + createStatusLEDWidget("R1", "mtdiag", false, MTDIAG1SectionWidget); + R2StatusLED = + createStatusLEDWidget("R2", "mtdiag", false, MTDIAG1SectionWidget); + R3StatusLED = + createStatusLEDWidget("R3", "mtdiag", false, MTDIAG1SectionWidget); + R4StatusLED = + createStatusLEDWidget("R4", "mtdiag", false, MTDIAG1SectionWidget); + R5StatusLED = + createStatusLEDWidget("R5", "mtdiag", false, MTDIAG1SectionWidget); + R6StatusLED = + createStatusLEDWidget("R6", "mtdiag", false, MTDIAG1SectionWidget); + R7StatusLED = + createStatusLEDWidget("R7", "mtdiag", false, MTDIAG1SectionWidget); + + MTDIAG1CollapseSection->contentLayout()->addWidget(R0StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R1StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R2StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R3StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R4StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R5StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R6StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R7StatusLED); +#pragma endregion + +#pragma region MT Diagnostics + MTDiagnosticsScrollArea = new QScrollArea(centerUtilityWidget); + QWidget *MTDiagnosticsWidget = new QWidget(MTDiagnosticsScrollArea); + MTDiagnosticsScrollArea->setWidget(MTDiagnosticsWidget); + MTDiagnosticsScrollArea->setWidgetResizable(true); + QVBoxLayout *MTDiagnosticsLayout = new QVBoxLayout(MTDiagnosticsWidget); + MTDiagnosticsWidget->setLayout(MTDiagnosticsLayout); + MTDiagnosticsLayout->setMargin(0); + MTDiagnosticsLayout->setSpacing(8); + + MenuSectionWidget *MTDiagnosticsSectionWidget = + new MenuSectionWidget(centerUtilityWidget); + Style::setStyle(MTDiagnosticsSectionWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *MTDiagnosticsCollapseSection = new MenuCollapseSection( + "MT Diagnostics", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + MTDiagnosticsSectionWidget); + MTDiagnosticsSectionWidget->contentLayout()->addWidget( + MTDiagnosticsCollapseSection); + MTDiagnosticsCollapseSection->contentLayout()->setSpacing(8); + + QLabel *AFEDIAG0Label = new QLabel("AFEDIAG0 (%)"); + Style::setStyle(AFEDIAG0Label, style::properties::label::menuSmall); + QLabel *AFEDIAG1Label = new QLabel("AFEDIAG1 (%)"); + Style::setStyle(AFEDIAG1Label, style::properties::label::menuSmall); + QLabel *AFEDIAG2Label = new QLabel("AFEDIAG2 (V)"); + Style::setStyle(AFEDIAG2Label, style::properties::label::menuSmall); + + AFEDIAG0LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); + AFEDIAG1LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); + AFEDIAG2LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); + AFEDIAG0LineEdit->setReadOnly(true); + AFEDIAG1LineEdit->setReadOnly(true); + AFEDIAG2LineEdit->setReadOnly(true); + connectLineEditToNumber(AFEDIAG0LineEdit, afeDiag0, "V"); + connectLineEditToNumber(AFEDIAG1LineEdit, afeDiag1, "V"); + connectLineEditToNumber(AFEDIAG2LineEdit, afeDiag2, "V"); + + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0Label); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0LineEdit); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1Label); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1LineEdit); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2Label); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2LineEdit); + + MTDiagnosticsLayout->addWidget(MTDiagnosticsSectionWidget); + MTDiagnosticsLayout->addWidget(MTDIAG1SectionWidget); + MTDiagnosticsLayout->addStretch(); +#pragma endregion + + centerUtilityLayout->addWidget(DIGIOScrollArea); + centerUtilityLayout->addWidget(MTDiagnosticsScrollArea); + +#pragma endregion + +#pragma region Right Utility Widget + QScrollArea *rightUtilityScrollArea = new QScrollArea(this); + QWidget *rightUtilityWidget = new QWidget(rightUtilityScrollArea); + rightUtilityScrollArea->setWidget(rightUtilityWidget); + rightUtilityScrollArea->setWidgetResizable(true); + QVBoxLayout *rightUtilityLayout = new QVBoxLayout(rightUtilityWidget); + rightUtilityWidget->setLayout(rightUtilityLayout); + rightUtilityLayout->setMargin(0); + rightUtilityLayout->setSpacing(8); + + MenuSectionWidget *faultRegisterSectionWidget = + new MenuSectionWidget(rightUtilityWidget); + Style::setStyle(faultRegisterSectionWidget, + style::properties::widget::basicComponent); + MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection( + "Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, + faultRegisterSectionWidget); + faultRegisterSectionWidget->contentLayout()->addWidget( + faultRegisterCollapseSection); + faultRegisterCollapseSection->contentLayout()->setSpacing(8); + + VDDUnderVoltageStatusLED = createStatusLEDWidget( + "VDD Under Voltage", "fault", false, faultRegisterCollapseSection); + VDDOverVoltageStatusLED = createStatusLEDWidget( + "VDD Over Voltage", "fault", false, faultRegisterCollapseSection); + VDRIVEUnderVoltageStatusLED = createStatusLEDWidget( + "VDRIVE Under Voltage", "fault", false, faultRegisterCollapseSection); + VDRIVEOverVoltageStatusLED = createStatusLEDWidget( + "VDRIVE Over Voltage", "fault", false, faultRegisterCollapseSection); + AFEDIAGStatusLED = createStatusLEDWidget("AFEDIAG", "fault", false, + faultRegisterCollapseSection); + NVMCRCFaultStatusLED = createStatusLEDWidget("NVM CRC Fault", "fault", false, + faultRegisterCollapseSection); + ECCDoubleBitErrorStatusLED = createStatusLEDWidget( + "ECC Double Bit Error", "fault", false, faultRegisterCollapseSection); + OscillatorDriftStatusLED = createStatusLEDWidget( + "Oscillator Drift", "fault", false, faultRegisterCollapseSection); + CountSensorFalseStateStatusLED = createStatusLEDWidget( + "Count Sensor False State", "fault", false, faultRegisterCollapseSection); + AngleCrossCheckStatusLED = createStatusLEDWidget( + "Angle Cross Check", "fault", false, faultRegisterCollapseSection); + TurnCountSensorLevelsStatusLED = createStatusLEDWidget( + "Turn Count Sensor Levels", "fault", false, faultRegisterCollapseSection); + MTDIAGStatusLED = createStatusLEDWidget("MTDIAG", "fault", false, + faultRegisterCollapseSection); + TurnCounterCrossCheckStatusLED = createStatusLEDWidget( + "Turn Counter Cross Check", "fault", false, faultRegisterCollapseSection); + RadiusCheckStatusLED = createStatusLEDWidget("Radius Check", "fault", false, + faultRegisterCollapseSection); + SequencerWatchdogStatusLED = createStatusLEDWidget( + "Sequencer Watchdog", "fault", false, faultRegisterCollapseSection); + + faultRegisterCollapseSection->contentLayout()->addWidget( + VDDUnderVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + VDDOverVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + VDRIVEUnderVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + VDRIVEOverVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(AFEDIAGStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + NVMCRCFaultStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + ECCDoubleBitErrorStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + OscillatorDriftStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + CountSensorFalseStateStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + AngleCrossCheckStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + TurnCountSensorLevelsStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(MTDIAGStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + TurnCounterCrossCheckStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + RadiusCheckStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget( + SequencerWatchdogStatusLED); + + rightUtilityLayout->addWidget(faultRegisterSectionWidget); + rightUtilityLayout->addSpacerItem( + new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); +#pragma endregion + + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(false); + tool->topContainerMenuControl()->setVisible(false); + tool->leftContainer()->setVisible(true); + tool->rightContainer()->setVisible(true); + tool->bottomContainer()->setVisible(false); + tool->setLeftContainerWidth(240); + tool->setRightContainerWidth(224); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + + tool->leftStack()->addWidget(leftUtilityWidget); + tool->addWidgetToCentralContainerHelper(centerUtilityWidget); + tool->rightStack()->addWidget(rightUtilityScrollArea); + + return tool; +} + +void HarmonicCalibration::readDeviceProperties() { + uint32_t *uniqId3RegisterValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t page = m_admtController->getUniqueIdPage( + ADMTController::UniqueIDRegister::UNIQID3); + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::CNVPAGE); + + bool success = false; + + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, page) != -1) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) != -1) { + if (*cnvPageRegValue == page) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getUniqueIdRegister( + ADMTController::UniqueIDRegister::UNIQID3), + uniqId3RegisterValue) != -1) { + deviceRegisterMap = m_admtController->getUNIQID3RegisterMapping( + static_cast(*uniqId3RegisterValue)); + + if (deviceRegisterMap.at("Supply ID") == "5V") { + is5V = true; + } else if (deviceRegisterMap.at("Supply ID") == "3.3V") { + is5V = false; + } else { + is5V = false; + } + + deviceName = + QString::fromStdString(deviceRegisterMap.at("Product ID")); + + if (deviceRegisterMap.at("ASIL ID") == "ASIL QM") { + deviceType = QString::fromStdString("Industrial"); + } else if (deviceRegisterMap.at("ASIL ID") == "ASIL B") { + deviceType = QString::fromStdString("Automotive"); + } else { + deviceType = + QString::fromStdString(deviceRegisterMap.at("ASIL ID")); + } + + success = true; + } + } + } + } + + if (!success) { + StatusBarManager::pushMessage("Failed to read device properties"); + } +} + +void HarmonicCalibration::initializeADMT() { + bool success = resetDIGIO(); + success = resetGENERAL(); + + if (!success) { + StatusBarManager::pushMessage("Failed initialize ADMT"); + } +} + +bool HarmonicCalibration::readSequence() { + uint32_t *generalRegValue = new uint32_t; + uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::GENERAL); + uint32_t generalRegisterPage = m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::GENERAL); + + bool success = false; + + if (changeCNVPage(generalRegisterPage)) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + generalRegisterAddress, generalRegValue) != -1) { + if (*generalRegValue != UINT32_MAX) { + GENERALRegisterMap = m_admtController->getGeneralRegisterBitMapping( + static_cast(*generalRegValue)); + success = true; + } + } + } + + return success; +} + +bool HarmonicCalibration::writeSequence(const map &settings) { + uint32_t *generalRegValue = new uint32_t; + uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::GENERAL); + + bool success = false; + + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + generalRegisterAddress, generalRegValue) != -1) { + + uint32_t newGeneralRegValue = + m_admtController->setGeneralRegisterBitMapping(*generalRegValue, + settings); + uint32_t generalRegisterPage = m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::GENERAL); + + if (changeCNVPage(generalRegisterPage)) { + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + generalRegisterAddress, newGeneralRegValue) != -1) { + if (readSequence()) { + if (settings.at("Convert Synchronization") == + GENERALRegisterMap.at("Convert Synchronization") && + settings.at("Angle Filter") == + GENERALRegisterMap.at("Angle Filter") && + settings.at("8th Harmonic") == + GENERALRegisterMap.at("8th Harmonic") && + settings.at("Sequence Type") == + GENERALRegisterMap.at("Sequence Type") && + settings.at("Conversion Type") == + GENERALRegisterMap.at("Conversion Type")) { + success = true; + } + } + } + } + } + + return success; +} + +void HarmonicCalibration::applySequence() { + toggleWidget(applySequenceButton, false); + applySequenceButton->setText("Writing..."); + QTimer::singleShot(1000, this, [this]() { + this->toggleWidget(applySequenceButton, true); + applySequenceButton->setText("Apply"); + }); + uint32_t *generalRegValue = new uint32_t; + uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::GENERAL); + map settings; + + bool success = false; + + settings["Sequence Type"] = qvariant_cast( + sequenceTypeMenuCombo->combo()->currentData()); // sequenceType; + settings["Conversion Type"] = qvariant_cast( + conversionTypeMenuCombo->combo()->currentData()); // conversionType; + settings["Convert Synchronization"] = qvariant_cast( + convertSynchronizationMenuCombo->combo()->currentData()); // convertSync; + settings["Angle Filter"] = qvariant_cast( + angleFilterMenuCombo->combo()->currentData()); // angleFilter; + settings["8th Harmonic"] = qvariant_cast( + eighthHarmonicMenuCombo->combo()->currentData()); // eighthHarmonic; + + success = writeSequence(settings); + if (!success) + StatusBarManager::pushMessage("Failed to apply sequence settings"); + else + StatusBarManager::pushMessage("Sequence settings applied successfully"); +} + +bool HarmonicCalibration::changeCNVPage(uint32_t page) { + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::CNVPAGE); + + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, page) != -1) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) != -1) { + if (*cnvPageRegValue == page) { + return true; + } + } + } + + return false; +} + +void HarmonicCalibration::initializeMotor() { + motor_rpm = 60; + rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(motor_rpm)); + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, + rotate_vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + + amax = convertAccelTimetoAMAX(motorAccelTime); + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + + dmax = 3000; + writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); + + ramp_mode = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, + ramp_mode); + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + + target_pos = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, + target_pos); + + current_pos = 0; + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, + current_pos); +} + +void HarmonicCalibration::startDeviceStatusMonitor() { + if (!m_deviceStatusThread.isRunning()) { + isDeviceStatusMonitor = true; + m_deviceStatusThread = + QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, + deviceStatusMonitorRate); + m_deviceStatusWatcher.setFuture(m_deviceStatusThread); + } +} + +void HarmonicCalibration::stopDeviceStatusMonitor() { + isDeviceStatusMonitor = false; + if (m_deviceStatusThread.isRunning()) { + m_deviceStatusThread.cancel(); + m_deviceStatusWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) { + uint32_t *readValue = new uint32_t; + bool registerFault = false; + while (isDeviceStatusMonitor) { + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::FAULT), + 0) == 0) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::FAULT), + readValue) == 0) { + registerFault = m_admtController->checkRegisterFault( + static_cast(*readValue), + GENERALRegisterMap.at("Sequence Type") == 0 ? true : false); + Q_EMIT updateFaultStatusSignal(registerFault); + } else { + Q_EMIT updateFaultStatusSignal(true); + } + } else { + Q_EMIT updateFaultStatusSignal(true); + } + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::requestDisconnect() { + stopAcquisition(); + + stopAcquisitionUITask(); + stopCalibrationUITask(); + stopUtilityTask(); + + stopCalibrationStreamThread(); + + stopDeviceStatusMonitor(); + stopCurrentMotorPositionMonitor(); +} + +void HarmonicCalibration::startCurrentMotorPositionMonitor() { + if (!m_currentMotorPositionThread.isRunning()) { + isMotorPositionMonitor = true; + m_currentMotorPositionThread = + QtConcurrent::run(this, &HarmonicCalibration::currentMotorPositionTask, + motorPositionMonitorRate); + m_currentMotorPositionWatcher.setFuture(m_currentMotorPositionThread); + } +} + +void HarmonicCalibration::stopCurrentMotorPositionMonitor() { + isMotorPositionMonitor = false; + if (m_currentMotorPositionThread.isRunning()) { + m_currentMotorPositionThread.cancel(); + m_currentMotorPositionWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::currentMotorPositionTask(int sampleRate) { + double motorPosition = 0; + while (isMotorPositionMonitor) { + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, + motorPosition); + + Q_EMIT motorPositionChanged(motorPosition); + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::updateMotorPosition(double position) { + current_pos = position; + if (isAcquisitionTab) + updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); + else if (isCalibrationTab) + updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); +} + +bool HarmonicCalibration::resetGENERAL() { + bool success = false; + + uint32_t resetValue = 0x0000; + if (deviceRegisterMap.at("ASIL ID") == "ASIL QM") { + resetValue = 0x1231; + } // Industrial or ASIL QM + else if (deviceRegisterMap.at("ASIL ID") == "ASIL B") { + resetValue = 0x1200; + } // Automotive or ASIL B + + if (resetValue != 0x0000) { + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::GENERAL), + resetValue) == 0) { + success = true; + } + } + + return success; } #pragma region Acquisition Methods -bool HarmonicCalibration::updateChannelValues(){ - bool success = false; - rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, bufferSize); - if(rotation == static_cast(UINT64_MAX)) { return false; } - angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, bufferSize); - if(angle == static_cast(UINT64_MAX)) { return false; } - updateCountValue(); - if(count == static_cast(UINT64_MAX)) { return false; } - temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, bufferSize); - if(temp == static_cast(UINT64_MAX)) { return false; } - return success = true; -} - -void HarmonicCalibration::updateCountValue(){ - uint32_t *absAngleRegValue = new uint32_t; - bool success = false; - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0x0000) == 0){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), absAngleRegValue) == 0){ - count = m_admtController->getAbsAngleTurnCount(static_cast(*absAngleRegValue)); - success = true; - } - } - if(!success){ count = static_cast(UINT64_MAX); } -} - -void HarmonicCalibration::updateLineEditValues(){ - if(rotation == static_cast(UINT64_MAX)) { rotationValueLabel->setText("N/A"); } - else { rotationValueLabel->setText(QString::number(rotation) + "°"); } - if(angle == static_cast(UINT64_MAX)) { angleValueLabel->setText("N/A"); } - else { angleValueLabel->setText(QString::number(angle) + "°"); } - if(count == static_cast(UINT64_MAX)) { countValueLabel->setText("N/A"); } - else { countValueLabel->setText(QString::number(count)); } - if(temp == static_cast(UINT64_MAX)) { tempValueLabel->setText("N/A"); } - else { tempValueLabel->setText(QString::number(temp) + " °C"); } -} - -void HarmonicCalibration::startAcquisition() -{ - isStartAcquisition = true; - acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); - - m_acquisitionDataThread = QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples, acquisitionSampleRate); - m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); - m_acquisitionGraphThread = QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, acquisitionGraphSampleRate); - m_acquisitionGraphWatcher.setFuture(m_acquisitionGraphThread); -} - -void HarmonicCalibration::stopAcquisition() -{ - isStartAcquisition = false; - if(m_acquisitionDataThread.isRunning()) - { - m_acquisitionDataThread.cancel(); - m_acquisitionDataWatcher.waitForFinished(); - } - if(m_acquisitionGraphThread.isRunning()) - { - m_acquisitionGraphThread.cancel(); - m_acquisitionGraphWatcher.waitForFinished(); - } - - stopCurrentMotorPositionMonitor(); -} - -void HarmonicCalibration::updateFaultStatus(bool status) -{ - bool isChanged = (deviceStatusFault != status); - if(isChanged) - { - deviceStatusFault = status; - acquisitionFaultRegisterLEDWidget->setChecked(deviceStatusFault); - calibrationFaultRegisterLEDWidget->setChecked(deviceStatusFault); - } -} - -void HarmonicCalibration::updateAcquisitionMotorRPM() -{ - acquisitionMotorRPMLineEdit->setText(QString::number(motor_rpm)); -} - -void HarmonicCalibration::updateAcquisitionMotorRotationDirection() -{ - acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); -} - -void HarmonicCalibration::getAcquisitionSamples(int sampleRate) -{ - while(isStartAcquisition) - { - if(!updateChannelValues()) { break; } - - if(acquisitionDataMap.at(ANGLE) == false && acquisitionAngleList.size() > 0) acquisitionAngleList.clear(); - if(acquisitionDataMap.at(ABSANGLE) == false && acquisitionABSAngleList.size() > 0) acquisitionABSAngleList.clear(); - if(acquisitionDataMap.at(TURNCOUNT) == false && acquisitionTurnCountList.size() > 0) acquisitionTurnCountList.clear(); - if(acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) acquisitionTmp0List.clear(); - if(acquisitionDataMap.at(SINE) == false && acquisitionSineList.size() > 0) acquisitionSineList.clear(); - if(acquisitionDataMap.at(COSINE) == false && acquisitionCosineList.size() > 0) acquisitionCosineList.clear(); - if(acquisitionDataMap.at(RADIUS) == false && acquisitionRadiusList.size() > 0) acquisitionRadiusList.clear(); - - if(acquisitionDataMap.at(ANGLE)) prependAcquisitionData(angle, acquisitionAngleList); - if(acquisitionDataMap.at(ABSANGLE)) prependAcquisitionData(rotation, acquisitionABSAngleList); - if(acquisitionDataMap.at(TURNCOUNT)) prependAcquisitionData(count, acquisitionTurnCountList); - if(acquisitionDataMap.at(TMP0)) prependAcquisitionData(temp, acquisitionTmp0List); - if(acquisitionDataMap.at(SINE)) prependAcquisitionData(getAcquisitionParameterValue(SINE), acquisitionSineList); - if(acquisitionDataMap.at(COSINE)) prependAcquisitionData(getAcquisitionParameterValue(COSINE), acquisitionCosineList); - if(acquisitionDataMap.at(RADIUS)) prependAcquisitionData(getAcquisitionParameterValue(RADIUS), acquisitionRadiusList); - - QThread::msleep(sampleRate); - } -} - -double HarmonicCalibration::getAcquisitionParameterValue(const AcquisitionDataKey &key) -{ - uint32_t *readValue = new uint32_t; - switch(key) - { - case SINE: - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(ADMTController::SensorRegister::SINE), - readValue) == -1) return qQNaN(); - map sineRegisterMap = m_admtController->getSineRegisterBitMapping(static_cast(*readValue)); - return sineRegisterMap.at("SINE"); - break; - } - case COSINE: - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(ADMTController::SensorRegister::COSINE), - readValue) == -1) return qQNaN(); - map cosineRegisterMap = m_admtController->getCosineRegisterBitMapping(static_cast(*readValue)); - return cosineRegisterMap.at("COSINE"); - break; - } - case RADIUS: - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(ADMTController::SensorRegister::RADIUS), - readValue) == -1) return qQNaN(); - map radiusRegisterMap = m_admtController->getRadiusRegisterBitMapping(static_cast(*readValue)); - return radiusRegisterMap.at("RADIUS"); - break; - } - default: - return qQNaN(); - break; - } -} - -void HarmonicCalibration::plotAcquisition(QVector& list, PlotChannel* channel) -{ - channel->curve()->setSamples(list); - auto result = minmax_element(list.begin(), list.end()); - if(*result.first < acquisitionGraphYMin) acquisitionGraphYMin = *result.first; - if(*result.second > acquisitionGraphYMax) acquisitionGraphYMax = *result.second; -} - -void HarmonicCalibration::prependAcquisitionData(const double& data, QVector& list) -{ - list.prepend(data); - if(list.size() >= acquisitionDisplayLength){ - list.resize(acquisitionDisplayLength); - list.squeeze(); - } -} - -void HarmonicCalibration::resetAcquisitionYAxisScale() -{ - acquisitionGraphYMin = 0; - acquisitionGraphYMax = 360; - acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); - acquisitionGraphPlotWidget->replot(); -} - -void HarmonicCalibration::acquisitionPlotTask(int sampleRate) -{ - while(isStartAcquisition){ - if(acquisitionDataMap.at(ANGLE)) - plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel); - if(acquisitionDataMap.at(ABSANGLE)) - plotAcquisition(acquisitionABSAngleList, acquisitionABSAnglePlotChannel); - if(acquisitionDataMap.at(TURNCOUNT)) - plotAcquisition(acquisitionTurnCountList, acquisitionTurnCountPlotChannel); - if(acquisitionDataMap.at(TMP0)) - plotAcquisition(acquisitionTmp0List, acquisitionTmp0PlotChannel); - if(acquisitionDataMap.at(SINE)) - plotAcquisition(acquisitionSineList, acquisitionSinePlotChannel); - if(acquisitionDataMap.at(COSINE)) - plotAcquisition(acquisitionCosineList, acquisitionCosinePlotChannel); - if(acquisitionDataMap.at(RADIUS)) - plotAcquisition(acquisitionRadiusList, acquisitionRadiusPlotChannel); - - acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); - acquisitionGraphPlotWidget->replot(); - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::acquisitionUITask(int sampleRate) -{ - while(isAcquisitionTab) - { - if(isStartAcquisition) updateLineEditValues(); - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::startAcquisitionUITask() -{ - if(!m_acquisitionUIThread.isRunning()) - { - isAcquisitionTab = true; - m_acquisitionUIThread = QtConcurrent::run(this, &HarmonicCalibration::acquisitionUITask, acquisitionUITimerRate); - m_acquisitionUIWatcher.setFuture(m_acquisitionUIThread); - } -} - -void HarmonicCalibration::stopAcquisitionUITask() -{ - isAcquisitionTab = false; - if(m_acquisitionUIThread.isRunning()) - { - m_acquisitionUIThread.cancel(); - m_acquisitionUIWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::updateSequenceWidget(){ - if(GENERALRegisterMap.at("Sequence Type") == -1){ sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); } - else{ sequenceTypeMenuCombo->combo()->setCurrentIndex(sequenceTypeMenuCombo->combo()->findData(GENERALRegisterMap.at("Sequence Type"))); } - conversionTypeMenuCombo->combo()->setCurrentIndex(conversionTypeMenuCombo->combo()->findData(GENERALRegisterMap.at("Conversion Type"))); - if(GENERALRegisterMap.at("Convert Synchronization") == -1){ convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); } - else{ convertSynchronizationMenuCombo->combo()->setCurrentIndex(convertSynchronizationMenuCombo->combo()->findData(GENERALRegisterMap.at("Convert Synchronization"))); } - angleFilterMenuCombo->combo()->setCurrentIndex(angleFilterMenuCombo->combo()->findData(GENERALRegisterMap.at("Angle Filter"))); - eighthHarmonicMenuCombo->combo()->setCurrentIndex(eighthHarmonicMenuCombo->combo()->findData(GENERALRegisterMap.at("8th Harmonic"))); -} - -void HarmonicCalibration::applySequenceAndUpdate() -{ - applySequence(); - updateSequenceWidget(); -} - -void HarmonicCalibration::updateGeneralSettingEnabled(bool value) -{ - graphUpdateIntervalLineEdit->setEnabled(value); - displayLengthLineEdit->setEnabled(value); -} - -void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox* widget, PlotChannel* channel, AcquisitionDataKey key) -{ - connect(widget, &QCheckBox::stateChanged, [=](int state){ - if(state == Qt::Checked){ - channel->setEnabled(true); - acquisitionDataMap[key] = true; - } - else{ - channel->setEnabled(false); - acquisitionDataMap[key] = false; - } - }); -} - -void HarmonicCalibration::GMRReset() -{ - // Set Motor Angle to 315 degrees - target_pos = 0; - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); - - // Write 1 to ADMT IIO Attribute coil_rs - m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getDeviceAttribute(ADMTController::DeviceAttribute::SDP_COIL_RS), 1); - - // Write 0xc000 to CNVPAGE - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0xc000) != -1) - { - // Write 0x0000 to CNVPAGE - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), 0x0000) != -1) - { - // Read ABSANGLE - - StatusBarManager::pushMessage("GMR Reset Done"); - } - else { StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); } - } - else { StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); } -} - -void HarmonicCalibration::restart() -{ - if(m_running) { - run(false); - run(true); - } +bool HarmonicCalibration::updateChannelValues() { + bool success = false; + rotation = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + rotationChannelName, bufferSize); + if (rotation == static_cast(UINT64_MAX)) { + return false; + } + angle = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + angleChannelName, bufferSize); + if (angle == static_cast(UINT64_MAX)) { + return false; + } + updateCountValue(); + if (count == static_cast(UINT64_MAX)) { + return false; + } + temp = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + temperatureChannelName, bufferSize); + if (temp == static_cast(UINT64_MAX)) { + return false; + } + return success = true; +} + +void HarmonicCalibration::updateCountValue() { + uint32_t *absAngleRegValue = new uint32_t; + bool success = false; + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::CNVPAGE), + 0x0000) == 0) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister( + ADMTController::SensorRegister::ABSANGLE), + absAngleRegValue) == 0) { + count = m_admtController->getAbsAngleTurnCount( + static_cast(*absAngleRegValue)); + success = true; + } + } + if (!success) { + count = static_cast(UINT64_MAX); + } +} + +void HarmonicCalibration::updateLineEditValues() { + if (rotation == static_cast(UINT64_MAX)) { + rotationValueLabel->setText("N/A"); + } else { + rotationValueLabel->setText(QString::number(rotation) + "°"); + } + if (angle == static_cast(UINT64_MAX)) { + angleValueLabel->setText("N/A"); + } else { + angleValueLabel->setText(QString::number(angle) + "°"); + } + if (count == static_cast(UINT64_MAX)) { + countValueLabel->setText("N/A"); + } else { + countValueLabel->setText(QString::number(count)); + } + if (temp == static_cast(UINT64_MAX)) { + tempValueLabel->setText("N/A"); + } else { + tempValueLabel->setText(QString::number(temp) + " °C"); + } +} + +void HarmonicCalibration::startAcquisition() { + isStartAcquisition = true; + acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); + + m_acquisitionDataThread = QtConcurrent::run( + this, &HarmonicCalibration::getAcquisitionSamples, acquisitionSampleRate); + m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); + m_acquisitionGraphThread = + QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, + acquisitionGraphSampleRate); + m_acquisitionGraphWatcher.setFuture(m_acquisitionGraphThread); +} + +void HarmonicCalibration::stopAcquisition() { + isStartAcquisition = false; + if (m_acquisitionDataThread.isRunning()) { + m_acquisitionDataThread.cancel(); + m_acquisitionDataWatcher.waitForFinished(); + } + if (m_acquisitionGraphThread.isRunning()) { + m_acquisitionGraphThread.cancel(); + m_acquisitionGraphWatcher.waitForFinished(); + } + + stopCurrentMotorPositionMonitor(); +} + +void HarmonicCalibration::updateFaultStatus(bool status) { + bool isChanged = (deviceStatusFault != status); + if (isChanged) { + deviceStatusFault = status; + acquisitionFaultRegisterLEDWidget->setChecked(deviceStatusFault); + calibrationFaultRegisterLEDWidget->setChecked(deviceStatusFault); + } +} + +void HarmonicCalibration::updateAcquisitionMotorRPM() { + acquisitionMotorRPMLineEdit->setText(QString::number(motor_rpm)); +} + +void HarmonicCalibration::updateAcquisitionMotorRotationDirection() { + acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); +} + +void HarmonicCalibration::getAcquisitionSamples(int sampleRate) { + while (isStartAcquisition) { + if (!updateChannelValues()) { + break; + } + + if (acquisitionDataMap.at(ANGLE) == false && + acquisitionAngleList.size() > 0) + acquisitionAngleList.clear(); + if (acquisitionDataMap.at(ABSANGLE) == false && + acquisitionABSAngleList.size() > 0) + acquisitionABSAngleList.clear(); + if (acquisitionDataMap.at(TURNCOUNT) == false && + acquisitionTurnCountList.size() > 0) + acquisitionTurnCountList.clear(); + if (acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) + acquisitionTmp0List.clear(); + if (acquisitionDataMap.at(SINE) == false && acquisitionSineList.size() > 0) + acquisitionSineList.clear(); + if (acquisitionDataMap.at(COSINE) == false && + acquisitionCosineList.size() > 0) + acquisitionCosineList.clear(); + if (acquisitionDataMap.at(RADIUS) == false && + acquisitionRadiusList.size() > 0) + acquisitionRadiusList.clear(); + + if (acquisitionDataMap.at(ANGLE)) + prependAcquisitionData(angle, acquisitionAngleList); + if (acquisitionDataMap.at(ABSANGLE)) + prependAcquisitionData(rotation, acquisitionABSAngleList); + if (acquisitionDataMap.at(TURNCOUNT)) + prependAcquisitionData(count, acquisitionTurnCountList); + if (acquisitionDataMap.at(TMP0)) + prependAcquisitionData(temp, acquisitionTmp0List); + if (acquisitionDataMap.at(SINE)) + prependAcquisitionData(getAcquisitionParameterValue(SINE), + acquisitionSineList); + if (acquisitionDataMap.at(COSINE)) + prependAcquisitionData(getAcquisitionParameterValue(COSINE), + acquisitionCosineList); + if (acquisitionDataMap.at(RADIUS)) + prependAcquisitionData(getAcquisitionParameterValue(RADIUS), + acquisitionRadiusList); + + QThread::msleep(sampleRate); + } +} + +double HarmonicCalibration::getAcquisitionParameterValue( + const AcquisitionDataKey &key) { + uint32_t *readValue = new uint32_t; + switch (key) { + case SINE: { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister( + ADMTController::SensorRegister::SINE), + readValue) == -1) + return qQNaN(); + map sineRegisterMap = + m_admtController->getSineRegisterBitMapping( + static_cast(*readValue)); + return sineRegisterMap.at("SINE"); + break; + } + case COSINE: { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister( + ADMTController::SensorRegister::COSINE), + readValue) == -1) + return qQNaN(); + map cosineRegisterMap = + m_admtController->getCosineRegisterBitMapping( + static_cast(*readValue)); + return cosineRegisterMap.at("COSINE"); + break; + } + case RADIUS: { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister( + ADMTController::SensorRegister::RADIUS), + readValue) == -1) + return qQNaN(); + map radiusRegisterMap = + m_admtController->getRadiusRegisterBitMapping( + static_cast(*readValue)); + return radiusRegisterMap.at("RADIUS"); + break; + } + default: + return qQNaN(); + break; + } +} + +void HarmonicCalibration::plotAcquisition(QVector &list, + PlotChannel *channel) { + channel->curve()->setSamples(list); + auto result = minmax_element(list.begin(), list.end()); + if (*result.first < acquisitionGraphYMin) + acquisitionGraphYMin = *result.first; + if (*result.second > acquisitionGraphYMax) + acquisitionGraphYMax = *result.second; +} + +void HarmonicCalibration::prependAcquisitionData(const double &data, + QVector &list) { + list.prepend(data); + if (list.size() >= acquisitionDisplayLength) { + list.resize(acquisitionDisplayLength); + list.squeeze(); + } +} + +void HarmonicCalibration::resetAcquisitionYAxisScale() { + acquisitionGraphYMin = 0; + acquisitionGraphYMax = 360; + acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); + acquisitionGraphPlotWidget->replot(); +} + +void HarmonicCalibration::acquisitionPlotTask(int sampleRate) { + while (isStartAcquisition) { + if (acquisitionDataMap.at(ANGLE)) + plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel); + if (acquisitionDataMap.at(ABSANGLE)) + plotAcquisition(acquisitionABSAngleList, acquisitionABSAnglePlotChannel); + if (acquisitionDataMap.at(TURNCOUNT)) + plotAcquisition(acquisitionTurnCountList, + acquisitionTurnCountPlotChannel); + if (acquisitionDataMap.at(TMP0)) + plotAcquisition(acquisitionTmp0List, acquisitionTmp0PlotChannel); + if (acquisitionDataMap.at(SINE)) + plotAcquisition(acquisitionSineList, acquisitionSinePlotChannel); + if (acquisitionDataMap.at(COSINE)) + plotAcquisition(acquisitionCosineList, acquisitionCosinePlotChannel); + if (acquisitionDataMap.at(RADIUS)) + plotAcquisition(acquisitionRadiusList, acquisitionRadiusPlotChannel); + + acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, + acquisitionGraphYMax); + acquisitionGraphPlotWidget->replot(); + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::acquisitionUITask(int sampleRate) { + while (isAcquisitionTab) { + if (isStartAcquisition) + updateLineEditValues(); + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::startAcquisitionUITask() { + if (!m_acquisitionUIThread.isRunning()) { + isAcquisitionTab = true; + m_acquisitionUIThread = QtConcurrent::run( + this, &HarmonicCalibration::acquisitionUITask, acquisitionUITimerRate); + m_acquisitionUIWatcher.setFuture(m_acquisitionUIThread); + } +} + +void HarmonicCalibration::stopAcquisitionUITask() { + isAcquisitionTab = false; + if (m_acquisitionUIThread.isRunning()) { + m_acquisitionUIThread.cancel(); + m_acquisitionUIWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::updateSequenceWidget() { + if (GENERALRegisterMap.at("Sequence Type") == -1) { + sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); + } else { + sequenceTypeMenuCombo->combo()->setCurrentIndex( + sequenceTypeMenuCombo->combo()->findData( + GENERALRegisterMap.at("Sequence Type"))); + } + conversionTypeMenuCombo->combo()->setCurrentIndex( + conversionTypeMenuCombo->combo()->findData( + GENERALRegisterMap.at("Conversion Type"))); + if (GENERALRegisterMap.at("Convert Synchronization") == -1) { + convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); + } else { + convertSynchronizationMenuCombo->combo()->setCurrentIndex( + convertSynchronizationMenuCombo->combo()->findData( + GENERALRegisterMap.at("Convert Synchronization"))); + } + angleFilterMenuCombo->combo()->setCurrentIndex( + angleFilterMenuCombo->combo()->findData( + GENERALRegisterMap.at("Angle Filter"))); + eighthHarmonicMenuCombo->combo()->setCurrentIndex( + eighthHarmonicMenuCombo->combo()->findData( + GENERALRegisterMap.at("8th Harmonic"))); +} + +void HarmonicCalibration::applySequenceAndUpdate() { + applySequence(); + updateSequenceWidget(); +} + +void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { + graphUpdateIntervalLineEdit->setEnabled(value); + displayLengthLineEdit->setEnabled(value); +} + +void HarmonicCalibration::connectCheckBoxToAcquisitionGraph( + QCheckBox *widget, PlotChannel *channel, AcquisitionDataKey key) { + connect(widget, &QCheckBox::stateChanged, [this, channel, key](int state) { + if (state == Qt::Checked) { + channel->setEnabled(true); + acquisitionDataMap[key] = true; + } else { + channel->setEnabled(false); + acquisitionDataMap[key] = false; + } + }); +} + +void HarmonicCalibration::GMRReset() { + // Set Motor Angle to 315 degrees + target_pos = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, + target_pos); + + // Write 1 to ADMT IIO Attribute coil_rs + m_admtController->setDeviceAttributeValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getDeviceAttribute( + ADMTController::DeviceAttribute::SDP_COIL_RS), + 1); + + // Write 0xc000 to CNVPAGE + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::CNVPAGE), + 0xc000) != -1) { + // Write 0x0000 to CNVPAGE + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::CNVPAGE), + 0x0000) != -1) { + // Read ABSANGLE + + StatusBarManager::pushMessage("GMR Reset Done"); + } else { + StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); + } + } else { + StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); + } +} + +void HarmonicCalibration::restart() { + if (m_running) { + run(false); + run(true); + } } bool HarmonicCalibration::running() const { return m_running; } -void HarmonicCalibration::setRunning(bool newRunning) -{ - if(m_running == newRunning) - return; - m_running = newRunning; - Q_EMIT runningChanged(newRunning); +void HarmonicCalibration::setRunning(bool newRunning) { + if (m_running == newRunning) + return; + m_running = newRunning; + Q_EMIT runningChanged(newRunning); } void HarmonicCalibration::start() { run(true); } void HarmonicCalibration::stop() { run(false); } -void HarmonicCalibration::run(bool b) -{ - qInfo() << b; - QElapsedTimer tim; - tim.start(); +void HarmonicCalibration::run(bool b) { + qInfo() << b; + QElapsedTimer tim; + tim.start(); - if(!b) { - isStartAcquisition = false; - runButton->setChecked(false); - } - else{ - startAcquisition(); - } + if (!b) { + isStartAcquisition = false; + runButton->setChecked(false); + } else { + startAcquisition(); + } - updateGeneralSettingEnabled(!b); + updateGeneralSettingEnabled(!b); } #pragma endregion #pragma region Calibration Methods -void HarmonicCalibration::startCalibrationUITask() -{ - if(!m_calibrationUIThread.isRunning()) - { - isCalibrationTab = true; - m_calibrationUIThread = QtConcurrent::run(this, &HarmonicCalibration::calibrationUITask, calibrationUITimerRate); - m_calibrationUIWatcher.setFuture(m_calibrationUIThread); - } -} - -void HarmonicCalibration::stopCalibrationUITask() -{ - isCalibrationTab = false; - if(m_calibrationUIThread.isRunning()) - { - m_calibrationUIThread.cancel(); - m_calibrationUIWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::calibrationUITask(int sampleRate) -{ - while (isCalibrationTab) - { - if(isStartMotor) - { - if(isPostCalibration){ - postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); - postCalibrationRawDataPlotWidget->replot(); - } - else{ - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotWidget->replot(); - } - } - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::updateCalibrationMotorRPM() -{ - calibrationMotorRPMLineEdit->setText(QString::number(motor_rpm)); -} - -void HarmonicCalibration::updateCalibrationMotorRotationDirection() -{ - calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); -} - -void HarmonicCalibration::getCalibrationSamples() -{ - if(resetCurrentPositionToZero()){ - double step = 0; - if(isMotorRotationClockwise) step = motorFullStepPerRevolution; - else step = -motorFullStepPerRevolution; - if(isPostCalibration){ - int currentSamplesCount = graphPostDataList.size(); - while(isStartMotor && currentSamplesCount < totalSamplesCount){ - target_pos = current_pos + step; - moveMotorToPosition(target_pos, true); - updateChannelValue(ADMTController::Channel::ANGLE); - graphPostDataList.append(angle); - currentSamplesCount++; - } - } - else{ - int currentSamplesCount = graphDataList.size(); - while(isStartMotor && currentSamplesCount < totalSamplesCount){ - target_pos = current_pos + step; - if(moveMotorToPosition(target_pos, true) == false) { m_admtController->disconnectADMT(); } - if(updateChannelValue(ADMTController::Channel::ANGLE)) { break; } - graphDataList.append(angle); - currentSamplesCount++; - } - } - } - - stopMotor(); -} - -void HarmonicCalibration::startCalibration() -{ - totalSamplesCount = cycleCount * samplesPerCycle; - graphPostDataList.reserve(totalSamplesCount); - graphPostDataList.squeeze(); - graphDataList.reserve(totalSamplesCount); - graphDataList.squeeze(); - - //configureConversionType(calibrationMode); // TODO uncomment when conversion type is okay - configureCalibrationSequenceSettings(); - clearHarmonicRegisters(); - - toggleTabSwitching(false); - toggleCalibrationControls(false); - - calibrationDataGraphTabWidget->setCurrentIndex(0); - calibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); - - toggleCalibrationButtonState(1); - if(calibrationMode == 0) startContinuousCalibration(); - else startOneShotCalibration(); -} - -void HarmonicCalibration::stopCalibration() -{ - isStartMotor = false; - if(calibrationMode == 0) - { - stopContinuousCalibration(); - } - - toggleTabSwitching(true); - toggleCalibrationControls(true); -} - -void HarmonicCalibration::startContinuousCalibration() -{ - stopCurrentMotorPositionMonitor(); - stopDeviceStatusMonitor(); - - if(isPostCalibration) StatusBarManager::pushMessage("Acquiring Post Calibration Samples, Please Wait..."); - else StatusBarManager::pushMessage("Acquiring Calibration Samples, Please Wait..."); - startResetMotorToZero(); -} - -void HarmonicCalibration::stopContinuousCalibration() -{ - stopMotor(); - stopWaitForVelocityReachedThread(); - stopCalibrationStreamThread(); - - startCurrentMotorPositionMonitor(); - startDeviceStatusMonitor(); -} - -void HarmonicCalibration::startResetMotorToZero() -{ - isResetMotorToZero = true; - if(!m_resetMotorToZeroThread.isRunning()) - { - m_resetMotorToZeroThread = QtConcurrent::run(this, &HarmonicCalibration::resetMotorToZero); - m_resetMotorToZeroWatcher.setFuture(m_resetMotorToZeroThread); - } -} - -void HarmonicCalibration::stopResetMotorToZero() -{ - isResetMotorToZero = false; - if(m_resetMotorToZeroThread.isRunning()) - { - m_resetMotorToZeroThread.cancel(); - m_resetMotorToZeroWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::resetMotorToZero() -{ - if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) - { - if(current_pos != 0) - { - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, convertRPStoVMAX(convertRPMtoRPS(fast_motor_rpm))); - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); - while(isResetMotorToZero && current_pos != 0){ - if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) != 0) break; - QThread::msleep(readMotorDebounce); - } - if(current_pos == 0) - { - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); - } - } - } -} - -void HarmonicCalibration::startCalibrationStreamThread() -{ - if(!m_calibrationStreamThread.isRunning()) - { - m_admtController->stopStream = false; - - continuousCalibrationSampleRate = calculateContinuousCalibrationSampleRate(convertVMAXtoRPS(rotate_vmax), samplesPerCycle); - m_calibrationStreamThread = QtConcurrent::run([this]() { m_admtController->bufferedStreamIO(totalSamplesCount, continuousCalibrationSampleRate); }); - m_calibrationStreamWatcher.setFuture(m_calibrationStreamThread); - } -} - -void HarmonicCalibration::stopCalibrationStreamThread() -{ - m_admtController->stopStream = true; - if(m_calibrationStreamThread.isRunning()) - { - m_calibrationStreamThread.cancel(); - m_calibrationStreamWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::startWaitForVelocityReachedThread(int mode) -{ - if(!m_calibrationWaitVelocityWatcher.isRunning()) - { - isMotorVelocityCheck = true; - m_calibrationWaitVelocityThread = QtConcurrent::run(this, &HarmonicCalibration::waitForVelocityReached, mode, motorWaitVelocityReachedSampleRate); - m_calibrationWaitVelocityWatcher.setFuture(m_calibrationWaitVelocityThread); - } -} - -void HarmonicCalibration::stopWaitForVelocityReachedThread() -{ - isMotorVelocityCheck = false; - if(m_calibrationWaitVelocityWatcher.isRunning()) - { - m_calibrationWaitVelocityThread.cancel(); - m_calibrationWaitVelocityWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::waitForVelocityReached(int mode, int sampleRate) -{ - isMotorVelocityReached = false; - if(mode == 0) - { - QThread::msleep(floor(convertAMAXtoAccelTime(amax) * 1000)); - isMotorVelocityReached = true; - } - else if(mode == 1) - { - moveMotorContinuous(); - uint32_t *registerValue = new uint32_t; - while(isMotorVelocityCheck && !isMotorVelocityReached) - { - if(readMotorRegisterValue(m_admtController->getRampGeneratorDriverFeatureControlRegister(ADMTController::RampGeneratorDriverFeatureControlRegister::RAMP_STAT), registerValue) == 0){ - isMotorVelocityReached = m_admtController->checkVelocityReachedFlag(static_cast(*registerValue)); - } - - QThread::msleep(sampleRate); - } - - delete registerValue; - } -} - -int HarmonicCalibration::calculateContinuousCalibrationSampleRate(double motorRPS, int samplesPerCycle) -{ - return static_cast(floor(1 / motorRPS / samplesPerCycle * 1000 * 1000 * 1000)); // In nanoseconds -} - -void HarmonicCalibration::configureConversionType(int mode) -{ - readSequence(); - GENERALRegisterMap.at("Conversion Type") = mode; - writeSequence(GENERALRegisterMap); -} - -void HarmonicCalibration::configureCalibrationSequenceSettings() -{ - readSequence(); - GENERALRegisterMap.at("8th Harmonic") = 1; // User-supplied 8th Harmonic - writeSequence(GENERALRegisterMap); -} - -void HarmonicCalibration::getStreamedCalibrationSamples(int microSampleRate) -{ - int currentSamplesCount = graphDataList.size(); - moveMotorContinuous(); - while(isStartMotor && currentSamplesCount < totalSamplesCount) - { - graphDataList.append(m_admtController->streamedValue); - // graphPostDataList.append(m_admtController->streamedValue); - currentSamplesCount = graphDataList.size(); - // currentSamplesCount = graphDataPostList.size(); - - QThread::usleep(microSampleRate); - } -} - -void HarmonicCalibration::startOneShotCalibration() -{ - if(resetToZero && !isPostCalibration){ - clearCalibrationSamples(); - clearPostCalibrationSamples(); - clearAngleErrorGraphs(); - clearCorrectedAngleErrorGraphs(); - } - else if(resetToZero){ - clearPostCalibrationSamples(); - } - - QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getCalibrationSamples); - QFutureWatcher *watcher = new QFutureWatcher(this); - - connect(watcher, &QFutureWatcher::finished, this, [=]() { - toggleTabSwitching(true); - toggleCalibrationControls(true); - - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotChannel->xAxis()->setMax(graphDataList.size()); - calibrationRawDataPlotWidget->replot(); - isStartMotor = false; - - if(isPostCalibration) - { - if(static_cast(graphPostDataList.size()) == totalSamplesCount) - { - computeSineCosineOfAngles(graphPostDataList); - m_admtController->postcalibrate(vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, samplesPerCycle, !isMotorRotationClockwise); - populateCorrectedAngleErrorGraphs(); - isPostCalibration = false; - isStartMotor = false; - resetToZero = true; - toggleCalibrationButtonState(4); - } - else toggleCalibrationButtonState(2); - } - else{ - if(static_cast(graphDataList.size()) == totalSamplesCount) - { - computeSineCosineOfAngles(graphDataList); - calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle, !isMotorRotationClockwise)); - populateAngleErrorGraphs(); - calculateHarmonicValues(); - toggleCalibrationButtonState(2); - } - else{ - resetToZero = true; - toggleCalibrationButtonState(0); - } - } - }); - connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater())); - watcher->setFuture(future); -} - -void HarmonicCalibration::postCalibrateData() -{ - calibrationLogWrite("==== Post Calibration Start ====\n"); - flashHarmonicValues(); - isPostCalibration = true; - isStartMotor = true; - resetToZero = true; - - toggleTabSwitching(false); - toggleCalibrationControls(false); - - calibrationDataGraphTabWidget->setCurrentIndex(1); - postCalibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); - - toggleCalibrationButtonState(3); - if(calibrationMode == 0) startContinuousCalibration(); - else startOneShotCalibration(); -} - -void HarmonicCalibration::resetAllCalibrationState() -{ - clearCalibrationSamples(); - clearPostCalibrationSamples(); - calibrationDataGraphTabWidget->setCurrentIndex(0); - - clearAngleErrorGraphs(); - clearCorrectedAngleErrorGraphs(); - resultDataTabWidget->setCurrentIndex(0); - - toggleCalibrationButtonState(0); - - isPostCalibration = false; - isCalculatedCoeff = false; - resetToZero = true; - displayCalculatedCoeff(); -} - -void HarmonicCalibration::computeSineCosineOfAngles(QVector graphDataList) -{ - m_admtController->computeSineCosineOfAngles(vector(graphDataList.begin(), graphDataList.end())); - if(isPostCalibration){ - postCalibrationSineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_sine_scaled.data(), m_admtController->calibration_samples_sine_scaled.size()); - postCalibrationCosineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_cosine_scaled.data(), m_admtController->calibration_samples_cosine_scaled.size()); - postCalibrationRawDataPlotWidget->replot(); - } - else{ - calibrationSineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_sine_scaled.data(), m_admtController->calibration_samples_sine_scaled.size()); - calibrationCosineDataPlotChannel->curve()->setSamples(m_admtController->calibration_samples_cosine_scaled.data(), m_admtController->calibration_samples_cosine_scaled.size()); - calibrationRawDataPlotWidget->replot(); - } -} - -void HarmonicCalibration::populateAngleErrorGraphs() -{ - QVector angleError = QVector(m_admtController->angleError.begin(), m_admtController->angleError.end()); - QVector FFTAngleErrorMagnitude = QVector(m_admtController->FFTAngleErrorMagnitude.begin(), m_admtController->FFTAngleErrorMagnitude.end()); - QVector FFTAngleErrorPhase = QVector(m_admtController->FFTAngleErrorPhase.begin(), m_admtController->FFTAngleErrorPhase.end()); - - angleErrorPlotChannel->curve()->setSamples(angleError); - auto angleErrorMinMax = minmax_element(angleError.begin(), angleError.end()); - angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, *angleErrorMinMax.second); - angleErrorXPlotAxis->setInterval(0, angleError.size()); - angleErrorPlotWidget->replot(); - - FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); - FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); - auto angleErrorMagnitudeMinMax = minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); - auto angleErrorPhaseMinMax = minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); - double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first ? *angleErrorMagnitudeMinMax.first : *angleErrorPhaseMinMax.first; - double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second ? *angleErrorMagnitudeMinMax.second : *angleErrorPhaseMinMax.second; - FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); - FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); - FFTAngleErrorPlotWidget->replot(); - - resultDataTabWidget->setCurrentIndex(0); // Set tab to Angle Error -} - -void HarmonicCalibration::populateCorrectedAngleErrorGraphs() -{ - QVector correctedError(m_admtController->correctedError.begin(), m_admtController->correctedError.end()); - QVector FFTCorrectedErrorMagnitude(m_admtController->FFTCorrectedErrorMagnitude.begin(), m_admtController->FFTCorrectedErrorMagnitude.end()); - QVector FFTCorrectedErrorPhase(m_admtController->FFTCorrectedErrorPhase.begin(), m_admtController->FFTCorrectedErrorPhase.end()); - - correctedErrorPlotChannel->curve()->setSamples(correctedError); - auto correctedErrorMagnitudeMinMax = minmax_element(correctedError.begin(), correctedError.end()); - correctedErrorYPlotAxis->setInterval(*correctedErrorMagnitudeMinMax.first, *correctedErrorMagnitudeMinMax.second); - correctedErrorXPlotAxis->setMax(correctedError.size()); - correctedErrorPlotWidget->replot(); - - FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); - FFTCorrectedErrorMagnitudeChannel->curve()->setSamples(FFTCorrectedErrorMagnitude); - auto FFTCorrectedErrorMagnitudeMinMax = minmax_element(FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); - auto FFTCorrectedErrorPhaseMinMax = minmax_element(FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); - double FFTCorrectedErrorPlotMin = *FFTCorrectedErrorMagnitudeMinMax.first < *FFTCorrectedErrorPhaseMinMax.first ? *FFTCorrectedErrorMagnitudeMinMax.first : *FFTCorrectedErrorPhaseMinMax.first; - double FFTCorrectedErrorPlotMax = *FFTCorrectedErrorMagnitudeMinMax.second > *FFTCorrectedErrorPhaseMinMax.second ? *FFTCorrectedErrorMagnitudeMinMax.second : *FFTCorrectedErrorPhaseMinMax.second; - FFTCorrectedErrorYPlotAxis->setInterval(FFTCorrectedErrorPlotMin, FFTCorrectedErrorPlotMax); - FFTCorrectedErrorXPlotAxis->setMax(FFTCorrectedErrorMagnitude.size()); - FFTCorrectedErrorPlotWidget->replot(); - - resultDataTabWidget->setCurrentIndex(2); // Set tab to Angle Error -} - -void HarmonicCalibration::clearHarmonicRegisters() -{ - bool success = false; - uint32_t value = 0x0; - uint32_t harmonicCNVPage = m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1MAG); - if(changeCNVPage(harmonicCNVPage)) - { - success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), value) == 0 ? true : false; - success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), value) == 0 ? true : false; - success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), value) == 0 ? true : false; - success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), value) == 0 ? true : false; - success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), value) == 0 ? true : false; - success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), value) == 0 ? true : false; - success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), value) == 0 ? true : false; - success = m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), value) == 0 ? true : false; - } - - if(!success){ - calibrationLogWrite("Unable to clear Harmonic Registers!"); - } -} - -void HarmonicCalibration::flashHarmonicValues() -{ - if(changeCNVPage(0x02)){ - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), 0x01, 0x02); - - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), - H1_MAG_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), - H1_PHASE_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), - H2_MAG_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), - H2_PHASE_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), - H3_MAG_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), - H3_PHASE_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), - H8_MAG_HEX); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), - H8_PHASE_HEX); - - isCalculatedCoeff = true; - displayCalculatedCoeff(); - } - else{ - calibrationLogWrite("Unabled to flash Harmonic Registers!"); - } -} - -void HarmonicCalibration::calculateHarmonicValues() -{ - uint32_t *h1MagCurrent = new uint32_t, - *h1PhaseCurrent = new uint32_t, - *h2MagCurrent = new uint32_t, - *h2PhaseCurrent = new uint32_t, - *h3MagCurrent = new uint32_t, - *h3PhaseCurrent = new uint32_t, - *h8MagCurrent = new uint32_t, - *h8PhaseCurrent = new uint32_t; - - if(changeCNVPage(0x02)) - { - // Read and store current harmonic values - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); - m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); - - // Calculate harmonic coefficients (Hex) - H1_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_1), static_cast(*h1MagCurrent), "h1")); - H2_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_2), static_cast(*h2MagCurrent), "h2")); - H3_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_3), static_cast(*h3MagCurrent), "h3")); - H8_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude(static_cast(m_admtController->HAR_MAG_8), static_cast(*h8MagCurrent), "h8")); - H1_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_1), static_cast(*h1PhaseCurrent))); - H2_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_2), static_cast(*h2PhaseCurrent))); - H3_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_3), static_cast(*h3PhaseCurrent))); - H8_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase(static_cast(m_admtController->HAR_PHASE_8), static_cast(*h8PhaseCurrent))); - - calibrationLogWrite(); - calibrationLogWrite(QString("Calculated H1 Mag (Hex): 0x%1").arg(QString::number(H1_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H1 Phase (Hex): 0x%1").arg(QString::number(H1_PHASE_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H2 Mag (Hex): 0x%1").arg(QString::number(H2_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H2 Phase (Hex): 0x%1").arg(QString::number(H2_PHASE_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H3 Mag (Hex): 0x%1").arg(QString::number(H3_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H3 Phase (Hex): 0x%1").arg(QString::number(H3_PHASE_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H8 Mag (Hex): 0x%1").arg(QString::number(H8_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite(QString("Calculated H8 Phase (Hex): 0x%1").arg(QString::number(H8_PHASE_HEX, 16).rightJustified(4, '0'))); - - // Get actual harmonic values from hex - H1_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H1_MAG_HEX), "h1mag"); - H1_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H1_PHASE_HEX), "h1phase"); - H2_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H2_MAG_HEX), "h2mag"); - H2_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H2_PHASE_HEX), "h2phase"); - H3_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H3_MAG_HEX), "h3mag"); - H3_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H3_PHASE_HEX), "h3phase"); - H8_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H8_MAG_HEX), "h8mag"); - H8_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H8_PHASE_HEX), "h8phase"); - - calibrationLogWrite(); - calibrationLogWrite(QString("Calculated H1 Mag (Angle): %1°").arg(QString::number(H1_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H1 Phase (Angle): %1°").arg(QString::number(H1_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H2 Mag (Angle): %1°").arg(QString::number(H2_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H2 Phase (Angle): %1°").arg(QString::number(H2_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H3 Mag (Angle): %1°").arg(QString::number(H3_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H3 Phase (Angle): %1°").arg(QString::number(H3_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H8 Mag (Angle): %1°").arg(QString::number(H8_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H8 Phase (Angle): %1°").arg(QString::number(H8_PHASE_ANGLE))); - - if(isAngleDisplayFormat) updateCalculatedCoeffAngle(); - else updateCalculatedCoeffHex(); - isCalculatedCoeff = true; - } -} - -void HarmonicCalibration::updateCalculatedCoeffAngle() -{ - calibrationH1MagLabel->setText(QString::number(H1_MAG_ANGLE, 'f', 2) + "°"); - calibrationH2MagLabel->setText(QString::number(H2_MAG_ANGLE, 'f', 2) + "°"); - calibrationH3MagLabel->setText(QString::number(H3_MAG_ANGLE, 'f', 2) + "°"); - calibrationH8MagLabel->setText(QString::number(H8_MAG_ANGLE, 'f', 2) + "°"); - calibrationH1PhaseLabel->setText("Φ " + QString::number(H1_PHASE_ANGLE, 'f', 2)); - calibrationH2PhaseLabel->setText("Φ " + QString::number(H2_PHASE_ANGLE, 'f', 2)); - calibrationH3PhaseLabel->setText("Φ " + QString::number(H3_PHASE_ANGLE, 'f', 2)); - calibrationH8PhaseLabel->setText("Φ " + QString::number(H8_PHASE_ANGLE, 'f', 2)); -} - -void HarmonicCalibration::updateCalculatedCoeffHex() -{ - calibrationH1MagLabel->setText(QString("0x%1").arg(H1_MAG_HEX, 4, 16, QChar('0'))); - calibrationH2MagLabel->setText(QString("0x%1").arg(H2_MAG_HEX, 4, 16, QChar('0'))); - calibrationH3MagLabel->setText(QString("0x%1").arg(H3_MAG_HEX, 4, 16, QChar('0'))); - calibrationH8MagLabel->setText(QString("0x%1").arg(H8_MAG_HEX, 4, 16, QChar('0'))); - calibrationH1PhaseLabel->setText(QString("0x%1").arg(H1_PHASE_HEX, 4, 16, QChar('0'))); - calibrationH2PhaseLabel->setText(QString("0x%1").arg(H2_PHASE_HEX, 4, 16, QChar('0'))); - calibrationH3PhaseLabel->setText(QString("0x%1").arg(H3_PHASE_HEX, 4, 16, QChar('0'))); - calibrationH8PhaseLabel->setText(QString("0x%1").arg(H8_PHASE_HEX, 4, 16, QChar('0'))); -} - -void HarmonicCalibration::resetCalculatedCoeffAngle() -{ - calibrationH1MagLabel->setText("--.--°"); - calibrationH2MagLabel->setText("--.--°"); - calibrationH3MagLabel->setText("--.--°"); - calibrationH8MagLabel->setText("--.--°"); - calibrationH1PhaseLabel->setText("Φ --.--"); - calibrationH2PhaseLabel->setText("Φ --.--"); - calibrationH3PhaseLabel->setText("Φ --.--"); - calibrationH8PhaseLabel->setText("Φ --.--"); -} - -void HarmonicCalibration::resetCalculatedCoeffHex() -{ - calibrationH1MagLabel->setText("0x----"); - calibrationH2MagLabel->setText("0x----"); - calibrationH3MagLabel->setText("0x----"); - calibrationH8MagLabel->setText("0x----"); - calibrationH1PhaseLabel->setText("0x----"); - calibrationH2PhaseLabel->setText("0x----"); - calibrationH3PhaseLabel->setText("0x----"); - calibrationH8PhaseLabel->setText("0x----"); -} - -void HarmonicCalibration::displayCalculatedCoeff() -{ - if(isAngleDisplayFormat){ - if(isCalculatedCoeff){ - updateCalculatedCoeffAngle(); - } - else{ - resetCalculatedCoeffAngle(); - } - } - else{ - if(isCalculatedCoeff){ - updateCalculatedCoeffHex(); - } - else{ - resetCalculatedCoeffHex(); - } - } -} - -void HarmonicCalibration::calibrationLogWrite(QString message) -{ - logsPlainTextEdit->appendPlainText(message); -} - -void HarmonicCalibration::importCalibrationData() -{ - QString fileName = QFileDialog::getOpenFileName( - this, tr("Import"), "", - tr("Comma-separated values files (*.csv);;" - "Tab-delimited values files (*.txt)"), - nullptr, QFileDialog::Options()); - - FileManager fm("HarmonicCalibration"); - - try { - fm.open(fileName, FileManager::IMPORT); - - graphDataList = fm.read(0); - if(graphDataList.size() > 0) - { - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataXPlotAxis->setInterval(0, graphDataList.size()); - calibrationRawDataPlotWidget->replot(); - - computeSineCosineOfAngles(graphDataList); - calibrationLogWrite(m_admtController->calibrate(vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle, false)); // TODO: Hard-coded Clockwise - populateAngleErrorGraphs(); - toggleCalibrationButtonState(2); - } - } catch(FileManagerException &ex) { - calibrationLogWrite(QString(ex.what())); - } -} - -void HarmonicCalibration::extractCalibrationData() -{ - QStringList filter; - filter += QString(tr("Comma-separated values files (*.csv)")); - filter += QString(tr("Tab-delimited values files (*.txt)")); - filter += QString(tr("All Files(*)")); - - QString selectedFilter = filter[0]; - - QString fileName = QFileDialog::getSaveFileName(this, tr("Export"), "", filter.join(";;"), &selectedFilter, QFileDialog::Options()); - - if(fileName.split(".").size() <= 1) { - QString ext = selectedFilter.split(".")[1].split(")")[0]; - fileName += "." + ext; - } - - if(!fileName.isEmpty()) { - bool withScopyHeader = false; - FileManager fm("HarmonicCalibration"); - fm.open(fileName, FileManager::EXPORT); - - QVector preCalibrationAngleErrorsFFTMagnitude(m_admtController->angle_errors_fft_pre.begin(), m_admtController->angle_errors_fft_pre.end()); - QVector preCalibrationAngleErrorsFFTPhase(m_admtController->angle_errors_fft_phase_pre.begin(), m_admtController->angle_errors_fft_phase_pre.end()); - - QVector h1Mag = { H1_MAG_ANGLE }; - QVector h2Mag = { H2_MAG_ANGLE }; - QVector h3Mag = { H3_MAG_ANGLE }; - QVector h8Mag = { H8_MAG_ANGLE }; - QVector h1Phase = { H1_PHASE_ANGLE }; - QVector h2Phase = { H2_PHASE_ANGLE }; - QVector h3Phase = { H3_PHASE_ANGLE }; - QVector h8Phase = { H8_PHASE_ANGLE }; - - fm.save(graphDataList, "Raw Data"); - fm.save(preCalibrationAngleErrorsFFTMagnitude, "Pre-Calibration Angle Errors FFT Magnitude"); - fm.save(preCalibrationAngleErrorsFFTPhase, "Pre-Calibration Angle Errors FFT Phase"); - fm.save(h1Mag, "H1 Mag"); - fm.save(h2Mag, "H2 Mag"); - fm.save(h3Mag, "H3 Mag"); - fm.save(h8Mag, "H8 Mag"); - fm.save(h1Phase, "H1 Phase"); - fm.save(h2Phase, "H2 Phase"); - fm.save(h3Phase, "H3 Phase"); - fm.save(h8Phase, "H8 Phase"); - - fm.performWrite(withScopyHeader); - } -} - -void HarmonicCalibration::toggleTabSwitching(bool value) -{ - tabWidget->setTabEnabled(0, value); - tabWidget->setTabEnabled(2, value); - tabWidget->setTabEnabled(3, value); -} - -void HarmonicCalibration::toggleCalibrationButtonState(int state) -{ - switch(state) - { - case 0: // Idle - calibrationStartMotorButton->setEnabled(true); - calibrationStartMotorButton->setChecked(false); - calibrateDataButton->setEnabled(false); - calibrateDataButton->setChecked(false); - clearCalibrateDataButton->setEnabled(true); - break; - case 1: // Start Motor - calibrationStartMotorButton->setEnabled(true); - calibrateDataButton->setEnabled(false); - clearCalibrateDataButton->setEnabled(false); - break; - case 2: // After Start Motor - calibrationStartMotorButton->setEnabled(false); - calibrateDataButton->setEnabled(true); - calibrateDataButton->setChecked(false); - clearCalibrateDataButton->setEnabled(true); - break; - case 3: // Post-Calibration - calibrationStartMotorButton->setEnabled(false); - calibrateDataButton->setEnabled(true); - clearCalibrateDataButton->setEnabled(false); - break; - case 4: // After Post-Calibration - calibrationStartMotorButton->setEnabled(false); - calibrateDataButton->setEnabled(false); - clearCalibrateDataButton->setEnabled(true); - break; - } -} - -void HarmonicCalibration::canStartMotor(bool value) -{ - calibrationStartMotorButton->setEnabled(value); -} - -void HarmonicCalibration::canCalibrate(bool value) -{ - calibrateDataButton->setEnabled(value); -} - -void HarmonicCalibration::toggleCalibrationControls(bool value) -{ - // motorMaxVelocitySpinBox->setEnabled(value); - // motorAccelTimeSpinBox->setEnabled(value); - // motorMaxDisplacementSpinBox->setEnabled(value); - // m_calibrationMotorRampModeMenuCombo->setEnabled(value); - motorTargetPositionLineEdit->setEnabled(value); - calibrationModeMenuCombo->setEnabled(value); -} - -void HarmonicCalibration::clearCalibrationSamples() -{ - graphDataList.clear(); - calibrationRawDataPlotChannel->curve()->setData(nullptr); - calibrationSineDataPlotChannel->curve()->setData(nullptr); - calibrationCosineDataPlotChannel->curve()->setData(nullptr); - calibrationRawDataPlotWidget->replot(); -} - -void HarmonicCalibration::clearCalibrationSineCosine() -{ - calibrationSineDataPlotChannel->curve()->setData(nullptr); - calibrationCosineDataPlotChannel->curve()->setData(nullptr); - calibrationRawDataPlotWidget->replot(); -} - -void HarmonicCalibration::clearPostCalibrationSamples() -{ - graphPostDataList.clear(); - postCalibrationRawDataPlotChannel->curve()->setData(nullptr); - postCalibrationSineDataPlotChannel->curve()->setData(nullptr); - postCalibrationCosineDataPlotChannel->curve()->setData(nullptr); - postCalibrationRawDataPlotWidget->replot(); -} - -void HarmonicCalibration::clearAngleErrorGraphs() -{ - angleErrorPlotChannel->curve()->setData(nullptr); - angleErrorPlotWidget->replot(); - FFTAngleErrorMagnitudeChannel->curve()->setData(nullptr); - FFTAngleErrorPhaseChannel->curve()->setData(nullptr); - FFTAngleErrorPlotWidget->replot(); -} - -void HarmonicCalibration::clearCorrectedAngleErrorGraphs() -{ - correctedErrorPlotChannel->curve()->setData(nullptr); - correctedErrorPlotWidget->replot(); - FFTCorrectedErrorMagnitudeChannel->curve()->setData(nullptr); - FFTCorrectedErrorPhaseChannel->curve()->setData(nullptr); - FFTCorrectedErrorPlotWidget->replot(); +void HarmonicCalibration::startCalibrationUITask() { + if (!m_calibrationUIThread.isRunning()) { + isCalibrationTab = true; + m_calibrationUIThread = QtConcurrent::run( + this, &HarmonicCalibration::calibrationUITask, calibrationUITimerRate); + m_calibrationUIWatcher.setFuture(m_calibrationUIThread); + } +} + +void HarmonicCalibration::stopCalibrationUITask() { + isCalibrationTab = false; + if (m_calibrationUIThread.isRunning()) { + m_calibrationUIThread.cancel(); + m_calibrationUIWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::calibrationUITask(int sampleRate) { + while (isCalibrationTab) { + if (isStartMotor) { + if (isPostCalibration) { + postCalibrationRawDataPlotChannel->curve()->setSamples( + graphPostDataList); + postCalibrationRawDataPlotWidget->replot(); + } else { + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotWidget->replot(); + } + } + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::updateCalibrationMotorRPM() { + calibrationMotorRPMLineEdit->setText(QString::number(motor_rpm)); +} + +void HarmonicCalibration::updateCalibrationMotorRotationDirection() { + calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); +} + +void HarmonicCalibration::getCalibrationSamples() { + if (resetCurrentPositionToZero()) { + double step = 0; + if (isMotorRotationClockwise) + step = motorFullStepPerRevolution; + else + step = -motorFullStepPerRevolution; + if (isPostCalibration) { + int currentSamplesCount = graphPostDataList.size(); + while (isStartMotor && currentSamplesCount < totalSamplesCount) { + target_pos = current_pos + step; + moveMotorToPosition(target_pos, true); + updateChannelValue(ADMTController::Channel::ANGLE); + graphPostDataList.append(angle); + currentSamplesCount++; + } + } else { + int currentSamplesCount = graphDataList.size(); + while (isStartMotor && currentSamplesCount < totalSamplesCount) { + target_pos = current_pos + step; + if (moveMotorToPosition(target_pos, true) == false) { + m_admtController->disconnectADMT(); + } + if (updateChannelValue(ADMTController::Channel::ANGLE)) { + break; + } + graphDataList.append(angle); + currentSamplesCount++; + } + } + } + + stopMotor(); +} + +void HarmonicCalibration::startCalibration() { + totalSamplesCount = cycleCount * samplesPerCycle; + graphPostDataList.reserve(totalSamplesCount); + graphPostDataList.squeeze(); + graphDataList.reserve(totalSamplesCount); + graphDataList.squeeze(); + + // configureConversionType(calibrationMode); // TODO uncomment when conversion + // type is okay + configureCalibrationSequenceSettings(); + clearHarmonicRegisters(); + + toggleTabSwitching(false); + toggleCalibrationControls(false); + + calibrationDataGraphTabWidget->setCurrentIndex(0); + calibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); + + toggleCalibrationButtonState(1); + if (calibrationMode == 0) + startContinuousCalibration(); + else + startOneShotCalibration(); +} + +void HarmonicCalibration::stopCalibration() { + isStartMotor = false; + if (calibrationMode == 0) { + stopContinuousCalibration(); + } + + toggleTabSwitching(true); + toggleCalibrationControls(true); +} + +void HarmonicCalibration::startContinuousCalibration() { + stopCurrentMotorPositionMonitor(); + stopDeviceStatusMonitor(); + + if (isPostCalibration) + StatusBarManager::pushMessage( + "Acquiring Post Calibration Samples, Please Wait..."); + else + StatusBarManager::pushMessage( + "Acquiring Calibration Samples, Please Wait..."); + startResetMotorToZero(); +} + +void HarmonicCalibration::stopContinuousCalibration() { + stopMotor(); + stopWaitForVelocityReachedThread(); + stopCalibrationStreamThread(); + + startCurrentMotorPositionMonitor(); + startDeviceStatusMonitor(); +} + +void HarmonicCalibration::startResetMotorToZero() { + isResetMotorToZero = true; + if (!m_resetMotorToZeroThread.isRunning()) { + m_resetMotorToZeroThread = + QtConcurrent::run(this, &HarmonicCalibration::resetMotorToZero); + m_resetMotorToZeroWatcher.setFuture(m_resetMotorToZeroThread); + } +} + +void HarmonicCalibration::stopResetMotorToZero() { + isResetMotorToZero = false; + if (m_resetMotorToZeroThread.isRunning()) { + m_resetMotorToZeroThread.cancel(); + m_resetMotorToZeroWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::resetMotorToZero() { + if (readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, + current_pos) == 0) { + if (current_pos != 0) { + writeMotorAttributeValue( + ADMTController::MotorAttribute::ROTATE_VMAX, + convertRPStoVMAX(convertRPMtoRPS(fast_motor_rpm))); + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, + current_pos); + while (isResetMotorToZero && current_pos != 0) { + if (readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, + current_pos) != 0) + break; + QThread::msleep(readMotorDebounce); + } + if (current_pos == 0) { + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, + rotate_vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); + } + } + } +} + +void HarmonicCalibration::startCalibrationStreamThread() { + if (!m_calibrationStreamThread.isRunning()) { + m_admtController->stopStream = false; + + continuousCalibrationSampleRate = calculateContinuousCalibrationSampleRate( + convertVMAXtoRPS(rotate_vmax), samplesPerCycle); + m_calibrationStreamThread = QtConcurrent::run([this]() { + m_admtController->bufferedStreamIO(totalSamplesCount, + continuousCalibrationSampleRate); + }); + m_calibrationStreamWatcher.setFuture(m_calibrationStreamThread); + } +} + +void HarmonicCalibration::stopCalibrationStreamThread() { + m_admtController->stopStream = true; + if (m_calibrationStreamThread.isRunning()) { + m_calibrationStreamThread.cancel(); + m_calibrationStreamWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::startWaitForVelocityReachedThread(int mode) { + if (!m_calibrationWaitVelocityWatcher.isRunning()) { + isMotorVelocityCheck = true; + m_calibrationWaitVelocityThread = + QtConcurrent::run(this, &HarmonicCalibration::waitForVelocityReached, + mode, motorWaitVelocityReachedSampleRate); + m_calibrationWaitVelocityWatcher.setFuture(m_calibrationWaitVelocityThread); + } +} + +void HarmonicCalibration::stopWaitForVelocityReachedThread() { + isMotorVelocityCheck = false; + if (m_calibrationWaitVelocityWatcher.isRunning()) { + m_calibrationWaitVelocityThread.cancel(); + m_calibrationWaitVelocityWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::waitForVelocityReached(int mode, int sampleRate) { + isMotorVelocityReached = false; + if (mode == 0) { + QThread::msleep(floor(convertAMAXtoAccelTime(amax) * 1000)); + isMotorVelocityReached = true; + } else if (mode == 1) { + moveMotorContinuous(); + uint32_t *registerValue = new uint32_t; + while (isMotorVelocityCheck && !isMotorVelocityReached) { + if (readMotorRegisterValue( + m_admtController->getRampGeneratorDriverFeatureControlRegister( + ADMTController::RampGeneratorDriverFeatureControlRegister:: + RAMP_STAT), + registerValue) == 0) { + isMotorVelocityReached = m_admtController->checkVelocityReachedFlag( + static_cast(*registerValue)); + } + + QThread::msleep(sampleRate); + } + + delete registerValue; + } +} + +int HarmonicCalibration::calculateContinuousCalibrationSampleRate( + double motorRPS, int samplesPerCycle) { + return static_cast(floor(1 / motorRPS / samplesPerCycle * 1000 * 1000 * + 1000)); // In nanoseconds +} + +void HarmonicCalibration::configureConversionType(int mode) { + readSequence(); + GENERALRegisterMap.at("Conversion Type") = mode; + writeSequence(GENERALRegisterMap); +} + +void HarmonicCalibration::configureCalibrationSequenceSettings() { + readSequence(); + GENERALRegisterMap.at("8th Harmonic") = 1; // User-supplied 8th Harmonic + writeSequence(GENERALRegisterMap); +} + +void HarmonicCalibration::getStreamedCalibrationSamples(int microSampleRate) { + int currentSamplesCount = graphDataList.size(); + moveMotorContinuous(); + while (isStartMotor && currentSamplesCount < totalSamplesCount) { + graphDataList.append(m_admtController->streamedValue); + // graphPostDataList.append(m_admtController->streamedValue); + currentSamplesCount = graphDataList.size(); + // currentSamplesCount = graphDataPostList.size(); + + QThread::usleep(microSampleRate); + } +} + +void HarmonicCalibration::startOneShotCalibration() { + if (resetToZero && !isPostCalibration) { + clearCalibrationSamples(); + clearPostCalibrationSamples(); + clearAngleErrorGraphs(); + clearCorrectedAngleErrorGraphs(); + } else if (resetToZero) { + clearPostCalibrationSamples(); + } + + QFuture future = + QtConcurrent::run(this, &HarmonicCalibration::getCalibrationSamples); + QFutureWatcher *watcher = new QFutureWatcher(this); + + connect(watcher, &QFutureWatcher::finished, this, [this]() { + toggleTabSwitching(true); + toggleCalibrationControls(true); + + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotChannel->xAxis()->setMax(graphDataList.size()); + calibrationRawDataPlotWidget->replot(); + isStartMotor = false; + + if (isPostCalibration) { + if (static_cast(graphPostDataList.size()) == totalSamplesCount) { + computeSineCosineOfAngles(graphPostDataList); + m_admtController->postcalibrate( + vector(graphPostDataList.begin(), graphPostDataList.end()), + cycleCount, samplesPerCycle, !isMotorRotationClockwise); + populateCorrectedAngleErrorGraphs(); + isPostCalibration = false; + isStartMotor = false; + resetToZero = true; + toggleCalibrationButtonState(4); + } else + toggleCalibrationButtonState(2); + } else { + if (static_cast(graphDataList.size()) == totalSamplesCount) { + computeSineCosineOfAngles(graphDataList); + calibrationLogWrite(m_admtController->calibrate( + vector(graphDataList.begin(), graphDataList.end()), + cycleCount, samplesPerCycle, !isMotorRotationClockwise)); + populateAngleErrorGraphs(); + calculateHarmonicValues(); + toggleCalibrationButtonState(2); + } else { + resetToZero = true; + toggleCalibrationButtonState(0); + } + } + }); + connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater())); + watcher->setFuture(future); +} + +void HarmonicCalibration::postCalibrateData() { + calibrationLogWrite("==== Post Calibration Start ====\n"); + flashHarmonicValues(); + isPostCalibration = true; + isStartMotor = true; + resetToZero = true; + + toggleTabSwitching(false); + toggleCalibrationControls(false); + + calibrationDataGraphTabWidget->setCurrentIndex(1); + postCalibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); + + toggleCalibrationButtonState(3); + if (calibrationMode == 0) + startContinuousCalibration(); + else + startOneShotCalibration(); +} + +void HarmonicCalibration::resetAllCalibrationState() { + clearCalibrationSamples(); + clearPostCalibrationSamples(); + calibrationDataGraphTabWidget->setCurrentIndex(0); + + clearAngleErrorGraphs(); + clearCorrectedAngleErrorGraphs(); + resultDataTabWidget->setCurrentIndex(0); + + toggleCalibrationButtonState(0); + + isPostCalibration = false; + isCalculatedCoeff = false; + resetToZero = true; + displayCalculatedCoeff(); +} + +void HarmonicCalibration::computeSineCosineOfAngles( + QVector graphDataList) { + m_admtController->computeSineCosineOfAngles( + vector(graphDataList.begin(), graphDataList.end())); + if (isPostCalibration) { + postCalibrationSineDataPlotChannel->curve()->setSamples( + m_admtController->calibration_samples_sine_scaled.data(), + m_admtController->calibration_samples_sine_scaled.size()); + postCalibrationCosineDataPlotChannel->curve()->setSamples( + m_admtController->calibration_samples_cosine_scaled.data(), + m_admtController->calibration_samples_cosine_scaled.size()); + postCalibrationRawDataPlotWidget->replot(); + } else { + calibrationSineDataPlotChannel->curve()->setSamples( + m_admtController->calibration_samples_sine_scaled.data(), + m_admtController->calibration_samples_sine_scaled.size()); + calibrationCosineDataPlotChannel->curve()->setSamples( + m_admtController->calibration_samples_cosine_scaled.data(), + m_admtController->calibration_samples_cosine_scaled.size()); + calibrationRawDataPlotWidget->replot(); + } +} + +void HarmonicCalibration::populateAngleErrorGraphs() { + QVector angleError = QVector( + m_admtController->angleError.begin(), m_admtController->angleError.end()); + QVector FFTAngleErrorMagnitude = + QVector(m_admtController->FFTAngleErrorMagnitude.begin(), + m_admtController->FFTAngleErrorMagnitude.end()); + QVector FFTAngleErrorPhase = + QVector(m_admtController->FFTAngleErrorPhase.begin(), + m_admtController->FFTAngleErrorPhase.end()); + + angleErrorPlotChannel->curve()->setSamples(angleError); + auto angleErrorMinMax = minmax_element(angleError.begin(), angleError.end()); + angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, + *angleErrorMinMax.second); + angleErrorXPlotAxis->setInterval(0, angleError.size()); + angleErrorPlotWidget->replot(); + + FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); + FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); + auto angleErrorMagnitudeMinMax = minmax_element( + FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); + auto angleErrorPhaseMinMax = + minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); + double FFTAngleErrorPlotMin = + *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first + ? *angleErrorMagnitudeMinMax.first + : *angleErrorPhaseMinMax.first; + double FFTAngleErrorPlotMax = + *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second + ? *angleErrorMagnitudeMinMax.second + : *angleErrorPhaseMinMax.second; + FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, + FFTAngleErrorPlotMax); + FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); + FFTAngleErrorPlotWidget->replot(); + + resultDataTabWidget->setCurrentIndex(0); // Set tab to Angle Error +} + +void HarmonicCalibration::populateCorrectedAngleErrorGraphs() { + QVector correctedError(m_admtController->correctedError.begin(), + m_admtController->correctedError.end()); + QVector FFTCorrectedErrorMagnitude( + m_admtController->FFTCorrectedErrorMagnitude.begin(), + m_admtController->FFTCorrectedErrorMagnitude.end()); + QVector FFTCorrectedErrorPhase( + m_admtController->FFTCorrectedErrorPhase.begin(), + m_admtController->FFTCorrectedErrorPhase.end()); + + correctedErrorPlotChannel->curve()->setSamples(correctedError); + auto correctedErrorMagnitudeMinMax = + minmax_element(correctedError.begin(), correctedError.end()); + correctedErrorYPlotAxis->setInterval(*correctedErrorMagnitudeMinMax.first, + *correctedErrorMagnitudeMinMax.second); + correctedErrorXPlotAxis->setMax(correctedError.size()); + correctedErrorPlotWidget->replot(); + + FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); + FFTCorrectedErrorMagnitudeChannel->curve()->setSamples( + FFTCorrectedErrorMagnitude); + auto FFTCorrectedErrorMagnitudeMinMax = minmax_element( + FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); + auto FFTCorrectedErrorPhaseMinMax = minmax_element( + FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); + double FFTCorrectedErrorPlotMin = + *FFTCorrectedErrorMagnitudeMinMax.first < + *FFTCorrectedErrorPhaseMinMax.first + ? *FFTCorrectedErrorMagnitudeMinMax.first + : *FFTCorrectedErrorPhaseMinMax.first; + double FFTCorrectedErrorPlotMax = + *FFTCorrectedErrorMagnitudeMinMax.second > + *FFTCorrectedErrorPhaseMinMax.second + ? *FFTCorrectedErrorMagnitudeMinMax.second + : *FFTCorrectedErrorPhaseMinMax.second; + FFTCorrectedErrorYPlotAxis->setInterval(FFTCorrectedErrorPlotMin, + FFTCorrectedErrorPlotMax); + FFTCorrectedErrorXPlotAxis->setMax(FFTCorrectedErrorMagnitude.size()); + FFTCorrectedErrorPlotWidget->replot(); + + resultDataTabWidget->setCurrentIndex(2); // Set tab to Angle Error +} + +void HarmonicCalibration::clearHarmonicRegisters() { + bool success = false; + uint32_t value = 0x0; + uint32_t harmonicCNVPage = m_admtController->getHarmonicPage( + ADMTController::HarmonicRegister::H1MAG); + if (changeCNVPage(harmonicCNVPage)) { + success = + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H1MAG), + value) == 0 + ? true + : false; + success = + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H1PH), + value) == 0 + ? true + : false; + success = + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H2MAG), + value) == 0 + ? true + : false; + success = + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H2PH), + value) == 0 + ? true + : false; + success = + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H3MAG), + value) == 0 + ? true + : false; + success = + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H3PH), + value) == 0 + ? true + : false; + success = + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H8MAG), + value) == 0 + ? true + : false; + success = + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H8PH), + value) == 0 + ? true + : false; + } + + if (!success) { + calibrationLogWrite("Unable to clear Harmonic Registers!"); + } +} + +void HarmonicCalibration::flashHarmonicValues() { + if (changeCNVPage(0x02)) { + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), 0x01, + 0x02); + + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H1MAG), + H1_MAG_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H1PH), + H1_PHASE_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H2MAG), + H2_MAG_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H2PH), + H2_PHASE_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H3MAG), + H3_MAG_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H3PH), + H3_PHASE_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H8MAG), + H8_MAG_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H8PH), + H8_PHASE_HEX); + + isCalculatedCoeff = true; + displayCalculatedCoeff(); + } else { + calibrationLogWrite("Unabled to flash Harmonic Registers!"); + } +} + +void HarmonicCalibration::calculateHarmonicValues() { + uint32_t *h1MagCurrent = new uint32_t, *h1PhaseCurrent = new uint32_t, + *h2MagCurrent = new uint32_t, *h2PhaseCurrent = new uint32_t, + *h3MagCurrent = new uint32_t, *h3PhaseCurrent = new uint32_t, + *h8MagCurrent = new uint32_t, *h8PhaseCurrent = new uint32_t; + + if (changeCNVPage(0x02)) { + // Read and store current harmonic values + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H1MAG), + h1MagCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H2MAG), + h2MagCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H3MAG), + h3MagCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H8MAG), + h8MagCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H1PH), + h1PhaseCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H2PH), + h2PhaseCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H3PH), + h3PhaseCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister( + ADMTController::HarmonicRegister::H8PH), + h8PhaseCurrent); + + // Calculate harmonic coefficients (Hex) + H1_MAG_HEX = static_cast( + m_admtController->calculateHarmonicCoefficientMagnitude( + static_cast(m_admtController->HAR_MAG_1), + static_cast(*h1MagCurrent), "h1")); + H2_MAG_HEX = static_cast( + m_admtController->calculateHarmonicCoefficientMagnitude( + static_cast(m_admtController->HAR_MAG_2), + static_cast(*h2MagCurrent), "h2")); + H3_MAG_HEX = static_cast( + m_admtController->calculateHarmonicCoefficientMagnitude( + static_cast(m_admtController->HAR_MAG_3), + static_cast(*h3MagCurrent), "h3")); + H8_MAG_HEX = static_cast( + m_admtController->calculateHarmonicCoefficientMagnitude( + static_cast(m_admtController->HAR_MAG_8), + static_cast(*h8MagCurrent), "h8")); + H1_PHASE_HEX = static_cast( + m_admtController->calculateHarmonicCoefficientPhase( + static_cast(m_admtController->HAR_PHASE_1), + static_cast(*h1PhaseCurrent))); + H2_PHASE_HEX = static_cast( + m_admtController->calculateHarmonicCoefficientPhase( + static_cast(m_admtController->HAR_PHASE_2), + static_cast(*h2PhaseCurrent))); + H3_PHASE_HEX = static_cast( + m_admtController->calculateHarmonicCoefficientPhase( + static_cast(m_admtController->HAR_PHASE_3), + static_cast(*h3PhaseCurrent))); + H8_PHASE_HEX = static_cast( + m_admtController->calculateHarmonicCoefficientPhase( + static_cast(m_admtController->HAR_PHASE_8), + static_cast(*h8PhaseCurrent))); + + calibrationLogWrite(); + calibrationLogWrite( + QString("Calculated H1 Mag (Hex): 0x%1") + .arg(QString::number(H1_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite( + QString("Calculated H1 Phase (Hex): 0x%1") + .arg(QString::number(H1_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite( + QString("Calculated H2 Mag (Hex): 0x%1") + .arg(QString::number(H2_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite( + QString("Calculated H2 Phase (Hex): 0x%1") + .arg(QString::number(H2_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite( + QString("Calculated H3 Mag (Hex): 0x%1") + .arg(QString::number(H3_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite( + QString("Calculated H3 Phase (Hex): 0x%1") + .arg(QString::number(H3_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite( + QString("Calculated H8 Mag (Hex): 0x%1") + .arg(QString::number(H8_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite( + QString("Calculated H8 Phase (Hex): 0x%1") + .arg(QString::number(H8_PHASE_HEX, 16).rightJustified(4, '0'))); + + // Get actual harmonic values from hex + H1_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue( + static_cast(H1_MAG_HEX), "h1mag"); + H1_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue( + static_cast(H1_PHASE_HEX), "h1phase"); + H2_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue( + static_cast(H2_MAG_HEX), "h2mag"); + H2_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue( + static_cast(H2_PHASE_HEX), "h2phase"); + H3_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue( + static_cast(H3_MAG_HEX), "h3mag"); + H3_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue( + static_cast(H3_PHASE_HEX), "h3phase"); + H8_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue( + static_cast(H8_MAG_HEX), "h8mag"); + H8_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue( + static_cast(H8_PHASE_HEX), "h8phase"); + + calibrationLogWrite(); + calibrationLogWrite(QString("Calculated H1 Mag (Angle): %1°") + .arg(QString::number(H1_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H1 Phase (Angle): %1°") + .arg(QString::number(H1_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H2 Mag (Angle): %1°") + .arg(QString::number(H2_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H2 Phase (Angle): %1°") + .arg(QString::number(H2_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H3 Mag (Angle): %1°") + .arg(QString::number(H3_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H3 Phase (Angle): %1°") + .arg(QString::number(H3_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H8 Mag (Angle): %1°") + .arg(QString::number(H8_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H8 Phase (Angle): %1°") + .arg(QString::number(H8_PHASE_ANGLE))); + + if (isAngleDisplayFormat) + updateCalculatedCoeffAngle(); + else + updateCalculatedCoeffHex(); + isCalculatedCoeff = true; + } +} + +void HarmonicCalibration::updateCalculatedCoeffAngle() { + calibrationH1MagLabel->setText(QString::number(H1_MAG_ANGLE, 'f', 2) + "°"); + calibrationH2MagLabel->setText(QString::number(H2_MAG_ANGLE, 'f', 2) + "°"); + calibrationH3MagLabel->setText(QString::number(H3_MAG_ANGLE, 'f', 2) + "°"); + calibrationH8MagLabel->setText(QString::number(H8_MAG_ANGLE, 'f', 2) + "°"); + calibrationH1PhaseLabel->setText("Φ " + + QString::number(H1_PHASE_ANGLE, 'f', 2)); + calibrationH2PhaseLabel->setText("Φ " + + QString::number(H2_PHASE_ANGLE, 'f', 2)); + calibrationH3PhaseLabel->setText("Φ " + + QString::number(H3_PHASE_ANGLE, 'f', 2)); + calibrationH8PhaseLabel->setText("Φ " + + QString::number(H8_PHASE_ANGLE, 'f', 2)); +} + +void HarmonicCalibration::updateCalculatedCoeffHex() { + calibrationH1MagLabel->setText( + QString("0x%1").arg(H1_MAG_HEX, 4, 16, QChar('0'))); + calibrationH2MagLabel->setText( + QString("0x%1").arg(H2_MAG_HEX, 4, 16, QChar('0'))); + calibrationH3MagLabel->setText( + QString("0x%1").arg(H3_MAG_HEX, 4, 16, QChar('0'))); + calibrationH8MagLabel->setText( + QString("0x%1").arg(H8_MAG_HEX, 4, 16, QChar('0'))); + calibrationH1PhaseLabel->setText( + QString("0x%1").arg(H1_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH2PhaseLabel->setText( + QString("0x%1").arg(H2_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH3PhaseLabel->setText( + QString("0x%1").arg(H3_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH8PhaseLabel->setText( + QString("0x%1").arg(H8_PHASE_HEX, 4, 16, QChar('0'))); +} + +void HarmonicCalibration::resetCalculatedCoeffAngle() { + calibrationH1MagLabel->setText("--.--°"); + calibrationH2MagLabel->setText("--.--°"); + calibrationH3MagLabel->setText("--.--°"); + calibrationH8MagLabel->setText("--.--°"); + calibrationH1PhaseLabel->setText("Φ --.--"); + calibrationH2PhaseLabel->setText("Φ --.--"); + calibrationH3PhaseLabel->setText("Φ --.--"); + calibrationH8PhaseLabel->setText("Φ --.--"); +} + +void HarmonicCalibration::resetCalculatedCoeffHex() { + calibrationH1MagLabel->setText("0x----"); + calibrationH2MagLabel->setText("0x----"); + calibrationH3MagLabel->setText("0x----"); + calibrationH8MagLabel->setText("0x----"); + calibrationH1PhaseLabel->setText("0x----"); + calibrationH2PhaseLabel->setText("0x----"); + calibrationH3PhaseLabel->setText("0x----"); + calibrationH8PhaseLabel->setText("0x----"); +} + +void HarmonicCalibration::displayCalculatedCoeff() { + if (isAngleDisplayFormat) { + if (isCalculatedCoeff) { + updateCalculatedCoeffAngle(); + } else { + resetCalculatedCoeffAngle(); + } + } else { + if (isCalculatedCoeff) { + updateCalculatedCoeffHex(); + } else { + resetCalculatedCoeffHex(); + } + } +} + +void HarmonicCalibration::calibrationLogWrite(QString message) { + logsPlainTextEdit->appendPlainText(message); +} + +void HarmonicCalibration::importCalibrationData() { + QString fileName = + QFileDialog::getOpenFileName(this, tr("Import"), "", + tr("Comma-separated values files (*.csv);;" + "Tab-delimited values files (*.txt)"), + nullptr, QFileDialog::Options()); + + FileManager fm("HarmonicCalibration"); + + try { + fm.open(fileName, FileManager::IMPORT); + + graphDataList = fm.read(0); + if (graphDataList.size() > 0) { + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataXPlotAxis->setInterval(0, graphDataList.size()); + calibrationRawDataPlotWidget->replot(); + + computeSineCosineOfAngles(graphDataList); + calibrationLogWrite(m_admtController->calibrate( + vector(graphDataList.begin(), graphDataList.end()), + cycleCount, samplesPerCycle, false)); // TODO: Hard-coded Clockwise + populateAngleErrorGraphs(); + toggleCalibrationButtonState(2); + } + } catch (FileManagerException &ex) { + calibrationLogWrite(QString(ex.what())); + } +} + +void HarmonicCalibration::extractCalibrationData() { + QStringList filter; + filter += QString(tr("Comma-separated values files (*.csv)")); + filter += QString(tr("Tab-delimited values files (*.txt)")); + filter += QString(tr("All Files(*)")); + + QString selectedFilter = filter[0]; + + QString fileName = + QFileDialog::getSaveFileName(this, tr("Export"), "", filter.join(";;"), + &selectedFilter, QFileDialog::Options()); + + if (fileName.split(".").size() <= 1) { + QString ext = selectedFilter.split(".")[1].split(")")[0]; + fileName += "." + ext; + } + + if (!fileName.isEmpty()) { + bool withScopyHeader = false; + FileManager fm("HarmonicCalibration"); + fm.open(fileName, FileManager::EXPORT); + + QVector preCalibrationAngleErrorsFFTMagnitude( + m_admtController->angle_errors_fft_pre.begin(), + m_admtController->angle_errors_fft_pre.end()); + QVector preCalibrationAngleErrorsFFTPhase( + m_admtController->angle_errors_fft_phase_pre.begin(), + m_admtController->angle_errors_fft_phase_pre.end()); + + QVector h1Mag = {H1_MAG_ANGLE}; + QVector h2Mag = {H2_MAG_ANGLE}; + QVector h3Mag = {H3_MAG_ANGLE}; + QVector h8Mag = {H8_MAG_ANGLE}; + QVector h1Phase = {H1_PHASE_ANGLE}; + QVector h2Phase = {H2_PHASE_ANGLE}; + QVector h3Phase = {H3_PHASE_ANGLE}; + QVector h8Phase = {H8_PHASE_ANGLE}; + + fm.save(graphDataList, "Raw Data"); + fm.save(preCalibrationAngleErrorsFFTMagnitude, + "Pre-Calibration Angle Errors FFT Magnitude"); + fm.save(preCalibrationAngleErrorsFFTPhase, + "Pre-Calibration Angle Errors FFT Phase"); + fm.save(h1Mag, "H1 Mag"); + fm.save(h2Mag, "H2 Mag"); + fm.save(h3Mag, "H3 Mag"); + fm.save(h8Mag, "H8 Mag"); + fm.save(h1Phase, "H1 Phase"); + fm.save(h2Phase, "H2 Phase"); + fm.save(h3Phase, "H3 Phase"); + fm.save(h8Phase, "H8 Phase"); + + fm.performWrite(withScopyHeader); + } +} + +void HarmonicCalibration::toggleTabSwitching(bool value) { + tabWidget->setTabEnabled(0, value); + tabWidget->setTabEnabled(2, value); + tabWidget->setTabEnabled(3, value); +} + +void HarmonicCalibration::toggleCalibrationButtonState(int state) { + switch (state) { + case 0: // Idle + calibrationStartMotorButton->setEnabled(true); + calibrationStartMotorButton->setChecked(false); + calibrateDataButton->setEnabled(false); + calibrateDataButton->setChecked(false); + clearCalibrateDataButton->setEnabled(true); + break; + case 1: // Start Motor + calibrationStartMotorButton->setEnabled(true); + calibrateDataButton->setEnabled(false); + clearCalibrateDataButton->setEnabled(false); + break; + case 2: // After Start Motor + calibrationStartMotorButton->setEnabled(false); + calibrateDataButton->setEnabled(true); + calibrateDataButton->setChecked(false); + clearCalibrateDataButton->setEnabled(true); + break; + case 3: // Post-Calibration + calibrationStartMotorButton->setEnabled(false); + calibrateDataButton->setEnabled(true); + clearCalibrateDataButton->setEnabled(false); + break; + case 4: // After Post-Calibration + calibrationStartMotorButton->setEnabled(false); + calibrateDataButton->setEnabled(false); + clearCalibrateDataButton->setEnabled(true); + break; + } +} + +void HarmonicCalibration::canStartMotor(bool value) { + calibrationStartMotorButton->setEnabled(value); +} + +void HarmonicCalibration::canCalibrate(bool value) { + calibrateDataButton->setEnabled(value); +} + +void HarmonicCalibration::toggleCalibrationControls(bool value) { + // motorMaxVelocitySpinBox->setEnabled(value); + // motorAccelTimeSpinBox->setEnabled(value); + // motorMaxDisplacementSpinBox->setEnabled(value); + // m_calibrationMotorRampModeMenuCombo->setEnabled(value); + motorTargetPositionLineEdit->setEnabled(value); + calibrationModeMenuCombo->setEnabled(value); +} + +void HarmonicCalibration::clearCalibrationSamples() { + graphDataList.clear(); + calibrationRawDataPlotChannel->curve()->setData(nullptr); + calibrationSineDataPlotChannel->curve()->setData(nullptr); + calibrationCosineDataPlotChannel->curve()->setData(nullptr); + calibrationRawDataPlotWidget->replot(); +} + +void HarmonicCalibration::clearCalibrationSineCosine() { + calibrationSineDataPlotChannel->curve()->setData(nullptr); + calibrationCosineDataPlotChannel->curve()->setData(nullptr); + calibrationRawDataPlotWidget->replot(); +} + +void HarmonicCalibration::clearPostCalibrationSamples() { + graphPostDataList.clear(); + postCalibrationRawDataPlotChannel->curve()->setData(nullptr); + postCalibrationSineDataPlotChannel->curve()->setData(nullptr); + postCalibrationCosineDataPlotChannel->curve()->setData(nullptr); + postCalibrationRawDataPlotWidget->replot(); +} + +void HarmonicCalibration::clearAngleErrorGraphs() { + angleErrorPlotChannel->curve()->setData(nullptr); + angleErrorPlotWidget->replot(); + FFTAngleErrorMagnitudeChannel->curve()->setData(nullptr); + FFTAngleErrorPhaseChannel->curve()->setData(nullptr); + FFTAngleErrorPlotWidget->replot(); +} + +void HarmonicCalibration::clearCorrectedAngleErrorGraphs() { + correctedErrorPlotChannel->curve()->setData(nullptr); + correctedErrorPlotWidget->replot(); + FFTCorrectedErrorMagnitudeChannel->curve()->setData(nullptr); + FFTCorrectedErrorPhaseChannel->curve()->setData(nullptr); + FFTCorrectedErrorPlotWidget->replot(); } #pragma endregion #pragma region Motor Methods -bool HarmonicCalibration::moveMotorToPosition(double& position, bool validate) -{ - bool success = false; - bool canRead = true; - if(writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, position) == 0){ - if(validate){ - if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) - { - while(target_pos != current_pos && canRead) { - canRead = readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0 ? true : false; - } - if(canRead) success = true; - } - } - } - - return success; -} - -void HarmonicCalibration::moveMotorContinuous() -{ - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - setRampMode(isMotorRotationClockwise); -} - -bool HarmonicCalibration::resetCurrentPositionToZero() -{ - bool success = false; - if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) - { - if(current_pos != 0 && - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0) == 0 && - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) - { - while(current_pos != 0){ - if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) != 0) break; - QThread::msleep(readMotorDebounce); - } - if(current_pos == 0) - { - resetToZero = false; - success = true; - } - } - else{ - success = true; - } - } - - return success; -} - -void HarmonicCalibration::stopMotor() -{ - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); -} - -int HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute attribute, double& value) -{ - int result = -1; - if(!isDebug){ - result = m_admtController->getDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), - m_admtController->getMotorAttribute(attribute), - &value); - } - return result; -} - -int HarmonicCalibration::writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value) -{ - int result = -1; - if(!isDebug){ - result = m_admtController->setDeviceAttributeValue(m_admtController->getDeviceId(ADMTController::Device::TMC5240), - m_admtController->getMotorAttribute(attribute), - value); - } - return result; -} - -int HarmonicCalibration::readMotorRegisterValue(uint32_t address, uint32_t *value) -{ - int result = -1; - result = m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::TMC5240), - address, - value); - return result; -} - -void HarmonicCalibration::setRampMode(bool motorRotationClockwise) -{ - // Ramp Mode 1: Clockwise, Ramp Mode 2: Counter-Clockwise - isMotorRotationClockwise = motorRotationClockwise; - int mode = isMotorRotationClockwise ? 1 : 2; - writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, mode); -} - -void HarmonicCalibration::getRampMode() -{ - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - // Ramp Mode 1: Counter-Clockwise, Ramp Mode 2: Clockwise - if(ramp_mode == 1) isMotorRotationClockwise = false; - else if(ramp_mode == 2) isMotorRotationClockwise = true; +bool HarmonicCalibration::moveMotorToPosition(double &position, bool validate) { + bool success = false; + bool canRead = true; + if (writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, + position) == 0) { + if (validate) { + if (readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, + current_pos) == 0) { + while (target_pos != current_pos && canRead) { + canRead = + readMotorAttributeValue( + ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0 + ? true + : false; + } + if (canRead) + success = true; + } + } + } + + return success; +} + +void HarmonicCalibration::moveMotorContinuous() { + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, + rotate_vmax); + setRampMode(isMotorRotationClockwise); +} + +bool HarmonicCalibration::resetCurrentPositionToZero() { + bool success = false; + if (readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, + current_pos) == 0) { + if (current_pos != 0 && + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, + 0) == 0 && + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, + current_pos) == 0) { + while (current_pos != 0) { + if (readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, + current_pos) != 0) + break; + QThread::msleep(readMotorDebounce); + } + if (current_pos == 0) { + resetToZero = false; + success = true; + } + } else { + success = true; + } + } + + return success; +} + +void HarmonicCalibration::stopMotor() { + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); +} + +int HarmonicCalibration::readMotorAttributeValue( + ADMTController::MotorAttribute attribute, double &value) { + int result = -1; + if (!isDebug) { + result = m_admtController->getDeviceAttributeValue( + m_admtController->getDeviceId(ADMTController::Device::TMC5240), + m_admtController->getMotorAttribute(attribute), &value); + } + return result; +} + +int HarmonicCalibration::writeMotorAttributeValue( + ADMTController::MotorAttribute attribute, double value) { + int result = -1; + if (!isDebug) { + result = m_admtController->setDeviceAttributeValue( + m_admtController->getDeviceId(ADMTController::Device::TMC5240), + m_admtController->getMotorAttribute(attribute), value); + } + return result; +} + +int HarmonicCalibration::readMotorRegisterValue(uint32_t address, + uint32_t *value) { + int result = -1; + result = m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::TMC5240), address, + value); + return result; +} + +void HarmonicCalibration::setRampMode(bool motorRotationClockwise) { + // Ramp Mode 1: Clockwise, Ramp Mode 2: Counter-Clockwise + isMotorRotationClockwise = motorRotationClockwise; + int mode = isMotorRotationClockwise ? 1 : 2; + writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, mode); +} + +void HarmonicCalibration::getRampMode() { + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + // Ramp Mode 1: Counter-Clockwise, Ramp Mode 2: Clockwise + if (ramp_mode == 1) + isMotorRotationClockwise = false; + else if (ramp_mode == 2) + isMotorRotationClockwise = true; } #pragma endregion #pragma region Utility Methods -void HarmonicCalibration::startUtilityTask() -{ - if(!m_utilityThread.isRunning()) - { - isUtilityTab = true; - m_utilityThread = QtConcurrent::run(this, &HarmonicCalibration::utilityTask, utilityUITimerRate); - m_utilityWatcher.setFuture(m_utilityThread); - } -} - -void HarmonicCalibration::stopUtilityTask() -{ - isUtilityTab = false; - if(m_utilityThread.isRunning()) - { - m_utilityThread.cancel(); - m_utilityWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::utilityTask(int sampleRate){ - while(isUtilityTab) - { - getDIGIOENRegister(); - getFAULTRegister(); - if(hasMTDiagnostics) - { - getDIAG1Register(); - getDIAG2Register(); - } - - Q_EMIT commandLogWriteSignal(""); - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::toggleUtilityTask(bool run) -{ - if(run) - { - startUtilityTask(); - } - else - { - stopUtilityTask(); - } -} - -void HarmonicCalibration::getDIGIOENRegister(){ - uint32_t *digioRegValue = new uint32_t; - uint32_t digioEnPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - if(changeCNVPage(digioEnPage)) - { - uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN); - - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), digioRegisterAddress, digioRegValue) != -1){ - uint16_t *digioRegValue16 = new uint16_t; - *digioRegValue16 = static_cast(*digioRegValue); - - Q_EMIT DIGIORegisterChanged(digioRegValue16); - - Q_EMIT commandLogWriteSignal("DIGIOEN: 0b" + QString::number(*digioRegValue, 2).rightJustified(16, '0')); - - delete digioRegValue16; - } - else{ Q_EMIT commandLogWriteSignal("Failed to read DIGIOEN Register"); } - } - - delete digioRegValue; -} - -void HarmonicCalibration::updateDIGIOUI(uint16_t *registerValue) -{ - DIGIOENRegisterMap = m_admtController->getDIGIOENRegisterBitMapping(*registerValue); - updateDIGIOMonitorUI(); - updateDIGIOControlUI(); -} - -void HarmonicCalibration::updateDIGIOMonitorUI() -{ - map registerMap = DIGIOENRegisterMap; - DIGIOBusyStatusLED->setChecked(registerMap.at("BUSY")); - DIGIOCNVStatusLED->setChecked(registerMap.at("CNV")); - DIGIOSENTStatusLED->setChecked(registerMap.at("SENT")); - DIGIOACALCStatusLED->setChecked(registerMap.at("ACALC")); - DIGIOFaultStatusLED->setChecked(registerMap.at("FAULT")); - DIGIOBootloaderStatusLED->setChecked(registerMap.at("BOOTLOAD")); - - if(!registerMap.at("BUSY")) DIGIOBusyStatusLED->setText("BUSY (Output)"); - else{ - if(registerMap.at("DIGIO0EN")) DIGIOBusyStatusLED->setText("GPIO0 (Output)"); - else DIGIOBusyStatusLED->setText("GPIO0 (Input)"); - } - - if(!registerMap.at("CNV")) DIGIOCNVStatusLED->setText("CNV (Input)"); - else{ - if(registerMap.at("DIGIO1EN")) DIGIOCNVStatusLED->setText("GPIO1 (Output)"); - else DIGIOCNVStatusLED->setText("GPIO1 (Input)"); - } - - if(!registerMap.at("SENT")) DIGIOSENTStatusLED->setText("SENT (Output)"); - else{ - if(registerMap.at("DIGIO2EN")) DIGIOSENTStatusLED->setText("GPIO2 (Output)"); - else DIGIOSENTStatusLED->setText("GPIO2 (Input)"); - } - - if(!registerMap.at("ACALC")) DIGIOACALCStatusLED->setText("ACALC (Output)"); - else{ - if(registerMap.at("DIGIO3EN")) DIGIOACALCStatusLED->setText("GPIO3 (Output)"); - else DIGIOACALCStatusLED->setText("GPIO3 (Input)"); - } - - if(!registerMap.at("FAULT")) DIGIOFaultStatusLED->setText("FAULT (Output)"); - else{ - if(registerMap.at("DIGIO4EN")) DIGIOFaultStatusLED->setText("GPIO4 (Output)"); - else DIGIOFaultStatusLED->setText("GPIO4 (Input)"); - } - - if(!registerMap.at("BOOTLOAD")) DIGIOBootloaderStatusLED->setText("BOOTLOAD (Output)"); - else{ - if(registerMap.at("DIGIO5EN")) DIGIOBootloaderStatusLED->setText("GPIO5 (Output)"); - else DIGIOBootloaderStatusLED->setText("GPIO5 (Input)"); - } -} - -void HarmonicCalibration::updateDIGIOControlUI() -{ - map registerMap = DIGIOENRegisterMap; - - DIGIO0ENToggleSwitch->setChecked(registerMap.at("DIGIO0EN")); - DIGIO1ENToggleSwitch->setChecked(registerMap.at("DIGIO1EN")); - DIGIO2ENToggleSwitch->setChecked(registerMap.at("DIGIO2EN")); - DIGIO3ENToggleSwitch->setChecked(registerMap.at("DIGIO3EN")); - DIGIO4ENToggleSwitch->setChecked(registerMap.at("DIGIO4EN")); - DIGIO5ENToggleSwitch->setChecked(registerMap.at("DIGIO5EN")); - DIGIO0FNCToggleSwitch->setChecked(registerMap.at("BUSY")); - DIGIO1FNCToggleSwitch->setChecked(registerMap.at("CNV")); - DIGIO2FNCToggleSwitch->setChecked(registerMap.at("SENT")); - DIGIO3FNCToggleSwitch->setChecked(registerMap.at("ACALC")); - DIGIO4FNCToggleSwitch->setChecked(registerMap.at("FAULT")); - DIGIO5FNCToggleSwitch->setChecked(registerMap.at("BOOTLOAD")); -} - -void HarmonicCalibration::getDIAG2Register(){ - uint32_t *mtDiag2RegValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t mtDiag2RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG2); - uint32_t mtDiag2PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2); - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); - - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag2PageValue) != -1){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ - if(*cnvPageRegValue == mtDiag2PageValue){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag2RegisterAddress, mtDiag2RegValue) != -1){ - uint16_t *mtDiag2RegValue16 = new uint16_t; - *mtDiag2RegValue16 = static_cast(*mtDiag2RegValue); - - Q_EMIT DIAG2RegisterChanged(mtDiag2RegValue16); - - Q_EMIT commandLogWriteSignal("DIAG2: 0b" + QString::number(*mtDiag2RegValue, 2).rightJustified(16, '0')); - - delete mtDiag2RegValue16; - } - else{ Q_EMIT commandLogWriteSignal("Failed to read MT Diagnostic 2 Register"); } - } - else{ Q_EMIT commandLogWriteSignal("CNVPAGE for MT Diagnostic 2 is a different value, abort reading"); } - } - else{ Q_EMIT commandLogWriteSignal("Failed to read CNVPAGE for MT Diagnostic 2"); } - } - else{ Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 2"); } - - delete mtDiag2RegValue, cnvPageRegValue; -} - -void HarmonicCalibration::updateMTDiagnosticsUI(uint16_t *registerValue) -{ - DIAG2RegisterMap = m_admtController->getDiag2RegisterBitMapping(*registerValue); - - map regmap = DIAG2RegisterMap; - afeDiag0 = regmap.at("AFE Diagnostic 0 (-57%)"); - afeDiag1 = regmap.at("AFE Diagnostic 1 (+57%)"); - AFEDIAG0LineEdit->setText(QString::number(afeDiag0) + " V"); - AFEDIAG1LineEdit->setText(QString::number(afeDiag1) + " V"); -} - -void HarmonicCalibration::getDIAG1Register(){ - uint32_t *mtDiag1RegValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1); - uint32_t mtDiag1PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); - - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag1PageValue) != -1){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1){ - if(*cnvPageRegValue == mtDiag1PageValue){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1){ - uint16_t *mtDiag1RegValue16 = new uint16_t; - *mtDiag1RegValue16 = static_cast(*mtDiag1RegValue); - Q_EMIT DIAG1RegisterChanged(mtDiag1RegValue16); - - Q_EMIT commandLogWriteSignal("DIAG1: 0b" + QString::number(*mtDiag1RegValue16, 2).rightJustified(16, '0')); - - delete mtDiag1RegValue16; - } - else{ Q_EMIT commandLogWriteSignal("Failed to read MT Diagnostic 1 Register"); } - } - else{ Q_EMIT commandLogWriteSignal("CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); } - } - else{ Q_EMIT commandLogWriteSignal("Failed to read CNVPAGE for MT Diagnostic 1"); } - } - else{ Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 1"); } - - delete mtDiag1RegValue, cnvPageRegValue; -} - -void HarmonicCalibration::updateMTDiagnosticRegisterUI(uint16_t *registerValue) -{ - DIAG1RegisterMap = m_admtController->getDiag1RegisterBitMapping_Register(*registerValue); - DIAG1AFERegisterMap = m_admtController->getDiag1RegisterBitMapping_Afe(*registerValue, is5V); - - map regmap = DIAG1RegisterMap; - map afeRegmap = DIAG1AFERegisterMap; - R0StatusLED->setChecked(regmap.at("R0")); - R1StatusLED->setChecked(regmap.at("R1")); - R2StatusLED->setChecked(regmap.at("R2")); - R3StatusLED->setChecked(regmap.at("R3")); - R4StatusLED->setChecked(regmap.at("R4")); - R5StatusLED->setChecked(regmap.at("R5")); - R6StatusLED->setChecked(regmap.at("R6")); - R7StatusLED->setChecked(regmap.at("R7")); - afeDiag2 = afeRegmap.at("AFE Diagnostic 2"); - AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); -} - -void HarmonicCalibration::getFAULTRegister(){ - uint32_t *faultRegValue = new uint32_t; - uint32_t faultRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT); - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, 0); // Write all zeros to fault before read - - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, faultRegValue) != -1){ - uint16_t *faultRegValue16 = new uint16_t; - *faultRegValue16 = static_cast(*faultRegValue); - - Q_EMIT FaultRegisterChanged(faultRegValue16); - - Q_EMIT commandLogWriteSignal("FAULT: 0b" + QString::number(*faultRegValue, 2).rightJustified(16, '0')); - - delete faultRegValue16; - } - else{ Q_EMIT commandLogWriteSignal("Failed to read FAULT Register"); } - - delete faultRegValue; -} - -void HarmonicCalibration::updateFaultRegisterUI(uint16_t *faultRegValue) -{ - FAULTRegisterMap = m_admtController->getFaultRegisterBitMapping(*faultRegValue); - - map regmap = FAULTRegisterMap; - VDDUnderVoltageStatusLED->setChecked(regmap.at("VDD Under Voltage")); - VDDOverVoltageStatusLED->setChecked(regmap.at("VDD Over Voltage")); - VDRIVEUnderVoltageStatusLED->setChecked(regmap.at("VDRIVE Under Voltage")); - VDRIVEOverVoltageStatusLED->setChecked(regmap.at("VDRIVE Over Voltage")); - AFEDIAGStatusLED->setChecked(regmap.at("AFE Diagnostic")); - NVMCRCFaultStatusLED->setChecked(regmap.at("NVM CRC Fault")); - ECCDoubleBitErrorStatusLED->setChecked(regmap.at("ECC Double Bit Error")); - OscillatorDriftStatusLED->setChecked(regmap.at("Oscillator Drift")); - CountSensorFalseStateStatusLED->setChecked(regmap.at("Count Sensor False State")); - AngleCrossCheckStatusLED->setChecked(regmap.at("Angle Cross Check")); - TurnCountSensorLevelsStatusLED->setChecked(regmap.at("Turn Count Sensor Levels")); - MTDIAGStatusLED->setChecked(regmap.at("MT Diagnostic")); - TurnCounterCrossCheckStatusLED->setChecked(regmap.at("Turn Counter Cross Check")); - RadiusCheckStatusLED->setChecked(regmap.at("AMR Radius Check")); - SequencerWatchdogStatusLED->setChecked(regmap.at("Sequencer Watchdog")); -} - -void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) -{ - toggleUtilityTask(false); - - uint32_t *DIGIOENRegisterValue = new uint32_t; - uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - - if(changeCNVPage(DIGIOENPage)) - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) - { - map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); - - DIGIOSettings.at(DIGIOENName) = value; - - uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue), DIGIOSettings); - - if(changeCNVPage(DIGIOENPage)){ - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - static_cast(newRegisterValue)) != -1) - { - updateDIGIOControlUI(); - } - } - - } - } - - toggleUtilityTask(true); -} - -void HarmonicCalibration::toggleMTDiagnostics(int mode) -{ - switch(mode){ - case 0: - MTDiagnosticsScrollArea->hide(); - hasMTDiagnostics = false; - break; - case 1: - MTDiagnosticsScrollArea->show(); - hasMTDiagnostics = true; - break; - } -} - -void HarmonicCalibration::toggleFaultRegisterMode(int mode) -{ - switch(mode){ - case 0: - AFEDIAGStatusLED->hide(); - OscillatorDriftStatusLED->hide(); - AngleCrossCheckStatusLED->hide(); - TurnCountSensorLevelsStatusLED->hide(); - MTDIAGStatusLED->hide(); - SequencerWatchdogStatusLED->hide(); - break; - case 1: - AFEDIAGStatusLED->show(); - OscillatorDriftStatusLED->show(); - AngleCrossCheckStatusLED->show(); - TurnCountSensorLevelsStatusLED->show(); - MTDIAGStatusLED->show(); - SequencerWatchdogStatusLED->show(); - break; - } -} - -bool HarmonicCalibration::resetDIGIO() -{ - return (m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - 0x241b) == 0 ? true : false); -} - -void HarmonicCalibration::commandLogWrite(QString message) -{ - commandLogPlainTextEdit->appendPlainText(message); -} - -void HarmonicCalibration::clearCommandLog(){ - commandLogPlainTextEdit->clear(); +void HarmonicCalibration::startUtilityTask() { + if (!m_utilityThread.isRunning()) { + isUtilityTab = true; + m_utilityThread = QtConcurrent::run(this, &HarmonicCalibration::utilityTask, + utilityUITimerRate); + m_utilityWatcher.setFuture(m_utilityThread); + } +} + +void HarmonicCalibration::stopUtilityTask() { + isUtilityTab = false; + if (m_utilityThread.isRunning()) { + m_utilityThread.cancel(); + m_utilityWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::utilityTask(int sampleRate) { + while (isUtilityTab) { + getDIGIOENRegister(); + getFAULTRegister(); + if (hasMTDiagnostics) { + getDIAG1Register(); + getDIAG2Register(); + } + + Q_EMIT commandLogWriteSignal(""); + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::toggleUtilityTask(bool run) { + if (run) { + startUtilityTask(); + } else { + stopUtilityTask(); + } +} + +void HarmonicCalibration::getDIGIOENRegister() { + uint32_t *digioRegValue = new uint32_t; + uint32_t digioEnPage = m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::DIGIOEN); + if (changeCNVPage(digioEnPage)) { + uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::DIGIOEN); + + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + digioRegisterAddress, digioRegValue) != -1) { + uint16_t *digioRegValue16 = new uint16_t; + *digioRegValue16 = static_cast(*digioRegValue); + + Q_EMIT DIGIORegisterChanged(digioRegValue16); + + Q_EMIT commandLogWriteSignal( + "DIGIOEN: 0b" + + QString::number(*digioRegValue, 2).rightJustified(16, '0')); + + delete digioRegValue16; + } else { + Q_EMIT commandLogWriteSignal("Failed to read DIGIOEN Register"); + } + } + + delete digioRegValue; +} + +void HarmonicCalibration::updateDIGIOUI(uint16_t *registerValue) { + DIGIOENRegisterMap = + m_admtController->getDIGIOENRegisterBitMapping(*registerValue); + updateDIGIOMonitorUI(); + updateDIGIOControlUI(); +} + +void HarmonicCalibration::updateDIGIOMonitorUI() { + map registerMap = DIGIOENRegisterMap; + DIGIOBusyStatusLED->setChecked(registerMap.at("BUSY")); + DIGIOCNVStatusLED->setChecked(registerMap.at("CNV")); + DIGIOSENTStatusLED->setChecked(registerMap.at("SENT")); + DIGIOACALCStatusLED->setChecked(registerMap.at("ACALC")); + DIGIOFaultStatusLED->setChecked(registerMap.at("FAULT")); + DIGIOBootloaderStatusLED->setChecked(registerMap.at("BOOTLOAD")); + + if (!registerMap.at("BUSY")) + DIGIOBusyStatusLED->setText("BUSY (Output)"); + else { + if (registerMap.at("DIGIO0EN")) + DIGIOBusyStatusLED->setText("GPIO0 (Output)"); + else + DIGIOBusyStatusLED->setText("GPIO0 (Input)"); + } + + if (!registerMap.at("CNV")) + DIGIOCNVStatusLED->setText("CNV (Input)"); + else { + if (registerMap.at("DIGIO1EN")) + DIGIOCNVStatusLED->setText("GPIO1 (Output)"); + else + DIGIOCNVStatusLED->setText("GPIO1 (Input)"); + } + + if (!registerMap.at("SENT")) + DIGIOSENTStatusLED->setText("SENT (Output)"); + else { + if (registerMap.at("DIGIO2EN")) + DIGIOSENTStatusLED->setText("GPIO2 (Output)"); + else + DIGIOSENTStatusLED->setText("GPIO2 (Input)"); + } + + if (!registerMap.at("ACALC")) + DIGIOACALCStatusLED->setText("ACALC (Output)"); + else { + if (registerMap.at("DIGIO3EN")) + DIGIOACALCStatusLED->setText("GPIO3 (Output)"); + else + DIGIOACALCStatusLED->setText("GPIO3 (Input)"); + } + + if (!registerMap.at("FAULT")) + DIGIOFaultStatusLED->setText("FAULT (Output)"); + else { + if (registerMap.at("DIGIO4EN")) + DIGIOFaultStatusLED->setText("GPIO4 (Output)"); + else + DIGIOFaultStatusLED->setText("GPIO4 (Input)"); + } + + if (!registerMap.at("BOOTLOAD")) + DIGIOBootloaderStatusLED->setText("BOOTLOAD (Output)"); + else { + if (registerMap.at("DIGIO5EN")) + DIGIOBootloaderStatusLED->setText("GPIO5 (Output)"); + else + DIGIOBootloaderStatusLED->setText("GPIO5 (Input)"); + } +} + +void HarmonicCalibration::updateDIGIOControlUI() { + map registerMap = DIGIOENRegisterMap; + + DIGIO0ENToggleSwitch->setChecked(registerMap.at("DIGIO0EN")); + DIGIO1ENToggleSwitch->setChecked(registerMap.at("DIGIO1EN")); + DIGIO2ENToggleSwitch->setChecked(registerMap.at("DIGIO2EN")); + DIGIO3ENToggleSwitch->setChecked(registerMap.at("DIGIO3EN")); + DIGIO4ENToggleSwitch->setChecked(registerMap.at("DIGIO4EN")); + DIGIO5ENToggleSwitch->setChecked(registerMap.at("DIGIO5EN")); + DIGIO0FNCToggleSwitch->setChecked(registerMap.at("BUSY")); + DIGIO1FNCToggleSwitch->setChecked(registerMap.at("CNV")); + DIGIO2FNCToggleSwitch->setChecked(registerMap.at("SENT")); + DIGIO3FNCToggleSwitch->setChecked(registerMap.at("ACALC")); + DIGIO4FNCToggleSwitch->setChecked(registerMap.at("FAULT")); + DIGIO5FNCToggleSwitch->setChecked(registerMap.at("BOOTLOAD")); +} + +void HarmonicCalibration::getDIAG2Register() { + uint32_t *mtDiag2RegValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t mtDiag2RegisterAddress = m_admtController->getSensorRegister( + ADMTController::SensorRegister::DIAG2); + uint32_t mtDiag2PageValue = + m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2); + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::CNVPAGE); + + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, mtDiag2PageValue) != -1) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) != -1) { + if (*cnvPageRegValue == mtDiag2PageValue) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + mtDiag2RegisterAddress, mtDiag2RegValue) != -1) { + uint16_t *mtDiag2RegValue16 = new uint16_t; + *mtDiag2RegValue16 = static_cast(*mtDiag2RegValue); + + Q_EMIT DIAG2RegisterChanged(mtDiag2RegValue16); + + Q_EMIT commandLogWriteSignal( + "DIAG2: 0b" + + QString::number(*mtDiag2RegValue, 2).rightJustified(16, '0')); + + delete mtDiag2RegValue16; + } else { + Q_EMIT commandLogWriteSignal( + "Failed to read MT Diagnostic 2 Register"); + } + } else { + Q_EMIT commandLogWriteSignal( + "CNVPAGE for MT Diagnostic 2 is a different value, abort reading"); + } + } else { + Q_EMIT commandLogWriteSignal( + "Failed to read CNVPAGE for MT Diagnostic 2"); + } + } else { + Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 2"); + } + + delete mtDiag2RegValue, cnvPageRegValue; +} + +void HarmonicCalibration::updateMTDiagnosticsUI(uint16_t *registerValue) { + DIAG2RegisterMap = + m_admtController->getDiag2RegisterBitMapping(*registerValue); + + map regmap = DIAG2RegisterMap; + afeDiag0 = regmap.at("AFE Diagnostic 0 (-57%)"); + afeDiag1 = regmap.at("AFE Diagnostic 1 (+57%)"); + AFEDIAG0LineEdit->setText(QString::number(afeDiag0) + " V"); + AFEDIAG1LineEdit->setText(QString::number(afeDiag1) + " V"); +} + +void HarmonicCalibration::getDIAG1Register() { + uint32_t *mtDiag1RegValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister( + ADMTController::SensorRegister::DIAG1); + uint32_t mtDiag1PageValue = + m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); + uint32_t cnvPageAddress = m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::CNVPAGE); + + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, mtDiag1PageValue) != -1) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) != -1) { + if (*cnvPageRegValue == mtDiag1PageValue) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + mtDiag1RegisterAddress, mtDiag1RegValue) != -1) { + uint16_t *mtDiag1RegValue16 = new uint16_t; + *mtDiag1RegValue16 = static_cast(*mtDiag1RegValue); + Q_EMIT DIAG1RegisterChanged(mtDiag1RegValue16); + + Q_EMIT commandLogWriteSignal( + "DIAG1: 0b" + + QString::number(*mtDiag1RegValue16, 2).rightJustified(16, '0')); + + delete mtDiag1RegValue16; + } else { + Q_EMIT commandLogWriteSignal( + "Failed to read MT Diagnostic 1 Register"); + } + } else { + Q_EMIT commandLogWriteSignal( + "CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); + } + } else { + Q_EMIT commandLogWriteSignal( + "Failed to read CNVPAGE for MT Diagnostic 1"); + } + } else { + Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 1"); + } + + delete mtDiag1RegValue, cnvPageRegValue; +} + +void HarmonicCalibration::updateMTDiagnosticRegisterUI( + uint16_t *registerValue) { + DIAG1RegisterMap = + m_admtController->getDiag1RegisterBitMapping_Register(*registerValue); + DIAG1AFERegisterMap = + m_admtController->getDiag1RegisterBitMapping_Afe(*registerValue, is5V); + + map regmap = DIAG1RegisterMap; + map afeRegmap = DIAG1AFERegisterMap; + R0StatusLED->setChecked(regmap.at("R0")); + R1StatusLED->setChecked(regmap.at("R1")); + R2StatusLED->setChecked(regmap.at("R2")); + R3StatusLED->setChecked(regmap.at("R3")); + R4StatusLED->setChecked(regmap.at("R4")); + R5StatusLED->setChecked(regmap.at("R5")); + R6StatusLED->setChecked(regmap.at("R6")); + R7StatusLED->setChecked(regmap.at("R7")); + afeDiag2 = afeRegmap.at("AFE Diagnostic 2"); + AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); +} + +void HarmonicCalibration::getFAULTRegister() { + uint32_t *faultRegValue = new uint32_t; + uint32_t faultRegisterAddress = m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::FAULT); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + faultRegisterAddress, 0); // Write all zeros to fault before read + + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + faultRegisterAddress, faultRegValue) != -1) { + uint16_t *faultRegValue16 = new uint16_t; + *faultRegValue16 = static_cast(*faultRegValue); + + Q_EMIT FaultRegisterChanged(faultRegValue16); + + Q_EMIT commandLogWriteSignal( + "FAULT: 0b" + + QString::number(*faultRegValue, 2).rightJustified(16, '0')); + + delete faultRegValue16; + } else { + Q_EMIT commandLogWriteSignal("Failed to read FAULT Register"); + } + + delete faultRegValue; +} + +void HarmonicCalibration::updateFaultRegisterUI(uint16_t *faultRegValue) { + FAULTRegisterMap = + m_admtController->getFaultRegisterBitMapping(*faultRegValue); + + map regmap = FAULTRegisterMap; + VDDUnderVoltageStatusLED->setChecked(regmap.at("VDD Under Voltage")); + VDDOverVoltageStatusLED->setChecked(regmap.at("VDD Over Voltage")); + VDRIVEUnderVoltageStatusLED->setChecked(regmap.at("VDRIVE Under Voltage")); + VDRIVEOverVoltageStatusLED->setChecked(regmap.at("VDRIVE Over Voltage")); + AFEDIAGStatusLED->setChecked(regmap.at("AFE Diagnostic")); + NVMCRCFaultStatusLED->setChecked(regmap.at("NVM CRC Fault")); + ECCDoubleBitErrorStatusLED->setChecked(regmap.at("ECC Double Bit Error")); + OscillatorDriftStatusLED->setChecked(regmap.at("Oscillator Drift")); + CountSensorFalseStateStatusLED->setChecked( + regmap.at("Count Sensor False State")); + AngleCrossCheckStatusLED->setChecked(regmap.at("Angle Cross Check")); + TurnCountSensorLevelsStatusLED->setChecked( + regmap.at("Turn Count Sensor Levels")); + MTDIAGStatusLED->setChecked(regmap.at("MT Diagnostic")); + TurnCounterCrossCheckStatusLED->setChecked( + regmap.at("Turn Counter Cross Check")); + RadiusCheckStatusLED->setChecked(regmap.at("AMR Radius Check")); + SequencerWatchdogStatusLED->setChecked(regmap.at("Sequencer Watchdog")); +} + +void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) { + toggleUtilityTask(false); + + uint32_t *DIGIOENRegisterValue = new uint32_t; + uint32_t DIGIOENPage = m_admtController->getConfigurationPage( + ADMTController::ConfigurationRegister::DIGIOEN); + + if (changeCNVPage(DIGIOENPage)) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) { + map DIGIOSettings = + m_admtController->getDIGIOENRegisterBitMapping( + static_cast(*DIGIOENRegisterValue)); + + DIGIOSettings.at(DIGIOENName) = value; + + uint16_t newRegisterValue = + m_admtController->setDIGIOENRegisterBitMapping( + static_cast(*DIGIOENRegisterValue), DIGIOSettings); + + if (changeCNVPage(DIGIOENPage)) { + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::DIGIOEN), + static_cast(newRegisterValue)) != -1) { + updateDIGIOControlUI(); + } + } + } + } + + toggleUtilityTask(true); +} + +void HarmonicCalibration::toggleMTDiagnostics(int mode) { + switch (mode) { + case 0: + MTDiagnosticsScrollArea->hide(); + hasMTDiagnostics = false; + break; + case 1: + MTDiagnosticsScrollArea->show(); + hasMTDiagnostics = true; + break; + } +} + +void HarmonicCalibration::toggleFaultRegisterMode(int mode) { + switch (mode) { + case 0: + AFEDIAGStatusLED->hide(); + OscillatorDriftStatusLED->hide(); + AngleCrossCheckStatusLED->hide(); + TurnCountSensorLevelsStatusLED->hide(); + MTDIAGStatusLED->hide(); + SequencerWatchdogStatusLED->hide(); + break; + case 1: + AFEDIAGStatusLED->show(); + OscillatorDriftStatusLED->show(); + AngleCrossCheckStatusLED->show(); + TurnCountSensorLevelsStatusLED->show(); + MTDIAGStatusLED->show(); + SequencerWatchdogStatusLED->show(); + break; + } +} + +bool HarmonicCalibration::resetDIGIO() { + return (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::DIGIOEN), + 0x241b) == 0 + ? true + : false); +} + +void HarmonicCalibration::commandLogWrite(QString message) { + commandLogPlainTextEdit->appendPlainText(message); +} + +void HarmonicCalibration::clearCommandLog() { + commandLogPlainTextEdit->clear(); } #pragma endregion #pragma region Register Methods -void HarmonicCalibration::readAllRegisters() -{ - readAllRegistersButton->setEnabled(false); - readAllRegistersButton->setText(QString("Reading Registers...")); - QTimer::singleShot(1000, this, [this](){ - readAllRegistersButton->setEnabled(true); - readAllRegistersButton->setText(QString("Read All Registers")); - }); - - cnvPageRegisterBlock->readButton()->click(); - digIORegisterBlock->readButton()->click(); - faultRegisterBlock->readButton()->click(); - generalRegisterBlock->readButton()->click(); - digIOEnRegisterBlock->readButton()->click(); - eccDcdeRegisterBlock->readButton()->click(); - eccDisRegisterBlock->readButton()->click(); - absAngleRegisterBlock->readButton()->click(); - angleRegisterBlock->readButton()->click(); - sineRegisterBlock->readButton()->click(); - cosineRegisterBlock->readButton()->click(); - tmp0RegisterBlock->readButton()->click(); - cnvCntRegisterBlock->readButton()->click(); - uniqID0RegisterBlock->readButton()->click(); - uniqID1RegisterBlock->readButton()->click(); - uniqID2RegisterBlock->readButton()->click(); - uniqID3RegisterBlock->readButton()->click(); - h1MagRegisterBlock->readButton()->click(); - h1PhRegisterBlock->readButton()->click(); - h2MagRegisterBlock->readButton()->click(); - h2PhRegisterBlock->readButton()->click(); - h3MagRegisterBlock->readButton()->click(); - h3PhRegisterBlock->readButton()->click(); - h8MagRegisterBlock->readButton()->click(); - h8PhRegisterBlock->readButton()->click(); - - if(GENERALRegisterMap.at("Sequence Type") == 1){ - angleSecRegisterBlock->readButton()->click(); - secAnglIRegisterBlock->readButton()->click(); - secAnglQRegisterBlock->readButton()->click(); - tmp1RegisterBlock->readButton()->click(); - angleCkRegisterBlock->readButton()->click(); - radiusRegisterBlock->readButton()->click(); - diag1RegisterBlock->readButton()->click(); - diag2RegisterBlock->readButton()->click(); - } -} - -void HarmonicCalibration::toggleRegisters(int mode) -{ - switch(mode){ - case 0: - angleSecRegisterBlock->hide(); - secAnglIRegisterBlock->hide(); - secAnglQRegisterBlock->hide(); - tmp1RegisterBlock->hide(); - angleCkRegisterBlock->hide(); - radiusRegisterBlock->hide(); - diag1RegisterBlock->hide(); - diag2RegisterBlock->hide(); - break; - case 1: - angleSecRegisterBlock->show(); - secAnglIRegisterBlock->show(); - secAnglQRegisterBlock->show(); - tmp1RegisterBlock->show(); - angleCkRegisterBlock->show(); - radiusRegisterBlock->show(); - diag1RegisterBlock->show(); - diag2RegisterBlock->show(); - break; - } +void HarmonicCalibration::readAllRegisters() { + readAllRegistersButton->setEnabled(false); + readAllRegistersButton->setText(QString("Reading Registers...")); + QTimer::singleShot(1000, this, [this]() { + readAllRegistersButton->setEnabled(true); + readAllRegistersButton->setText(QString("Read All Registers")); + }); + + cnvPageRegisterBlock->readButton()->click(); + digIORegisterBlock->readButton()->click(); + faultRegisterBlock->readButton()->click(); + generalRegisterBlock->readButton()->click(); + digIOEnRegisterBlock->readButton()->click(); + eccDcdeRegisterBlock->readButton()->click(); + eccDisRegisterBlock->readButton()->click(); + absAngleRegisterBlock->readButton()->click(); + angleRegisterBlock->readButton()->click(); + sineRegisterBlock->readButton()->click(); + cosineRegisterBlock->readButton()->click(); + tmp0RegisterBlock->readButton()->click(); + cnvCntRegisterBlock->readButton()->click(); + uniqID0RegisterBlock->readButton()->click(); + uniqID1RegisterBlock->readButton()->click(); + uniqID2RegisterBlock->readButton()->click(); + uniqID3RegisterBlock->readButton()->click(); + h1MagRegisterBlock->readButton()->click(); + h1PhRegisterBlock->readButton()->click(); + h2MagRegisterBlock->readButton()->click(); + h2PhRegisterBlock->readButton()->click(); + h3MagRegisterBlock->readButton()->click(); + h3PhRegisterBlock->readButton()->click(); + h8MagRegisterBlock->readButton()->click(); + h8PhRegisterBlock->readButton()->click(); + + if (GENERALRegisterMap.at("Sequence Type") == 1) { + angleSecRegisterBlock->readButton()->click(); + secAnglIRegisterBlock->readButton()->click(); + secAnglQRegisterBlock->readButton()->click(); + tmp1RegisterBlock->readButton()->click(); + angleCkRegisterBlock->readButton()->click(); + radiusRegisterBlock->readButton()->click(); + diag1RegisterBlock->readButton()->click(); + diag2RegisterBlock->readButton()->click(); + } +} + +void HarmonicCalibration::toggleRegisters(int mode) { + switch (mode) { + case 0: + angleSecRegisterBlock->hide(); + secAnglIRegisterBlock->hide(); + secAnglQRegisterBlock->hide(); + tmp1RegisterBlock->hide(); + angleCkRegisterBlock->hide(); + radiusRegisterBlock->hide(); + diag1RegisterBlock->hide(); + diag2RegisterBlock->hide(); + break; + case 1: + angleSecRegisterBlock->show(); + secAnglIRegisterBlock->show(); + secAnglQRegisterBlock->show(); + tmp1RegisterBlock->show(); + angleCkRegisterBlock->show(); + radiusRegisterBlock->show(); + diag1RegisterBlock->show(); + diag2RegisterBlock->show(); + break; + } } #pragma endregion #pragma region UI Helper Methods -void HarmonicCalibration::updateLabelValue(QLabel* label, int channelIndex) -{ - switch(channelIndex) - { - case ADMTController::Channel::ROTATION: - label->setText(QString("%1").arg(rotation, 0, 'f', 2) + "°"); - break; - case ADMTController::Channel::ANGLE: - label->setText(QString("%1").arg(angle, 0, 'f', 2) + "°"); - break; - case ADMTController::Channel::COUNT: - label->setText(QString::number(count)); - break; - case ADMTController::Channel::TEMPERATURE: - label->setText(QString("%1").arg(temp, 0, 'f', 2) + "°C"); - break; - } -} - -void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute) -{ - switch(attribute) - { - case ADMTController::MotorAttribute::AMAX: - label->setText(QString::number(amax)); - break; - case ADMTController::MotorAttribute::ROTATE_VMAX: - label->setText(QString::number(rotate_vmax)); - break; - case ADMTController::MotorAttribute::DMAX: - label->setText(QString::number(dmax)); - break; - case ADMTController::MotorAttribute::DISABLE: - label->setText(QString::number(disable)); - break; - case ADMTController::MotorAttribute::TARGET_POS: - label->setText(QString::number(target_pos)); - break; - case ADMTController::MotorAttribute::CURRENT_POS: - label->setText(QString::number(current_pos)); - break; - case ADMTController::MotorAttribute::RAMP_MODE: - label->setText(QString::number(ramp_mode)); - break; - } -} - -bool HarmonicCalibration::updateChannelValue(int channelIndex) -{ - bool success = false; - switch(channelIndex) - { - case ADMTController::Channel::ROTATION: - rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, 1); - if(rotation == static_cast(UINT64_MAX)) { success = false; } - break; - case ADMTController::Channel::ANGLE: - angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, 1); - if(angle == static_cast(UINT64_MAX)) { success = false; } - break; - case ADMTController::Channel::COUNT: - count = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, 1); - if(count == static_cast(UINT64_MAX)) { success = false; } - break; - case ADMTController::Channel::TEMPERATURE: - temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, 1); - if(temp == static_cast(UINT64_MAX)) { success = false; } - break; - } - return success; -} - -void HarmonicCalibration::updateLineEditValue(QLineEdit* lineEdit, double value){ - if(value == static_cast(UINT64_MAX)) { lineEdit->setText("N/A"); } - else { lineEdit->setText(QString::number(value)); } -} - -void HarmonicCalibration::toggleWidget(QPushButton *widget, bool value){ - widget->setEnabled(value); -} - -void HarmonicCalibration::changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel) -{ - customSwitch->setOnText(onLabel); - customSwitch->setOffText(offLabel); -} - -QCheckBox *HarmonicCalibration::createStatusLEDWidget(const QString &text, QVariant variant, bool checked, QWidget *parent) -{ - QCheckBox *checkBox = new QCheckBox(text, parent); - Style::setStyle(checkBox, style::properties::admt::checkBoxLED, variant, true); - checkBox->setChecked(checked); - checkBox->setEnabled(false); - return checkBox; -} - -MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString title, QColor color, QWidget *parent) -{ - MenuControlButton *menuControlButton = new MenuControlButton(parent); - menuControlButton->setName(title); - menuControlButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); - menuControlButton->setOpenMenuChecksThis(true); - menuControlButton->setDoubleClickToOpenMenu(true); - menuControlButton->setColor(color); - menuControlButton->button()->setVisible(false); - menuControlButton->setCheckable(false); - menuControlButton->checkBox()->setChecked(true); - menuControlButton->layout()->setMargin(0); - return menuControlButton; +void HarmonicCalibration::updateLabelValue(QLabel *label, int channelIndex) { + switch (channelIndex) { + case ADMTController::Channel::ROTATION: + label->setText(QString("%1").arg(rotation, 0, 'f', 2) + "°"); + break; + case ADMTController::Channel::ANGLE: + label->setText(QString("%1").arg(angle, 0, 'f', 2) + "°"); + break; + case ADMTController::Channel::COUNT: + label->setText(QString::number(count)); + break; + case ADMTController::Channel::TEMPERATURE: + label->setText(QString("%1").arg(temp, 0, 'f', 2) + "°C"); + break; + } +} + +void HarmonicCalibration::updateLabelValue( + QLabel *label, ADMTController::MotorAttribute attribute) { + switch (attribute) { + case ADMTController::MotorAttribute::AMAX: + label->setText(QString::number(amax)); + break; + case ADMTController::MotorAttribute::ROTATE_VMAX: + label->setText(QString::number(rotate_vmax)); + break; + case ADMTController::MotorAttribute::DMAX: + label->setText(QString::number(dmax)); + break; + case ADMTController::MotorAttribute::DISABLE: + label->setText(QString::number(disable)); + break; + case ADMTController::MotorAttribute::TARGET_POS: + label->setText(QString::number(target_pos)); + break; + case ADMTController::MotorAttribute::CURRENT_POS: + label->setText(QString::number(current_pos)); + break; + case ADMTController::MotorAttribute::RAMP_MODE: + label->setText(QString::number(ramp_mode)); + break; + } +} + +bool HarmonicCalibration::updateChannelValue(int channelIndex) { + bool success = false; + switch (channelIndex) { + case ADMTController::Channel::ROTATION: + rotation = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + rotationChannelName, 1); + if (rotation == static_cast(UINT64_MAX)) { + success = false; + } + break; + case ADMTController::Channel::ANGLE: + angle = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + angleChannelName, 1); + if (angle == static_cast(UINT64_MAX)) { + success = false; + } + break; + case ADMTController::Channel::COUNT: + count = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + countChannelName, 1); + if (count == static_cast(UINT64_MAX)) { + success = false; + } + break; + case ADMTController::Channel::TEMPERATURE: + temp = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + temperatureChannelName, 1); + if (temp == static_cast(UINT64_MAX)) { + success = false; + } + break; + } + return success; +} + +void HarmonicCalibration::updateLineEditValue(QLineEdit *lineEdit, + double value) { + if (value == static_cast(UINT64_MAX)) { + lineEdit->setText("N/A"); + } else { + lineEdit->setText(QString::number(value)); + } +} + +void HarmonicCalibration::toggleWidget(QPushButton *widget, bool value) { + widget->setEnabled(value); +} + +void HarmonicCalibration::changeCustomSwitchLabel(CustomSwitch *customSwitch, + QString onLabel, + QString offLabel) { + customSwitch->setOnText(onLabel); + customSwitch->setOffText(offLabel); +} + +QCheckBox *HarmonicCalibration::createStatusLEDWidget(const QString &text, + QVariant variant, + bool checked, + QWidget *parent) { + QCheckBox *checkBox = new QCheckBox(text, parent); + Style::setStyle(checkBox, style::properties::admt::checkBoxLED, variant, + true); + checkBox->setChecked(checked); + checkBox->setEnabled(false); + return checkBox; +} + +MenuControlButton * +HarmonicCalibration::createChannelToggleWidget(const QString title, + QColor color, QWidget *parent) { + MenuControlButton *menuControlButton = new MenuControlButton(parent); + menuControlButton->setName(title); + menuControlButton->setCheckBoxStyle( + MenuControlButton::CheckboxStyle::CS_CIRCLE); + menuControlButton->setOpenMenuChecksThis(true); + menuControlButton->setDoubleClickToOpenMenu(true); + menuControlButton->setColor(color); + menuControlButton->button()->setVisible(false); + menuControlButton->setCheckable(false); + menuControlButton->checkBox()->setChecked(true); + menuControlButton->layout()->setMargin(0); + return menuControlButton; } #pragma endregion #pragma region Connect Methods -void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, int& variable, int min, int max) -{ - QIntValidator *validator = new QIntValidator(min, max, this); - lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, min, max]() { - bool ok; - int value = lineEdit->text().toInt(&ok); - if (ok && value >= min && value <= max) { - variable = value; - } else { - lineEdit->setText(QString::number(variable)); - } - }); -} - -void HarmonicCalibration::connectLineEditToNumber(QLineEdit* lineEdit, double& variable, QString unit) -{ - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, unit]() { - bool ok; - double value = lineEdit->text().replace(unit, "").trimmed().toDouble(&ok); - if (ok) { - variable = value; - - } else { - lineEdit->setText(QString::number(variable) + " " + unit); - } - }); -} - -void HarmonicCalibration::connectLineEditToDouble(QLineEdit* lineEdit, double& variable) -{ - QDoubleValidator *validator = new QDoubleValidator(this); - validator->setNotation(QDoubleValidator::StandardNotation); - lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { - bool ok; - double value = lineEdit->text().toDouble(&ok); - if (ok){ - variable = value; - } else { - lineEdit->setText(QString::number(variable)); +void HarmonicCalibration::connectLineEditToNumber(QLineEdit *lineEdit, + int &variable, int min, + int max) { + QIntValidator *validator = new QIntValidator(min, max, this); + lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, this, + [&variable, lineEdit, min, max]() { + bool ok; + int value = lineEdit->text().toInt(&ok); + if (ok && value >= min && value <= max) { + variable = value; + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + +void HarmonicCalibration::connectLineEditToNumber(QLineEdit *lineEdit, + double &variable, + QString unit) { + connect(lineEdit, &QLineEdit::editingFinished, this, + [&variable, lineEdit, unit]() { + bool ok; + double value = + lineEdit->text().replace(unit, "").trimmed().toDouble(&ok); + if (ok) { + variable = value; + + } else { + lineEdit->setText(QString::number(variable) + " " + unit); + } + }); +} + +void HarmonicCalibration::connectLineEditToDouble(QLineEdit *lineEdit, + double &variable) { + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok) { + variable = value; + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + +void HarmonicCalibration::connectLineEditToNumberWrite( + QLineEdit *lineEdit, double &variable, + ADMTController::MotorAttribute attribute) { + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, attribute, &variable]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok) { + variable = value; + writeMotorAttributeValue(attribute, variable); + + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + +void HarmonicCalibration::connectMenuComboToNumber(MenuCombo *menuCombo, + double &variable) { + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), + [this, &combo, &variable]() { + variable = qvariant_cast(combo->currentData()); + }); +} + +void HarmonicCalibration::connectMenuComboToNumber(MenuCombo *menuCombo, + int &variable) { + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), + [this, combo, &variable]() { + variable = qvariant_cast(combo->currentData()); + }); +} + +void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit *lineEdit, + double &vmax) { + connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, &vmax]() { + bool ok; + double rps = lineEdit->text().toDouble(&ok); + if (ok) { + vmax = convertRPStoVMAX(rps); + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, + vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + amax = convertAccelTimetoAMAX(motorAccelTime); + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + // StatusBarManager::pushMessage("Applied VMAX: " + + // QString::number(vmax)); StatusBarManager::pushMessage("Applied AMAX: " + // + QString::number(amax)); + } else { + lineEdit->setText(QString::number(convertVMAXtoRPS(vmax))); + } + }); +} + +void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit *lineEdit, + double &amax) { + connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, &amax]() { + bool ok; + double accelTime = lineEdit->text().toDouble(&ok); + if (ok) { + amax = convertAccelTimetoAMAX(accelTime); + // StatusBarManager::pushMessage("Applied AMAX: " + + // QString::number(amax)); + } else { + lineEdit->setText(QString::number(convertAMAXtoAccelTime(amax))); + } + }); +} + +void HarmonicCalibration::connectRegisterBlockToRegistry( + RegisterBlockWidget *widget) { + uint32_t *readValue = new uint32_t; + connect(widget->readButton(), &QPushButton::clicked, this, [this, widget, readValue] { + bool ok = false, success = false; + + if (widget->getCnvPage() != UINT32_MAX) { + ok = this->changeCNVPage(widget->getCnvPage()); + } else { + ok = true; + } + + if (ok) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + widget->getAddress(), readValue) == 0) { + widget->setValue(*readValue); + } + } else { + StatusBarManager::pushMessage("Failed to read registry"); + } + }); + if (widget->getAccessPermission() == + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE || + widget->getAccessPermission() == + RegisterBlockWidget::ACCESS_PERMISSION::WRITE) { + connect(widget->writeButton(), &QPushButton::clicked, this, [this, widget, readValue] { + bool ok = false, success = false; + + if (widget->getCnvPage() != UINT32_MAX) { + ok = this->changeCNVPage(widget->getCnvPage()); + } else { + ok = true; + } + + if (ok) { + if (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + widget->getAddress(), widget->getValue()) == 0) { + if (m_admtController->readDeviceRegistry( + m_admtController->getDeviceId( + ADMTController::Device::ADMT4000), + widget->getAddress(), readValue) == 0) { + widget->setValue(*readValue); + success = true; + } } - }); -} + } -void HarmonicCalibration::connectLineEditToNumberWrite(QLineEdit* lineEdit, double& variable, ADMTController::MotorAttribute attribute) -{ - QDoubleValidator *validator = new QDoubleValidator(this); - validator->setNotation(QDoubleValidator::StandardNotation); - lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, [=, &variable]() { - bool ok; - double value = lineEdit->text().toDouble(&ok); - if (ok) { - variable = value; - writeMotorAttributeValue(attribute, variable); - - } else { - lineEdit->setText(QString::number(variable)); - } - }); -} - -void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, double& variable) -{ - QComboBox *combo = menuCombo->combo(); - connect(combo, QOverload::of(&QComboBox::currentIndexChanged), [=, &variable]() { - variable = qvariant_cast(combo->currentData()); - }); -} - -void HarmonicCalibration::connectMenuComboToNumber(MenuCombo* menuCombo, int& variable) -{ - QComboBox *combo = menuCombo->combo(); - connect(combo, QOverload::of(&QComboBox::currentIndexChanged), [=, &variable]() { - variable = qvariant_cast(combo->currentData()); - }); -} - -void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit* lineEdit, double& vmax) -{ - connect(lineEdit, &QLineEdit::editingFinished, [=, &vmax]() { - bool ok; - double rps = lineEdit->text().toDouble(&ok); - if (ok) { - vmax = convertRPStoVMAX(rps); - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - amax = convertAccelTimetoAMAX(motorAccelTime); - writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - // StatusBarManager::pushMessage("Applied VMAX: " + QString::number(vmax)); - // StatusBarManager::pushMessage("Applied AMAX: " + QString::number(amax)); - } else { - lineEdit->setText(QString::number(convertVMAXtoRPS(vmax))); - } - }); -} - -void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit* lineEdit, double& amax) -{ - connect(lineEdit, &QLineEdit::editingFinished, [=, &amax]() { - bool ok; - double accelTime = lineEdit->text().toDouble(&ok); - if (ok) { - amax = convertAccelTimetoAMAX(accelTime); - // StatusBarManager::pushMessage("Applied AMAX: " + QString::number(amax)); - } else { - lineEdit->setText(QString::number(convertAMAXtoAccelTime(amax))); - } - }); -} - -void HarmonicCalibration::connectRegisterBlockToRegistry(RegisterBlockWidget* widget) -{ - uint32_t *readValue = new uint32_t; - connect(widget->readButton(), &QPushButton::clicked, this, [=]{ - bool ok = false, success = false; - - if(widget->getCnvPage() != UINT32_MAX) - { - ok = this->changeCNVPage(widget->getCnvPage()); - } - else { ok = true; } - - if(ok){ - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) - { widget->setValue(*readValue); } - } - else{ StatusBarManager::pushMessage("Failed to read registry"); } - }); - if(widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::READWRITE || - widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::WRITE){ - connect(widget->writeButton(), &QPushButton::clicked, this, [=]{ - bool ok = false, success = false; - - if(widget->getCnvPage() != UINT32_MAX) - { - ok = this->changeCNVPage(widget->getCnvPage()); - } - else { ok = true; } - - if(ok){ - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), widget->getValue()) == 0) - { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), widget->getAddress(), readValue) == 0) - { - widget->setValue(*readValue); - success = true; - } - } - } - - if(!success) { StatusBarManager::pushMessage("Failed to write to registry"); } - }); - } -} - -void HarmonicCalibration::connectLineEditToRPM(QLineEdit* lineEdit, double& variable) -{ - QDoubleValidator *validator = new QDoubleValidator(this); - validator->setNotation(QDoubleValidator::StandardNotation); - lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, this, [=, &variable]() { - bool ok; - double value = lineEdit->text().toDouble(&ok); - if (ok){ - variable = value; - rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(variable)); - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - amax = convertAccelTimetoAMAX(motorAccelTime); - writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - } else { - lineEdit->setText(QString::number(variable)); - } + if (!success) { + StatusBarManager::pushMessage("Failed to write to registry"); + } }); + } +} + +void HarmonicCalibration::connectLineEditToRPM(QLineEdit *lineEdit, + double &variable) { + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, this, [this, lineEdit, &variable]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok) { + variable = value; + rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(variable)); + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, + rotate_vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + amax = convertAccelTimetoAMAX(motorAccelTime); + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + } else { + lineEdit->setText(QString::number(variable)); + } + }); } #pragma endregion #pragma region Convert Methods -double HarmonicCalibration::convertRPStoVMAX(double rps) -{ - return (rps * motorMicrostepPerRevolution * motorTimeUnit); +double HarmonicCalibration::convertRPStoVMAX(double rps) { + return (rps * motorMicrostepPerRevolution * motorTimeUnit); } -double HarmonicCalibration::convertVMAXtoRPS(double vmax) -{ - return (vmax / motorMicrostepPerRevolution / motorTimeUnit); +double HarmonicCalibration::convertVMAXtoRPS(double vmax) { + return (vmax / motorMicrostepPerRevolution / motorTimeUnit); } -double HarmonicCalibration::convertAccelTimetoAMAX(double accelTime) -{ - return (rotate_vmax * static_cast(1 << 17) / accelTime / motorfCLK); // 1 << 17 = 2^17 = 131072 +double HarmonicCalibration::convertAccelTimetoAMAX(double accelTime) { + return (rotate_vmax * static_cast(1 << 17) / accelTime / + motorfCLK); // 1 << 17 = 2^17 = 131072 } -double HarmonicCalibration::convertAMAXtoAccelTime(double amax) -{ - return ((rotate_vmax * static_cast(1 << 17)) / (amax * motorfCLK)); // 1 << 17 = 2^17 = 131072 +double HarmonicCalibration::convertAMAXtoAccelTime(double amax) { + return ((rotate_vmax * static_cast(1 << 17)) / + (amax * motorfCLK)); // 1 << 17 = 2^17 = 131072 } -double HarmonicCalibration::convertRPMtoRPS(double rpm) -{ - return (rpm / 60); -} +double HarmonicCalibration::convertRPMtoRPS(double rpm) { return (rpm / 60); } -double HarmonicCalibration::convertRPStoRPM(double rps) -{ - return (rps * 60); -} +double HarmonicCalibration::convertRPStoRPM(double rps) { return (rps * 60); } #pragma endregion #pragma region Debug Methods -QString HarmonicCalibration::readRegmapDumpAttributeValue() -{ - QString output = ""; - char value[1024]; - int result = -1; - result = m_admtController->getDeviceAttributeValueString(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getDeviceAttribute(ADMTController::DeviceAttribute::REGMAP_DUMP), - value, 1024); - output = QString(value); - return output; -} -#pragma endregion \ No newline at end of file +QString HarmonicCalibration::readRegmapDumpAttributeValue() { + QString output = ""; + char value[1024]; + int result = -1; + result = m_admtController->getDeviceAttributeValueString( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getDeviceAttribute( + ADMTController::DeviceAttribute::REGMAP_DUMP), + value, 1024); + output = QString(value); + return output; +} +#pragma endregion +#include "moc_harmoniccalibration.cpp" diff --git a/plugins/admt/src/widgets/horizontalspinbox.cpp b/plugins/admt/src/widgets/horizontalspinbox.cpp index 968821432d..1df7333ed9 100644 --- a/plugins/admt/src/widgets/horizontalspinbox.cpp +++ b/plugins/admt/src/widgets/horizontalspinbox.cpp @@ -19,122 +19,113 @@ * */ -#include -#include #include "widgets/horizontalspinbox.h" +#include +#include using namespace scopy::admt; -HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, QString unit, QWidget *parent) - : QWidget(parent) - , m_value(initialValue) - , m_unit(unit) -{ - QVBoxLayout *container = new QVBoxLayout(this); - setLayout(container); - container->setMargin(0); - container->setSpacing(4); - - if(header != ""){ - QLabel *headerLabel = new QLabel(header, this); - Style::setStyle(headerLabel, style::properties::label::menuSmall); - container->addWidget(headerLabel); - } - - QWidget *controlWidget = new QWidget(this); - QHBoxLayout *controlLayout = new QHBoxLayout(controlWidget); - controlWidget->setLayout(controlLayout); - controlLayout->setMargin(0); - controlLayout->setSpacing(2); - - m_lineEdit = new QLineEdit(controlWidget); - QDoubleValidator *validator = new QDoubleValidator(this); - validator->setNotation(QDoubleValidator::StandardNotation); - m_lineEdit->setValidator(validator); - applyLineEditStyle(m_lineEdit); - - if(QString::compare(m_unit, "") != 0) { - QWidget *lineEditContainer = new QWidget(controlWidget); - QHBoxLayout *lineEditLayout = new QHBoxLayout(lineEditContainer); - lineEditContainer->setLayout(lineEditLayout); - lineEditLayout->setMargin(0); - lineEditLayout->setSpacing(0); - - m_unitLabel = new QLabel(m_unit, controlWidget); - applyUnitLabelStyle(m_unitLabel); - - m_lineEdit->setTextMargins(12, 4, 0, 4); - - lineEditLayout->addWidget(m_lineEdit); - lineEditLayout->addWidget(m_unitLabel); - controlLayout->addWidget(lineEditContainer); - } - else{ - controlLayout->addWidget(m_lineEdit); - } - - m_minusButton = new QPushButton(controlWidget); - m_minusButton->setIcon(QIcon(":/admt/minus.svg")); - applyPushButtonStyle(m_minusButton); - - m_plusButton = new QPushButton(controlWidget); - m_plusButton->setIcon(QIcon(":/admt/plus.svg")); - applyPushButtonStyle(m_plusButton, 0, 4, 0, 4); - - controlLayout->addWidget(m_minusButton); - controlLayout->addWidget(m_plusButton); - - container->addWidget(controlWidget); - - setValue(m_value); - connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(onLineEditTextEdited())); - connect(m_minusButton, SIGNAL(clicked()), SLOT(onMinusButtonPressed())); - connect(m_plusButton, SIGNAL(clicked()), SLOT(onPlusButtonPressed())); +HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, + QString unit, QWidget *parent) + : QWidget(parent), m_value(initialValue), m_unit(unit) { + QVBoxLayout *container = new QVBoxLayout(this); + setLayout(container); + container->setMargin(0); + container->setSpacing(4); + + if (header != "") { + QLabel *headerLabel = new QLabel(header, this); + Style::setStyle(headerLabel, style::properties::label::menuSmall); + container->addWidget(headerLabel); + } + + QWidget *controlWidget = new QWidget(this); + QHBoxLayout *controlLayout = new QHBoxLayout(controlWidget); + controlWidget->setLayout(controlLayout); + controlLayout->setMargin(0); + controlLayout->setSpacing(2); + + m_lineEdit = new QLineEdit(controlWidget); + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + m_lineEdit->setValidator(validator); + applyLineEditStyle(m_lineEdit); + + if (QString::compare(m_unit, "") != 0) { + QWidget *lineEditContainer = new QWidget(controlWidget); + QHBoxLayout *lineEditLayout = new QHBoxLayout(lineEditContainer); + lineEditContainer->setLayout(lineEditLayout); + lineEditLayout->setMargin(0); + lineEditLayout->setSpacing(0); + + m_unitLabel = new QLabel(m_unit, controlWidget); + applyUnitLabelStyle(m_unitLabel); + + m_lineEdit->setTextMargins(12, 4, 0, 4); + + lineEditLayout->addWidget(m_lineEdit); + lineEditLayout->addWidget(m_unitLabel); + controlLayout->addWidget(lineEditContainer); + } else { + controlLayout->addWidget(m_lineEdit); + } + + m_minusButton = new QPushButton(controlWidget); + m_minusButton->setIcon(QIcon(":/admt/minus.svg")); + applyPushButtonStyle(m_minusButton); + + m_plusButton = new QPushButton(controlWidget); + m_plusButton->setIcon(QIcon(":/admt/plus.svg")); + applyPushButtonStyle(m_plusButton, 0, 4, 0, 4); + + controlLayout->addWidget(m_minusButton); + controlLayout->addWidget(m_plusButton); + + container->addWidget(controlWidget); + + setValue(m_value); + connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(onLineEditTextEdited())); + connect(m_minusButton, SIGNAL(clicked()), SLOT(onMinusButtonPressed())); + connect(m_plusButton, SIGNAL(clicked()), SLOT(onPlusButtonPressed())); } -void HorizontalSpinBox::onMinusButtonPressed() -{ - m_value--; - setValue(m_value); - Q_EMIT m_lineEdit->editingFinished(); +void HorizontalSpinBox::onMinusButtonPressed() { + m_value--; + setValue(m_value); + Q_EMIT m_lineEdit->editingFinished(); } -void HorizontalSpinBox::onPlusButtonPressed() -{ - m_value++; - setValue(m_value); - Q_EMIT m_lineEdit->editingFinished(); +void HorizontalSpinBox::onPlusButtonPressed() { + m_value++; + setValue(m_value); + Q_EMIT m_lineEdit->editingFinished(); } -void HorizontalSpinBox::onLineEditTextEdited() -{ - QLineEdit *lineEdit = static_cast(QObject::sender()); - bool ok; - double value = lineEdit->text().toDouble(&ok); - if (ok) { - m_value = value; - } - setValue(m_value); +void HorizontalSpinBox::onLineEditTextEdited() { + QLineEdit *lineEdit = static_cast(QObject::sender()); + bool ok; + double value = lineEdit->text().toDouble(&ok); + if (ok) { + m_value = value; + } + setValue(m_value); } -void HorizontalSpinBox::setValue(double value) -{ - m_lineEdit->setText(QString::number(value)); +void HorizontalSpinBox::setValue(double value) { + m_lineEdit->setText(QString::number(value)); } -void HorizontalSpinBox::setEnabled(double value) -{ - m_lineEdit->setEnabled(value); - m_minusButton->setEnabled(value); - m_plusButton->setEnabled(value); - if(QString::compare(m_unit, "") != 0){ - applyUnitLabelStyle(m_unitLabel, value); - } +void HorizontalSpinBox::setEnabled(double value) { + m_lineEdit->setEnabled(value); + m_minusButton->setEnabled(value); + m_plusButton->setEnabled(value); + if (QString::compare(m_unit, "") != 0) { + applyUnitLabelStyle(m_unitLabel, value); + } } -void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) -{ - QString style = QString(R"css( +void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) { + QString style = QString(R"css( QLineEdit { font-family: Open Sans; font-size: 16px; @@ -154,17 +145,21 @@ void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) color: #9c4600; } )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setAlignment(Qt::AlignRight); - widget->setContentsMargins(0, 0, 0, 0); - widget->setTextMargins(6, 4, 6, 4); + style = style.replace(QString("&&colorname&&"), + Style::getAttribute(json::global::ch0)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setAlignment(Qt::AlignRight); + widget->setContentsMargins(0, 0, 0, 0); + widget->setTextMargins(6, 4, 6, 4); } -void HorizontalSpinBox::applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius, int topRightBorderRadius, int bottomLeftBorderRadius, int bottomRightBorderRadius) -{ - QString style = QString(R"css( +void HorizontalSpinBox::applyPushButtonStyle(QPushButton *widget, + int topLeftBorderRadius, + int topRightBorderRadius, + int bottomLeftBorderRadius, + int bottomRightBorderRadius) { + QString style = QString(R"css( QPushButton{ background-color: black; font-family: Open Sans; @@ -182,19 +177,24 @@ void HorizontalSpinBox::applyPushButtonStyle(QPushButton *widget, int topLeftBor color: #2d3d9c; } )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::interactive_primary_idle)); - style = style.replace(QString("&&topLeftBorderRadius&&"), QString::number(topLeftBorderRadius)); - style = style.replace(QString("&&topRightBorderRadius&&"), QString::number(topRightBorderRadius)); - style = style.replace(QString("&&bottomLeftBorderRadius&&"), QString::number(bottomLeftBorderRadius)); - style = style.replace(QString("&&bottomRightBorderRadius&&"), QString::number(bottomRightBorderRadius)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setFixedWidth(38); + style = + style.replace(QString("&&colorname&&"), + Style::getAttribute(json::theme::interactive_primary_idle)); + style = style.replace(QString("&&topLeftBorderRadius&&"), + QString::number(topLeftBorderRadius)); + style = style.replace(QString("&&topRightBorderRadius&&"), + QString::number(topRightBorderRadius)); + style = style.replace(QString("&&bottomLeftBorderRadius&&"), + QString::number(bottomLeftBorderRadius)); + style = style.replace(QString("&&bottomRightBorderRadius&&"), + QString::number(bottomRightBorderRadius)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setFixedWidth(38); } -void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget, bool isEnabled) -{ - QString style = QString(R"css( +void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget, bool isEnabled) { + QString style = QString(R"css( background-color: &&backgroundcolor&&; font-family: Open Sans; font-size: 16px; @@ -202,18 +202,18 @@ void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget, bool isEnabled) color: &&colorname&&; border: none; )css"); - if(isEnabled){ - style = style.replace(QString("&&backgroundcolor&&"), "black"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); - } - else{ - style = style.replace(QString("&&backgroundcolor&&"), "#18181d"); - style = style.replace(QString("&&colorname&&"), "#9c4600"); - } - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setAlignment(Qt::AlignRight); - widget->setContentsMargins(0, 4, 12, 4); + if (isEnabled) { + style = style.replace(QString("&&backgroundcolor&&"), "black"); + style = style.replace(QString("&&colorname&&"), + Style::getAttribute(json::global::ch0)); + } else { + style = style.replace(QString("&&backgroundcolor&&"), "#18181d"); + style = style.replace(QString("&&colorname&&"), "#9c4600"); + } + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setAlignment(Qt::AlignRight); + widget->setContentsMargins(0, 4, 12, 4); } -QLineEdit *HorizontalSpinBox::lineEdit() { return m_lineEdit; } \ No newline at end of file +QLineEdit *HorizontalSpinBox::lineEdit() { return m_lineEdit; } diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp index 37701b87d0..04c8c435bb 100644 --- a/plugins/admt/src/widgets/registerblockwidget.cpp +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -19,123 +19,125 @@ * */ -#include -#include #include "widgets/registerblockwidget.h" #include "style_properties.h" +#include +#include using namespace scopy; using namespace scopy::admt; -RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t cnvPage, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent) - : QWidget(parent) - , m_address(address) - , m_cnvPage(cnvPage) - , m_accessPermission(accessPermission) -{ - QVBoxLayout *container = new QVBoxLayout(this); - setLayout(container); - container->setMargin(0); - container->setSpacing(0); - MenuSectionWidget *menuSectionWidget = new MenuSectionWidget(this); - Style::setStyle(menuSectionWidget, style::properties::widget::basicComponent); - QLabel *headerLabel = new QLabel(header, menuSectionWidget); - Style::setStyle(headerLabel, style::properties::label::menuMedium); - menuSectionWidget->setFixedHeight(180); - menuSectionWidget->contentLayout()->setSpacing(Style::getDimension(json::global::unit_0_5)); - - QLabel *descriptionLabel = new QLabel(description, menuSectionWidget); - descriptionLabel->setWordWrap(true); - descriptionLabel->setMinimumHeight(24); - descriptionLabel->setAlignment(Qt::AlignTop); - descriptionLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); - - m_spinBox = new PaddedSpinBox(menuSectionWidget); - Style::setStyle(m_spinBox, style::properties::admt::spinBox); - m_spinBox->setButtonSymbols(m_spinBox->ButtonSymbols::NoButtons); - - m_value = 0x00; - m_spinBox->setValue(m_value); - - QWidget *buttonsWidget = new QWidget(menuSectionWidget); - QHBoxLayout *buttonsContainer = new QHBoxLayout(buttonsWidget); - buttonsWidget->setLayout(buttonsContainer); - - buttonsContainer->setMargin(0); - buttonsContainer->setSpacing(Style::getDimension(json::global::unit_0_5)); - switch(m_accessPermission) - { - case ACCESS_PERMISSION::READWRITE: - addReadButton(buttonsWidget); - addWriteButton(buttonsWidget); - break; - case ACCESS_PERMISSION::WRITE: - addWriteButton(buttonsWidget); - break; - case ACCESS_PERMISSION::READ: - addReadButton(buttonsWidget); - m_spinBox->setReadOnly(true); - break; - } - - menuSectionWidget->contentLayout()->addWidget(headerLabel); - menuSectionWidget->contentLayout()->addWidget(descriptionLabel); - menuSectionWidget->contentLayout()->addWidget(m_spinBox); - menuSectionWidget->contentLayout()->addWidget(buttonsWidget); - - container->addWidget(menuSectionWidget); - container->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Preferred)); - - connect(m_spinBox, QOverload::of(&QSpinBox::valueChanged), this, &RegisterBlockWidget::onValueChanged); +RegisterBlockWidget::RegisterBlockWidget( + QString header, QString description, uint32_t address, uint32_t cnvPage, + RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent) + : QWidget(parent), m_address(address), m_cnvPage(cnvPage), + m_accessPermission(accessPermission) { + QVBoxLayout *container = new QVBoxLayout(this); + setLayout(container); + container->setMargin(0); + container->setSpacing(0); + MenuSectionWidget *menuSectionWidget = new MenuSectionWidget(this); + Style::setStyle(menuSectionWidget, style::properties::widget::basicComponent); + QLabel *headerLabel = new QLabel(header, menuSectionWidget); + Style::setStyle(headerLabel, style::properties::label::menuMedium); + menuSectionWidget->setFixedHeight(180); + menuSectionWidget->contentLayout()->setSpacing( + Style::getDimension(json::global::unit_0_5)); + + QLabel *descriptionLabel = new QLabel(description, menuSectionWidget); + descriptionLabel->setWordWrap(true); + descriptionLabel->setMinimumHeight(24); + descriptionLabel->setAlignment(Qt::AlignTop); + descriptionLabel->setSizePolicy(QSizePolicy::Preferred, + QSizePolicy::MinimumExpanding); + + m_spinBox = new PaddedSpinBox(menuSectionWidget); + Style::setStyle(m_spinBox, style::properties::admt::spinBox); + m_spinBox->setButtonSymbols(m_spinBox->ButtonSymbols::NoButtons); + + m_value = 0x00; + m_spinBox->setValue(m_value); + + QWidget *buttonsWidget = new QWidget(menuSectionWidget); + QHBoxLayout *buttonsContainer = new QHBoxLayout(buttonsWidget); + buttonsWidget->setLayout(buttonsContainer); + + buttonsContainer->setMargin(0); + buttonsContainer->setSpacing(Style::getDimension(json::global::unit_0_5)); + switch (m_accessPermission) { + case ACCESS_PERMISSION::READWRITE: + addReadButton(buttonsWidget); + addWriteButton(buttonsWidget); + break; + case ACCESS_PERMISSION::WRITE: + addWriteButton(buttonsWidget); + break; + case ACCESS_PERMISSION::READ: + addReadButton(buttonsWidget); + m_spinBox->setReadOnly(true); + break; + } + + menuSectionWidget->contentLayout()->addWidget(headerLabel); + menuSectionWidget->contentLayout()->addWidget(descriptionLabel); + menuSectionWidget->contentLayout()->addWidget(m_spinBox); + menuSectionWidget->contentLayout()->addWidget(buttonsWidget); + + container->addWidget(menuSectionWidget); + container->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, + QSizePolicy::Preferred)); + + connect(m_spinBox, QOverload::of(&QSpinBox::valueChanged), this, + &RegisterBlockWidget::onValueChanged); } RegisterBlockWidget::~RegisterBlockWidget() {} -void RegisterBlockWidget::onValueChanged(int newValue){ m_value = static_cast(newValue); } +void RegisterBlockWidget::onValueChanged(int newValue) { + m_value = static_cast(newValue); +} uint32_t RegisterBlockWidget::getValue() { return m_value; } -void RegisterBlockWidget::setValue(uint32_t value) -{ - m_value = value; - m_spinBox->setValue(m_value); +void RegisterBlockWidget::setValue(uint32_t value) { + m_value = value; + m_spinBox->setValue(m_value); } uint32_t RegisterBlockWidget::getAddress() { return m_address; } uint32_t RegisterBlockWidget::getCnvPage() { return m_cnvPage; } -RegisterBlockWidget::ACCESS_PERMISSION RegisterBlockWidget::getAccessPermission() { return m_accessPermission; } +RegisterBlockWidget::ACCESS_PERMISSION +RegisterBlockWidget::getAccessPermission() { + return m_accessPermission; +} -void RegisterBlockWidget::addReadButton(QWidget *parent) -{ - m_readButton = new QPushButton("Read", parent); - Style::setStyle(m_readButton, style::properties::button::basicButton); - parent->layout()->addWidget(m_readButton); +void RegisterBlockWidget::addReadButton(QWidget *parent) { + m_readButton = new QPushButton("Read", parent); + Style::setStyle(m_readButton, style::properties::button::basicButton); + parent->layout()->addWidget(m_readButton); } QPushButton *RegisterBlockWidget::readButton() { return m_readButton; } -void RegisterBlockWidget::addWriteButton(QWidget *parent) -{ - m_writeButton = new QPushButton("Write", parent); - Style::setStyle(m_writeButton, style::properties::button::basicButton); - parent->layout()->addWidget(m_writeButton); +void RegisterBlockWidget::addWriteButton(QWidget *parent) { + m_writeButton = new QPushButton("Write", parent); + Style::setStyle(m_writeButton, style::properties::button::basicButton); + parent->layout()->addWidget(m_writeButton); } QPushButton *RegisterBlockWidget::writeButton() { return m_writeButton; } -PaddedSpinBox::PaddedSpinBox(QWidget *parent) - : QSpinBox(parent) -{ - setDisplayIntegerBase(16); - setMinimum(0); - setMaximum(INT_MAX); +PaddedSpinBox::PaddedSpinBox(QWidget *parent) : QSpinBox(parent) { + setDisplayIntegerBase(16); + setMinimum(0); + setMaximum(INT_MAX); } PaddedSpinBox::~PaddedSpinBox() {} -QString PaddedSpinBox::textFromValue(int value) const -{ - return QString("0x%1").arg(value, 4, 16, QChar('0')); -} \ No newline at end of file +QString PaddedSpinBox::textFromValue(int value) const { + return QString("0x%1").arg(value, 4, 16, QChar('0')); +} +#include "moc_registerblockwidget.cpp" diff --git a/plugins/admt/test/CMakeLists.txt b/plugins/admt/test/CMakeLists.txt index 2b852586f3..58e12bc642 100644 --- a/plugins/admt/test/CMakeLists.txt +++ b/plugins/admt/test/CMakeLists.txt @@ -22,4 +22,4 @@ cmake_minimum_required(VERSION 3.5) include(ScopyTest) -setup_scopy_tests(pluginloader) \ No newline at end of file +setup_scopy_tests(pluginloader) diff --git a/plugins/admt/test/tst_pluginloader.cpp b/plugins/admt/test/tst_pluginloader.cpp new file mode 100644 index 0000000000..8ed3b7c047 --- /dev/null +++ b/plugins/admt/test/tst_pluginloader.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2023 Analog Devices Inc. + * + * This file is part of Scopy + * (see https://www.github.com/analogdevicesinc/scopy). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "qpluginloader.h" + +#include +#include + +#include + +using namespace scopy; + +class TST_ADMTPlugin : public QObject { + Q_OBJECT +private Q_SLOTS: + void fileExists(); + void isLibrary(); + void loaded(); + void className(); + void instanceNotNull(); + void multipleInstances(); + void qobjectcast_to_plugin(); + void clone(); + void name(); + void metadata(); +}; + +#define PLUGIN_LOCATION "../../plugins" +#define FILENAME PLUGIN_LOCATION "/libscopy-admtplugin.so" + +void TST_ADMTPlugin::fileExists() { + QFile f(FILENAME); + bool ret; + ret = f.open(QIODevice::ReadOnly); + if (ret) + f.close(); + QVERIFY(ret); +} + +void TST_ADMTPlugin::isLibrary() { QVERIFY(QLibrary::isLibrary(FILENAME)); } + +void TST_ADMTPlugin::className() { + QPluginLoader qp(FILENAME, this); + QVERIFY(qp.metaData().value("className") == "ADMTPlugin"); +} + +void TST_ADMTPlugin::loaded() { + QPluginLoader qp(FILENAME, this); + qp.load(); + QVERIFY(qp.isLoaded()); +} + +void TST_ADMTPlugin::instanceNotNull() { + QPluginLoader qp(FILENAME, this); + QVERIFY(qp.instance() != nullptr); +} + +void TST_ADMTPlugin::multipleInstances() { + QPluginLoader qp1(FILENAME, this); + QPluginLoader qp2(FILENAME, this); + + QVERIFY(qp1.instance() == qp2.instance()); +} + +void TST_ADMTPlugin::qobjectcast_to_plugin() { + QPluginLoader qp(FILENAME, this); + auto instance = qobject_cast(qp.instance()); + QVERIFY(instance != nullptr); +} + +void TST_ADMTPlugin::clone() { + QPluginLoader qp(FILENAME, this); + + Plugin *p1 = nullptr, *p2 = nullptr; + auto original = qobject_cast(qp.instance()); + p1 = original->clone(); + QVERIFY(p1 != nullptr); + p2 = original->clone(); + QVERIFY(p2 != nullptr); + QVERIFY(p1 != p2); +} + +void TST_ADMTPlugin::name() { + QPluginLoader qp(FILENAME, this); + + Plugin *p1 = nullptr, *p2 = nullptr; + auto original = qobject_cast(qp.instance()); + p1 = original->clone(); + qDebug() << p1->name(); +} + +void TST_ADMTPlugin::metadata() { + QPluginLoader qp(FILENAME, this); + + Plugin *p1 = nullptr, *p2 = nullptr; + auto original = qobject_cast(qp.instance()); + original->initMetadata(); + p1 = original->clone(); + qDebug() << p1->metadata(); + QVERIFY(!p1->metadata().isEmpty()); +} + +QTEST_MAIN(TST_ADMTPlugin) + +#include "tst_pluginloader.moc" \ No newline at end of file From 32930e8bb3ec910b4f5866cff0133cdad72152d7 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 27 Feb 2025 14:10:16 +0800 Subject: [PATCH 091/112] admt: Applied clang-format for C++ files Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 437 +- plugins/admt/include/admt/admtplugin.h | 33 +- plugins/admt/include/admt/admtstylehelper.h | 65 +- .../admt/include/admt/harmoniccalibration.h | 627 +- .../include/admt/widgets/horizontalspinbox.h | 40 +- .../admt/widgets/registerblockwidget.h | 59 +- plugins/admt/src/admtcontroller.cpp | 3256 +++--- plugins/admt/src/admtplugin.cpp | 197 +- plugins/admt/src/admtstylehelper.cpp | 295 +- plugins/admt/src/harmoniccalibration.cpp | 9526 ++++++++--------- .../admt/src/widgets/horizontalspinbox.cpp | 258 +- .../admt/src/widgets/registerblockwidget.cpp | 170 +- plugins/admt/test/tst_pluginloader.cpp | 132 +- 13 files changed, 7190 insertions(+), 7905 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 95d0d9ba48..797be6ee59 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -47,255 +47,246 @@ using namespace std; namespace scopy::admt { -class SCOPY_ADMT_EXPORT ADMTController : public QObject { - Q_OBJECT +class SCOPY_ADMT_EXPORT ADMTController : public QObject +{ + Q_OBJECT public: - ADMTController(QString uri, QObject *parent = nullptr); - ~ADMTController(); + ADMTController(QString uri, QObject *parent = nullptr); + ~ADMTController(); - int HAR_MAG_1, HAR_MAG_2, HAR_MAG_3, HAR_MAG_8, HAR_PHASE_1, HAR_PHASE_2, - HAR_PHASE_3, HAR_PHASE_8, sampleCount = 0; + int HAR_MAG_1, HAR_MAG_2, HAR_MAG_3, HAR_MAG_8, HAR_PHASE_1, HAR_PHASE_2, HAR_PHASE_3, HAR_PHASE_8, + sampleCount = 0; - bool stopStream = false; + bool stopStream = false; - double streamedValue = 0.0; - QVector streamBufferedValues; - QVector streamBufferedIntervals; + double streamedValue = 0.0; + QVector streamBufferedValues; + QVector streamBufferedIntervals; - QElapsedTimer elapsedStreamTimer; + QElapsedTimer elapsedStreamTimer; - vector angle_errors_fft_pre, angle_errors_fft_phase_pre, - angle_errors_fft_post, angle_errors_fft_phase_post, - calibration_samples_sine, calibration_samples_cosine, - calibration_samples_sine_scaled, calibration_samples_cosine_scaled, - angleError, FFTAngleErrorMagnitude, FFTAngleErrorPhase, correctedError, - FFTCorrectedErrorMagnitude, FFTCorrectedErrorPhase; + vector angle_errors_fft_pre, angle_errors_fft_phase_pre, angle_errors_fft_post, + angle_errors_fft_phase_post, calibration_samples_sine, calibration_samples_cosine, + calibration_samples_sine_scaled, calibration_samples_cosine_scaled, angleError, FFTAngleErrorMagnitude, + FFTAngleErrorPhase, correctedError, FFTCorrectedErrorMagnitude, FFTCorrectedErrorPhase; - enum Channel { ROTATION, ANGLE, COUNT, TEMPERATURE, CHANNEL_COUNT }; + enum Channel + { + ROTATION, + ANGLE, + COUNT, + TEMPERATURE, + CHANNEL_COUNT + }; - enum Device { ADMT4000, TMC5240, DEVICE_COUNT }; + enum Device + { + ADMT4000, + TMC5240, + DEVICE_COUNT + }; - enum DeviceAttribute { - PAGE, - SEQUENCER_MODE, - ANGLE_FILT, - CONVERSION_MODE, - H8_CTRL, - SDP_GPIO_CTRL, - SDP_GPIO0_BUSY, - SDP_COIL_RS, - REGMAP_DUMP, - DEVICE_ATTR_COUNT - }; + enum DeviceAttribute + { + PAGE, + SEQUENCER_MODE, + ANGLE_FILT, + CONVERSION_MODE, + H8_CTRL, + SDP_GPIO_CTRL, + SDP_GPIO0_BUSY, + SDP_COIL_RS, + REGMAP_DUMP, + DEVICE_ATTR_COUNT + }; - enum MotorAttribute { - AMAX, - ROTATE_VMAX, - DMAX, - DISABLE, - TARGET_POS, - CURRENT_POS, - RAMP_MODE, - MOTOR_ATTR_COUNT - }; + enum MotorAttribute + { + AMAX, + ROTATE_VMAX, + DMAX, + DISABLE, + TARGET_POS, + CURRENT_POS, + RAMP_MODE, + MOTOR_ATTR_COUNT + }; - enum MotorRampMode { POSITION, RAMP_MODE_1 }; + enum MotorRampMode + { + POSITION, + RAMP_MODE_1 + }; - enum HarmonicRegister { - H1MAG, - H1PH, - H2MAG, - H2PH, - H3MAG, - H3PH, - H8MAG, - H8PH, - HARMONIC_REGISTER_COUNT - }; + enum HarmonicRegister + { + H1MAG, + H1PH, + H2MAG, + H2PH, + H3MAG, + H3PH, + H8MAG, + H8PH, + HARMONIC_REGISTER_COUNT + }; - enum ConfigurationRegister { - CNVPAGE, - DIGIO, - FAULT, - GENERAL, - DIGIOEN, - ANGLECK, - ECCDCDE, - ECCDIS, - CONFIGURATION_REGISTER_COUNT - }; + enum ConfigurationRegister + { + CNVPAGE, + DIGIO, + FAULT, + GENERAL, + DIGIOEN, + ANGLECK, + ECCDCDE, + ECCDIS, + CONFIGURATION_REGISTER_COUNT + }; - enum SensorRegister { - ABSANGLE, - ANGLEREG, - ANGLESEC, - SINE, - COSINE, - SECANGLI, - SECANGLQ, - RADIUS, - DIAG1, - DIAG2, - TMP0, - TMP1, - CNVCNT, - SENSOR_REGISTER_COUNT - }; + enum SensorRegister + { + ABSANGLE, + ANGLEREG, + ANGLESEC, + SINE, + COSINE, + SECANGLI, + SECANGLQ, + RADIUS, + DIAG1, + DIAG2, + TMP0, + TMP1, + CNVCNT, + SENSOR_REGISTER_COUNT + }; - enum UniqueIDRegister { - UNIQID0, - UNIQID1, - UNIQID2, - UNIQID3, - UNIQID_REGISTER_COUNT - }; + enum UniqueIDRegister + { + UNIQID0, + UNIQID1, + UNIQID2, + UNIQID3, + UNIQID_REGISTER_COUNT + }; - enum RampGeneratorDriverFeatureControlRegister { - VDCMIN, - SW_MODE, - RAMP_STAT, - XLATCH, - RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT - }; + enum RampGeneratorDriverFeatureControlRegister + { + VDCMIN, + SW_MODE, + RAMP_STAT, + XLATCH, + RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT + }; - const char *ChannelIds[CHANNEL_COUNT] = {"rot", "angl", "count", "temp"}; - const char *DeviceIds[DEVICE_COUNT] = {"admt4000", "tmc5240"}; - const char *DeviceAttributes[DEVICE_ATTR_COUNT] = { - "page", "sequencer_mode", "angle_filt", "conversion_mode", - "h8_ctrl", "sdp_gpio_ctrl", "sdp_gpio0_busy", "sdp_coil_rs", - "regmap_dump"}; - const char *MotorAttributes[MOTOR_ATTR_COUNT] = { - "amax", "rotate_vmax", "dmax", "disable", - "target_pos", "current_pos", "ramp_mode"}; - const uint32_t ConfigurationRegisters[CONFIGURATION_REGISTER_COUNT] = { - 0x01, 0x04, 0x06, 0x10, 0x12, 0x13, 0x1D, 0x23}; - const uint32_t ConfigurationPages[CONFIGURATION_REGISTER_COUNT] = { - UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x02, 0x02, 0x02, 0x02, 0x02}; - const uint32_t UniqueIdRegisters[UNIQID_REGISTER_COUNT] = {0x1E, 0x1F, 0x20, - 0x21}; - const uint32_t UniqueIdPages[UNIQID_REGISTER_COUNT] = {0x02, 0x02, 0x02, - 0x02}; - const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = { - 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C}; - const uint32_t HarmonicPages[HARMONIC_REGISTER_COUNT] = { - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}; - const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = { - 0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, - 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14}; - const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = { - UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; + const char *ChannelIds[CHANNEL_COUNT] = {"rot", "angl", "count", "temp"}; + const char *DeviceIds[DEVICE_COUNT] = {"admt4000", "tmc5240"}; + const char *DeviceAttributes[DEVICE_ATTR_COUNT] = { + "page", "sequencer_mode", "angle_filt", "conversion_mode", "h8_ctrl", + "sdp_gpio_ctrl", "sdp_gpio0_busy", "sdp_coil_rs", "regmap_dump"}; + const char *MotorAttributes[MOTOR_ATTR_COUNT] = {"amax", "rotate_vmax", "dmax", "disable", + "target_pos", "current_pos", "ramp_mode"}; + const uint32_t ConfigurationRegisters[CONFIGURATION_REGISTER_COUNT] = {0x01, 0x04, 0x06, 0x10, + 0x12, 0x13, 0x1D, 0x23}; + const uint32_t ConfigurationPages[CONFIGURATION_REGISTER_COUNT] = {UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x02, + 0x02, 0x02, 0x02, 0x02}; + const uint32_t UniqueIdRegisters[UNIQID_REGISTER_COUNT] = {0x1E, 0x1F, 0x20, 0x21}; + const uint32_t UniqueIdPages[UNIQID_REGISTER_COUNT] = {0x02, 0x02, 0x02, 0x02}; + const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = {0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C}; + const uint32_t HarmonicPages[HARMONIC_REGISTER_COUNT] = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}; + const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = {0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, + 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14}; + const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = {UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; - const uint32_t RampGeneratorDriverFeatureControlRegisters - [RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT] = {0x33, 0x34, - 0x35, 0x36}; + const uint32_t + RampGeneratorDriverFeatureControlRegisters[RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT] = { + 0x33, 0x34, 0x35, 0x36}; - const char *getChannelId(Channel channel); - const char *getDeviceId(Device device); - const char *getDeviceAttribute(DeviceAttribute attribute); - const char *getMotorAttribute(MotorAttribute attribute); - const uint32_t getConfigurationRegister(ConfigurationRegister registerID); - const uint32_t getConfigurationPage(ConfigurationRegister registerID); - const uint32_t getUniqueIdRegister(UniqueIDRegister registerID); - const uint32_t getHarmonicRegister(HarmonicRegister registerID); - const uint32_t getHarmonicPage(HarmonicRegister registerID); - const uint32_t getUniqueIdPage(UniqueIDRegister registerID); - const uint32_t getSensorRegister(SensorRegister registerID); - const uint32_t getSensorPage(SensorRegister registerID); + const char *getChannelId(Channel channel); + const char *getDeviceId(Device device); + const char *getDeviceAttribute(DeviceAttribute attribute); + const char *getMotorAttribute(MotorAttribute attribute); + const uint32_t getConfigurationRegister(ConfigurationRegister registerID); + const uint32_t getConfigurationPage(ConfigurationRegister registerID); + const uint32_t getUniqueIdRegister(UniqueIDRegister registerID); + const uint32_t getHarmonicRegister(HarmonicRegister registerID); + const uint32_t getHarmonicPage(HarmonicRegister registerID); + const uint32_t getUniqueIdPage(UniqueIDRegister registerID); + const uint32_t getSensorRegister(SensorRegister registerID); + const uint32_t getSensorPage(SensorRegister registerID); - const uint32_t getRampGeneratorDriverFeatureControlRegister( - RampGeneratorDriverFeatureControlRegister registerID); + const uint32_t + getRampGeneratorDriverFeatureControlRegister(RampGeneratorDriverFeatureControlRegister registerID); - void connectADMT(); - void disconnectADMT(); - int getChannelIndex(const char *deviceName, const char *channelName); - double getChannelValue(const char *deviceName, const char *channelName, - int bufferSize = 1); - int getDeviceAttributeValue(const char *deviceName, const char *attributeName, - double *returnValue); - int getDeviceAttributeValueString(const char *deviceName, - const char *attributeName, - char *returnValue, size_t byteLength = 512); - int setDeviceAttributeValue(const char *deviceName, const char *attributeName, - double writeValue); - QString calibrate(vector PANG, int cycles, int samplesPerCycle, - bool CCW); - int writeDeviceRegistry(const char *deviceName, uint32_t address, - uint32_t value); - int readDeviceRegistry(const char *deviceName, uint32_t address, - uint32_t *returnValue); - void computeSineCosineOfAngles(const vector &angles); - uint16_t calculateHarmonicCoefficientMagnitude(uint16_t harmonicCoefficient, - uint16_t originalValue, - const string &key); - uint16_t calculateHarmonicCoefficientPhase(uint16_t harmonicPhase, - uint16_t originalValue); - double getActualHarmonicRegisterValue(uint16_t registerValue, - const string key); - map getFaultRegisterBitMapping(uint16_t registerValue); - map getGeneralRegisterBitMapping(uint16_t registerValue); - map getDIGIOENRegisterBitMapping(uint16_t registerValue); - map getDIGIORegisterBitMapping(uint16_t registerValue); - map getDiag1RegisterBitMapping_Register(uint16_t registerValue); - map getDiag1RegisterBitMapping_Afe(uint16_t registerValue, - bool is5V); - map getDiag2RegisterBitMapping(uint16_t registerValue); - uint16_t setGeneralRegisterBitMapping(uint16_t currentRegisterValue, - map settings); - void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle, - bool CCW); - int getAbsAngleTurnCount(uint16_t registerValue); - uint16_t setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, - map settings); - uint16_t setDIGIORegisterBitMapping(uint16_t currentRegisterValue, - map settings); - void unwrapAngles(vector &angles_rad); - map getUNIQID3RegisterMapping(uint16_t registerValue); - map getSineRegisterBitMapping(uint16_t registerValue); - map getCosineRegisterBitMapping(uint16_t registerValue); - map getRadiusRegisterBitMapping(uint16_t registerValue); - map getAngleSecRegisterBitMapping(uint16_t registerValue); - map getSecAnglQRegisterBitMapping(uint16_t registerValue); - map getSecAnglIRegisterBitMapping(uint16_t registerValue); - map getTmp1RegisterBitMapping(uint16_t registerValue, - bool is5V); - bool checkRegisterFault(uint16_t registerValue, bool isMode1); - int streamIO(); - void bufferedStreamIO(int totalSamples, int targetSampleRate); - bool checkVelocityReachedFlag(uint16_t registerValue); + void connectADMT(); + void disconnectADMT(); + int getChannelIndex(const char *deviceName, const char *channelName); + double getChannelValue(const char *deviceName, const char *channelName, int bufferSize = 1); + int getDeviceAttributeValue(const char *deviceName, const char *attributeName, double *returnValue); + int getDeviceAttributeValueString(const char *deviceName, const char *attributeName, char *returnValue, + size_t byteLength = 512); + int setDeviceAttributeValue(const char *deviceName, const char *attributeName, double writeValue); + QString calibrate(vector PANG, int cycles, int samplesPerCycle, bool CCW); + int writeDeviceRegistry(const char *deviceName, uint32_t address, uint32_t value); + int readDeviceRegistry(const char *deviceName, uint32_t address, uint32_t *returnValue); + void computeSineCosineOfAngles(const vector &angles); + uint16_t calculateHarmonicCoefficientMagnitude(uint16_t harmonicCoefficient, uint16_t originalValue, + const string &key); + uint16_t calculateHarmonicCoefficientPhase(uint16_t harmonicPhase, uint16_t originalValue); + double getActualHarmonicRegisterValue(uint16_t registerValue, const string key); + map getFaultRegisterBitMapping(uint16_t registerValue); + map getGeneralRegisterBitMapping(uint16_t registerValue); + map getDIGIOENRegisterBitMapping(uint16_t registerValue); + map getDIGIORegisterBitMapping(uint16_t registerValue); + map getDiag1RegisterBitMapping_Register(uint16_t registerValue); + map getDiag1RegisterBitMapping_Afe(uint16_t registerValue, bool is5V); + map getDiag2RegisterBitMapping(uint16_t registerValue); + uint16_t setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings); + void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle, bool CCW); + int getAbsAngleTurnCount(uint16_t registerValue); + uint16_t setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings); + uint16_t setDIGIORegisterBitMapping(uint16_t currentRegisterValue, map settings); + void unwrapAngles(vector &angles_rad); + map getUNIQID3RegisterMapping(uint16_t registerValue); + map getSineRegisterBitMapping(uint16_t registerValue); + map getCosineRegisterBitMapping(uint16_t registerValue); + map getRadiusRegisterBitMapping(uint16_t registerValue); + map getAngleSecRegisterBitMapping(uint16_t registerValue); + map getSecAnglQRegisterBitMapping(uint16_t registerValue); + map getSecAnglIRegisterBitMapping(uint16_t registerValue); + map getTmp1RegisterBitMapping(uint16_t registerValue, bool is5V); + bool checkRegisterFault(uint16_t registerValue, bool isMode1); + int streamIO(); + void bufferedStreamIO(int totalSamples, int targetSampleRate); + bool checkVelocityReachedFlag(uint16_t registerValue); public Q_SLOTS: - void handleStreamData(double value); - void handleStreamBufferedData(const QVector &value); - void handleStreamBufferedDataInterval(const QVector &value); + void handleStreamData(double value); + void handleStreamBufferedData(const QVector &value); + void handleStreamBufferedDataInterval(const QVector &value); Q_SIGNALS: - void streamData(double value); - void streamBufferedData(const QVector &value); - void streamBufferedDataInterval(const QVector &value); + void streamData(double value); + void streamBufferedData(const QVector &value); + void streamBufferedDataInterval(const QVector &value); private: - iio_context *m_iioCtx; - iio_buffer *m_iioBuffer; - Connection *m_conn; - QString uri; + iio_context *m_iioCtx; + iio_buffer *m_iioBuffer; + Connection *m_conn; + QString uri; - unsigned int bitReverse(unsigned int x, int log2n); - template void fft(Iter_T a, Iter_T b, int log2n); - void performFFT(const vector &angle_errors, - vector &angle_errors_fft, - vector &angle_errors_fft_phase, int cycleCount); - int linear_fit(vector x, vector y, double *slope, - double *intercept); - int calculate_angle_error(vector angle_meas, - vector &angle_error_ret, - double *max_angle_err); - void getPreCalibrationFFT(const vector &PANG, - vector &angle_errors_fft_pre, - vector &angle_errors_fft_phase_pre, - int cycleCount, int samplesPerCycle); - void getPostCalibrationFFT(const vector &updated_PANG, - vector &angle_errors_fft_post, - vector &angle_errors_fft_phase_post, - int cycleCount, int samplesPerCycle); + unsigned int bitReverse(unsigned int x, int log2n); + template + void fft(Iter_T a, Iter_T b, int log2n); + void performFFT(const vector &angle_errors, vector &angle_errors_fft, + vector &angle_errors_fft_phase, int cycleCount); + int linear_fit(vector x, vector y, double *slope, double *intercept); + int calculate_angle_error(vector angle_meas, vector &angle_error_ret, double *max_angle_err); + void getPreCalibrationFFT(const vector &PANG, vector &angle_errors_fft_pre, + vector &angle_errors_fft_phase_pre, int cycleCount, int samplesPerCycle); + void getPostCalibrationFFT(const vector &updated_PANG, vector &angle_errors_fft_post, + vector &angle_errors_fft_phase_post, int cycleCount, int samplesPerCycle); }; } // namespace scopy::admt diff --git a/plugins/admt/include/admt/admtplugin.h b/plugins/admt/include/admt/admtplugin.h index 7a3ff7f956..23f91c8579 100644 --- a/plugins/admt/include/admt/admtplugin.h +++ b/plugins/admt/include/admt/admtplugin.h @@ -39,29 +39,30 @@ namespace scopy { namespace admt { -class SCOPY_ADMT_EXPORT ADMTPlugin : public QObject, public PluginBase { - Q_OBJECT - SCOPY_PLUGIN; +class SCOPY_ADMT_EXPORT ADMTPlugin : public QObject, public PluginBase +{ + Q_OBJECT + SCOPY_PLUGIN; public: - bool compatible(QString m_param, QString category) override; - bool loadPage() override; - bool loadIcon() override; - void loadToolList() override; - void unload() override; - void initMetadata() override; - QString description() override; + bool compatible(QString m_param, QString category) override; + bool loadPage() override; + bool loadIcon() override; + void loadToolList() override; + void unload() override; + void initMetadata() override; + QString description() override; public Q_SLOTS: - bool onConnect() override; - bool onDisconnect() override; + bool onConnect() override; + bool onDisconnect() override; private: - iio_context *m_ctx; - QWidget *harmonicCalibration; - QLineEdit *edit; + iio_context *m_ctx; + QWidget *harmonicCalibration; + QLineEdit *edit; - ADMTController *m_admtController; + ADMTController *m_admtController; }; } // namespace admt } // namespace scopy diff --git a/plugins/admt/include/admt/admtstylehelper.h b/plugins/admt/include/admt/admtstylehelper.h index cc17814d02..77cdeab639 100644 --- a/plugins/admt/include/admt/admtstylehelper.h +++ b/plugins/admt/include/admt/admtstylehelper.h @@ -38,49 +38,42 @@ namespace scopy { namespace admt { -class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject { - Q_OBJECT +class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject +{ + Q_OBJECT protected: - ADMTStyleHelper(QObject *parent = nullptr); - ~ADMTStyleHelper(); + ADMTStyleHelper(QObject *parent = nullptr); + ~ADMTStyleHelper(); public: - // singleton - ADMTStyleHelper(ADMTStyleHelper &other) = delete; - void operator=(const ADMTStyleHelper &) = delete; - static ADMTStyleHelper *GetInstance(); + // singleton + ADMTStyleHelper(ADMTStyleHelper &other) = delete; + void operator=(const ADMTStyleHelper &) = delete; + static ADMTStyleHelper *GetInstance(); public: - static void initColorMap(); - static QString getColor(QString id); - static void TopContainerButtonStyle(QPushButton *btn, - QString objectName = ""); - static void PlotWidgetStyle(PlotWidget *widget, QString objectName = ""); - static void ComboBoxStyle(QComboBox *widget, QString objectName = ""); - static void LineEditStyle(QLineEdit *widget, QString objectName = ""); - static void ColoredSquareCheckbox(QCheckBox *chk, QColor color, - QString objectName = ""); - static void StartButtonStyle(QPushButton *btn, QString objectName = ""); - static void - TextStyle(QWidget *widget, const char *styleHelperColor = json::global::white, - bool isBold = false, - QString objectName = ""); // void TextStyle(QWidget *widget, const - // QString& styleHelperColor, bool isBold - // = false, QString objectName = ""); - static void MenuSmallLabel(QLabel *label, QString objectName = ""); - static void LineStyle(QFrame *line, QString objectName = ""); - static void UIBackgroundStyle(QWidget *widget, QString objectName = ""); - static void GraphChannelStyle(QWidget *widget, QLayout *layout, - QString objectName = ""); - static void CalculatedCoeffWidgetRowStyle(QWidget *widget, - QHBoxLayout *layout, QLabel *hLabel, - QLabel *hMagLabel, - QLabel *hPhaseLabel, - QString objectName = ""); + static void initColorMap(); + static QString getColor(QString id); + static void TopContainerButtonStyle(QPushButton *btn, QString objectName = ""); + static void PlotWidgetStyle(PlotWidget *widget, QString objectName = ""); + static void ComboBoxStyle(QComboBox *widget, QString objectName = ""); + static void LineEditStyle(QLineEdit *widget, QString objectName = ""); + static void ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName = ""); + static void StartButtonStyle(QPushButton *btn, QString objectName = ""); + static void TextStyle(QWidget *widget, const char *styleHelperColor = json::global::white, bool isBold = false, + QString objectName = ""); // void TextStyle(QWidget *widget, const + // QString& styleHelperColor, bool isBold + // = false, QString objectName = ""); + static void MenuSmallLabel(QLabel *label, QString objectName = ""); + static void LineStyle(QFrame *line, QString objectName = ""); + static void UIBackgroundStyle(QWidget *widget, QString objectName = ""); + static void GraphChannelStyle(QWidget *widget, QLayout *layout, QString objectName = ""); + static void CalculatedCoeffWidgetRowStyle(QWidget *widget, QHBoxLayout *layout, QLabel *hLabel, + QLabel *hMagLabel, QLabel *hPhaseLabel, QString objectName = ""); private: - QMap colorMap; - static ADMTStyleHelper *pinstance_; + QMap colorMap; + static ADMTStyleHelper *pinstance_; }; } // namespace admt } // namespace scopy diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index eb78eb9a35..acd4ecffb2 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -76,377 +76,334 @@ #include #include -enum AcquisitionDataKey { - RADIUS, - ANGLE, - TURNCOUNT, - ABSANGLE, - SINE, - COSINE, - SECANGLI, - SECANGLQ, - ANGLESEC, - DIAG1, - DIAG2, - TMP0, - TMP1, - CNVCNT, - SCRADIUS, - SPIFAULT +enum AcquisitionDataKey +{ + RADIUS, + ANGLE, + TURNCOUNT, + ABSANGLE, + SINE, + COSINE, + SECANGLI, + SECANGLQ, + ANGLESEC, + DIAG1, + DIAG2, + TMP0, + TMP1, + CNVCNT, + SCRADIUS, + SPIFAULT }; namespace scopy { namespace admt { -class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget { - Q_OBJECT +class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget +{ + Q_OBJECT public: - HarmonicCalibration(ADMTController *m_admtController, bool isDebug = false, - QWidget *parent = nullptr); - ~HarmonicCalibration(); - bool running() const; - void setRunning(bool newRunning); - void requestDisconnect(); + HarmonicCalibration(ADMTController *m_admtController, bool isDebug = false, QWidget *parent = nullptr); + ~HarmonicCalibration(); + bool running() const; + void setRunning(bool newRunning); + void requestDisconnect(); public Q_SLOTS: - void run(bool); - void stop(); - void start(); - void restart(); - void calibrationLogWrite(QString message = ""); - void commandLogWrite(QString message = ""); - void updateFaultStatus(bool value); - void updateMotorPosition(double position); - void updateDIGIOUI(uint16_t *registerValue); - void updateFaultRegisterUI(uint16_t *registerValue); - void updateMTDiagnosticRegisterUI(uint16_t *registerValue); - void updateMTDiagnosticsUI(uint16_t *registerValue); + void run(bool); + void stop(); + void start(); + void restart(); + void calibrationLogWrite(QString message = ""); + void commandLogWrite(QString message = ""); + void updateFaultStatus(bool value); + void updateMotorPosition(double position); + void updateDIGIOUI(uint16_t *registerValue); + void updateFaultRegisterUI(uint16_t *registerValue); + void updateMTDiagnosticRegisterUI(uint16_t *registerValue); + void updateMTDiagnosticsUI(uint16_t *registerValue); Q_SIGNALS: - void runningChanged(bool); - void canCalibrateChanged(bool); - void updateUtilityUI(); - void calibrationLogWriteSignal(QString message); - void commandLogWriteSignal(QString message); - void updateFaultStatusSignal(bool value); - void motorPositionChanged(double position); - void DIGIORegisterChanged(uint16_t *registerValue); - void FaultRegisterChanged(uint16_t *registerValue); - void DIAG1RegisterChanged(uint16_t *registerValue); - void DIAG2RegisterChanged(uint16_t *registerValue); + void runningChanged(bool); + void canCalibrateChanged(bool); + void updateUtilityUI(); + void calibrationLogWriteSignal(QString message); + void commandLogWriteSignal(QString message); + void updateFaultStatusSignal(bool value); + void motorPositionChanged(double position); + void DIGIORegisterChanged(uint16_t *registerValue); + void FaultRegisterChanged(uint16_t *registerValue); + void DIAG1RegisterChanged(uint16_t *registerValue); + void DIAG2RegisterChanged(uint16_t *registerValue); private: - ADMTController *m_admtController; - iio_context *m_ctx; - bool m_running, isDebug; - ToolTemplate *tool; - GearBtn *settingsButton; - InfoBtn *infoButton; - RunBtn *runButton; - - const char *rotationChannelName, *angleChannelName, *countChannelName, - *temperatureChannelName; - - double rotation, angle, count, temp = 0.0, motor_rpm, amax, rotate_vmax, dmax, - disable, target_pos, current_pos, ramp_mode, - afeDiag0, afeDiag1, afeDiag2; - - QPushButton *openLastMenuButton, *calibrationStartMotorButton, - *calibrateDataButton, *extractDataButton, *clearCalibrateDataButton, - *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; - QButtonGroup *rightMenuButtonGroup; - - QLineEdit *acquisitionMotorRPMLineEdit, *calibrationMotorRPMLineEdit, - *motorTargetPositionLineEdit, *graphUpdateIntervalLineEdit, - *displayLengthLineEdit, *dataGraphSamplesLineEdit, - *tempGraphSamplesLineEdit, *acquisitionMotorCurrentPositionLineEdit, - *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, - *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, - *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, - *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit, - *calibrationMotorCurrentPositionLineEdit, *AFEDIAG0LineEdit, - *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; - - QLabel *rawAngleValueLabel, *rotationValueLabel, *angleValueLabel, - *countValueLabel, *tempValueLabel, *motorAmaxValueLabel, - *motorRotateVmaxValueLabel, *motorDmaxValueLabel, *motorDisableValueLabel, - *motorTargetPosValueLabel, *motorCurrentPosValueLabel, - *motorRampModeValueLabel, *calibrationH1MagLabel, - *calibrationH1PhaseLabel, *calibrationH2MagLabel, - *calibrationH2PhaseLabel, *calibrationH3MagLabel, - *calibrationH3PhaseLabel, *calibrationH8MagLabel, - *calibrationH8PhaseLabel; - - MenuHeaderWidget *header; - - MenuSectionWidget *rightMenuSectionWidget; - MenuCollapseSection *rotationCollapse, *angleCollapse, *countCollapse, - *tempCollapse; - MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, - *m_tempGraphDirectionMenuCombo, *m_calibrationMotorRampModeMenuCombo, - *sequenceTypeMenuCombo, *conversionTypeMenuCombo, *cnvSourceMenuCombo, - *convertSynchronizationMenuCombo, *angleFilterMenuCombo, - *eighthHarmonicMenuCombo, *calibrationModeMenuCombo; - - QTabWidget *tabWidget, *calibrationDataGraphTabWidget, *resultDataTabWidget; - - QListWidget *rawDataListWidget; - - QPlainTextEdit *logsPlainTextEdit, *commandLogPlainTextEdit; - - QCheckBox *acquisitionFaultRegisterLEDWidget, - *calibrationFaultRegisterLEDWidget, *DIGIOBusyStatusLED, - *DIGIOCNVStatusLED, *DIGIOSENTStatusLED, *DIGIOACALCStatusLED, - *DIGIOFaultStatusLED, *DIGIOBootloaderStatusLED, *R0StatusLED, - *R1StatusLED, *R2StatusLED, *R3StatusLED, *R4StatusLED, *R5StatusLED, - *R6StatusLED, *R7StatusLED, *VDDUnderVoltageStatusLED, - *VDDOverVoltageStatusLED, *VDRIVEUnderVoltageStatusLED, - *VDRIVEOverVoltageStatusLED, *AFEDIAGStatusLED, *NVMCRCFaultStatusLED, - *ECCDoubleBitErrorStatusLED, *OscillatorDriftStatusLED, - *CountSensorFalseStateStatusLED, *AngleCrossCheckStatusLED, - *TurnCountSensorLevelsStatusLED, *MTDIAGStatusLED, - *TurnCounterCrossCheckStatusLED, *RadiusCheckStatusLED, - *SequencerWatchdogStatusLED; - - QScrollArea *MTDiagnosticsScrollArea; - - PlotWidget *acquisitionGraphPlotWidget, *angleErrorPlotWidget, - *calibrationRawDataPlotWidget, *FFTAngleErrorPlotWidget, - *correctedErrorPlotWidget, *postCalibrationRawDataPlotWidget, - *FFTCorrectedErrorPlotWidget; - PlotAxis *acquisitionXPlotAxis, *acquisitionYPlotAxis, - *calibrationRawDataXPlotAxis, *calibrationRawDataYPlotAxis, - *angleErrorXPlotAxis, *angleErrorYPlotAxis, *FFTAngleErrorXPlotAxis, - *FFTAngleErrorYPlotAxis, *correctedErrorXPlotAxis, - *correctedErrorYPlotAxis, *FFTCorrectedErrorXPlotAxis, - *FFTCorrectedErrorYPlotAxis, *postCalibrationRawDataXPlotAxis, - *postCalibrationRawDataYPlotAxis; - PlotChannel *acquisitionAnglePlotChannel, *acquisitionABSAnglePlotChannel, - *acquisitionTurnCountPlotChannel, *acquisitionTmp0PlotChannel, - *acquisitionTmp1PlotChannel, *acquisitionSinePlotChannel, - *acquisitionCosinePlotChannel, *acquisitionRadiusPlotChannel, - *acquisitionSecAnglQPlotChannel, *acquisitionSecAnglIPlotChannel, - *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, - *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, - *calibrationCosineDataPlotChannel, *FFTAngleErrorMagnitudeChannel, - *FFTAngleErrorPhaseChannel, *correctedErrorPlotChannel, - *postCalibrationRawDataPlotChannel, *postCalibrationSineDataPlotChannel, - *postCalibrationCosineDataPlotChannel, *FFTCorrectedErrorMagnitudeChannel, - *FFTCorrectedErrorPhaseChannel; - - HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, - *motorMaxDisplacementSpinBox, *motorTargetPositionSpinBox; - - CustomSwitch *acquisitionMotorDirectionSwitch, - *calibrationMotorDirectionSwitch, *calibrationDisplayFormatSwitch, - *DIGIO0ENToggleSwitch, *DIGIO0FNCToggleSwitch, *DIGIO1ENToggleSwitch, - *DIGIO1FNCToggleSwitch, *DIGIO2ENToggleSwitch, *DIGIO2FNCToggleSwitch, - *DIGIO3ENToggleSwitch, *DIGIO3FNCToggleSwitch, *DIGIO4ENToggleSwitch, - *DIGIO4FNCToggleSwitch, *DIGIO5ENToggleSwitch, *DIGIO5FNCToggleSwitch, - *DIGIOALLToggleSwitch; - - RegisterBlockWidget *cnvPageRegisterBlock, *digIORegisterBlock, - *faultRegisterBlock, *generalRegisterBlock, *digIOEnRegisterBlock, - *angleCkRegisterBlock, *eccDcdeRegisterBlock, *eccDisRegisterBlock, - *absAngleRegisterBlock, *angleRegisterBlock, *angleSecRegisterBlock, - *sineRegisterBlock, *cosineRegisterBlock, *secAnglIRegisterBlock, - *secAnglQRegisterBlock, *radiusRegisterBlock, *diag1RegisterBlock, - *diag2RegisterBlock, *tmp0RegisterBlock, *tmp1RegisterBlock, - *cnvCntRegisterBlock, *uniqID0RegisterBlock, *uniqID1RegisterBlock, - *uniqID2RegisterBlock, *uniqID3RegisterBlock, *h1MagRegisterBlock, - *h1PhRegisterBlock, *h2MagRegisterBlock, *h2PhRegisterBlock, - *h3MagRegisterBlock, *h3PhRegisterBlock, *h8MagRegisterBlock, - *h8PhRegisterBlock; - - QFuture m_deviceStatusThread, m_currentMotorPositionThread, - m_acquisitionUIThread, m_acquisitionDataThread, m_acquisitionGraphThread, - m_calibrationUIThread, m_calibrationStreamThread, - m_calibrationWaitVelocityThread, m_calibrationContinuousThread, - m_resetMotorToZeroThread, m_utilityUIThread, m_utilityThread; - QFutureWatcher m_deviceStatusWatcher, m_currentMotorPositionWatcher, - m_acquisitionUIWatcher, m_acquisitionDataWatcher, - m_acquisitionGraphWatcher, m_calibrationUIWatcher, - m_calibrationStreamWatcher, m_calibrationWaitVelocityWatcher, - m_calibrationContinuousWatcher, m_resetMotorToZeroWatcher, - m_utilityUIWatcher, m_utilityWatcher; - - ToolTemplate *createAcquisitionWidget(); - ToolTemplate *createCalibrationWidget(); - ToolTemplate *createRegistersWidget(); - ToolTemplate *createUtilityWidget(); - - void readDeviceProperties(); - void initializeADMT(); - bool readSequence(); - bool writeSequence(const map &settings); - void applySequence(); - bool changeCNVPage(uint32_t page); - void initializeMotor(); - void startDeviceStatusMonitor(); - void stopDeviceStatusMonitor(); - void getDeviceFaultStatus(int sampleRate); - void startCurrentMotorPositionMonitor(); - void stopCurrentMotorPositionMonitor(); - void currentMotorPositionTask(int sampleRate); - bool resetGENERAL(); + ADMTController *m_admtController; + iio_context *m_ctx; + bool m_running, isDebug; + ToolTemplate *tool; + GearBtn *settingsButton; + InfoBtn *infoButton; + RunBtn *runButton; + + const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; + + double rotation, angle, count, temp = 0.0, motor_rpm, amax, rotate_vmax, dmax, disable, target_pos, current_pos, + ramp_mode, afeDiag0, afeDiag1, afeDiag2; + + QPushButton *openLastMenuButton, *calibrationStartMotorButton, *calibrateDataButton, *extractDataButton, + *clearCalibrateDataButton, *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; + QButtonGroup *rightMenuButtonGroup; + + QLineEdit *acquisitionMotorRPMLineEdit, *calibrationMotorRPMLineEdit, *motorTargetPositionLineEdit, + *graphUpdateIntervalLineEdit, *displayLengthLineEdit, *dataGraphSamplesLineEdit, + *tempGraphSamplesLineEdit, *acquisitionMotorCurrentPositionLineEdit, *calibrationH1MagLineEdit, + *calibrationH2MagLineEdit, *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, + *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, *calibrationH3PhaseLineEdit, + *calibrationH8PhaseLineEdit, *calibrationMotorCurrentPositionLineEdit, *AFEDIAG0LineEdit, + *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; + + QLabel *rawAngleValueLabel, *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, + *motorAmaxValueLabel, *motorRotateVmaxValueLabel, *motorDmaxValueLabel, *motorDisableValueLabel, + *motorTargetPosValueLabel, *motorCurrentPosValueLabel, *motorRampModeValueLabel, *calibrationH1MagLabel, + *calibrationH1PhaseLabel, *calibrationH2MagLabel, *calibrationH2PhaseLabel, *calibrationH3MagLabel, + *calibrationH3PhaseLabel, *calibrationH8MagLabel, *calibrationH8PhaseLabel; + + MenuHeaderWidget *header; + + MenuSectionWidget *rightMenuSectionWidget; + MenuCollapseSection *rotationCollapse, *angleCollapse, *countCollapse, *tempCollapse; + MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo, + *m_calibrationMotorRampModeMenuCombo, *sequenceTypeMenuCombo, *conversionTypeMenuCombo, + *cnvSourceMenuCombo, *convertSynchronizationMenuCombo, *angleFilterMenuCombo, *eighthHarmonicMenuCombo, + *calibrationModeMenuCombo; + + QTabWidget *tabWidget, *calibrationDataGraphTabWidget, *resultDataTabWidget; + + QListWidget *rawDataListWidget; + + QPlainTextEdit *logsPlainTextEdit, *commandLogPlainTextEdit; + + QCheckBox *acquisitionFaultRegisterLEDWidget, *calibrationFaultRegisterLEDWidget, *DIGIOBusyStatusLED, + *DIGIOCNVStatusLED, *DIGIOSENTStatusLED, *DIGIOACALCStatusLED, *DIGIOFaultStatusLED, + *DIGIOBootloaderStatusLED, *R0StatusLED, *R1StatusLED, *R2StatusLED, *R3StatusLED, *R4StatusLED, + *R5StatusLED, *R6StatusLED, *R7StatusLED, *VDDUnderVoltageStatusLED, *VDDOverVoltageStatusLED, + *VDRIVEUnderVoltageStatusLED, *VDRIVEOverVoltageStatusLED, *AFEDIAGStatusLED, *NVMCRCFaultStatusLED, + *ECCDoubleBitErrorStatusLED, *OscillatorDriftStatusLED, *CountSensorFalseStateStatusLED, + *AngleCrossCheckStatusLED, *TurnCountSensorLevelsStatusLED, *MTDIAGStatusLED, + *TurnCounterCrossCheckStatusLED, *RadiusCheckStatusLED, *SequencerWatchdogStatusLED; + + QScrollArea *MTDiagnosticsScrollArea; + + PlotWidget *acquisitionGraphPlotWidget, *angleErrorPlotWidget, *calibrationRawDataPlotWidget, + *FFTAngleErrorPlotWidget, *correctedErrorPlotWidget, *postCalibrationRawDataPlotWidget, + *FFTCorrectedErrorPlotWidget; + PlotAxis *acquisitionXPlotAxis, *acquisitionYPlotAxis, *calibrationRawDataXPlotAxis, + *calibrationRawDataYPlotAxis, *angleErrorXPlotAxis, *angleErrorYPlotAxis, *FFTAngleErrorXPlotAxis, + *FFTAngleErrorYPlotAxis, *correctedErrorXPlotAxis, *correctedErrorYPlotAxis, + *FFTCorrectedErrorXPlotAxis, *FFTCorrectedErrorYPlotAxis, *postCalibrationRawDataXPlotAxis, + *postCalibrationRawDataYPlotAxis; + PlotChannel *acquisitionAnglePlotChannel, *acquisitionABSAnglePlotChannel, *acquisitionTurnCountPlotChannel, + *acquisitionTmp0PlotChannel, *acquisitionTmp1PlotChannel, *acquisitionSinePlotChannel, + *acquisitionCosinePlotChannel, *acquisitionRadiusPlotChannel, *acquisitionSecAnglQPlotChannel, + *acquisitionSecAnglIPlotChannel, *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, + *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel, + *FFTAngleErrorMagnitudeChannel, *FFTAngleErrorPhaseChannel, *correctedErrorPlotChannel, + *postCalibrationRawDataPlotChannel, *postCalibrationSineDataPlotChannel, + *postCalibrationCosineDataPlotChannel, *FFTCorrectedErrorMagnitudeChannel, + *FFTCorrectedErrorPhaseChannel; + + HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, *motorMaxDisplacementSpinBox, + *motorTargetPositionSpinBox; + + CustomSwitch *acquisitionMotorDirectionSwitch, *calibrationMotorDirectionSwitch, + *calibrationDisplayFormatSwitch, *DIGIO0ENToggleSwitch, *DIGIO0FNCToggleSwitch, *DIGIO1ENToggleSwitch, + *DIGIO1FNCToggleSwitch, *DIGIO2ENToggleSwitch, *DIGIO2FNCToggleSwitch, *DIGIO3ENToggleSwitch, + *DIGIO3FNCToggleSwitch, *DIGIO4ENToggleSwitch, *DIGIO4FNCToggleSwitch, *DIGIO5ENToggleSwitch, + *DIGIO5FNCToggleSwitch, *DIGIOALLToggleSwitch; + + RegisterBlockWidget *cnvPageRegisterBlock, *digIORegisterBlock, *faultRegisterBlock, *generalRegisterBlock, + *digIOEnRegisterBlock, *angleCkRegisterBlock, *eccDcdeRegisterBlock, *eccDisRegisterBlock, + *absAngleRegisterBlock, *angleRegisterBlock, *angleSecRegisterBlock, *sineRegisterBlock, + *cosineRegisterBlock, *secAnglIRegisterBlock, *secAnglQRegisterBlock, *radiusRegisterBlock, + *diag1RegisterBlock, *diag2RegisterBlock, *tmp0RegisterBlock, *tmp1RegisterBlock, *cnvCntRegisterBlock, + *uniqID0RegisterBlock, *uniqID1RegisterBlock, *uniqID2RegisterBlock, *uniqID3RegisterBlock, + *h1MagRegisterBlock, *h1PhRegisterBlock, *h2MagRegisterBlock, *h2PhRegisterBlock, *h3MagRegisterBlock, + *h3PhRegisterBlock, *h8MagRegisterBlock, *h8PhRegisterBlock; + + QFuture m_deviceStatusThread, m_currentMotorPositionThread, m_acquisitionUIThread, + m_acquisitionDataThread, m_acquisitionGraphThread, m_calibrationUIThread, m_calibrationStreamThread, + m_calibrationWaitVelocityThread, m_calibrationContinuousThread, m_resetMotorToZeroThread, + m_utilityUIThread, m_utilityThread; + QFutureWatcher m_deviceStatusWatcher, m_currentMotorPositionWatcher, m_acquisitionUIWatcher, + m_acquisitionDataWatcher, m_acquisitionGraphWatcher, m_calibrationUIWatcher, m_calibrationStreamWatcher, + m_calibrationWaitVelocityWatcher, m_calibrationContinuousWatcher, m_resetMotorToZeroWatcher, + m_utilityUIWatcher, m_utilityWatcher; + + ToolTemplate *createAcquisitionWidget(); + ToolTemplate *createCalibrationWidget(); + ToolTemplate *createRegistersWidget(); + ToolTemplate *createUtilityWidget(); + + void readDeviceProperties(); + void initializeADMT(); + bool readSequence(); + bool writeSequence(const map &settings); + void applySequence(); + bool changeCNVPage(uint32_t page); + void initializeMotor(); + void startDeviceStatusMonitor(); + void stopDeviceStatusMonitor(); + void getDeviceFaultStatus(int sampleRate); + void startCurrentMotorPositionMonitor(); + void stopCurrentMotorPositionMonitor(); + void currentMotorPositionTask(int sampleRate); + bool resetGENERAL(); #pragma region Acquisition Methods - bool updateChannelValues(); - void updateCountValue(); - void updateLineEditValues(); - void startAcquisition(); - void stopAcquisition(); - void updateAcquisitionMotorRPM(); - void updateAcquisitionMotorRotationDirection(); - void getAcquisitionSamples(int sampleRate); - double getAcquisitionParameterValue(const AcquisitionDataKey &key); - void plotAcquisition(QVector &list, PlotChannel *channel); - void prependAcquisitionData(const double &data, QVector &list); - void resetAcquisitionYAxisScale(); - void acquisitionPlotTask(int sampleRate); - void acquisitionUITask(int sampleRate); - void startAcquisitionUITask(); - void stopAcquisitionUITask(); - void updateSequenceWidget(); - void applySequenceAndUpdate(); - void updateGeneralSettingEnabled(bool value); - void connectCheckBoxToAcquisitionGraph(QCheckBox *widget, - PlotChannel *channel, - AcquisitionDataKey key); - void GMRReset(); + bool updateChannelValues(); + void updateCountValue(); + void updateLineEditValues(); + void startAcquisition(); + void stopAcquisition(); + void updateAcquisitionMotorRPM(); + void updateAcquisitionMotorRotationDirection(); + void getAcquisitionSamples(int sampleRate); + double getAcquisitionParameterValue(const AcquisitionDataKey &key); + void plotAcquisition(QVector &list, PlotChannel *channel); + void prependAcquisitionData(const double &data, QVector &list); + void resetAcquisitionYAxisScale(); + void acquisitionPlotTask(int sampleRate); + void acquisitionUITask(int sampleRate); + void startAcquisitionUITask(); + void stopAcquisitionUITask(); + void updateSequenceWidget(); + void applySequenceAndUpdate(); + void updateGeneralSettingEnabled(bool value); + void connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, AcquisitionDataKey key); + void GMRReset(); #pragma endregion #pragma region Calibration Methods - void startCalibrationUITask(); - void stopCalibrationUITask(); - void calibrationUITask(int sampleRate); - void updateCalibrationMotorRPM(); - void updateCalibrationMotorRotationDirection(); - void getCalibrationSamples(); - void startCalibration(); - void stopCalibration(); - void startContinuousCalibration(); - void stopContinuousCalibration(); - void startCalibrationStreamThread(); - void stopCalibrationStreamThread(); - void startWaitForVelocityReachedThread(int mode); - void stopWaitForVelocityReachedThread(); - void waitForVelocityReached(int mode, int sampleRate); - int calculateContinuousCalibrationSampleRate(double motorRPS, - int samplesPerCycle); - void configureConversionType(int mode); - void configureCalibrationSequenceSettings(); - void getStreamedCalibrationSamples(int microSampleRate); - void startOneShotCalibration(); - void postCalibrateData(); - void resetAllCalibrationState(); - void computeSineCosineOfAngles(QVector graphDataList); - void populateAngleErrorGraphs(); - void populateCorrectedAngleErrorGraphs(); - void clearHarmonicRegisters(); - void flashHarmonicValues(); - void calculateHarmonicValues(); - void updateCalculatedCoeffAngle(); - void updateCalculatedCoeffHex(); - void resetCalculatedCoeffAngle(); - void resetCalculatedCoeffHex(); - void displayCalculatedCoeff(); - void importCalibrationData(); - void extractCalibrationData(); - void toggleTabSwitching(bool value); - void toggleCalibrationButtonState(int state); - void canStartMotor(bool value); - void canCalibrate(bool); - void toggleCalibrationControls(bool value); - void clearCalibrationSamples(); - void clearCalibrationSineCosine(); - void clearPostCalibrationSamples(); - void clearAngleErrorGraphs(); - void clearCorrectedAngleErrorGraphs(); + void startCalibrationUITask(); + void stopCalibrationUITask(); + void calibrationUITask(int sampleRate); + void updateCalibrationMotorRPM(); + void updateCalibrationMotorRotationDirection(); + void getCalibrationSamples(); + void startCalibration(); + void stopCalibration(); + void startContinuousCalibration(); + void stopContinuousCalibration(); + void startCalibrationStreamThread(); + void stopCalibrationStreamThread(); + void startWaitForVelocityReachedThread(int mode); + void stopWaitForVelocityReachedThread(); + void waitForVelocityReached(int mode, int sampleRate); + int calculateContinuousCalibrationSampleRate(double motorRPS, int samplesPerCycle); + void configureConversionType(int mode); + void configureCalibrationSequenceSettings(); + void getStreamedCalibrationSamples(int microSampleRate); + void startOneShotCalibration(); + void postCalibrateData(); + void resetAllCalibrationState(); + void computeSineCosineOfAngles(QVector graphDataList); + void populateAngleErrorGraphs(); + void populateCorrectedAngleErrorGraphs(); + void clearHarmonicRegisters(); + void flashHarmonicValues(); + void calculateHarmonicValues(); + void updateCalculatedCoeffAngle(); + void updateCalculatedCoeffHex(); + void resetCalculatedCoeffAngle(); + void resetCalculatedCoeffHex(); + void displayCalculatedCoeff(); + void importCalibrationData(); + void extractCalibrationData(); + void toggleTabSwitching(bool value); + void toggleCalibrationButtonState(int state); + void canStartMotor(bool value); + void canCalibrate(bool); + void toggleCalibrationControls(bool value); + void clearCalibrationSamples(); + void clearCalibrationSineCosine(); + void clearPostCalibrationSamples(); + void clearAngleErrorGraphs(); + void clearCorrectedAngleErrorGraphs(); #pragma endregion #pragma region Motor Methods - bool moveMotorToPosition(double &position, bool validate = true); - void moveMotorContinuous(); - bool resetCurrentPositionToZero(); - void stopMotor(); - int readMotorAttributeValue(ADMTController::MotorAttribute attribute, - double &value); - int writeMotorAttributeValue(ADMTController::MotorAttribute attribute, - double value); - int readMotorRegisterValue(uint32_t address, uint32_t *value); - void setRampMode(bool motorRotationClockwise); - void getRampMode(); - void startResetMotorToZero(); - void stopResetMotorToZero(); - void resetMotorToZero(); + bool moveMotorToPosition(double &position, bool validate = true); + void moveMotorContinuous(); + bool resetCurrentPositionToZero(); + void stopMotor(); + int readMotorAttributeValue(ADMTController::MotorAttribute attribute, double &value); + int writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value); + int readMotorRegisterValue(uint32_t address, uint32_t *value); + void setRampMode(bool motorRotationClockwise); + void getRampMode(); + void startResetMotorToZero(); + void stopResetMotorToZero(); + void resetMotorToZero(); #pragma endregion #pragma region Utility Methods - void startUtilityTask(); - void stopUtilityTask(); - void utilityTask(int sampleRate); - void toggleUtilityTask(bool run); - void getDIGIOENRegister(); - void updateDIGIOMonitorUI(); - void updateDIGIOControlUI(); - void getDIAG2Register(); - void getDIAG1Register(); - void getFAULTRegister(); - void toggleDIGIOEN(string DIGIOENName, bool value); - void toggleMTDiagnostics(int mode); - void toggleFaultRegisterMode(int mode); - bool resetDIGIO(); - void clearCommandLog(); + void startUtilityTask(); + void stopUtilityTask(); + void utilityTask(int sampleRate); + void toggleUtilityTask(bool run); + void getDIGIOENRegister(); + void updateDIGIOMonitorUI(); + void updateDIGIOControlUI(); + void getDIAG2Register(); + void getDIAG1Register(); + void getFAULTRegister(); + void toggleDIGIOEN(string DIGIOENName, bool value); + void toggleMTDiagnostics(int mode); + void toggleFaultRegisterMode(int mode); + bool resetDIGIO(); + void clearCommandLog(); #pragma endregion #pragma region Register Methods - void readAllRegisters(); - void toggleRegisters(int mode); + void readAllRegisters(); + void toggleRegisters(int mode); #pragma endregion #pragma region UI Helper Methods - void updateLabelValue(QLabel *label, int channelIndex); - void updateLabelValue(QLabel *label, - ADMTController::MotorAttribute attribute); - bool updateChannelValue(int channelIndex); - void updateLineEditValue(QLineEdit *lineEdit, double value); - void toggleWidget(QPushButton *widget, bool value); - void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, - QString offLabel); - QCheckBox *createStatusLEDWidget(const QString &text, QVariant variant = true, - bool checked = false, - QWidget *parent = nullptr); - MenuControlButton *createChannelToggleWidget(const QString title, - QColor color, - QWidget *parent = nullptr); + void updateLabelValue(QLabel *label, int channelIndex); + void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); + bool updateChannelValue(int channelIndex); + void updateLineEditValue(QLineEdit *lineEdit, double value); + void toggleWidget(QPushButton *widget, bool value); + void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel); + QCheckBox *createStatusLEDWidget(const QString &text, QVariant variant = true, bool checked = false, + QWidget *parent = nullptr); + MenuControlButton *createChannelToggleWidget(const QString title, QColor color, QWidget *parent = nullptr); #pragma endregion #pragma region Connect Methods - void connectLineEditToNumber(QLineEdit *lineEdit, int &variable, int min, - int max); - void connectLineEditToNumber(QLineEdit *lineEdit, double &variable, - QString unit = ""); - void connectLineEditToDouble(QLineEdit *lineEdit, double &variable); - void connectLineEditToNumberWrite(QLineEdit *lineEdit, double &variable, - ADMTController::MotorAttribute attribute); - void connectMenuComboToNumber(MenuCombo *menuCombo, double &variable); - void connectMenuComboToNumber(MenuCombo *menuCombo, int &variable); - void connectLineEditToRPSConversion(QLineEdit *lineEdit, double &vmax); - void connectLineEditToAMAXConversion(QLineEdit *lineEdit, double &amax); - void connectRegisterBlockToRegistry(RegisterBlockWidget *widget); - void connectLineEditToRPM(QLineEdit *lineEdit, double &variable); + void connectLineEditToNumber(QLineEdit *lineEdit, int &variable, int min, int max); + void connectLineEditToNumber(QLineEdit *lineEdit, double &variable, QString unit = ""); + void connectLineEditToDouble(QLineEdit *lineEdit, double &variable); + void connectLineEditToNumberWrite(QLineEdit *lineEdit, double &variable, + ADMTController::MotorAttribute attribute); + void connectMenuComboToNumber(MenuCombo *menuCombo, double &variable); + void connectMenuComboToNumber(MenuCombo *menuCombo, int &variable); + void connectLineEditToRPSConversion(QLineEdit *lineEdit, double &vmax); + void connectLineEditToAMAXConversion(QLineEdit *lineEdit, double &amax); + void connectRegisterBlockToRegistry(RegisterBlockWidget *widget); + void connectLineEditToRPM(QLineEdit *lineEdit, double &variable); #pragma endregion #pragma region Convert Methods - double convertRPStoVMAX(double rps); - double convertVMAXtoRPS(double vmax); - double convertAccelTimetoAMAX(double accelTime); - double convertAMAXtoAccelTime(double amax); - double convertRPMtoRPS(double rpm); - double convertRPStoRPM(double rps); + double convertRPStoVMAX(double rps); + double convertVMAXtoRPS(double vmax); + double convertAccelTimetoAMAX(double accelTime); + double convertAMAXtoAccelTime(double amax); + double convertRPMtoRPS(double rpm); + double convertRPStoRPM(double rps); #pragma endregion #pragma region Debug Methods - QString readRegmapDumpAttributeValue(); + QString readRegmapDumpAttributeValue(); #pragma endregion }; } // namespace admt diff --git a/plugins/admt/include/admt/widgets/horizontalspinbox.h b/plugins/admt/include/admt/widgets/horizontalspinbox.h index 2d148996e4..c97f30cf73 100644 --- a/plugins/admt/include/admt/widgets/horizontalspinbox.h +++ b/plugins/admt/include/admt/widgets/horizontalspinbox.h @@ -33,32 +33,30 @@ #include namespace scopy::admt { -class SCOPY_ADMT_EXPORT HorizontalSpinBox : public QWidget { - Q_OBJECT +class SCOPY_ADMT_EXPORT HorizontalSpinBox : public QWidget +{ + Q_OBJECT public: - HorizontalSpinBox(QString header = "", double initialValue = 0.0, - QString unit = "", QWidget *parent = nullptr); - QLineEdit *lineEdit(); - void setEnabled(double value); + HorizontalSpinBox(QString header = "", double initialValue = 0.0, QString unit = "", QWidget *parent = nullptr); + QLineEdit *lineEdit(); + void setEnabled(double value); public Q_SLOTS: - void setValue(double); + void setValue(double); protected Q_SLOTS: - void onMinusButtonPressed(); - void onPlusButtonPressed(); - void onLineEditTextEdited(); + void onMinusButtonPressed(); + void onPlusButtonPressed(); + void onLineEditTextEdited(); private: - double m_value = 0; - QString m_unit = ""; - QLineEdit *m_lineEdit; - QPushButton *m_minusButton, *m_plusButton; - QLabel *m_unitLabel; - void applyLineEditStyle(QLineEdit *widget); - void applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius = 0, - int topRightBorderRadius = 0, - int bottomLeftBorderRadius = 0, - int bottomRightBorderRadius = 0); - void applyUnitLabelStyle(QLabel *widget, bool isEnabled = true); + double m_value = 0; + QString m_unit = ""; + QLineEdit *m_lineEdit; + QPushButton *m_minusButton, *m_plusButton; + QLabel *m_unitLabel; + void applyLineEditStyle(QLineEdit *widget); + void applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius = 0, int topRightBorderRadius = 0, + int bottomLeftBorderRadius = 0, int bottomRightBorderRadius = 0); + void applyUnitLabelStyle(QLabel *widget, bool isEnabled = true); }; } // namespace scopy::admt diff --git a/plugins/admt/include/admt/widgets/registerblockwidget.h b/plugins/admt/include/admt/widgets/registerblockwidget.h index bcfd5d9c7d..27db3aa2b3 100644 --- a/plugins/admt/include/admt/widgets/registerblockwidget.h +++ b/plugins/admt/include/admt/widgets/registerblockwidget.h @@ -34,46 +34,51 @@ #include namespace scopy::admt { -class SCOPY_ADMT_EXPORT RegisterBlockWidget : public QWidget { - Q_OBJECT +class SCOPY_ADMT_EXPORT RegisterBlockWidget : public QWidget +{ + Q_OBJECT public: - enum ACCESS_PERMISSION { READ, WRITE, READWRITE }; + enum ACCESS_PERMISSION + { + READ, + WRITE, + READWRITE + }; - QPushButton *m_readButton, *m_writeButton; + QPushButton *m_readButton, *m_writeButton; - RegisterBlockWidget(QString header, QString description, uint32_t address, - uint32_t cnvPage, - RegisterBlockWidget::ACCESS_PERMISSION accessPermission, - QWidget *parent = nullptr); - virtual ~RegisterBlockWidget(); - QPushButton *readButton(); - QPushButton *writeButton(); - uint32_t getAddress(); - uint32_t getCnvPage(); - uint32_t getValue(); - void setValue(uint32_t value); - RegisterBlockWidget::ACCESS_PERMISSION getAccessPermission(); + RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t cnvPage, + RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent = nullptr); + virtual ~RegisterBlockWidget(); + QPushButton *readButton(); + QPushButton *writeButton(); + uint32_t getAddress(); + uint32_t getCnvPage(); + uint32_t getValue(); + void setValue(uint32_t value); + RegisterBlockWidget::ACCESS_PERMISSION getAccessPermission(); public Q_SLOTS: - void onValueChanged(int); + void onValueChanged(int); private: - uint32_t m_address, m_value, m_cnvPage; - RegisterBlockWidget::ACCESS_PERMISSION m_accessPermission; + uint32_t m_address, m_value, m_cnvPage; + RegisterBlockWidget::ACCESS_PERMISSION m_accessPermission; - QSpinBox *m_spinBox; + QSpinBox *m_spinBox; - void addReadButton(QWidget *parent); - void addWriteButton(QWidget *parent); + void addReadButton(QWidget *parent); + void addWriteButton(QWidget *parent); }; -class SCOPY_ADMT_EXPORT PaddedSpinBox : public QSpinBox { - Q_OBJECT +class SCOPY_ADMT_EXPORT PaddedSpinBox : public QSpinBox +{ + Q_OBJECT public: - PaddedSpinBox(QWidget *parent = nullptr); - virtual ~PaddedSpinBox(); + PaddedSpinBox(QWidget *parent = nullptr); + virtual ~PaddedSpinBox(); protected: - QString textFromValue(int value) const override; + QString textFromValue(int value) const override; }; } // namespace scopy::admt diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 68abd1341d..dd8a50f955 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -46,277 +46,273 @@ using namespace scopy::admt; using namespace std; ADMTController::ADMTController(QString uri, QObject *parent) - : QObject(parent), uri(uri) { - connect(this, &ADMTController::streamData, this, - &ADMTController::handleStreamData); - connect(this, &ADMTController::streamBufferedData, this, - &ADMTController::handleStreamBufferedData); - connect(this, &ADMTController::streamBufferedDataInterval, this, - &ADMTController::handleStreamBufferedDataInterval); + : QObject(parent) + , uri(uri) +{ + connect(this, &ADMTController::streamData, this, &ADMTController::handleStreamData); + connect(this, &ADMTController::streamBufferedData, this, &ADMTController::handleStreamBufferedData); + connect(this, &ADMTController::streamBufferedDataInterval, this, + &ADMTController::handleStreamBufferedDataInterval); } ADMTController::~ADMTController() {} -void ADMTController::connectADMT() { - m_conn = ConnectionProvider::open(uri); - m_iioCtx = m_conn->context(); +void ADMTController::connectADMT() +{ + m_conn = ConnectionProvider::open(uri); + m_iioCtx = m_conn->context(); } -void ADMTController::disconnectADMT() { - if (!m_conn || !m_iioCtx) { - return; - } +void ADMTController::disconnectADMT() +{ + if(!m_conn || !m_iioCtx) { + return; + } - ConnectionProvider::close(uri); - m_conn = nullptr; - m_iioCtx = nullptr; + ConnectionProvider::close(uri); + m_conn = nullptr; + m_iioCtx = nullptr; } -const char *ADMTController::getChannelId(Channel channel) { - if (channel >= 0 && channel < CHANNEL_COUNT) { - return ChannelIds[channel]; - } - return "Unknown"; +const char *ADMTController::getChannelId(Channel channel) +{ + if(channel >= 0 && channel < CHANNEL_COUNT) { + return ChannelIds[channel]; + } + return "Unknown"; } -const char *ADMTController::getDeviceId(Device device) { - if (device >= 0 && device < DEVICE_COUNT) { - return DeviceIds[device]; - } - return "Unknown"; +const char *ADMTController::getDeviceId(Device device) +{ + if(device >= 0 && device < DEVICE_COUNT) { + return DeviceIds[device]; + } + return "Unknown"; } -const char *ADMTController::getDeviceAttribute(DeviceAttribute attribute) { - if (attribute >= 0 && attribute < DEVICE_ATTR_COUNT) { - return DeviceAttributes[attribute]; - } - return "Unknown"; +const char *ADMTController::getDeviceAttribute(DeviceAttribute attribute) +{ + if(attribute >= 0 && attribute < DEVICE_ATTR_COUNT) { + return DeviceAttributes[attribute]; + } + return "Unknown"; } -const char *ADMTController::getMotorAttribute(MotorAttribute attribute) { - if (attribute >= 0 && attribute < MOTOR_ATTR_COUNT) { - return MotorAttributes[attribute]; - } - return "Unknown"; +const char *ADMTController::getMotorAttribute(MotorAttribute attribute) +{ + if(attribute >= 0 && attribute < MOTOR_ATTR_COUNT) { + return MotorAttributes[attribute]; + } + return "Unknown"; } -const uint32_t -ADMTController::getHarmonicRegister(HarmonicRegister registerID) { - if (registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT) { - return HarmonicRegisters[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getHarmonicRegister(HarmonicRegister registerID) +{ + if(registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT) { + return HarmonicRegisters[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getHarmonicPage(HarmonicRegister registerID) { - if (registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT) { - return HarmonicPages[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getHarmonicPage(HarmonicRegister registerID) +{ + if(registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT) { + return HarmonicPages[registerID]; + } + return UINT32_MAX; } -const uint32_t -ADMTController::getConfigurationRegister(ConfigurationRegister registerID) { - if (registerID >= 0 && registerID < CONFIGURATION_REGISTER_COUNT) { - return ConfigurationRegisters[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getConfigurationRegister(ConfigurationRegister registerID) +{ + if(registerID >= 0 && registerID < CONFIGURATION_REGISTER_COUNT) { + return ConfigurationRegisters[registerID]; + } + return UINT32_MAX; } -const uint32_t -ADMTController::getConfigurationPage(ConfigurationRegister registerID) { - if (registerID >= 0 && registerID < CONFIGURATION_REGISTER_COUNT) { - return ConfigurationPages[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getConfigurationPage(ConfigurationRegister registerID) +{ + if(registerID >= 0 && registerID < CONFIGURATION_REGISTER_COUNT) { + return ConfigurationPages[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getSensorRegister(SensorRegister registerID) { - if (registerID >= 0 && registerID < SENSOR_REGISTER_COUNT) { - return SensorRegisters[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getSensorRegister(SensorRegister registerID) +{ + if(registerID >= 0 && registerID < SENSOR_REGISTER_COUNT) { + return SensorRegisters[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getSensorPage(SensorRegister registerID) { - if (registerID >= 0 && registerID < SENSOR_REGISTER_COUNT) { - return SensorPages[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getSensorPage(SensorRegister registerID) +{ + if(registerID >= 0 && registerID < SENSOR_REGISTER_COUNT) { + return SensorPages[registerID]; + } + return UINT32_MAX; } -const uint32_t -ADMTController::getUniqueIdRegister(UniqueIDRegister registerID) { - if (registerID >= 0 && registerID < UNIQID_REGISTER_COUNT) { - return UniqueIdRegisters[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getUniqueIdRegister(UniqueIDRegister registerID) +{ + if(registerID >= 0 && registerID < UNIQID_REGISTER_COUNT) { + return UniqueIdRegisters[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getUniqueIdPage(UniqueIDRegister registerID) { - if (registerID >= 0 && registerID < UNIQID_REGISTER_COUNT) { - return UniqueIdPages[registerID]; - } - return UINT32_MAX; +const uint32_t ADMTController::getUniqueIdPage(UniqueIDRegister registerID) +{ + if(registerID >= 0 && registerID < UNIQID_REGISTER_COUNT) { + return UniqueIdPages[registerID]; + } + return UINT32_MAX; } -const uint32_t ADMTController::getRampGeneratorDriverFeatureControlRegister( - RampGeneratorDriverFeatureControlRegister registerID) { - if (registerID >= 0 && - registerID < RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT) { - return RampGeneratorDriverFeatureControlRegisters[registerID]; - } - return UINT32_MAX; +const uint32_t +ADMTController::getRampGeneratorDriverFeatureControlRegister(RampGeneratorDriverFeatureControlRegister registerID) +{ + if(registerID >= 0 && registerID < RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT) { + return RampGeneratorDriverFeatureControlRegisters[registerID]; + } + return UINT32_MAX; } -int ADMTController::getChannelIndex(const char *deviceName, - const char *channelName) { - iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); - if (admtDevice == NULL) { - return -1; - } - int channelCount = iio_device_get_channels_count(admtDevice); - iio_channel *channel; - std::string message = ""; - for (int i = 0; i < channelCount; i++) { - channel = iio_device_get_channel(admtDevice, i); - const char *deviceChannel = iio_channel_get_id(channel); - - std::string strDeviceChannel = std::string(deviceChannel); - std::string strChannelName = std::string(channelName); - - if (deviceChannel != nullptr && strDeviceChannel == strChannelName) { - message = message + "[" + std::to_string(i) + "]" + - std::string(deviceChannel) + ", "; - return iio_channel_get_index(channel); - } else { - channel = NULL; - } - } - return -1; +int ADMTController::getChannelIndex(const char *deviceName, const char *channelName) +{ + iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); + if(admtDevice == NULL) { + return -1; + } + int channelCount = iio_device_get_channels_count(admtDevice); + iio_channel *channel; + std::string message = ""; + for(int i = 0; i < channelCount; i++) { + channel = iio_device_get_channel(admtDevice, i); + const char *deviceChannel = iio_channel_get_id(channel); + + std::string strDeviceChannel = std::string(deviceChannel); + std::string strChannelName = std::string(channelName); + + if(deviceChannel != nullptr && strDeviceChannel == strChannelName) { + message = message + "[" + std::to_string(i) + "]" + std::string(deviceChannel) + ", "; + return iio_channel_get_index(channel); + } else { + channel = NULL; + } + } + return -1; } -double ADMTController::getChannelValue(const char *deviceName, - const char *channelName, - int bufferSize) { - if (!m_iioCtx) { - return static_cast(UINT64_MAX); - } // return QString("No context available."); - double value; - - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if (deviceCount < 1) - return static_cast( - UINT64_MAX); // return QString("No devices found"); - - iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); - if (admtDevice == NULL) - return static_cast( - UINT64_MAX); // return QString("No ADMT4000 device"); - - int channelCount = iio_device_get_channels_count(admtDevice); - if (channelCount < 1) - return static_cast( - UINT64_MAX); // return QString("No channels found."); - - iio_channel *channel; - std::string message = ""; - for (int i = 0; i < channelCount; i++) { - channel = iio_device_get_channel(admtDevice, i); - const char *deviceChannel = iio_channel_get_id(channel); - - if (deviceChannel != nullptr && - std::string(deviceChannel) == std::string(channelName)) { - message = message + "[" + std::to_string(i) + "]" + - std::string(deviceChannel) + ", "; - break; - } else { - channel = NULL; - } - } - if (channel == NULL) - return static_cast( - UINT64_MAX); // return QString("Channel not found."); - iio_channel_enable(channel); - - double scale = 1.0; - int offsetAttrVal = 0; - const char *scaleAttrName = "scale"; - const char *offsetAttrName = "offset"; - const char *scaleAttr = iio_channel_find_attr(channel, scaleAttrName); - if (scaleAttr == NULL) - return static_cast( - UINT64_MAX); // return QString("No scale attribute"); - const char *offsetAttr = iio_channel_find_attr(channel, offsetAttrName); - if (offsetAttr == NULL) - return static_cast( - UINT64_MAX); // return QString("No offset attribute"); - - double *scaleVal = new double(1); - int scaleRet = iio_channel_attr_read_double(channel, scaleAttr, scaleVal); - if (scaleRet != 0) - return static_cast( - UINT64_MAX); // return QString("Cannot read scale attribute"); - scale = *scaleVal; - - char *offsetDst = new char[maxAttrSize]; - iio_channel_attr_read(channel, offsetAttr, offsetDst, maxAttrSize); - offsetAttrVal = std::atoi(offsetDst); - - iio_buffer *iioBuffer = - iio_device_create_buffer(admtDevice, bufferSize, false); - if (iioBuffer == NULL) - return static_cast( - UINT64_MAX); // return QString("Cannot create buffer."); - - ssize_t numBytesRead; - int8_t *pointerData, *pointerEnd; - void *buffer; - ptrdiff_t pointerIncrement; - - numBytesRead = iio_buffer_refill(iioBuffer); - if (numBytesRead < 0) - return static_cast( - UINT64_MAX); // return QString("Cannot refill buffer."); - - pointerIncrement = reinterpret_cast(iio_buffer_step(iioBuffer)); - pointerEnd = static_cast(iio_buffer_end(iioBuffer)); - - const struct iio_data_format *format = iio_channel_get_data_format(channel); - const struct iio_data_format channelFormat = *format; - unsigned int repeat = channelFormat.repeat; - uint8_t bitLength = static_cast(channelFormat.bits); - size_t offset = static_cast(channelFormat.shift); - - QString result; - std::list rawSamples; - // std::list unsignedSamples; - std::list castSamples; - - size_t sample, bytes; - - size_t sampleSize = channelFormat.length / 8 * repeat; - // if(sampleSize == 0) return QString("Sample size is zero."); - - buffer = malloc(sampleSize * bufferSize); - // if(!buffer) return QString("Cannot allocate memory for buffer."); - - bytes = iio_channel_read(channel, iioBuffer, buffer, sampleSize * bufferSize); - for (sample = 0; sample < bytes / sampleSize; ++sample) { - for (int j = 0; j < repeat; ++j) { - if (channelFormat.length / 8 == sizeof(int16_t)) { - rawSamples.push_back(*((int8_t *)buffer)); - int16_t rawValue = ((int16_t *)buffer)[sample + j]; - castSamples.push_back(rawValue); - value = (rawValue - static_cast(offsetAttrVal)) * scale; - result = QString::number(value); - } - } - } - - message = message + result.toStdString(); - iio_buffer_destroy(iioBuffer); - return value; // QString::fromStdString(message); +double ADMTController::getChannelValue(const char *deviceName, const char *channelName, int bufferSize) +{ + if(!m_iioCtx) { + return static_cast(UINT64_MAX); + } // return QString("No context available."); + double value; + + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount < 1) + return static_cast(UINT64_MAX); // return QString("No devices found"); + + iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); + if(admtDevice == NULL) + return static_cast(UINT64_MAX); // return QString("No ADMT4000 device"); + + int channelCount = iio_device_get_channels_count(admtDevice); + if(channelCount < 1) + return static_cast(UINT64_MAX); // return QString("No channels found."); + + iio_channel *channel; + std::string message = ""; + for(int i = 0; i < channelCount; i++) { + channel = iio_device_get_channel(admtDevice, i); + const char *deviceChannel = iio_channel_get_id(channel); + + if(deviceChannel != nullptr && std::string(deviceChannel) == std::string(channelName)) { + message = message + "[" + std::to_string(i) + "]" + std::string(deviceChannel) + ", "; + break; + } else { + channel = NULL; + } + } + if(channel == NULL) + return static_cast(UINT64_MAX); // return QString("Channel not found."); + iio_channel_enable(channel); + + double scale = 1.0; + int offsetAttrVal = 0; + const char *scaleAttrName = "scale"; + const char *offsetAttrName = "offset"; + const char *scaleAttr = iio_channel_find_attr(channel, scaleAttrName); + if(scaleAttr == NULL) + return static_cast(UINT64_MAX); // return QString("No scale attribute"); + const char *offsetAttr = iio_channel_find_attr(channel, offsetAttrName); + if(offsetAttr == NULL) + return static_cast(UINT64_MAX); // return QString("No offset attribute"); + + double *scaleVal = new double(1); + int scaleRet = iio_channel_attr_read_double(channel, scaleAttr, scaleVal); + if(scaleRet != 0) + return static_cast(UINT64_MAX); // return QString("Cannot read scale attribute"); + scale = *scaleVal; + + char *offsetDst = new char[maxAttrSize]; + iio_channel_attr_read(channel, offsetAttr, offsetDst, maxAttrSize); + offsetAttrVal = std::atoi(offsetDst); + + iio_buffer *iioBuffer = iio_device_create_buffer(admtDevice, bufferSize, false); + if(iioBuffer == NULL) + return static_cast(UINT64_MAX); // return QString("Cannot create buffer."); + + ssize_t numBytesRead; + int8_t *pointerData, *pointerEnd; + void *buffer; + ptrdiff_t pointerIncrement; + + numBytesRead = iio_buffer_refill(iioBuffer); + if(numBytesRead < 0) + return static_cast(UINT64_MAX); // return QString("Cannot refill buffer."); + + pointerIncrement = reinterpret_cast(iio_buffer_step(iioBuffer)); + pointerEnd = static_cast(iio_buffer_end(iioBuffer)); + + const struct iio_data_format *format = iio_channel_get_data_format(channel); + const struct iio_data_format channelFormat = *format; + unsigned int repeat = channelFormat.repeat; + uint8_t bitLength = static_cast(channelFormat.bits); + size_t offset = static_cast(channelFormat.shift); + + QString result; + std::list rawSamples; + // std::list unsignedSamples; + std::list castSamples; + + size_t sample, bytes; + + size_t sampleSize = channelFormat.length / 8 * repeat; + // if(sampleSize == 0) return QString("Sample size is zero."); + + buffer = malloc(sampleSize * bufferSize); + // if(!buffer) return QString("Cannot allocate memory for buffer."); + + bytes = iio_channel_read(channel, iioBuffer, buffer, sampleSize * bufferSize); + for(sample = 0; sample < bytes / sampleSize; ++sample) { + for(int j = 0; j < repeat; ++j) { + if(channelFormat.length / 8 == sizeof(int16_t)) { + rawSamples.push_back(*((int8_t *)buffer)); + int16_t rawValue = ((int16_t *)buffer)[sample + j]; + castSamples.push_back(rawValue); + value = (rawValue - static_cast(offsetAttrVal)) * scale; + result = QString::number(value); + } + } + } + + message = message + result.toStdString(); + iio_buffer_destroy(iioBuffer); + return value; // QString::fromStdString(message); } /** @brief Get the attribute value of a device @@ -327,54 +323,51 @@ double ADMTController::getChannelValue(const char *deviceName, * stored * @return On success, 0 is returned. * @return On error, -1 is returned. */ -int ADMTController::getDeviceAttributeValue(const char *deviceName, - const char *attributeName, - double *returnValue) { - if (!m_iioCtx) { - return -1; - } - int result = -1; - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if (deviceCount == 0) { - return result; - } - iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); - if (iioDevice == NULL) { - return result; - } - const char *hasAttr = iio_device_find_attr(iioDevice, attributeName); - if (hasAttr == NULL) { - return result; - } - result = iio_device_attr_read_double(iioDevice, attributeName, returnValue); - - return result; +int ADMTController::getDeviceAttributeValue(const char *deviceName, const char *attributeName, double *returnValue) +{ + if(!m_iioCtx) { + return -1; + } + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount == 0) { + return result; + } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) { + return result; + } + const char *hasAttr = iio_device_find_attr(iioDevice, attributeName); + if(hasAttr == NULL) { + return result; + } + result = iio_device_attr_read_double(iioDevice, attributeName, returnValue); + + return result; } -int ADMTController::getDeviceAttributeValueString(const char *deviceName, - const char *attributeName, - char *returnValue, - size_t byteLength) { - if (!m_iioCtx) { - return -1; - } - int result = -1; - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if (deviceCount == 0) { - return result; - } - iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); - if (iioDevice == NULL) { - return result; - } - const char *hasAttr = iio_device_find_attr(iioDevice, attributeName); - if (hasAttr == NULL) { - return result; - } - result = - iio_device_attr_read(iioDevice, attributeName, returnValue, byteLength); - - return result; +int ADMTController::getDeviceAttributeValueString(const char *deviceName, const char *attributeName, char *returnValue, + size_t byteLength) +{ + if(!m_iioCtx) { + return -1; + } + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount == 0) { + return result; + } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) { + return result; + } + const char *hasAttr = iio_device_find_attr(iioDevice, attributeName); + if(hasAttr == NULL) { + return result; + } + result = iio_device_attr_read(iioDevice, attributeName, returnValue, byteLength); + + return result; } /** @brief Set the attribute value of a device @@ -384,590 +377,572 @@ int ADMTController::getDeviceAttributeValueString(const char *deviceName, * @param writeValue A double variable of the value to be set * @return On success, 0 is returned. * @return On error, -1 is returned. */ -int ADMTController::setDeviceAttributeValue(const char *deviceName, - const char *attributeName, - double writeValue) { - if (!m_iioCtx) { - return -1; - } - int result = -1; - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if (deviceCount == 0) { - return result; - } - iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); - if (iioDevice == NULL) { - return result; - } - const char *hasAttr = iio_device_find_attr(iioDevice, attributeName); - if (hasAttr == NULL) { - return result; - } - result = iio_device_attr_write_double(iioDevice, attributeName, writeValue); - - return result; +int ADMTController::setDeviceAttributeValue(const char *deviceName, const char *attributeName, double writeValue) +{ + if(!m_iioCtx) { + return -1; + } + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount == 0) { + return result; + } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) { + return result; + } + const char *hasAttr = iio_device_find_attr(iioDevice, attributeName); + if(hasAttr == NULL) { + return result; + } + result = iio_device_attr_write_double(iioDevice, attributeName, writeValue); + + return result; } -int ADMTController::writeDeviceRegistry(const char *deviceName, - uint32_t address, uint32_t value) { - if (!m_iioCtx) { - return -1; - } - int result = -1; - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if (deviceCount == 0) { - return result; - } - iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); - if (iioDevice == NULL) { - return result; - } - result = iio_device_reg_write(iioDevice, address, value); - - return result; +int ADMTController::writeDeviceRegistry(const char *deviceName, uint32_t address, uint32_t value) +{ + if(!m_iioCtx) { + return -1; + } + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount == 0) { + return result; + } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) { + return result; + } + result = iio_device_reg_write(iioDevice, address, value); + + return result; } -int ADMTController::readDeviceRegistry(const char *deviceName, uint32_t address, - uint32_t *returnValue) { - if (!m_iioCtx) { - return -1; - } - if (address == UINT32_MAX) { - return -1; - } - int result = -1; - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if (deviceCount == 0) { - return result; - } - iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); - if (iioDevice == NULL) { - return result; - } - result = iio_device_reg_read(iioDevice, address, returnValue); - - return result; +int ADMTController::readDeviceRegistry(const char *deviceName, uint32_t address, uint32_t *returnValue) +{ + if(!m_iioCtx) { + return -1; + } + if(address == UINT32_MAX) { + return -1; + } + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount == 0) { + return result; + } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) { + return result; + } + result = iio_device_reg_read(iioDevice, address, returnValue); + + return result; } /* bit reversal from online example */ -unsigned int ADMTController::bitReverse(unsigned int x, int log2n) { - int n = 0; - int mask = 0x1; - for (int i = 0; i < log2n; i++) { - n <<= 1; - n |= (x & 1); - x >>= 1; - } - return n; +unsigned int ADMTController::bitReverse(unsigned int x, int log2n) +{ + int n = 0; + int mask = 0x1; + for(int i = 0; i < log2n; i++) { + n <<= 1; + n |= (x & 1); + x >>= 1; + } + return n; } template -void ADMTController::fft(Iter_T a, Iter_T b, int log2n) { - typedef typename iterator_traits::value_type complex; - const complex J(0, 1); - int n = 1 << log2n; - for (unsigned int i = 0; i < n; ++i) { - b[bitReverse(i, log2n)] = a[i]; - } - for (int s = 1; s <= log2n; ++s) { - int m = 1 << s; - int m2 = m >> 1; - complex w(1, 0); - complex wm = exp(-J * (M_PI / m2)); - for (int j = 0; j < m2; ++j) { - for (int k = j; k < n; k += m) { - complex t = w * b[k + m2]; - complex u = b[k]; - b[k] = u + t; - b[k + m2] = u - t; - } - w *= wm; - } - } +void ADMTController::fft(Iter_T a, Iter_T b, int log2n) +{ + typedef typename iterator_traits::value_type complex; + const complex J(0, 1); + int n = 1 << log2n; + for(unsigned int i = 0; i < n; ++i) { + b[bitReverse(i, log2n)] = a[i]; + } + for(int s = 1; s <= log2n; ++s) { + int m = 1 << s; + int m2 = m >> 1; + complex w(1, 0); + complex wm = exp(-J * (M_PI / m2)); + for(int j = 0; j < m2; ++j) { + for(int k = j; k < n; k += m) { + complex t = w * b[k + m2]; + complex u = b[k]; + b[k] = u + t; + b[k + m2] = u - t; + } + w *= wm; + } + } } /* For linear fitting (hard-coded based on examples and formula for polynomial * fitting) */ -int ADMTController::linear_fit(vector x, vector y, - double *slope, double *intercept) { - /* x, y, x^2, y^2, xy, xy^2 */ - double sum_x = 0, sum_y = 0, sum_x2 = 0, sum_y2 = 0, sum_xy = 0; - int i; - - if (x.size() != y.size()) - return -22; - - for (i = 0; i < x.size(); i++) { - sum_x += x[i]; - sum_y += y[i]; - sum_x2 += (x[i] * x[i]); - sum_y2 += (y[i] * y[i]); - sum_xy += (x[i] * y[i]); - } - - *slope = - (x.size() * sum_xy - sum_x * sum_y) / (x.size() * sum_x2 - sum_x * sum_x); - - *intercept = - (sum_y * sum_x2 - sum_x * sum_xy) / (x.size() * sum_x2 - sum_x * sum_x); - - return 0; +int ADMTController::linear_fit(vector x, vector y, double *slope, double *intercept) +{ + /* x, y, x^2, y^2, xy, xy^2 */ + double sum_x = 0, sum_y = 0, sum_x2 = 0, sum_y2 = 0, sum_xy = 0; + int i; + + if(x.size() != y.size()) + return -22; + + for(i = 0; i < x.size(); i++) { + sum_x += x[i]; + sum_y += y[i]; + sum_x2 += (x[i] * x[i]); + sum_y2 += (y[i] * y[i]); + sum_xy += (x[i] * y[i]); + } + + *slope = (x.size() * sum_xy - sum_x * sum_y) / (x.size() * sum_x2 - sum_x * sum_x); + + *intercept = (sum_y * sum_x2 - sum_x * sum_xy) / (x.size() * sum_x2 - sum_x * sum_x); + + return 0; } -int ADMTController::calculate_angle_error(vector angle_meas, - vector &angle_error_ret, - double *max_angle_err) { - vector angle_meas_rad(angle_meas.size()); // radian converted input - vector angle_meas_rad_unwrap( - angle_meas.size()); // unwrapped radian input - vector angle_fit( - angle_meas.size()); // array for polynomial fitted data - vector x_data(angle_meas.size()); - double coeff_a, coeff_b; // coefficients generated by polynomial fitting - - // convert to radian - for (int i = 0; i < angle_meas_rad.size(); i++) - angle_meas_rad[i] = angle_meas[i] * M_PI / 180.0; - - // unwrap angle (extracted from decompiled Angle GSF Unit) - double num = 0.0; - angle_meas_rad_unwrap[0] = angle_meas_rad[0]; - for (int i = 1; i < angle_meas_rad.size(); i++) { - double num2 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1]); - double num3 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] + - M_PI * 2.0); - double num4 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] - - M_PI * 2.0); - if (num3 < num2 && num3 < num4) - num += M_PI * 2.0; - - else if (num4 < num2 && num4 < num3) - num -= M_PI * 2.0; - - angle_meas_rad_unwrap[i] = angle_meas_rad[i] + num; - } - - // set initial point to zero - double offset = angle_meas_rad_unwrap[0]; - for (int i = 0; i < angle_meas_rad_unwrap.size(); ++i) - angle_meas_rad_unwrap[i] -= offset; - - /* Generate xdata for polynomial fitting */ - iota(x_data.begin(), x_data.end(), 1); - - // linear angle fitting (generated coefficients not same with matlab and - // python) expecting 0.26 -0.26 getting ~0.27 ~-0.27 as of 4/2/2024 - /* input args: x, y, *slope, *intercept */ - linear_fit(x_data, angle_meas_rad_unwrap, &coeff_a, &coeff_b); - - // generate data using coefficients from polynomial fitting - for (int i = 0; i < angle_fit.size(); i++) { - angle_fit[i] = coeff_a * x_data[i]; - } - - // get angle error using pass by ref angle_error_ret - for (int i = 0; i < angle_error_ret.size(); i++) { - angle_error_ret[i] = angle_meas_rad_unwrap[i] - angle_fit[i]; - // cout << "angle_err_ret " << angle_error_ret[i] << "\n"; - } - - // Find the offset for error and subtract (using angle_error_ret) - auto minmax = minmax_element(angle_error_ret.begin(), angle_error_ret.end()); - double angle_err_offset = (*minmax.first + *minmax.second) / 2; - - for (int i = 0; i < angle_error_ret.size(); i++) - angle_error_ret[i] -= angle_err_offset; - - // Convert back to degrees (angle_error_ret) - for (int i = 0; i < angle_meas.size(); i++) - angle_error_ret[i] *= (180 / M_PI); - - // Find maximum absolute angle error - *max_angle_err = *minmax.second; - - return 0; +int ADMTController::calculate_angle_error(vector angle_meas, vector &angle_error_ret, + double *max_angle_err) +{ + vector angle_meas_rad(angle_meas.size()); // radian converted input + vector angle_meas_rad_unwrap(angle_meas.size()); // unwrapped radian input + vector angle_fit(angle_meas.size()); // array for polynomial fitted data + vector x_data(angle_meas.size()); + double coeff_a, coeff_b; // coefficients generated by polynomial fitting + + // convert to radian + for(int i = 0; i < angle_meas_rad.size(); i++) + angle_meas_rad[i] = angle_meas[i] * M_PI / 180.0; + + // unwrap angle (extracted from decompiled Angle GSF Unit) + double num = 0.0; + angle_meas_rad_unwrap[0] = angle_meas_rad[0]; + for(int i = 1; i < angle_meas_rad.size(); i++) { + double num2 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1]); + double num3 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] + M_PI * 2.0); + double num4 = abs(angle_meas_rad[i] + num - angle_meas_rad_unwrap[i - 1] - M_PI * 2.0); + if(num3 < num2 && num3 < num4) + num += M_PI * 2.0; + + else if(num4 < num2 && num4 < num3) + num -= M_PI * 2.0; + + angle_meas_rad_unwrap[i] = angle_meas_rad[i] + num; + } + + // set initial point to zero + double offset = angle_meas_rad_unwrap[0]; + for(int i = 0; i < angle_meas_rad_unwrap.size(); ++i) + angle_meas_rad_unwrap[i] -= offset; + + /* Generate xdata for polynomial fitting */ + iota(x_data.begin(), x_data.end(), 1); + + // linear angle fitting (generated coefficients not same with matlab and + // python) expecting 0.26 -0.26 getting ~0.27 ~-0.27 as of 4/2/2024 + /* input args: x, y, *slope, *intercept */ + linear_fit(x_data, angle_meas_rad_unwrap, &coeff_a, &coeff_b); + + // generate data using coefficients from polynomial fitting + for(int i = 0; i < angle_fit.size(); i++) { + angle_fit[i] = coeff_a * x_data[i]; + } + + // get angle error using pass by ref angle_error_ret + for(int i = 0; i < angle_error_ret.size(); i++) { + angle_error_ret[i] = angle_meas_rad_unwrap[i] - angle_fit[i]; + // cout << "angle_err_ret " << angle_error_ret[i] << "\n"; + } + + // Find the offset for error and subtract (using angle_error_ret) + auto minmax = minmax_element(angle_error_ret.begin(), angle_error_ret.end()); + double angle_err_offset = (*minmax.first + *minmax.second) / 2; + + for(int i = 0; i < angle_error_ret.size(); i++) + angle_error_ret[i] -= angle_err_offset; + + // Convert back to degrees (angle_error_ret) + for(int i = 0; i < angle_meas.size(); i++) + angle_error_ret[i] *= (180 / M_PI); + + // Find maximum absolute angle error + *max_angle_err = *minmax.second; + + return 0; } // Function to unwrap angles that can span multiple cycles -void ADMTController::unwrapAngles(vector &angles_rad) { - for (size_t i = 1; i < angles_rad.size(); ++i) { - // Calculate the difference between the current angle and the previous one - double diff = angles_rad[i] - angles_rad[i - 1]; - - // If the difference is greater than pi, subtract 2*pi (unwrap backward) - if (diff > M_PI) { - angles_rad[i] -= 2 * M_PI; - } - // If the difference is less than -pi, add 2*pi (unwrap forward) - else if (diff < -M_PI) { - angles_rad[i] += 2 * M_PI; - } - } +void ADMTController::unwrapAngles(vector &angles_rad) +{ + for(size_t i = 1; i < angles_rad.size(); ++i) { + // Calculate the difference between the current angle and the previous one + double diff = angles_rad[i] - angles_rad[i - 1]; + + // If the difference is greater than pi, subtract 2*pi (unwrap backward) + if(diff > M_PI) { + angles_rad[i] -= 2 * M_PI; + } + // If the difference is less than -pi, add 2*pi (unwrap forward) + else if(diff < -M_PI) { + angles_rad[i] += 2 * M_PI; + } + } } -QString ADMTController::calibrate(vector PANG, int cycleCount, - int samplesPerCycle, bool CCW) { - int circshiftData = 0; - QString result = ""; - - /* Check CCW flag to know if array is to be reversed */ - if (CCW) - reverse(PANG.begin(), PANG.end()); - - /* Randomize starting point of array */ - if (circshiftData) { - int shift = rand() % PANG.size(); - rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); - } - - // Declare vectors for pre-calibration FFT results - angle_errors_fft_pre = vector(PANG.size() / 2); - angle_errors_fft_phase_pre = vector(PANG.size() / 2); - - // Call the new function for pre-calibration FFT - getPreCalibrationFFT(PANG, angle_errors_fft_pre, angle_errors_fft_phase_pre, - cycleCount, samplesPerCycle); - - // Extract HMag parameters - double H1Mag = angle_errors_fft_pre[cycleCount]; - double H2Mag = angle_errors_fft_pre[2 * cycleCount]; - double H3Mag = angle_errors_fft_pre[3 * cycleCount]; - double H8Mag = angle_errors_fft_pre[8 * cycleCount]; - - /* Display HMAG values */ - result.append("H1Mag = " + QString::number(H1Mag) + "\n"); - result.append("H2Mag = " + QString::number(H2Mag) + "\n"); - result.append("H3Mag = " + QString::number(H3Mag) + "\n"); - result.append("H8Mag = " + QString::number(H8Mag) + "\n"); - - // Extract HPhase parameters - double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycleCount]); - double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycleCount]); - double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycleCount]); - double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycleCount]); - - /* Display HPHASE values */ - result.append("H1Phase = " + QString::number(H1Phase) + "\n"); - result.append("H2Phase = " + QString::number(H2Phase) + "\n"); - result.append("H3Phase = " + QString::number(H3Phase) + "\n"); - result.append("H8Phase = " + QString::number(H8Phase) + "\n"); - - double H1 = H1Mag * cos(M_PI / 180 * (H1Phase)); - double H2 = H2Mag * cos(M_PI / 180 * (H2Phase)); - double H3 = H3Mag * cos(M_PI / 180 * (H3Phase)); - double H8 = H8Mag * cos(M_PI / 180 * (H8Phase)); - - double init_err = H1 + H2 + H3 + H8; - double init_angle = PANG[0] - init_err; - - double H1PHcor, H2PHcor, H3PHcor, H8PHcor; - - /* Counterclockwise, slope of error FIT is negative */ - if (CCW) { - H1Phase *= -1; - H2Phase *= -1; - H3Phase *= -1; - H8Phase *= -1; - } - - /* Clockwise */ - H1PHcor = H1Phase - (1 * init_angle - 90); - H2PHcor = H2Phase - (2 * init_angle - 90); - H3PHcor = H3Phase - (3 * init_angle - 90); - H8PHcor = H8Phase - (8 * init_angle - 90); - - /* Get modulo from 360 */ - H1PHcor = (int)H1PHcor % 360; - H2PHcor = (int)H2PHcor % 360; - H3PHcor = (int)H3PHcor % 360; - H8PHcor = (int)H8PHcor % 360; - - // HMag Scaling - H1Mag = H1Mag * 0.6072; - H2Mag = H2Mag * 0.6072; - H3Mag = H3Mag * 0.6072; - H8Mag = H8Mag * 0.6072; - - // Derive register compatible HMAG values - double mag_scale_factor_11bit = 11.2455 / (1 << 11); - double mag_scale_factor_8bit = 1.40076 / (1 << 8); - HAR_MAG_1 = (int)(H1Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit - HAR_MAG_2 = (int)(H2Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit - HAR_MAG_3 = (int)(H3Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit - HAR_MAG_8 = (int)(H8Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit - - // Derive register compatible HPHASE values - double pha_scale_factor_12bit = 360.0 / (1 << 12); // in Deg - HAR_PHASE_1 = - (int)(H1PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - HAR_PHASE_2 = - (int)(H2PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - HAR_PHASE_3 = - (int)(H3PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - HAR_PHASE_8 = - (int)(H8PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number - - result.append("HMAG1: " + QString::number(HAR_MAG_1) + "\n"); - result.append("HMAG2: " + QString::number(HAR_MAG_2) + "\n"); - result.append("HMAG3: " + QString::number(HAR_MAG_3) + "\n"); - result.append("HMAG8: " + QString::number(HAR_MAG_8) + "\n"); - - result.append("HPHASE1: " + QString::number(HAR_PHASE_1) + "\n"); - result.append("HPHASE2: " + QString::number(HAR_PHASE_2) + "\n"); - result.append("HPHASE3: " + QString::number(HAR_PHASE_3) + "\n"); - result.append("HPHASE8: " + QString::number(HAR_PHASE_8) + "\n"); - - return result; +QString ADMTController::calibrate(vector PANG, int cycleCount, int samplesPerCycle, bool CCW) +{ + int circshiftData = 0; + QString result = ""; + + /* Check CCW flag to know if array is to be reversed */ + if(CCW) + reverse(PANG.begin(), PANG.end()); + + /* Randomize starting point of array */ + if(circshiftData) { + int shift = rand() % PANG.size(); + rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); + } + + // Declare vectors for pre-calibration FFT results + angle_errors_fft_pre = vector(PANG.size() / 2); + angle_errors_fft_phase_pre = vector(PANG.size() / 2); + + // Call the new function for pre-calibration FFT + getPreCalibrationFFT(PANG, angle_errors_fft_pre, angle_errors_fft_phase_pre, cycleCount, samplesPerCycle); + + // Extract HMag parameters + double H1Mag = angle_errors_fft_pre[cycleCount]; + double H2Mag = angle_errors_fft_pre[2 * cycleCount]; + double H3Mag = angle_errors_fft_pre[3 * cycleCount]; + double H8Mag = angle_errors_fft_pre[8 * cycleCount]; + + /* Display HMAG values */ + result.append("H1Mag = " + QString::number(H1Mag) + "\n"); + result.append("H2Mag = " + QString::number(H2Mag) + "\n"); + result.append("H3Mag = " + QString::number(H3Mag) + "\n"); + result.append("H8Mag = " + QString::number(H8Mag) + "\n"); + + // Extract HPhase parameters + double H1Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[cycleCount]); + double H2Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[2 * cycleCount]); + double H3Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[3 * cycleCount]); + double H8Phase = (180 / M_PI) * (angle_errors_fft_phase_pre[8 * cycleCount]); + + /* Display HPHASE values */ + result.append("H1Phase = " + QString::number(H1Phase) + "\n"); + result.append("H2Phase = " + QString::number(H2Phase) + "\n"); + result.append("H3Phase = " + QString::number(H3Phase) + "\n"); + result.append("H8Phase = " + QString::number(H8Phase) + "\n"); + + double H1 = H1Mag * cos(M_PI / 180 * (H1Phase)); + double H2 = H2Mag * cos(M_PI / 180 * (H2Phase)); + double H3 = H3Mag * cos(M_PI / 180 * (H3Phase)); + double H8 = H8Mag * cos(M_PI / 180 * (H8Phase)); + + double init_err = H1 + H2 + H3 + H8; + double init_angle = PANG[0] - init_err; + + double H1PHcor, H2PHcor, H3PHcor, H8PHcor; + + /* Counterclockwise, slope of error FIT is negative */ + if(CCW) { + H1Phase *= -1; + H2Phase *= -1; + H3Phase *= -1; + H8Phase *= -1; + } + + /* Clockwise */ + H1PHcor = H1Phase - (1 * init_angle - 90); + H2PHcor = H2Phase - (2 * init_angle - 90); + H3PHcor = H3Phase - (3 * init_angle - 90); + H8PHcor = H8Phase - (8 * init_angle - 90); + + /* Get modulo from 360 */ + H1PHcor = (int)H1PHcor % 360; + H2PHcor = (int)H2PHcor % 360; + H3PHcor = (int)H3PHcor % 360; + H8PHcor = (int)H8PHcor % 360; + + // HMag Scaling + H1Mag = H1Mag * 0.6072; + H2Mag = H2Mag * 0.6072; + H3Mag = H3Mag * 0.6072; + H8Mag = H8Mag * 0.6072; + + // Derive register compatible HMAG values + double mag_scale_factor_11bit = 11.2455 / (1 << 11); + double mag_scale_factor_8bit = 1.40076 / (1 << 8); + HAR_MAG_1 = (int)(H1Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit + HAR_MAG_2 = (int)(H2Mag / mag_scale_factor_11bit) & (0x7FF); // 11 bit + HAR_MAG_3 = (int)(H3Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit + HAR_MAG_8 = (int)(H8Mag / mag_scale_factor_8bit) & (0xFF); // 8 bit + + // Derive register compatible HPHASE values + double pha_scale_factor_12bit = 360.0 / (1 << 12); // in Deg + HAR_PHASE_1 = (int)(H1PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + HAR_PHASE_2 = (int)(H2PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + HAR_PHASE_3 = (int)(H3PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + HAR_PHASE_8 = (int)(H8PHcor / pha_scale_factor_12bit) & (0xFFF); // 12bit number + + result.append("HMAG1: " + QString::number(HAR_MAG_1) + "\n"); + result.append("HMAG2: " + QString::number(HAR_MAG_2) + "\n"); + result.append("HMAG3: " + QString::number(HAR_MAG_3) + "\n"); + result.append("HMAG8: " + QString::number(HAR_MAG_8) + "\n"); + + result.append("HPHASE1: " + QString::number(HAR_PHASE_1) + "\n"); + result.append("HPHASE2: " + QString::number(HAR_PHASE_2) + "\n"); + result.append("HPHASE3: " + QString::number(HAR_PHASE_3) + "\n"); + result.append("HPHASE8: " + QString::number(HAR_PHASE_8) + "\n"); + + return result; } -void ADMTController::getPreCalibrationFFT( - const vector &PANG, vector &angle_errors_fft_pre, - vector &angle_errors_fft_phase_pre, int cycleCount, - int samplesPerCycle) { - // Calculate the angle errors before calibration - double max_err_pre = 0; - vector angle_errors_pre(PANG.size()); - - // Calculate angle errors - calculate_angle_error(PANG, angle_errors_pre, &max_err_pre); - // Store the calculated angle errors (angle_errors_pre) - angleError = angle_errors_pre; - - // Perform FFT on pre-calibration angle errors - performFFT(angle_errors_pre, angle_errors_fft_pre, angle_errors_fft_phase_pre, - cycleCount); - - // Store the FFT Angle Error Magnitude and Phase - FFTAngleErrorMagnitude = angle_errors_fft_pre; - FFTAngleErrorPhase = angle_errors_fft_phase_pre; +void ADMTController::getPreCalibrationFFT(const vector &PANG, vector &angle_errors_fft_pre, + vector &angle_errors_fft_phase_pre, int cycleCount, + int samplesPerCycle) +{ + // Calculate the angle errors before calibration + double max_err_pre = 0; + vector angle_errors_pre(PANG.size()); + + // Calculate angle errors + calculate_angle_error(PANG, angle_errors_pre, &max_err_pre); + // Store the calculated angle errors (angle_errors_pre) + angleError = angle_errors_pre; + + // Perform FFT on pre-calibration angle errors + performFFT(angle_errors_pre, angle_errors_fft_pre, angle_errors_fft_phase_pre, cycleCount); + + // Store the FFT Angle Error Magnitude and Phase + FFTAngleErrorMagnitude = angle_errors_fft_pre; + FFTAngleErrorPhase = angle_errors_fft_phase_pre; } -void ADMTController::postcalibrate(vector PANG, int cycleCount, - int samplesPerCycle, bool CCW) { - int circshiftData = 0; - QString result = ""; - - /* Check CCW flag to know if array is to be reversed */ - if (CCW) - reverse(PANG.begin(), PANG.end()); - - /* Randomize starting point of array */ - if (circshiftData) { - int shift = rand() % PANG.size(); - rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); - } - - // Declare vectors for pre-calibration FFT results - angle_errors_fft_post = vector(PANG.size() / 2); - angle_errors_fft_phase_post = vector(PANG.size() / 2); - - // Call the new function for post-calibration FFT - getPostCalibrationFFT(PANG, angle_errors_fft_post, - angle_errors_fft_phase_post, cycleCount, - samplesPerCycle); +void ADMTController::postcalibrate(vector PANG, int cycleCount, int samplesPerCycle, bool CCW) +{ + int circshiftData = 0; + QString result = ""; + + /* Check CCW flag to know if array is to be reversed */ + if(CCW) + reverse(PANG.begin(), PANG.end()); + + /* Randomize starting point of array */ + if(circshiftData) { + int shift = rand() % PANG.size(); + rotate(PANG.begin(), PANG.begin() + shift, PANG.end()); + } + + // Declare vectors for pre-calibration FFT results + angle_errors_fft_post = vector(PANG.size() / 2); + angle_errors_fft_phase_post = vector(PANG.size() / 2); + + // Call the new function for post-calibration FFT + getPostCalibrationFFT(PANG, angle_errors_fft_post, angle_errors_fft_phase_post, cycleCount, samplesPerCycle); } -void ADMTController::getPostCalibrationFFT( - const vector &updated_PANG, vector &angle_errors_fft_post, - vector &angle_errors_fft_phase_post, int cycleCount, - int samplesPerCycle) { - // Calculate the angle errors after calibration - double max_err_post = 0; - vector angle_errors_post(updated_PANG.size()); - - // Calculate angle errors - calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post); - // Corrected Error (angle_errors_post) - correctedError = angle_errors_post; - - // Perform FFT on post-calibration angle errors - performFFT(angle_errors_post, angle_errors_fft_post, - angle_errors_fft_phase_post, cycleCount); - // FFT Corrected Error (angle_errors_fft_post) - FFTCorrectedErrorMagnitude = angle_errors_fft_post; - // FFT Corrected Error Phase (angle_errors_fft_phase_post) - FFTCorrectedErrorPhase = angle_errors_fft_phase_post; +void ADMTController::getPostCalibrationFFT(const vector &updated_PANG, vector &angle_errors_fft_post, + vector &angle_errors_fft_phase_post, int cycleCount, + int samplesPerCycle) +{ + // Calculate the angle errors after calibration + double max_err_post = 0; + vector angle_errors_post(updated_PANG.size()); + + // Calculate angle errors + calculate_angle_error(updated_PANG, angle_errors_post, &max_err_post); + // Corrected Error (angle_errors_post) + correctedError = angle_errors_post; + + // Perform FFT on post-calibration angle errors + performFFT(angle_errors_post, angle_errors_fft_post, angle_errors_fft_phase_post, cycleCount); + // FFT Corrected Error (angle_errors_fft_post) + FFTCorrectedErrorMagnitude = angle_errors_fft_post; + // FFT Corrected Error Phase (angle_errors_fft_phase_post) + FFTCorrectedErrorPhase = angle_errors_fft_phase_post; } -void ADMTController::performFFT(const vector &angle_errors, - vector &angle_errors_fft, - vector &angle_errors_fft_phase, - int cycleCount) { - typedef complex cx; - - int L = angle_errors.size(); // Original signal length (L) - int N = pow( - 2, ceil(log2(L))); // Ensure size is a power of 2 (padding if necessary) - - vector fft_in(N, cx(0, 0)); // Input signal (zero-padded if necessary) - vector fft_out(N); // Output signal (complex) - - // Format angle errors into the fft_in vector - for (int i = 0; i < L; i++) { - fft_in[i] = cx(angle_errors[i], 0); - } - - // Perform FFT - fft(fft_in.data(), fft_out.data(), log2(N)); - - // Temporary vectors to store magnitude and phase - vector angle_errors_fft_temp(N); - vector angle_errors_fft_phase_temp(N); - - // Calculate magnitude and phase for all values - for (int i = 0; i < N; i++) { - // Magnitude: Normalize by L (original signal length) - angle_errors_fft_temp[i] = abs(fft_out[i]) * 2.0 / L; - angle_errors_fft_phase_temp[i] = - atan2(fft_out[i].imag(), fft_out[i].real()); - } - - // Prepare vectors for upper half of FFT (positive frequencies) - vector angle_errors_fft_upper_half(N / 2); - vector angle_errors_fft_phase_upper_half(N / 2); - - // Get upper half only (due to symmetry in real-valued signal FFT) - for (int i = 0; i < N / 2; i++) { - angle_errors_fft_upper_half[i] = angle_errors_fft_temp[i]; - angle_errors_fft_phase_upper_half[i] = angle_errors_fft_phase_temp[i]; - } - - // Resize final vectors based on cycle count (if needed) - angle_errors_fft = angle_errors_fft_upper_half; - angle_errors_fft_phase = angle_errors_fft_phase_upper_half; +void ADMTController::performFFT(const vector &angle_errors, vector &angle_errors_fft, + vector &angle_errors_fft_phase, int cycleCount) +{ + typedef complex cx; + + int L = angle_errors.size(); // Original signal length (L) + int N = pow(2, ceil(log2(L))); // Ensure size is a power of 2 (padding if necessary) + + vector fft_in(N, cx(0, 0)); // Input signal (zero-padded if necessary) + vector fft_out(N); // Output signal (complex) + + // Format angle errors into the fft_in vector + for(int i = 0; i < L; i++) { + fft_in[i] = cx(angle_errors[i], 0); + } + + // Perform FFT + fft(fft_in.data(), fft_out.data(), log2(N)); + + // Temporary vectors to store magnitude and phase + vector angle_errors_fft_temp(N); + vector angle_errors_fft_phase_temp(N); + + // Calculate magnitude and phase for all values + for(int i = 0; i < N; i++) { + // Magnitude: Normalize by L (original signal length) + angle_errors_fft_temp[i] = abs(fft_out[i]) * 2.0 / L; + angle_errors_fft_phase_temp[i] = atan2(fft_out[i].imag(), fft_out[i].real()); + } + + // Prepare vectors for upper half of FFT (positive frequencies) + vector angle_errors_fft_upper_half(N / 2); + vector angle_errors_fft_phase_upper_half(N / 2); + + // Get upper half only (due to symmetry in real-valued signal FFT) + for(int i = 0; i < N / 2; i++) { + angle_errors_fft_upper_half[i] = angle_errors_fft_temp[i]; + angle_errors_fft_phase_upper_half[i] = angle_errors_fft_phase_temp[i]; + } + + // Resize final vectors based on cycle count (if needed) + angle_errors_fft = angle_errors_fft_upper_half; + angle_errors_fft_phase = angle_errors_fft_phase_upper_half; } -void ADMTController::computeSineCosineOfAngles(const vector &angles) { - // Vectors to store sine and cosine values - calibration_samples_sine = vector(angles.size()); - calibration_samples_cosine = vector(angles.size()); - calibration_samples_sine_scaled = vector(angles.size()); - calibration_samples_cosine_scaled = vector(angles.size()); - - const double scaleMin = 0.0; - const double scaleMax = 360.0; - - // Convert angles to radians and compute sine, cosine, and their scaled - // versions - for (size_t i = 0; i < angles.size(); ++i) { - double radians = angles[i] * M_PI / 180.0; // Convert degrees to radians - calibration_samples_sine[i] = sin(radians); - calibration_samples_cosine[i] = cos(radians); - - // Scale sine and cosine to the range 0 to 360 - calibration_samples_sine_scaled[i] = - ((calibration_samples_sine[i] + 1) / 2) * (scaleMax - scaleMin) + - scaleMin; - calibration_samples_cosine_scaled[i] = - ((calibration_samples_cosine[i] + 1) / 2) * (scaleMax - scaleMin) + - scaleMin; - } +void ADMTController::computeSineCosineOfAngles(const vector &angles) +{ + // Vectors to store sine and cosine values + calibration_samples_sine = vector(angles.size()); + calibration_samples_cosine = vector(angles.size()); + calibration_samples_sine_scaled = vector(angles.size()); + calibration_samples_cosine_scaled = vector(angles.size()); + + const double scaleMin = 0.0; + const double scaleMax = 360.0; + + // Convert angles to radians and compute sine, cosine, and their scaled + // versions + for(size_t i = 0; i < angles.size(); ++i) { + double radians = angles[i] * M_PI / 180.0; // Convert degrees to radians + calibration_samples_sine[i] = sin(radians); + calibration_samples_cosine[i] = cos(radians); + + // Scale sine and cosine to the range 0 to 360 + calibration_samples_sine_scaled[i] = + ((calibration_samples_sine[i] + 1) / 2) * (scaleMax - scaleMin) + scaleMin; + calibration_samples_cosine_scaled[i] = + ((calibration_samples_cosine[i] + 1) / 2) * (scaleMax - scaleMin) + scaleMin; + } } // Function to insert the harmonic coefficient magnitude directly into the // register -uint16_t ADMTController::calculateHarmonicCoefficientMagnitude( - uint16_t harmonicCoefficient, uint16_t originalValue, const string &key) { - uint16_t result = 0; - - // Switch case for different bitmapping based on the key - if (key == "h1" || key == "h2") { - // For h1 and h2: [15:11 reserved], [10:0 write] - result = harmonicCoefficient & 0x07FF; - originalValue = (originalValue & 0xF800) | result; - } else if (key == "h3" || key == "h8") { - // For h3 and h8: [15:8 reserved], [7:0 write] - result = harmonicCoefficient & 0x00FF; - originalValue = (originalValue & 0xFF00) | result; - } else { - // Handle invalid key, return the original value unchanged - return originalValue; - } - - return originalValue; // Return the updated original value +uint16_t ADMTController::calculateHarmonicCoefficientMagnitude(uint16_t harmonicCoefficient, uint16_t originalValue, + const string &key) +{ + uint16_t result = 0; + + // Switch case for different bitmapping based on the key + if(key == "h1" || key == "h2") { + // For h1 and h2: [15:11 reserved], [10:0 write] + result = harmonicCoefficient & 0x07FF; + originalValue = (originalValue & 0xF800) | result; + } else if(key == "h3" || key == "h8") { + // For h3 and h8: [15:8 reserved], [7:0 write] + result = harmonicCoefficient & 0x00FF; + originalValue = (originalValue & 0xFF00) | result; + } else { + // Handle invalid key, return the original value unchanged + return originalValue; + } + + return originalValue; // Return the updated original value } // Function to insert the harmonic coefficient phase directly into the register -uint16_t -ADMTController::calculateHarmonicCoefficientPhase(uint16_t harmonicPhase, - uint16_t originalValue) { - uint16_t result = 0; +uint16_t ADMTController::calculateHarmonicCoefficientPhase(uint16_t harmonicPhase, uint16_t originalValue) +{ + uint16_t result = 0; - // Mask to keep only bits 11:0 (since phase is represented in 12 bits) - result = harmonicPhase & 0x0FFF; + // Mask to keep only bits 11:0 (since phase is represented in 12 bits) + result = harmonicPhase & 0x0FFF; - // Clear bits 11:0 of the original value, keeping bits 15:12 intact - uint16_t preservedValue = (originalValue & 0xF000) | result; + // Clear bits 11:0 of the original value, keeping bits 15:12 intact + uint16_t preservedValue = (originalValue & 0xF000) | result; - return preservedValue; + return preservedValue; } -double ADMTController::getActualHarmonicRegisterValue(uint16_t registerValue, - const string key) { - double result = 0.0; - const double cordicScaler = 0.6072; - - // Switch case for different bitmapping based on the key - if (key == "h1mag" || key == "h2mag") { - // For h1h2mag: value is in bits [10:0], bits [15:12] are reserved - const double LSB = 0.005493; - - // Extract the value from bits [10:0] - uint16_t extractedValue = registerValue & 0x07FF; - - // Convert the extracted value by applying CORDIC scaler and LSB - result = extractedValue * LSB / cordicScaler; - } else if (key == "h3mag" || key == "h8mag") { - // For h3h8mag: value is in bits [7:0], bits [15:8] are reserved - const double LSB = 0.005493; - - // Extract the value from bits [7:0] - uint16_t extractedValue = registerValue & 0x00FF; - - // Convert the extracted value by applying CORDIC scaler and LSB - result = extractedValue * LSB / cordicScaler; - } else if (key == "h1phase" || key == "h2phase" || key == "h3phase" || - key == "h8phase") { - // For Phase: value is in bits [11:0], bits [15:12] are reserved - const double LSB = 0.087891; - - // Extract the value from bits [11:0] - uint16_t extractedValue = registerValue & 0x0FFF; - - // Convert the extracted value by applying the LSB - result = extractedValue * LSB; - } else { - // Indicating an error or invalid key - result = -404.0; - } - - return result; +double ADMTController::getActualHarmonicRegisterValue(uint16_t registerValue, const string key) +{ + double result = 0.0; + const double cordicScaler = 0.6072; + + // Switch case for different bitmapping based on the key + if(key == "h1mag" || key == "h2mag") { + // For h1h2mag: value is in bits [10:0], bits [15:12] are reserved + const double LSB = 0.005493; + + // Extract the value from bits [10:0] + uint16_t extractedValue = registerValue & 0x07FF; + + // Convert the extracted value by applying CORDIC scaler and LSB + result = extractedValue * LSB / cordicScaler; + } else if(key == "h3mag" || key == "h8mag") { + // For h3h8mag: value is in bits [7:0], bits [15:8] are reserved + const double LSB = 0.005493; + + // Extract the value from bits [7:0] + uint16_t extractedValue = registerValue & 0x00FF; + + // Convert the extracted value by applying CORDIC scaler and LSB + result = extractedValue * LSB / cordicScaler; + } else if(key == "h1phase" || key == "h2phase" || key == "h3phase" || key == "h8phase") { + // For Phase: value is in bits [11:0], bits [15:12] are reserved + const double LSB = 0.087891; + + // Extract the value from bits [11:0] + uint16_t extractedValue = registerValue & 0x0FFF; + + // Convert the extracted value by applying the LSB + result = extractedValue * LSB; + } else { + // Indicating an error or invalid key + result = -404.0; + } + + return result; } -map -ADMTController::getFaultRegisterBitMapping(uint16_t registerValue) { - map result; - - // Extract each bit and store the result in the map - // Rain: Current returns it as value. - result["Sequencer Watchdog"] = (registerValue >> 15) & 0x01; - result["AMR Radius Check"] = (registerValue >> 14) & 0x01; - result["Turn Counter Cross Check"] = (registerValue >> 13) & 0x01; - result["MT Diagnostic"] = (registerValue >> 12) & 0x01; - result["Turn Count Sensor Levels"] = (registerValue >> 11) & 0x01; - result["Angle Cross Check"] = (registerValue >> 10) & 0x01; - result["Count Sensor False State"] = (registerValue >> 9) & 0x01; - result["Oscillator Drift"] = (registerValue >> 8) & 0x01; - result["ECC Double Bit Error"] = (registerValue >> 7) & 0x01; - result["Reserved"] = (registerValue >> 6) & 0x01; - result["NVM CRC Fault"] = (registerValue >> 5) & 0x01; - result["AFE Diagnostic"] = (registerValue >> 4) & 0x01; - result["VDRIVE Over Voltage"] = (registerValue >> 3) & 0x01; - result["VDRIVE Under Voltage"] = (registerValue >> 2) & 0x01; - result["VDD Over Voltage"] = (registerValue >> 1) & 0x01; - result["VDD Under Voltage"] = (registerValue >> 0) & 0x01; - - return result; +map ADMTController::getFaultRegisterBitMapping(uint16_t registerValue) +{ + map result; + + // Extract each bit and store the result in the map + // Rain: Current returns it as value. + result["Sequencer Watchdog"] = (registerValue >> 15) & 0x01; + result["AMR Radius Check"] = (registerValue >> 14) & 0x01; + result["Turn Counter Cross Check"] = (registerValue >> 13) & 0x01; + result["MT Diagnostic"] = (registerValue >> 12) & 0x01; + result["Turn Count Sensor Levels"] = (registerValue >> 11) & 0x01; + result["Angle Cross Check"] = (registerValue >> 10) & 0x01; + result["Count Sensor False State"] = (registerValue >> 9) & 0x01; + result["Oscillator Drift"] = (registerValue >> 8) & 0x01; + result["ECC Double Bit Error"] = (registerValue >> 7) & 0x01; + result["Reserved"] = (registerValue >> 6) & 0x01; + result["NVM CRC Fault"] = (registerValue >> 5) & 0x01; + result["AFE Diagnostic"] = (registerValue >> 4) & 0x01; + result["VDRIVE Over Voltage"] = (registerValue >> 3) & 0x01; + result["VDRIVE Under Voltage"] = (registerValue >> 2) & 0x01; + result["VDD Over Voltage"] = (registerValue >> 1) & 0x01; + result["VDD Under Voltage"] = (registerValue >> 0) & 0x01; + + return result; } // // How to read each value sample // for (const auto& pair : result) { @@ -975,958 +950,905 @@ ADMTController::getFaultRegisterBitMapping(uint16_t registerValue) { // std::endl; // } -map -ADMTController::getGeneralRegisterBitMapping(uint16_t registerValue) { - map result; - - // Bit 15: STORAGE[7] - result["STORAGE[7]"] = - ((registerValue >> 15) & 0x01) ? 1 : 0; // ? "Set" : "Not Set"; - - // Bits 14:13: Convert Synchronization - uint16_t convertSync = (registerValue >> 13) & 0x03; - switch (convertSync) { - case 0x00: - result["Convert Synchronization"] = 0; // "Disabled"; - break; - case 0x03: - result["Convert Synchronization"] = 1; // "Enabled"; - break; - default: - result["Convert Synchronization"] = -1; // "Reserved"; - break; - } - - // Bit 12: Angle Filter - result["Angle Filter"] = - ((registerValue >> 12) & 0x01) ? 1 : 0; // ? "Enabled" : "Disabled"; - - // Bit 11: STORAGE[6] - result["STORAGE[6]"] = - ((registerValue >> 11) & 0x01) ? 1 : 0; // ? "Set" : "Not Set"; - - // Bit 10: 8th Harmonic - result["8th Harmonic"] = - ((registerValue >> 10) & 0x01) - ? 1 - : 0; // ? "User-Supplied Values" : "ADI Factory Values"; - - // // Bit 9: Reserved (skipped) - // result["Reserved"] = "Reserved"; - - // Bits 8:6: STORAGE[5:3] - // uint16_t storage_5_3 = (registerValue >> 6) & 0x07; - // result["STORAGE[5:3]"] = std::to_string(storage_5_3); - - // Bits 5:4: Sequence Type - uint16_t sequenceType = (registerValue >> 4) & 0x03; - switch (sequenceType) { - case 0x00: - result["Sequence Type"] = 1; // "Mode 2"; - break; - case 0x03: - result["Sequence Type"] = 0; // "Mode 1"; - break; - default: - result["Sequence Type"] = -1; // "Reserved"; - break; - } - - // Bits 3:1: STORAGE[2:0] - // uint16_t storage_2_0 = (registerValue >> 1) & 0x07; - // result["STORAGE[2:0]"] = std::to_string(storage_2_0); - - // Bit 0: Conversion Type - result["Conversion Type"] = - (registerValue & 0x01) - ? 1 - : 0; // ? "One-shot conversion" : "Continuous conversions"; - - return result; +map ADMTController::getGeneralRegisterBitMapping(uint16_t registerValue) +{ + map result; + + // Bit 15: STORAGE[7] + result["STORAGE[7]"] = ((registerValue >> 15) & 0x01) ? 1 : 0; // ? "Set" : "Not Set"; + + // Bits 14:13: Convert Synchronization + uint16_t convertSync = (registerValue >> 13) & 0x03; + switch(convertSync) { + case 0x00: + result["Convert Synchronization"] = 0; // "Disabled"; + break; + case 0x03: + result["Convert Synchronization"] = 1; // "Enabled"; + break; + default: + result["Convert Synchronization"] = -1; // "Reserved"; + break; + } + + // Bit 12: Angle Filter + result["Angle Filter"] = ((registerValue >> 12) & 0x01) ? 1 : 0; // ? "Enabled" : "Disabled"; + + // Bit 11: STORAGE[6] + result["STORAGE[6]"] = ((registerValue >> 11) & 0x01) ? 1 : 0; // ? "Set" : "Not Set"; + + // Bit 10: 8th Harmonic + result["8th Harmonic"] = + ((registerValue >> 10) & 0x01) ? 1 : 0; // ? "User-Supplied Values" : "ADI Factory Values"; + + // // Bit 9: Reserved (skipped) + // result["Reserved"] = "Reserved"; + + // Bits 8:6: STORAGE[5:3] + // uint16_t storage_5_3 = (registerValue >> 6) & 0x07; + // result["STORAGE[5:3]"] = std::to_string(storage_5_3); + + // Bits 5:4: Sequence Type + uint16_t sequenceType = (registerValue >> 4) & 0x03; + switch(sequenceType) { + case 0x00: + result["Sequence Type"] = 1; // "Mode 2"; + break; + case 0x03: + result["Sequence Type"] = 0; // "Mode 1"; + break; + default: + result["Sequence Type"] = -1; // "Reserved"; + break; + } + + // Bits 3:1: STORAGE[2:0] + // uint16_t storage_2_0 = (registerValue >> 1) & 0x07; + // result["STORAGE[2:0]"] = std::to_string(storage_2_0); + + // Bit 0: Conversion Type + result["Conversion Type"] = + (registerValue & 0x01) ? 1 : 0; // ? "One-shot conversion" : "Continuous conversions"; + + return result; } // // How to read each value sample // for (const auto& pair : result) { // std::cout << pair.first << ": " << pair.second << std::endl; // } -map -ADMTController::getDIGIOENRegisterBitMapping(uint16_t registerValue) { - map result; - - // // Bits 15:14: Reserved (skipped) - // result["Reserved (15:14)"] = "Reserved"; - - // Bit 13: DIGIO5EN - result["DIGIO5EN"] = - ((registerValue >> 13) & 0x01) - ? true - : false; // ? "GPIO5 output enable" : "GPIO5 output disable"; - - // Bit 12: DIGIO4EN - result["DIGIO4EN"] = - ((registerValue >> 12) & 0x01) - ? true - : false; // ? "GPIO4 output enable" : "GPIO4 output disable"; - - // Bit 11: DIGIO3EN - result["DIGIO3EN"] = - ((registerValue >> 11) & 0x01) - ? true - : false; // ? "GPIO3 output enable" : "GPIO3 output disable"; - - // Bit 10: DIGIO2EN - result["DIGIO2EN"] = - ((registerValue >> 10) & 0x01) - ? true - : false; // ? "GPIO2 output enable" : "GPIO2 output disable"; - - // Bit 9: DIGIO1EN - result["DIGIO1EN"] = - ((registerValue >> 9) & 0x01) - ? true - : false; // ? "GPIO1 output enable" : "GPIO1 output disable"; - - // Bit 8: DIGIO0EN - result["DIGIO0EN"] = - ((registerValue >> 8) & 0x01) - ? true - : false; // ? "GPIO0 output enable" : "GPIO0 output disable"; - - // // Bits 7:6: Reserved (skipped) - // result["Reserved (7:6)"] = "Reserved"; - - // Bit 5: Bootload - result["BOOTLOAD"] = ((registerValue >> 5) & 0x01) - ? true - : false; // ? "GPIO5" : "Bootload (Output only)"; - - // Bit 4: Fault - result["FAULT"] = ((registerValue >> 4) & 0x01) - ? true - : false; // ? "GPIO4" : "Fault (Output only)"; - - // Bit 3: Acalc - result["ACALC"] = ((registerValue >> 3) & 0x01) - ? true - : false; // ? "GPIO3" : "Acalc (Output only)"; - - // Bit 2: Sent - result["SENT"] = ((registerValue >> 2) & 0x01) - ? true - : false; // ? "GPIO2" : "Sent (Output only)"; - - // Bit 1: Cnv - result["CNV"] = ((registerValue >> 1) & 0x01) - ? true - : false; // ? "GPIO1" : "Cnv (Output only)"; - - // Bit 0: Busy - result["BUSY"] = (registerValue & 0x01) - ? true - : false; // ? "GPIO0" : "Busy (Output only)"; - - return result; +map ADMTController::getDIGIOENRegisterBitMapping(uint16_t registerValue) +{ + map result; + + // // Bits 15:14: Reserved (skipped) + // result["Reserved (15:14)"] = "Reserved"; + + // Bit 13: DIGIO5EN + result["DIGIO5EN"] = + ((registerValue >> 13) & 0x01) ? true : false; // ? "GPIO5 output enable" : "GPIO5 output disable"; + + // Bit 12: DIGIO4EN + result["DIGIO4EN"] = + ((registerValue >> 12) & 0x01) ? true : false; // ? "GPIO4 output enable" : "GPIO4 output disable"; + + // Bit 11: DIGIO3EN + result["DIGIO3EN"] = + ((registerValue >> 11) & 0x01) ? true : false; // ? "GPIO3 output enable" : "GPIO3 output disable"; + + // Bit 10: DIGIO2EN + result["DIGIO2EN"] = + ((registerValue >> 10) & 0x01) ? true : false; // ? "GPIO2 output enable" : "GPIO2 output disable"; + + // Bit 9: DIGIO1EN + result["DIGIO1EN"] = + ((registerValue >> 9) & 0x01) ? true : false; // ? "GPIO1 output enable" : "GPIO1 output disable"; + + // Bit 8: DIGIO0EN + result["DIGIO0EN"] = + ((registerValue >> 8) & 0x01) ? true : false; // ? "GPIO0 output enable" : "GPIO0 output disable"; + + // // Bits 7:6: Reserved (skipped) + // result["Reserved (7:6)"] = "Reserved"; + + // Bit 5: Bootload + result["BOOTLOAD"] = ((registerValue >> 5) & 0x01) ? true : false; // ? "GPIO5" : "Bootload (Output only)"; + + // Bit 4: Fault + result["FAULT"] = ((registerValue >> 4) & 0x01) ? true : false; // ? "GPIO4" : "Fault (Output only)"; + + // Bit 3: Acalc + result["ACALC"] = ((registerValue >> 3) & 0x01) ? true : false; // ? "GPIO3" : "Acalc (Output only)"; + + // Bit 2: Sent + result["SENT"] = ((registerValue >> 2) & 0x01) ? true : false; // ? "GPIO2" : "Sent (Output only)"; + + // Bit 1: Cnv + result["CNV"] = ((registerValue >> 1) & 0x01) ? true : false; // ? "GPIO1" : "Cnv (Output only)"; + + // Bit 0: Busy + result["BUSY"] = (registerValue & 0x01) ? true : false; // ? "GPIO0" : "Busy (Output only)"; + + return result; } -map -ADMTController::getDIGIORegisterBitMapping(uint16_t registerValue) { - map result; +map ADMTController::getDIGIORegisterBitMapping(uint16_t registerValue) +{ + map result; - // Bits 15:6: Reserved (skipped) + // Bits 15:6: Reserved (skipped) - // Bit 5: GPIO5 - result["GPIO5"] = ((registerValue >> 5) & 0x01) ? true : false; + // Bit 5: GPIO5 + result["GPIO5"] = ((registerValue >> 5) & 0x01) ? true : false; - // Bit 4: GPIO4 - result["GPIO4"] = ((registerValue >> 4) & 0x01) ? true : false; + // Bit 4: GPIO4 + result["GPIO4"] = ((registerValue >> 4) & 0x01) ? true : false; - // Bit 3: GPIO3 - result["GPIO3"] = ((registerValue >> 3) & 0x01) ? true : false; + // Bit 3: GPIO3 + result["GPIO3"] = ((registerValue >> 3) & 0x01) ? true : false; - // Bit 2: GPIO2 - result["GPIO2"] = ((registerValue >> 2) & 0x01) ? true : false; + // Bit 2: GPIO2 + result["GPIO2"] = ((registerValue >> 2) & 0x01) ? true : false; - // Bit 1: GPIO1 - result["GPIO1"] = ((registerValue >> 1) & 0x01) ? true : false; + // Bit 1: GPIO1 + result["GPIO1"] = ((registerValue >> 1) & 0x01) ? true : false; - // Bit 0: GPIO0 - result["GPIO0"] = (registerValue & 0x01) ? true : false; + // Bit 0: GPIO0 + result["GPIO0"] = (registerValue & 0x01) ? true : false; - return result; + return result; } -map -ADMTController::getDiag1RegisterBitMapping_Register(uint16_t registerValue) { - map result; - - // Bits 15 to 8: R7 to R0 (Enabled or Disabled) - result["R7"] = ((registerValue >> 15) & 0x01) ? true : false; - result["R6"] = ((registerValue >> 14) & 0x01) ? true : false; - result["R5"] = ((registerValue >> 13) & 0x01) ? true : false; - result["R4"] = ((registerValue >> 12) & 0x01) ? true : false; - result["R3"] = ((registerValue >> 11) & 0x01) ? true : false; - result["R2"] = ((registerValue >> 10) & 0x01) ? true : false; - result["R1"] = ((registerValue >> 9) & 0x01) ? true : false; - result["R0"] = ((registerValue >> 8) & 0x01) ? true : false; - - return result; +map ADMTController::getDiag1RegisterBitMapping_Register(uint16_t registerValue) +{ + map result; + + // Bits 15 to 8: R7 to R0 (Enabled or Disabled) + result["R7"] = ((registerValue >> 15) & 0x01) ? true : false; + result["R6"] = ((registerValue >> 14) & 0x01) ? true : false; + result["R5"] = ((registerValue >> 13) & 0x01) ? true : false; + result["R4"] = ((registerValue >> 12) & 0x01) ? true : false; + result["R3"] = ((registerValue >> 11) & 0x01) ? true : false; + result["R2"] = ((registerValue >> 10) & 0x01) ? true : false; + result["R1"] = ((registerValue >> 9) & 0x01) ? true : false; + result["R0"] = ((registerValue >> 8) & 0x01) ? true : false; + + return result; } -map -ADMTController::getDiag1RegisterBitMapping_Afe(uint16_t registerValue, - bool is5V) { - map result; +map ADMTController::getDiag1RegisterBitMapping_Afe(uint16_t registerValue, bool is5V) +{ + map result; - // Bits 7:0: AFE Diagnostic 2 - Measurement of Fixed voltage (stored in 2's - // complement) - int8_t afeDiagnostic = - static_cast(registerValue & 0x00FF); // Interpret as signed 8-bit + // Bits 7:0: AFE Diagnostic 2 - Measurement of Fixed voltage (stored in 2's + // complement) + int8_t afeDiagnostic = static_cast(registerValue & 0x00FF); // Interpret as signed 8-bit - // Choose the correct resolution based on the voltage level (5V or 3.3V part) - double resolution = - is5V ? 0.0048828 : 0.003222; // 0.0048828 for 5V, 0.003222 for 3.3V + // Choose the correct resolution based on the voltage level (5V or 3.3V part) + double resolution = is5V ? 0.0048828 : 0.003222; // 0.0048828 for 5V, 0.003222 for 3.3V - // Convert the AFE Diagnostic value to a voltage - double diagnosticVoltage = static_cast(afeDiagnostic) * resolution; - result["AFE Diagnostic 2"] = diagnosticVoltage; + // Convert the AFE Diagnostic value to a voltage + double diagnosticVoltage = static_cast(afeDiagnostic) * resolution; + result["AFE Diagnostic 2"] = diagnosticVoltage; - return result; + return result; } -map -ADMTController::getDiag2RegisterBitMapping(uint16_t registerValue) { - map result; +map ADMTController::getDiag2RegisterBitMapping(uint16_t registerValue) +{ + map result; - // Bits 15:8: AFE Diagnostic 1 - Measurement of AFE +57% diagnostic resistor - uint16_t afeDiagnostic1 = (registerValue >> 8) & 0x00FF; + // Bits 15:8: AFE Diagnostic 1 - Measurement of AFE +57% diagnostic resistor + uint16_t afeDiagnostic1 = (registerValue >> 8) & 0x00FF; - // Convert AFE Diagnostic 1 value to double - // Rain: adjust scaling factor as needed with actual method. - double diagnostic1Voltage = static_cast(afeDiagnostic1) * - 0.01; // what I found (to be confirmed) + // Convert AFE Diagnostic 1 value to double + // Rain: adjust scaling factor as needed with actual method. + double diagnostic1Voltage = static_cast(afeDiagnostic1) * 0.01; // what I found (to be confirmed) - // Store the result with fixed precision - result["AFE Diagnostic 1 (+57%)"] = diagnostic1Voltage; + // Store the result with fixed precision + result["AFE Diagnostic 1 (+57%)"] = diagnostic1Voltage; - // Bits 7:0: AFE Diagnostic 0 - Measurement of AFE -57% diagnostic resistor - uint16_t afeDiagnostic0 = registerValue & 0x00FF; + // Bits 7:0: AFE Diagnostic 0 - Measurement of AFE -57% diagnostic resistor + uint16_t afeDiagnostic0 = registerValue & 0x00FF; - // Convert AFE Diagnostic 0 value to double - // Rain: adjust scaling factor as needed with actual method. - double diagnostic0Voltage = static_cast(afeDiagnostic0) * - 0.01; // what I found (to be confirmed) + // Convert AFE Diagnostic 0 value to double + // Rain: adjust scaling factor as needed with actual method. + double diagnostic0Voltage = static_cast(afeDiagnostic0) * 0.01; // what I found (to be confirmed) - // Store the result with fixed precision - result["AFE Diagnostic 0 (-57%)"] = diagnostic0Voltage; + // Store the result with fixed precision + result["AFE Diagnostic 0 (-57%)"] = diagnostic0Voltage; - return result; + return result; } -uint16_t -ADMTController::setGeneralRegisterBitMapping(uint16_t currentRegisterValue, - map settings) { - uint16_t registerValue = - currentRegisterValue; // Start with the current register value - - // Bit 15: STORAGE[7] (preserve original value) - // Do nothing, as STORAGE[7] is preserved. - - // Bits 14:13: Convert Synchronization - if (settings["Convert Synchronization"] == 1) { // Enabled - registerValue |= (0x03 << 13); // Set bits 14:13 to 0b11 - } else if (settings["Convert Synchronization"] == 0) { // Disabled - registerValue &= ~(0x03 << 13); // Clear bits 14:13 (set to 0b00) - } - - // Bit 12: Angle Filter - if (settings["Angle Filter"] == 1) { // Enabled - registerValue |= (1 << 12); // Set bit 12 - } else if (settings["Angle Filter"] == 0) { // Disabled - registerValue &= ~(1 << 12); // Clear bit 12 - } - - // Bit 11: STORAGE[6] (preserve original value) - // Do nothing, as STORAGE[6] is preserved. - - // Bit 10: 8th Harmonic - if (settings["8th Harmonic"] == 1) { // User-Supplied Values - registerValue |= (1 << 10); // Set bit 10 - } else if (settings["8th Harmonic"] == 0) { // ADI Factory Values - registerValue &= ~(1 << 10); // Clear bit 10 - } - - // Bit 9: Reserved (no change) - - // Bits 8:6: STORAGE[5:3] (preserve original value) - // Do nothing, as STORAGE[5:3] is preserved. - - // Bits 5:4: Sequence Type - if (settings["Sequence Type"] == 0) { // Mode 1 - registerValue |= (0x03 << 4); // Set bits 5:4 to 0b11 - } else if (settings["Sequence Type"] == 1) { // Mode 2 - registerValue &= ~(0x03 << 4); // Clear bits 5:4 (set to 0b00) - } - - // Bits 3:1: STORAGE[2:0] (preserve original value) - // Do nothing, as STORAGE[2:0] is preserved. - - // Bit 0: Conversion Type - if (settings["Conversion Type"] == 1) { // One-shot conversion - registerValue |= (1 << 0); // Set bit 0 - } else if (settings["Conversion Type"] == 0) { // Continuous conversions - registerValue &= ~(1 << 0); // Clear bit 0 - } - - return registerValue; +uint16_t ADMTController::setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings) +{ + uint16_t registerValue = currentRegisterValue; // Start with the current register value + + // Bit 15: STORAGE[7] (preserve original value) + // Do nothing, as STORAGE[7] is preserved. + + // Bits 14:13: Convert Synchronization + if(settings["Convert Synchronization"] == 1) { // Enabled + registerValue |= (0x03 << 13); // Set bits 14:13 to 0b11 + } else if(settings["Convert Synchronization"] == 0) { // Disabled + registerValue &= ~(0x03 << 13); // Clear bits 14:13 (set to 0b00) + } + + // Bit 12: Angle Filter + if(settings["Angle Filter"] == 1) { // Enabled + registerValue |= (1 << 12); // Set bit 12 + } else if(settings["Angle Filter"] == 0) { // Disabled + registerValue &= ~(1 << 12); // Clear bit 12 + } + + // Bit 11: STORAGE[6] (preserve original value) + // Do nothing, as STORAGE[6] is preserved. + + // Bit 10: 8th Harmonic + if(settings["8th Harmonic"] == 1) { // User-Supplied Values + registerValue |= (1 << 10); // Set bit 10 + } else if(settings["8th Harmonic"] == 0) { // ADI Factory Values + registerValue &= ~(1 << 10); // Clear bit 10 + } + + // Bit 9: Reserved (no change) + + // Bits 8:6: STORAGE[5:3] (preserve original value) + // Do nothing, as STORAGE[5:3] is preserved. + + // Bits 5:4: Sequence Type + if(settings["Sequence Type"] == 0) { // Mode 1 + registerValue |= (0x03 << 4); // Set bits 5:4 to 0b11 + } else if(settings["Sequence Type"] == 1) { // Mode 2 + registerValue &= ~(0x03 << 4); // Clear bits 5:4 (set to 0b00) + } + + // Bits 3:1: STORAGE[2:0] (preserve original value) + // Do nothing, as STORAGE[2:0] is preserved. + + // Bit 0: Conversion Type + if(settings["Conversion Type"] == 1) { // One-shot conversion + registerValue |= (1 << 0); // Set bit 0 + } else if(settings["Conversion Type"] == 0) { // Continuous conversions + registerValue &= ~(1 << 0); // Clear bit 0 + } + + return registerValue; } -int ADMTController::getAbsAngleTurnCount(uint16_t registerValue) { - // Bits 15:8: Turn count in quarter turns - uint8_t turnCount = (registerValue & 0xFF00) >> 8; - - if (turnCount <= 0xD5) { - // Straight binary turn count - return turnCount / 4; // Convert from quarter turns to whole turns - } else if (turnCount == 0xD6) { - // Invalid turn count - return -1; - } else { - // 2's complement turn count - int8_t signedTurnCount = - static_cast(turnCount); // Handle as signed value - return signedTurnCount / 4; // Convert from quarter turns to whole turns - } +int ADMTController::getAbsAngleTurnCount(uint16_t registerValue) +{ + // Bits 15:8: Turn count in quarter turns + uint8_t turnCount = (registerValue & 0xFF00) >> 8; + + if(turnCount <= 0xD5) { + // Straight binary turn count + return turnCount / 4; // Convert from quarter turns to whole turns + } else if(turnCount == 0xD6) { + // Invalid turn count + return -1; + } else { + // 2's complement turn count + int8_t signedTurnCount = static_cast(turnCount); // Handle as signed value + return signedTurnCount / 4; // Convert from quarter turns to whole turns + } } -uint16_t -ADMTController::setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, - map settings) { - uint16_t registerValue = - currentRegisterValue; // Start with the current register value - - // Bits 15:14: (preserve original value) - - // Bit 13: DIGIO5EN - if (settings["DIGIO5EN"]) // "Enabled" - { - registerValue |= (1 << 13); // Set bit 13 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 13); // Clear bit 13 (Disabled) - } - - // Bit 12: DIGIO4EN - if (settings["DIGIO4EN"]) // "Enabled" - { - registerValue |= (1 << 12); // Set bit 12 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 12); // Clear bit 12 (Disabled) - } - - // Bit 11: DIGIO3EN - if (settings["DIGIO3EN"]) // "Enabled" - { - registerValue |= (1 << 11); // Set bit 11 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 11); // Clear bit 11 (Disabled) - } - - // Bit 10: DIGIO2EN - if (settings["DIGIO2EN"]) // "Enabled" - { - registerValue |= (1 << 10); // Set bit 10 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 10); // Clear bit 10 (Disabled) - } - - // Bit 9: DIGIO1EN - if (settings["DIGIO1EN"]) // "Enabled" - { - registerValue |= (1 << 9); // Set bit 9 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 9); // Clear bit 9 (Disabled) - } - - // Bit 8: DIGIO0EN - if (settings["DIGIO0EN"]) // "Enabled" - { - registerValue |= (1 << 8); // Set bit 8 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 8); // Clear bit 8 (Disabled) - } - - // Bits 7:6: (preserve original value) - - // Bit 5: Bootload - if (settings["BOOTLOAD"]) // "Enabled" - { - registerValue |= (1 << 5); // Set bit 5 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 5); // Clear bit 5 (Disabled) - } - - // Bit 4: Fault - if (settings["FAULT"]) // "Enabled" - { - registerValue |= (1 << 4); // Set bit 4 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 4); // Clear bit 4 (Disabled) - } - - // Bit 3: Acalc - if (settings["ACALC"]) // "Enabled" - { - registerValue |= (1 << 3); // Set bit 3 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 3); // Clear bit 3 (Disabled) - } - - // Bit 2: Sent - if (settings["SENT"]) // "Enabled" - { - registerValue |= (1 << 2); // Set bit 2 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 2); // Clear bit 2 (Disabled) - } - - // Bit 1: Cnv - if (settings["CNV"]) // "Enabled" - { - registerValue |= (1 << 1); // Set bit 1 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 1); // Clear bit 1 (Disabled) - } - - // Bit 0: Sent - if (settings["BUSY"]) // "Enabled" - { - registerValue |= (1 << 0); // Set bit 0 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 0); // Clear bit 0 (Disabled) - } - - return registerValue; +uint16_t ADMTController::setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings) +{ + uint16_t registerValue = currentRegisterValue; // Start with the current register value + + // Bits 15:14: (preserve original value) + + // Bit 13: DIGIO5EN + if(settings["DIGIO5EN"]) // "Enabled" + { + registerValue |= (1 << 13); // Set bit 13 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 13); // Clear bit 13 (Disabled) + } + + // Bit 12: DIGIO4EN + if(settings["DIGIO4EN"]) // "Enabled" + { + registerValue |= (1 << 12); // Set bit 12 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 12); // Clear bit 12 (Disabled) + } + + // Bit 11: DIGIO3EN + if(settings["DIGIO3EN"]) // "Enabled" + { + registerValue |= (1 << 11); // Set bit 11 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 11); // Clear bit 11 (Disabled) + } + + // Bit 10: DIGIO2EN + if(settings["DIGIO2EN"]) // "Enabled" + { + registerValue |= (1 << 10); // Set bit 10 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 10); // Clear bit 10 (Disabled) + } + + // Bit 9: DIGIO1EN + if(settings["DIGIO1EN"]) // "Enabled" + { + registerValue |= (1 << 9); // Set bit 9 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 9); // Clear bit 9 (Disabled) + } + + // Bit 8: DIGIO0EN + if(settings["DIGIO0EN"]) // "Enabled" + { + registerValue |= (1 << 8); // Set bit 8 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 8); // Clear bit 8 (Disabled) + } + + // Bits 7:6: (preserve original value) + + // Bit 5: Bootload + if(settings["BOOTLOAD"]) // "Enabled" + { + registerValue |= (1 << 5); // Set bit 5 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 5); // Clear bit 5 (Disabled) + } + + // Bit 4: Fault + if(settings["FAULT"]) // "Enabled" + { + registerValue |= (1 << 4); // Set bit 4 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 4); // Clear bit 4 (Disabled) + } + + // Bit 3: Acalc + if(settings["ACALC"]) // "Enabled" + { + registerValue |= (1 << 3); // Set bit 3 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 3); // Clear bit 3 (Disabled) + } + + // Bit 2: Sent + if(settings["SENT"]) // "Enabled" + { + registerValue |= (1 << 2); // Set bit 2 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 2); // Clear bit 2 (Disabled) + } + + // Bit 1: Cnv + if(settings["CNV"]) // "Enabled" + { + registerValue |= (1 << 1); // Set bit 1 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 1); // Clear bit 1 (Disabled) + } + + // Bit 0: Sent + if(settings["BUSY"]) // "Enabled" + { + registerValue |= (1 << 0); // Set bit 0 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 0); // Clear bit 0 (Disabled) + } + + return registerValue; } -uint16_t -ADMTController::setDIGIORegisterBitMapping(uint16_t currentRegisterValue, - map settings) { - uint16_t registerValue = - currentRegisterValue; // Start with the current register value - - // Bits 15:6: (preserve original value) - - // Bit 5: GPIO5 - if (settings["GPIO5"]) // "Enabled" - { - registerValue |= (1 << 5); // Set bit 5 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 5); // Clear bit 5 (Disabled) - } - - // Bit 4: GPIO4 - if (settings["GPIO4"]) // "Enabled" - { - registerValue |= (1 << 4); // Set bit 4 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 4); // Clear bit 4 (Disabled) - } - - // Bit 3: GPIO3 - if (settings["GPIO3"]) // "Enabled" - { - registerValue |= (1 << 3); // Set bit 3 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 3); // Clear bit 3 (Disabled) - } - - // Bit 2: GPIO2 - if (settings["GPIO2"]) // "Enabled" - { - registerValue |= (1 << 2); // Set bit 2 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 2); // Clear bit 2 (Disabled) - } - - // Bit 1: GPIO1 - if (settings["GPIO1"]) // "Enabled" - { - registerValue |= (1 << 1); // Set bit 1 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 1); // Clear bit 1 (Disabled) - } - - // Bit 0: GPIO0 - if (settings["GPIO0"]) // "Enabled" - { - registerValue |= (1 << 0); // Set bit 0 to 1 (Enabled) - } else // "Disabled" - { - registerValue &= ~(1 << 0); // Clear bit 0 (Disabled) - } - - return registerValue; +uint16_t ADMTController::setDIGIORegisterBitMapping(uint16_t currentRegisterValue, map settings) +{ + uint16_t registerValue = currentRegisterValue; // Start with the current register value + + // Bits 15:6: (preserve original value) + + // Bit 5: GPIO5 + if(settings["GPIO5"]) // "Enabled" + { + registerValue |= (1 << 5); // Set bit 5 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 5); // Clear bit 5 (Disabled) + } + + // Bit 4: GPIO4 + if(settings["GPIO4"]) // "Enabled" + { + registerValue |= (1 << 4); // Set bit 4 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 4); // Clear bit 4 (Disabled) + } + + // Bit 3: GPIO3 + if(settings["GPIO3"]) // "Enabled" + { + registerValue |= (1 << 3); // Set bit 3 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 3); // Clear bit 3 (Disabled) + } + + // Bit 2: GPIO2 + if(settings["GPIO2"]) // "Enabled" + { + registerValue |= (1 << 2); // Set bit 2 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 2); // Clear bit 2 (Disabled) + } + + // Bit 1: GPIO1 + if(settings["GPIO1"]) // "Enabled" + { + registerValue |= (1 << 1); // Set bit 1 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 1); // Clear bit 1 (Disabled) + } + + // Bit 0: GPIO0 + if(settings["GPIO0"]) // "Enabled" + { + registerValue |= (1 << 0); // Set bit 0 to 1 (Enabled) + } else // "Disabled" + { + registerValue &= ~(1 << 0); // Clear bit 0 (Disabled) + } + + return registerValue; } -map -ADMTController::getUNIQID3RegisterMapping(uint16_t registerValue) { - map result; - - // Bits 15:11 - Reserved (ignore) - - // Bits 10:08 - Product ID (3 bits) - uint8_t productID = (registerValue >> 8) & 0x07; - switch (productID) { - case 0x00: - result["Product ID"] = "ADMT4000"; - break; - case 0x01: - result["Product ID"] = "ADMT4001"; - break; - default: - result["Product ID"] = "Unidentified"; - break; - } - - // Bits 7:06 - Supply ID (2 bits) - uint8_t supplyID = (registerValue >> 6) & 0x03; - switch (supplyID) { - case 0x00: - result["Supply ID"] = "3.3V"; - break; - case 0x02: - result["Supply ID"] = "5V"; - break; - default: - result["Supply ID"] = "Unknown"; - break; - } - - // Bits 5:03 - ASIL ID (3 bits) - uint8_t asilID = - (registerValue >> 3) & 0x07; // Show both Seq 1 & 2 if unknown - switch (asilID) { - case 0x00: - result["ASIL ID"] = "ASIL QM"; - break; - case 0x01: - result["ASIL ID"] = "ASIL A"; - break; - case 0x02: - result["ASIL ID"] = "ASIL B"; - break; - case 0x03: - result["ASIL ID"] = "ASIL C"; - break; - case 0x04: - result["ASIL ID"] = "ASIL D"; - break; - default: - result["ASIL ID"] = "Unidentified ASIL"; - break; - } - - // Bits 2:00 - Revision ID (3 bits) - uint8_t revisionID = registerValue & 0x07; - switch (revisionID) { - case 0x01: - result["Revision ID"] = "S1"; - break; - case 0x02: - result["Revision ID"] = "S2"; - break; - default: - result["Revision ID"] = "Unknown"; - break; - } - - return result; +map ADMTController::getUNIQID3RegisterMapping(uint16_t registerValue) +{ + map result; + + // Bits 15:11 - Reserved (ignore) + + // Bits 10:08 - Product ID (3 bits) + uint8_t productID = (registerValue >> 8) & 0x07; + switch(productID) { + case 0x00: + result["Product ID"] = "ADMT4000"; + break; + case 0x01: + result["Product ID"] = "ADMT4001"; + break; + default: + result["Product ID"] = "Unidentified"; + break; + } + + // Bits 7:06 - Supply ID (2 bits) + uint8_t supplyID = (registerValue >> 6) & 0x03; + switch(supplyID) { + case 0x00: + result["Supply ID"] = "3.3V"; + break; + case 0x02: + result["Supply ID"] = "5V"; + break; + default: + result["Supply ID"] = "Unknown"; + break; + } + + // Bits 5:03 - ASIL ID (3 bits) + uint8_t asilID = (registerValue >> 3) & 0x07; // Show both Seq 1 & 2 if unknown + switch(asilID) { + case 0x00: + result["ASIL ID"] = "ASIL QM"; + break; + case 0x01: + result["ASIL ID"] = "ASIL A"; + break; + case 0x02: + result["ASIL ID"] = "ASIL B"; + break; + case 0x03: + result["ASIL ID"] = "ASIL C"; + break; + case 0x04: + result["ASIL ID"] = "ASIL D"; + break; + default: + result["ASIL ID"] = "Unidentified ASIL"; + break; + } + + // Bits 2:00 - Revision ID (3 bits) + uint8_t revisionID = registerValue & 0x07; + switch(revisionID) { + case 0x01: + result["Revision ID"] = "S1"; + break; + case 0x02: + result["Revision ID"] = "S2"; + break; + default: + result["Revision ID"] = "Unknown"; + break; + } + + return result; } -map -ADMTController::getSineRegisterBitMapping(uint16_t registerValue) { - map result; +map ADMTController::getSineRegisterBitMapping(uint16_t registerValue) +{ + map result; - // Bit 0 - Extract the status - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the status + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bit 1 - Reserved (ignore) + // Bit 1 - Reserved (ignore) - // Bits 15:2 - Extract the sine value - int16_t sineValueRaw = - (registerValue >> 2); // Shift right by 2 to discard Bits [1:0] + // Bits 15:2 - Extract the sine value + int16_t sineValueRaw = (registerValue >> 2); // Shift right by 2 to discard Bits [1:0] - // Check if the value is negative (2's complement format) - if (sineValueRaw & 0x2000) { - sineValueRaw |= 0xC000; - } + // Check if the value is negative (2's complement format) + if(sineValueRaw & 0x2000) { + sineValueRaw |= 0xC000; + } - // Convert the raw uncorrected sine value to a double - result["SINE"] = static_cast(sineValueRaw); + // Convert the raw uncorrected sine value to a double + result["SINE"] = static_cast(sineValueRaw); - return result; + return result; } -map -ADMTController::getCosineRegisterBitMapping(uint16_t registerValue) { - map result; +map ADMTController::getCosineRegisterBitMapping(uint16_t registerValue) +{ + map result; - // Bit 0 - Extract the status - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the status + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bit 1 - Reserved (ignore) + // Bit 1 - Reserved (ignore) - // Bits 15:2 - Extract the cosine value - int16_t cosineValueRaw = - (registerValue >> 2); // Shift right by 2 to discard Bits [1:0] + // Bits 15:2 - Extract the cosine value + int16_t cosineValueRaw = (registerValue >> 2); // Shift right by 2 to discard Bits [1:0] - // Check if the value is negative (2's complement format) - if (cosineValueRaw & 0x2000) { - cosineValueRaw |= 0xC000; - } + // Check if the value is negative (2's complement format) + if(cosineValueRaw & 0x2000) { + cosineValueRaw |= 0xC000; + } - // Convert the raw uncorrected cosine value to a double - result["COSINE"] = static_cast(cosineValueRaw); + // Convert the raw uncorrected cosine value to a double + result["COSINE"] = static_cast(cosineValueRaw); - return result; + return result; } -map -ADMTController::getRadiusRegisterBitMapping(uint16_t registerValue) { - map result; +map ADMTController::getRadiusRegisterBitMapping(uint16_t registerValue) +{ + map result; - // Bit 0 - Extract the STATUS - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the STATUS + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bits 15:1 - Extract the RADIUS value - uint16_t radiusRaw = - (registerValue >> 1); // Shift right by 1 to discard Bit 0 + // Bits 15:1 - Extract the RADIUS value + uint16_t radiusRaw = (registerValue >> 1); // Shift right by 1 to discard Bit 0 - // Apply the resolution to convert the raw value - constexpr double resolution = 0.000924; // mV/V - result["RADIUS"] = static_cast(radiusRaw) * resolution; + // Apply the resolution to convert the raw value + constexpr double resolution = 0.000924; // mV/V + result["RADIUS"] = static_cast(radiusRaw) * resolution; - return result; + return result; } -map -ADMTController::getAngleSecRegisterBitMapping(uint16_t registerValue) { - map result; +map ADMTController::getAngleSecRegisterBitMapping(uint16_t registerValue) +{ + map result; - // Bit 0 - Extract the STATUS - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the STATUS + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bits 15:4 - Extract the ANGLESEC value - uint16_t angleSecRaw = - (registerValue >> 4); // Right-shift by 4 to discard Bits [3:0] + // Bits 15:4 - Extract the ANGLESEC value + uint16_t angleSecRaw = (registerValue >> 4); // Right-shift by 4 to discard Bits [3:0] - // Calculate the actual angle using the given resolution (360° / 4096) - constexpr double resolution = 360.0 / 4096.0; // 0.087890625 degrees per LSB - result["ANGLESEC"] = angleSecRaw * resolution; + // Calculate the actual angle using the given resolution (360° / 4096) + constexpr double resolution = 360.0 / 4096.0; // 0.087890625 degrees per LSB + result["ANGLESEC"] = angleSecRaw * resolution; - return result; + return result; } -map -ADMTController::getSecAnglQRegisterBitMapping(uint16_t registerValue) { - map result; +map ADMTController::getSecAnglQRegisterBitMapping(uint16_t registerValue) +{ + map result; - // Bit 0 - Extract the STATUS - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the STATUS + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bits 15:2 - Extract the SECANGLQ raw value - int16_t secAnglQRaw = static_cast( - (registerValue & 0xFFFC) >> 2); // Mask Bits [1:0] and shift right by 2 + // Bits 15:2 - Extract the SECANGLQ raw value + int16_t secAnglQRaw = + static_cast((registerValue & 0xFFFC) >> 2); // Mask Bits [1:0] and shift right by 2 - // Convert the 2's complement raw value to the actual signed value - if (secAnglQRaw & 0x2000) { // Check the sign bit (Bit 13) - secAnglQRaw |= 0xC000; // Sign extend to preserve the 16-bit signed value - } + // Convert the 2's complement raw value to the actual signed value + if(secAnglQRaw & 0x2000) { // Check the sign bit (Bit 13) + secAnglQRaw |= 0xC000; // Sign extend to preserve the 16-bit signed value + } - // Store the SECANGLQ raw uncorrected value - result["SECANGLQ"] = static_cast(secAnglQRaw); + // Store the SECANGLQ raw uncorrected value + result["SECANGLQ"] = static_cast(secAnglQRaw); - return result; + return result; } -map -ADMTController::getSecAnglIRegisterBitMapping(uint16_t registerValue) { - map result; +map ADMTController::getSecAnglIRegisterBitMapping(uint16_t registerValue) +{ + map result; - // Bit 0 - Extract the STATUS bit - result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; + // Bit 0 - Extract the STATUS bit + result["Status"] = (registerValue & 0x01) ? 1.0 : 0.0; - // Bits 15:2 - Extract the SECANGLI raw value - int16_t secAnglIRaw = static_cast( - (registerValue & 0xFFFC) >> 2); // Mask Bits [1:0] and shift right by 2 + // Bits 15:2 - Extract the SECANGLI raw value + int16_t secAnglIRaw = + static_cast((registerValue & 0xFFFC) >> 2); // Mask Bits [1:0] and shift right by 2 - // Convert the 2's complement raw value to the actual signed value - if (secAnglIRaw & 0x2000) { // Check the sign bit (Bit 13) - secAnglIRaw |= 0xC000; // Sign extend to preserve the 16-bit signed value - } + // Convert the 2's complement raw value to the actual signed value + if(secAnglIRaw & 0x2000) { // Check the sign bit (Bit 13) + secAnglIRaw |= 0xC000; // Sign extend to preserve the 16-bit signed value + } - // Store the SECANGLI raw value (optional, for debugging or diagnostic - // purposes) - result["SECANGLI"] = static_cast(secAnglIRaw); + // Store the SECANGLI raw value (optional, for debugging or diagnostic + // purposes) + result["SECANGLI"] = static_cast(secAnglIRaw); - return result; + return result; } -map -ADMTController::getTmp1RegisterBitMapping(uint16_t registerValue, bool is5V) { - map result; +map ADMTController::getTmp1RegisterBitMapping(uint16_t registerValue, bool is5V) +{ + map result; - // Bits 15:4 - Extract the TMP1 raw value - uint16_t tmp1Raw = (registerValue & 0xFFF0) >> 4; + // Bits 15:4 - Extract the TMP1 raw value + uint16_t tmp1Raw = (registerValue & 0xFFF0) >> 4; - // Store the raw TMP1 value (for diagnostics) - result["TMP1Raw"] = static_cast(tmp1Raw); + // Store the raw TMP1 value (for diagnostics) + result["TMP1Raw"] = static_cast(tmp1Raw); - // Calculate TMP1 temperature in degrees Celsius based on VDD - double tmp1DegC = 0.0; - if (is5V == true) { - tmp1DegC = (tmp1Raw - 1238.0) / 13.45; - } else { - tmp1DegC = (tmp1Raw - 1208.0) / 13.61; - } + // Calculate TMP1 temperature in degrees Celsius based on VDD + double tmp1DegC = 0.0; + if(is5V == true) { + tmp1DegC = (tmp1Raw - 1238.0) / 13.45; + } else { + tmp1DegC = (tmp1Raw - 1208.0) / 13.61; + } - // Store the calculated temperature in degrees Celsius - result["TMP1"] = tmp1DegC; + // Store the calculated temperature in degrees Celsius + result["TMP1"] = tmp1DegC; - return result; + return result; } -bool ADMTController::checkRegisterFault(uint16_t registerValue, bool isMode1) { - // Mode-specific checks - if (isMode1) { - return ((registerValue >> 14) & 0x01) || // AMR Radius Check - ((registerValue >> 13) & 0x01) || // Turn Counter Cross Check - ((registerValue >> 9) & 0x01) || // Count Sensor False State - ((registerValue >> 7) & 0x01) || // ECC Double Bit Error - ((registerValue >> 5) & 0x01) || // NVM CRC Fault - ((registerValue >> 3) & 0x01) || // VDRIVE Over Voltage - ((registerValue >> 2) & 0x01) || // VDRIVE Under Voltage - ((registerValue >> 1) & 0x01) || // VDD Over Voltage - ((registerValue >> 0) & 0x01); // VDD Under Voltage - } else { - // Check all bits if not in Mode 1 - return ((registerValue >> 15) & 0x01) || // Sequencer Watchdog - ((registerValue >> 14) & 0x01) || // AMR Radius Check - ((registerValue >> 13) & 0x01) || // Turn Counter Cross Check - ((registerValue >> 12) & 0x01) || // MT Diagnostic - ((registerValue >> 11) & 0x01) || // Turn Count Sensor Levels - ((registerValue >> 10) & 0x01) || // Angle Cross Check - ((registerValue >> 9) & 0x01) || // Count Sensor False State - ((registerValue >> 8) & 0x01) || // Oscillator Drift - ((registerValue >> 7) & 0x01) || // ECC Double Bit Error - ((registerValue >> 6) & 0x01) || // Reserved - ((registerValue >> 5) & 0x01) || // NVM CRC Fault - ((registerValue >> 4) & 0x01) || // AFE Diagnostic - ((registerValue >> 3) & 0x01) || // VDRIVE Over Voltage - ((registerValue >> 2) & 0x01) || // VDRIVE Under Voltage - ((registerValue >> 1) & 0x01) || // VDD Over Voltage - ((registerValue >> 0) & 0x01); // VDD Under Voltage - } +bool ADMTController::checkRegisterFault(uint16_t registerValue, bool isMode1) +{ + // Mode-specific checks + if(isMode1) { + return ((registerValue >> 14) & 0x01) || // AMR Radius Check + ((registerValue >> 13) & 0x01) || // Turn Counter Cross Check + ((registerValue >> 9) & 0x01) || // Count Sensor False State + ((registerValue >> 7) & 0x01) || // ECC Double Bit Error + ((registerValue >> 5) & 0x01) || // NVM CRC Fault + ((registerValue >> 3) & 0x01) || // VDRIVE Over Voltage + ((registerValue >> 2) & 0x01) || // VDRIVE Under Voltage + ((registerValue >> 1) & 0x01) || // VDD Over Voltage + ((registerValue >> 0) & 0x01); // VDD Under Voltage + } else { + // Check all bits if not in Mode 1 + return ((registerValue >> 15) & 0x01) || // Sequencer Watchdog + ((registerValue >> 14) & 0x01) || // AMR Radius Check + ((registerValue >> 13) & 0x01) || // Turn Counter Cross Check + ((registerValue >> 12) & 0x01) || // MT Diagnostic + ((registerValue >> 11) & 0x01) || // Turn Count Sensor Levels + ((registerValue >> 10) & 0x01) || // Angle Cross Check + ((registerValue >> 9) & 0x01) || // Count Sensor False State + ((registerValue >> 8) & 0x01) || // Oscillator Drift + ((registerValue >> 7) & 0x01) || // ECC Double Bit Error + ((registerValue >> 6) & 0x01) || // Reserved + ((registerValue >> 5) & 0x01) || // NVM CRC Fault + ((registerValue >> 4) & 0x01) || // AFE Diagnostic + ((registerValue >> 3) & 0x01) || // VDRIVE Over Voltage + ((registerValue >> 2) & 0x01) || // VDRIVE Under Voltage + ((registerValue >> 1) & 0x01) || // VDD Over Voltage + ((registerValue >> 0) & 0x01); // VDD Under Voltage + } } -int ADMTController::streamIO() { - int result = -1; - const char *deviceName = "admt4000"; - const char *channelName = "rot"; - const char *scaleAttrName = "scale"; - const char *offsetAttrName = "offset"; - size_t samples = 1; - bool isOutput = false; - bool isCyclic = false; - - unsigned int i, j, major, minor; - char git_tag[8]; - iio_library_get_version(&major, &minor, git_tag); - bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; - - double *scaleAttrValue = new double(1); - int offsetAttrValue = 0; - char *offsetDst = new char[maxAttrSize]; - - if (!m_iioCtx) - return result; // Check if the context is valid - if (iio_context_get_devices_count(m_iioCtx) < 1) - return result; // Check if there are devices in the context - struct iio_device *admtDevice = - iio_context_find_device(m_iioCtx, deviceName); // Find the ADMT device - if (admtDevice == NULL) - return result; - struct iio_channel *channel = iio_device_find_channel( - admtDevice, channelName, isOutput); // Find the rotation channel - if (channel == NULL) - return result; - iio_channel_enable(channel); // Enable the channel - int scaleRet = iio_channel_attr_read_double( - channel, scaleAttrName, scaleAttrValue); // Read the scale attribute - if (scaleRet != 0) - return scaleRet; - iio_channel_attr_read(channel, offsetAttrName, offsetDst, - maxAttrSize); // Read the offset attribute - offsetAttrValue = atoi(offsetDst); - struct iio_buffer *buffer = iio_device_create_buffer( - admtDevice, samples, isCyclic); // Create a buffer - - while (!stopStream) { - ssize_t numBytesRead; - char *pointerData, *pointerEnd; - ptrdiff_t pointerIncrement; - - numBytesRead = iio_buffer_refill(buffer); - if (numBytesRead < 0) - break; - - pointerIncrement = iio_buffer_step(buffer); - pointerEnd = static_cast(iio_buffer_end(buffer)); - - const struct iio_data_format *format = iio_channel_get_data_format(channel); - unsigned int repeat = has_repeat ? format->repeat : 1; - - for (pointerData = static_cast(iio_buffer_first(buffer, channel)); - pointerData < pointerEnd; pointerData += pointerIncrement) { - for (int j = 0; j < repeat; j++) { - if (format->length / 8 == sizeof(int16_t)) { - int16_t rawValue = (reinterpret_cast(pointerData))[j]; - double scaledValue = (rawValue - offsetAttrValue) * *scaleAttrValue; - Q_EMIT streamData(scaledValue); - } - } - } - } - - iio_buffer_destroy(buffer); - return 0; +int ADMTController::streamIO() +{ + int result = -1; + const char *deviceName = "admt4000"; + const char *channelName = "rot"; + const char *scaleAttrName = "scale"; + const char *offsetAttrName = "offset"; + size_t samples = 1; + bool isOutput = false; + bool isCyclic = false; + + unsigned int i, j, major, minor; + char git_tag[8]; + iio_library_get_version(&major, &minor, git_tag); + bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; + + double *scaleAttrValue = new double(1); + int offsetAttrValue = 0; + char *offsetDst = new char[maxAttrSize]; + + if(!m_iioCtx) + return result; // Check if the context is valid + if(iio_context_get_devices_count(m_iioCtx) < 1) + return result; // Check if there are devices in the context + struct iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); // Find the ADMT device + if(admtDevice == NULL) + return result; + struct iio_channel *channel = + iio_device_find_channel(admtDevice, channelName, isOutput); // Find the rotation channel + if(channel == NULL) + return result; + iio_channel_enable(channel); // Enable the channel + int scaleRet = iio_channel_attr_read_double(channel, scaleAttrName, scaleAttrValue); // Read the scale attribute + if(scaleRet != 0) + return scaleRet; + iio_channel_attr_read(channel, offsetAttrName, offsetDst, + maxAttrSize); // Read the offset attribute + offsetAttrValue = atoi(offsetDst); + struct iio_buffer *buffer = iio_device_create_buffer(admtDevice, samples, isCyclic); // Create a buffer + + while(!stopStream) { + ssize_t numBytesRead; + char *pointerData, *pointerEnd; + ptrdiff_t pointerIncrement; + + numBytesRead = iio_buffer_refill(buffer); + if(numBytesRead < 0) + break; + + pointerIncrement = iio_buffer_step(buffer); + pointerEnd = static_cast(iio_buffer_end(buffer)); + + const struct iio_data_format *format = iio_channel_get_data_format(channel); + unsigned int repeat = has_repeat ? format->repeat : 1; + + for(pointerData = static_cast(iio_buffer_first(buffer, channel)); pointerData < pointerEnd; + pointerData += pointerIncrement) { + for(int j = 0; j < repeat; j++) { + if(format->length / 8 == sizeof(int16_t)) { + int16_t rawValue = (reinterpret_cast(pointerData))[j]; + double scaledValue = (rawValue - offsetAttrValue) * *scaleAttrValue; + Q_EMIT streamData(scaledValue); + } + } + } + } + + iio_buffer_destroy(buffer); + return 0; } void ADMTController::handleStreamData(double value) { streamedValue = value; } -void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) { - streamBufferedIntervals.clear(); - QVector bufferedValues; - vector rawBufferedValues; - sampleCount = 0; - - int result = -1; - const char *deviceName = "admt4000"; - const char *channelName = "rot"; - const char *scaleAttrName = "scale"; - const char *offsetAttrName = "offset"; - size_t samples = 1; - bool isOutput = false; - bool isCyclic = true; - - unsigned int i, j, major, minor; - char git_tag[8]; - iio_library_get_version(&major, &minor, git_tag); - bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; - - double *scaleAttrValue = new double(1); - int offsetAttrValue = 0; - char *offsetDst = new char[maxAttrSize]; - - if (!m_iioCtx) - return; // result; // Check if the context is valid - if (iio_context_get_devices_count(m_iioCtx) < 1) - return; // result; // Check if there are devices in the context - struct iio_device *admtDevice = - iio_context_find_device(m_iioCtx, deviceName); // Find the ADMT device - if (admtDevice == NULL) - return; // result; - struct iio_channel *channel = iio_device_find_channel( - admtDevice, channelName, isOutput); // Find the rotation channel - if (channel == NULL) - return; // result; - iio_channel_enable(channel); // Enable the channel - int scaleRet = iio_channel_attr_read_double( - channel, scaleAttrName, scaleAttrValue); // Read the scale attribute - if (scaleRet != 0) - return; // scaleRet; - iio_channel_attr_read(channel, offsetAttrName, offsetDst, - maxAttrSize); // Read the offset attribute - offsetAttrValue = atoi(offsetDst); - struct iio_buffer *buffer = iio_device_create_buffer( - admtDevice, samples, isCyclic); // Create a buffer - - while (!stopStream && sampleCount < totalSamples) { - elapsedStreamTimer.start(); - - ssize_t numBytesRead; - char *pointerData, *pointerEnd; - ptrdiff_t pointerIncrement; - - numBytesRead = iio_buffer_refill(buffer); - if (numBytesRead < 0) - break; - - pointerIncrement = iio_buffer_step(buffer); - pointerEnd = static_cast(iio_buffer_end(buffer)); - - const struct iio_data_format *format = iio_channel_get_data_format(channel); - unsigned int repeat = has_repeat ? format->repeat : 1; - int j = 0; - - for (pointerData = static_cast(iio_buffer_first(buffer, channel)); - pointerData < pointerEnd; pointerData += pointerIncrement) { - for (j = 0; j < repeat; j++) { - if (format->length / 8 == sizeof(int16_t)) { - rawBufferedValues.push_back( - (reinterpret_cast(pointerData))[j]); - sampleCount++; - continue; - } - } - } - - qint64 elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); - while (elapsedNanoseconds < targetSampleRate) { - elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); - } - streamBufferedIntervals.append(elapsedNanoseconds); - } - iio_buffer_destroy(buffer); - - for (int i = 0; i < rawBufferedValues.size(); i++) { - double scaledValue = - (rawBufferedValues[i] - offsetAttrValue) * *scaleAttrValue; - bufferedValues.append(scaledValue); - } - - Q_EMIT streamBufferedData(bufferedValues); - Q_EMIT streamBufferedDataInterval(streamBufferedIntervals); +void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) +{ + streamBufferedIntervals.clear(); + QVector bufferedValues; + vector rawBufferedValues; + sampleCount = 0; + + int result = -1; + const char *deviceName = "admt4000"; + const char *channelName = "rot"; + const char *scaleAttrName = "scale"; + const char *offsetAttrName = "offset"; + size_t samples = 1; + bool isOutput = false; + bool isCyclic = true; + + unsigned int i, j, major, minor; + char git_tag[8]; + iio_library_get_version(&major, &minor, git_tag); + bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; + + double *scaleAttrValue = new double(1); + int offsetAttrValue = 0; + char *offsetDst = new char[maxAttrSize]; + + if(!m_iioCtx) + return; // result; // Check if the context is valid + if(iio_context_get_devices_count(m_iioCtx) < 1) + return; // result; // Check if there are devices in the context + struct iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); // Find the ADMT device + if(admtDevice == NULL) + return; // result; + struct iio_channel *channel = + iio_device_find_channel(admtDevice, channelName, isOutput); // Find the rotation channel + if(channel == NULL) + return; // result; + iio_channel_enable(channel); // Enable the channel + int scaleRet = iio_channel_attr_read_double(channel, scaleAttrName, scaleAttrValue); // Read the scale attribute + if(scaleRet != 0) + return; // scaleRet; + iio_channel_attr_read(channel, offsetAttrName, offsetDst, + maxAttrSize); // Read the offset attribute + offsetAttrValue = atoi(offsetDst); + struct iio_buffer *buffer = iio_device_create_buffer(admtDevice, samples, isCyclic); // Create a buffer + + while(!stopStream && sampleCount < totalSamples) { + elapsedStreamTimer.start(); + + ssize_t numBytesRead; + char *pointerData, *pointerEnd; + ptrdiff_t pointerIncrement; + + numBytesRead = iio_buffer_refill(buffer); + if(numBytesRead < 0) + break; + + pointerIncrement = iio_buffer_step(buffer); + pointerEnd = static_cast(iio_buffer_end(buffer)); + + const struct iio_data_format *format = iio_channel_get_data_format(channel); + unsigned int repeat = has_repeat ? format->repeat : 1; + int j = 0; + + for(pointerData = static_cast(iio_buffer_first(buffer, channel)); pointerData < pointerEnd; + pointerData += pointerIncrement) { + for(j = 0; j < repeat; j++) { + if(format->length / 8 == sizeof(int16_t)) { + rawBufferedValues.push_back((reinterpret_cast(pointerData))[j]); + sampleCount++; + continue; + } + } + } + + qint64 elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); + while(elapsedNanoseconds < targetSampleRate) { + elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); + } + streamBufferedIntervals.append(elapsedNanoseconds); + } + iio_buffer_destroy(buffer); + + for(int i = 0; i < rawBufferedValues.size(); i++) { + double scaledValue = (rawBufferedValues[i] - offsetAttrValue) * *scaleAttrValue; + bufferedValues.append(scaledValue); + } + + Q_EMIT streamBufferedData(bufferedValues); + Q_EMIT streamBufferedDataInterval(streamBufferedIntervals); } -void ADMTController::handleStreamBufferedData(const QVector &value) { - streamBufferedValues = value; -} +void ADMTController::handleStreamBufferedData(const QVector &value) { streamBufferedValues = value; } -bool ADMTController::checkVelocityReachedFlag(uint16_t registerValue) { - // Bit 8 - 1: Signals that the target velocity is reached. This flag becomes - // set while VACTUAL and VMAX match. - return ((registerValue >> 8) & 0x01) ? true : false; +bool ADMTController::checkVelocityReachedFlag(uint16_t registerValue) +{ + // Bit 8 - 1: Signals that the target velocity is reached. This flag becomes + // set while VACTUAL and VMAX match. + return ((registerValue >> 8) & 0x01) ? true : false; } -void ADMTController::handleStreamBufferedDataInterval( - const QVector &value) { - streamBufferedIntervals = value; +void ADMTController::handleStreamBufferedDataInterval(const QVector &value) +{ + streamBufferedIntervals = value; } #include "moc_admtcontroller.cpp" diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index 2749880fda..2105dc985b 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -34,120 +34,125 @@ using namespace scopy::admt; const bool isDebug = false; -bool ADMTPlugin::compatible(QString m_param, QString category) { - m_name = "ADMT4000"; - bool ret = false; - Connection *conn = ConnectionProvider::GetInstance()->open(m_param); - - if (!conn) { - qWarning(CAT_ADMTPLUGIN) << "No context available for ADMT"; - return false; - } - - iio_device *admtDevice = iio_context_find_device(conn->context(), "admt4000"); - if (admtDevice) { - ret = true; - } - - ConnectionProvider::close(m_param); - if (isDebug) - return true; - return ret; -} +bool ADMTPlugin::compatible(QString m_param, QString category) +{ + m_name = "ADMT4000"; + bool ret = false; + Connection *conn = ConnectionProvider::GetInstance()->open(m_param); + + if(!conn) { + qWarning(CAT_ADMTPLUGIN) << "No context available for ADMT"; + return false; + } + + iio_device *admtDevice = iio_context_find_device(conn->context(), "admt4000"); + if(admtDevice) { + ret = true; + } -bool ADMTPlugin::loadPage() { - // Here you must write the code for the plugin info page - // Below is an example for an iio device - /*m_page = new QWidget(); - m_page->setLayout(new QVBoxLayout(m_page)); - m_page->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_infoPage = new InfoPage(m_page); - m_infoPage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - m_page->layout()->addWidget(m_infoPage); - m_page->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Preferred, - QSizePolicy::Expanding)); - - auto cp = ContextProvider::GetInstance(); - struct iio_context *context = cp->open(m_param); - ssize_t attributeCount = iio_context_get_attrs_count(context); - for(int i = 0; i < attributeCount; ++i) { - const char *name; - const char *value; - int ret = iio_context_get_attr(context, i, &name, &value); - if(ret < 0) { - qWarning(CAT_ADMTPLUGIN) << "Could not read attribute with - index:" << i; continue; - } - - m_infoPage->update(name, value); - } - cp->close(m_param); - m_page->ensurePolished();*/ - return true; + ConnectionProvider::close(m_param); + if(isDebug) + return true; + return ret; } -bool ADMTPlugin::loadIcon() { - SCOPY_PLUGIN_ICON(":/gui/icons/adalm.svg"); - return true; +bool ADMTPlugin::loadPage() +{ + // Here you must write the code for the plugin info page + // Below is an example for an iio device + /*m_page = new QWidget(); + m_page->setLayout(new QVBoxLayout(m_page)); + m_page->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_infoPage = new InfoPage(m_page); + m_infoPage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + m_page->layout()->addWidget(m_infoPage); + m_page->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Preferred, + QSizePolicy::Expanding)); + + auto cp = ContextProvider::GetInstance(); + struct iio_context *context = cp->open(m_param); + ssize_t attributeCount = iio_context_get_attrs_count(context); + for(int i = 0; i < attributeCount; ++i) { + const char *name; + const char *value; + int ret = iio_context_get_attr(context, i, &name, &value); + if(ret < 0) { + qWarning(CAT_ADMTPLUGIN) << "Could not read attribute with + index:" << i; continue; + } + + m_infoPage->update(name, value); + } + cp->close(m_param); + m_page->ensurePolished();*/ + return true; } -void ADMTPlugin::loadToolList() { - m_toolList.append(SCOPY_NEW_TOOLMENUENTRY( - "harmoniccalibration", "Harmonic Calibration", - ":/gui/icons/scopy-default/icons/tool_oscilloscope.svg")); +bool ADMTPlugin::loadIcon() +{ + SCOPY_PLUGIN_ICON(":/gui/icons/adalm.svg"); + return true; } -void ADMTPlugin::unload() { /*delete m_infoPage;*/ +void ADMTPlugin::loadToolList() +{ + m_toolList.append(SCOPY_NEW_TOOLMENUENTRY("harmoniccalibration", "Harmonic Calibration", + ":/gui/icons/scopy-default/icons/tool_oscilloscope.svg")); } -QString ADMTPlugin::description() { - return "Plugin for ADMT Harmonic Calibration"; +void ADMTPlugin::unload() +{ /*delete m_infoPage;*/ } -bool ADMTPlugin::onConnect() { - // This method is called when you try to connect to a device and the plugin is - // compatible to that device - // In case of success the function must return true and false otherwise +QString ADMTPlugin::description() { return "Plugin for ADMT Harmonic Calibration"; } + +bool ADMTPlugin::onConnect() +{ + // This method is called when you try to connect to a device and the plugin is + // compatible to that device + // In case of success the function must return true and false otherwise - Connection *conn = ConnectionProvider::GetInstance()->open(m_param); - if (conn == nullptr) - return false; - m_ctx = conn->context(); - m_toolList[0]->setEnabled(true); - m_toolList[0]->setRunBtnVisible(false); + Connection *conn = ConnectionProvider::GetInstance()->open(m_param); + if(conn == nullptr) + return false; + m_ctx = conn->context(); + m_toolList[0]->setEnabled(true); + m_toolList[0]->setRunBtnVisible(false); - m_admtController = new ADMTController(m_param, this); - m_admtController->connectADMT(); - harmonicCalibration = new HarmonicCalibration(m_admtController, isDebug); - m_toolList[0]->setTool(harmonicCalibration); + m_admtController = new ADMTController(m_param, this); + m_admtController->connectADMT(); + harmonicCalibration = new HarmonicCalibration(m_admtController, isDebug); + m_toolList[0]->setTool(harmonicCalibration); - return true; + return true; } -bool ADMTPlugin::onDisconnect() { - // This method is called when the disconnect button is pressed - // It must remove all connections that were established on the connection - - dynamic_cast(harmonicCalibration)->requestDisconnect(); - - for (auto &tool : m_toolList) { - tool->setEnabled(false); - tool->setRunning(false); - tool->setRunBtnVisible(false); - QWidget *w = tool->tool(); - if (w) { - tool->setTool(nullptr); - delete (w); - } - } - - m_admtController->disconnectADMT(); - return true; +bool ADMTPlugin::onDisconnect() +{ + // This method is called when the disconnect button is pressed + // It must remove all connections that were established on the connection + + dynamic_cast(harmonicCalibration)->requestDisconnect(); + + for(auto &tool : m_toolList) { + tool->setEnabled(false); + tool->setRunning(false); + tool->setRunBtnVisible(false); + QWidget *w = tool->tool(); + if(w) { + tool->setTool(nullptr); + delete(w); + } + } + + m_admtController->disconnectADMT(); + return true; } -void ADMTPlugin::initMetadata() { - loadMetadata( - R"plugin( +void ADMTPlugin::initMetadata() +{ + loadMetadata( + R"plugin( { "priority":102, "category":[ diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp index c979a2b97f..bffddafc19 100644 --- a/plugins/admt/src/admtstylehelper.cpp +++ b/plugins/admt/src/admtstylehelper.cpp @@ -29,42 +29,44 @@ ADMTStyleHelper *ADMTStyleHelper::pinstance_{nullptr}; ADMTStyleHelper::ADMTStyleHelper(QObject *parent) {} -ADMTStyleHelper *ADMTStyleHelper::GetInstance() { - if (pinstance_ == nullptr) { - pinstance_ = new ADMTStyleHelper( - QApplication::instance()); // singleton has the app as parent - } - return pinstance_; +ADMTStyleHelper *ADMTStyleHelper::GetInstance() +{ + if(pinstance_ == nullptr) { + pinstance_ = new ADMTStyleHelper(QApplication::instance()); // singleton has the app as parent + } + return pinstance_; } ADMTStyleHelper::~ADMTStyleHelper() {} -void ADMTStyleHelper::initColorMap() { - auto sh = ADMTStyleHelper::GetInstance(); - sh->colorMap.insert("CH0", "#FF7200"); - sh->colorMap.insert("CH1", "#9013FE"); - sh->colorMap.insert("CH2", "#27B34F"); - sh->colorMap.insert("CH3", "#F8E71C"); - sh->colorMap.insert("CH4", "#4A64FF"); - sh->colorMap.insert("CH5", "#02BCD4"); - sh->colorMap.insert("CH6", "#F44336"); - sh->colorMap.insert("CH7", "#F5A623"); - sh->colorMap.insert("CH8", "#1981AE"); - sh->colorMap.insert("CH9", "#6FCEA6"); - sh->colorMap.insert("CH10", "#F7A1DA"); - sh->colorMap.insert("CH11", "#E3F5FC"); +void ADMTStyleHelper::initColorMap() +{ + auto sh = ADMTStyleHelper::GetInstance(); + sh->colorMap.insert("CH0", "#FF7200"); + sh->colorMap.insert("CH1", "#9013FE"); + sh->colorMap.insert("CH2", "#27B34F"); + sh->colorMap.insert("CH3", "#F8E71C"); + sh->colorMap.insert("CH4", "#4A64FF"); + sh->colorMap.insert("CH5", "#02BCD4"); + sh->colorMap.insert("CH6", "#F44336"); + sh->colorMap.insert("CH7", "#F5A623"); + sh->colorMap.insert("CH8", "#1981AE"); + sh->colorMap.insert("CH9", "#6FCEA6"); + sh->colorMap.insert("CH10", "#F7A1DA"); + sh->colorMap.insert("CH11", "#E3F5FC"); } -QString ADMTStyleHelper::getColor(QString id) { - auto sh = ADMTStyleHelper::GetInstance(); - return sh->colorMap[id]; +QString ADMTStyleHelper::getColor(QString id) +{ + auto sh = ADMTStyleHelper::GetInstance(); + return sh->colorMap[id]; } -void ADMTStyleHelper::TopContainerButtonStyle(QPushButton *btn, - QString objectName) { - if (!objectName.isEmpty()) - btn->setObjectName(objectName); - QString style = QString(R"css( +void ADMTStyleHelper::TopContainerButtonStyle(QPushButton *btn, QString objectName) +{ + if(!objectName.isEmpty()) + btn->setObjectName(objectName); + QString style = QString(R"css( QPushButton { width: 88px; height: 48px; @@ -88,22 +90,23 @@ void ADMTStyleHelper::TopContainerButtonStyle(QPushButton *btn, background-color:#272730; } })css"); - style.replace("&&ScopyBlue&&", - Style::getAttribute(json::theme::interactive_primary_idle)); - btn->setStyleSheet(style); + style.replace("&&ScopyBlue&&", Style::getAttribute(json::theme::interactive_primary_idle)); + btn->setStyleSheet(style); } -void ADMTStyleHelper::PlotWidgetStyle(PlotWidget *widget, QString objectName) { - if (!objectName.isEmpty()) - widget->setObjectName(objectName); - widget->setContentsMargins(10, 10, 10, 6); - widget->plot()->canvas()->setStyleSheet("background-color: black;"); +void ADMTStyleHelper::PlotWidgetStyle(PlotWidget *widget, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + widget->setContentsMargins(10, 10, 10, 6); + widget->plot()->canvas()->setStyleSheet("background-color: black;"); } -void ADMTStyleHelper::ComboBoxStyle(QComboBox *widget, QString objectName) { - if (!objectName.isEmpty()) - widget->setObjectName(objectName); - QString style = QString(R"css( +void ADMTStyleHelper::ComboBoxStyle(QComboBox *widget, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + QString style = QString(R"css( QWidget { } QComboBox { @@ -155,14 +158,14 @@ void ADMTStyleHelper::ComboBoxStyle(QComboBox *widget, QString objectName) { selection-color: transparent; } )css"); - style = style.replace(QString("&&colorname&&"), - Style::getAttribute(json::global::ch0)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); } -void ADMTStyleHelper::LineEditStyle(QLineEdit *widget, QString objectName) { - QString style = QString(R"css( +void ADMTStyleHelper::LineEditStyle(QLineEdit *widget, QString objectName) +{ + QString style = QString(R"css( QLineEdit { font-family: Open Sans; font-size: 16px; @@ -180,20 +183,19 @@ void ADMTStyleHelper::LineEditStyle(QLineEdit *widget, QString objectName) { color: #9c4600; } )css"); - style = style.replace(QString("&&colorname&&"), - Style::getAttribute(json::global::ch0)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setContentsMargins(0, 0, 0, 0); - widget->setTextMargins(12, 4, 12, 4); - widget->setAlignment(Qt::AlignRight); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setContentsMargins(0, 0, 0, 0); + widget->setTextMargins(12, 4, 12, 4); + widget->setAlignment(Qt::AlignRight); } -void ADMTStyleHelper::ColoredSquareCheckbox(QCheckBox *chk, QColor color, - QString objectName) { - if (!objectName.isEmpty()) - chk->setObjectName(objectName); - QString style = QString(R"css( +void ADMTStyleHelper::ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName) +{ + if(!objectName.isEmpty()) + chk->setObjectName(objectName); + QString style = QString(R"css( QCheckBox { width:16px; height:16px; @@ -209,16 +211,16 @@ void ADMTStyleHelper::ColoredSquareCheckbox(QCheckBox *chk, QColor color, QCheckBox::indicator:unchecked { background-color: &&UIElementBackground&&; } QCheckBox::indicator:checked { background-color: &&colorname&&; } )css"); - style.replace("&&colorname&&", color.name()); - style.replace("&&UIElementBackground&&", - Style::getAttribute(json::theme::background_primary)); - chk->setStyleSheet(style); + style.replace("&&colorname&&", color.name()); + style.replace("&&UIElementBackground&&", Style::getAttribute(json::theme::background_primary)); + chk->setStyleSheet(style); } -void ADMTStyleHelper::StartButtonStyle(QPushButton *btn, QString objectName) { - if (!objectName.isEmpty()) - btn->setObjectName(objectName); - QString style = QString(R"css( +void ADMTStyleHelper::StartButtonStyle(QPushButton *btn, QString objectName) +{ + if(!objectName.isEmpty()) + btn->setObjectName(objectName); + QString style = QString(R"css( QPushButton { border-radius: 2px; padding-left: 20px; @@ -239,49 +241,46 @@ void ADMTStyleHelper::StartButtonStyle(QPushButton *btn, QString objectName) { QPushButton:disabled { background-color: grey; })css"); - btn->setCheckable(true); - btn->setChecked(false); - btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - btn->setFixedHeight(36); - btn->setStyleSheet(style); - QIcon playIcon; - playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/play.svg", "white", 1), - QIcon::Normal, QIcon::Off); - playIcon.addPixmap( - Util::ChangeSVGColor(":/gui/icons/scopy-default/icons/play_stop.svg", - "white", 1), - QIcon::Normal, QIcon::On); - btn->setIcon(playIcon); - btn->setIconSize(QSize(64, 64)); + btn->setCheckable(true); + btn->setChecked(false); + btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + btn->setFixedHeight(36); + btn->setStyleSheet(style); + QIcon playIcon; + playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/play.svg", "white", 1), QIcon::Normal, QIcon::Off); + playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/scopy-default/icons/play_stop.svg", "white", 1), + QIcon::Normal, QIcon::On); + btn->setIcon(playIcon); + btn->setIconSize(QSize(64, 64)); } -void ADMTStyleHelper::TextStyle(QWidget *widget, const char *styleHelperColor, - bool isBold, QString objectName) { - if (!objectName.isEmpty()) - widget->setObjectName(objectName); - QString existingStyle = widget->styleSheet(); - QString style = QString(R"css( +void ADMTStyleHelper::TextStyle(QWidget *widget, const char *styleHelperColor, bool isBold, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + QString existingStyle = widget->styleSheet(); + QString style = QString(R"css( font-size: 16px; font-weight: &&fontweight&&; text-align: right; color: &&colorname&&; )css"); - style = style.replace(QString("&&colorname&&"), - Style::getAttribute(styleHelperColor)); - QString fontWeight = QString("normal"); - if (isBold) { - fontWeight = QString("bold"); - } - style = style.replace(QString("&&fontweight&&"), fontWeight); - widget->setStyleSheet(existingStyle + style); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(styleHelperColor)); + QString fontWeight = QString("normal"); + if(isBold) { + fontWeight = QString("bold"); + } + style = style.replace(QString("&&fontweight&&"), fontWeight); + widget->setStyleSheet(existingStyle + style); } -void ADMTStyleHelper::MenuSmallLabel(QLabel *label, QString objectName) { - if (!objectName.isEmpty()) - label->setObjectName(objectName); - label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); +void ADMTStyleHelper::MenuSmallLabel(QLabel *label, QString objectName) +{ + if(!objectName.isEmpty()) + label->setObjectName(objectName); + label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - QString style = QString(R"css( + QString style = QString(R"css( QLabel { color: white; background-color: rgba(255,255,255,0); @@ -294,73 +293,73 @@ void ADMTStyleHelper::MenuSmallLabel(QLabel *label, QString objectName) { color: grey; } )css"); - label->setStyleSheet(style); + label->setStyleSheet(style); } -void ADMTStyleHelper::LineStyle(QFrame *line, QString objectName) { - if (!objectName.isEmpty()) - line->setObjectName(objectName); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Plain); - line->setFixedHeight(1); - QString lineStyle = QString(R"css( +void ADMTStyleHelper::LineStyle(QFrame *line, QString objectName) +{ + if(!objectName.isEmpty()) + line->setObjectName(objectName); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Plain); + line->setFixedHeight(1); + QString lineStyle = QString(R"css( QFrame { border: 1px solid #808085; } )css"); - line->setStyleSheet(lineStyle); + line->setStyleSheet(lineStyle); } -void ADMTStyleHelper::UIBackgroundStyle(QWidget *widget, QString objectName) { - if (!objectName.isEmpty()) - widget->setObjectName(objectName); - QString style = QString(R"css( +void ADMTStyleHelper::UIBackgroundStyle(QWidget *widget, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + QString style = QString(R"css( background-color: &&colorname&&; )css"); - style.replace(QString("&&colorname&&"), - Style::getAttribute(json::theme::background_primary)); - widget->setStyleSheet(style); + style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::background_primary)); + widget->setStyleSheet(style); } -void ADMTStyleHelper::GraphChannelStyle(QWidget *widget, QLayout *layout, - QString objectName) { - if (!objectName.isEmpty()) - widget->setObjectName(objectName); - widget->setLayout(layout); - ADMTStyleHelper::UIBackgroundStyle(widget); - layout->setContentsMargins(20, 13, 20, 5); - layout->setSpacing(20); +void ADMTStyleHelper::GraphChannelStyle(QWidget *widget, QLayout *layout, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); + widget->setLayout(layout); + ADMTStyleHelper::UIBackgroundStyle(widget); + layout->setContentsMargins(20, 13, 20, 5); + layout->setSpacing(20); } -void ADMTStyleHelper::CalculatedCoeffWidgetRowStyle( - QWidget *widget, QHBoxLayout *layout, QLabel *hLabel, QLabel *hMagLabel, - QLabel *hPhaseLabel, QString objectName) { - if (!objectName.isEmpty()) - widget->setObjectName(objectName); +void ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(QWidget *widget, QHBoxLayout *layout, QLabel *hLabel, + QLabel *hMagLabel, QLabel *hPhaseLabel, QString objectName) +{ + if(!objectName.isEmpty()) + widget->setObjectName(objectName); - widget->setLayout(layout); - QString style = QString(R"css( + widget->setLayout(layout); + QString style = QString(R"css( background-color: &&colorname&&; border-radius: 4px; )css"); - style.replace(QString("&&colorname&&"), - Style::getAttribute(json::theme::background_subtle)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - layout->setContentsMargins(12, 4, 12, 4); - - ADMTStyleHelper::TextStyle(hLabel, json::global::white, true); - ADMTStyleHelper::TextStyle(hMagLabel, json::global::ch0); - ADMTStyleHelper::TextStyle(hPhaseLabel, json::global::ch1); - - hLabel->setFixedWidth(24); - hMagLabel->setContentsMargins(0, 0, 32, 0); - hPhaseLabel->setFixedWidth(72); - - layout->addWidget(hLabel); - layout->addWidget(hMagLabel, 0, Qt::AlignRight); - layout->addWidget(hPhaseLabel); + style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::background_subtle)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + layout->setContentsMargins(12, 4, 12, 4); + + ADMTStyleHelper::TextStyle(hLabel, json::global::white, true); + ADMTStyleHelper::TextStyle(hMagLabel, json::global::ch0); + ADMTStyleHelper::TextStyle(hPhaseLabel, json::global::ch1); + + hLabel->setFixedWidth(24); + hMagLabel->setContentsMargins(0, 0, 32, 0); + hPhaseLabel->setFixedWidth(72); + + layout->addWidget(hLabel); + layout->addWidget(hMagLabel, 0, Qt::AlignRight); + layout->addWidget(hPhaseLabel); } #include "moc_admtstylehelper.cpp" \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 599d7ca563..34de97d74a 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -57,30 +57,25 @@ static bool hasMTDiagnostics = false; static bool isMotorRotationClockwise = true; static double fast_motor_rpm = 300; -static double motorFullStepAngle = 0.9; // TODO input as configuration +static double motorFullStepAngle = 0.9; // TODO input as configuration static double microStepResolution = 256; // TODO input as configuration -static int motorfCLK = 12500000; // 12.5 Mhz, TODO input as configuration -static double motorAccelTime = 1; // In seconds +static int motorfCLK = 12500000; // 12.5 Mhz, TODO input as configuration +static double motorAccelTime = 1; // In seconds static double motorFullStepPerRevolution = 360 / motorFullStepAngle; -static double motorMicrostepPerRevolution = - motorFullStepPerRevolution * microStepResolution; -static double motorTimeUnit = - static_cast(1 << 24) / motorfCLK; // t = 2^24/16Mhz +static double motorMicrostepPerRevolution = motorFullStepPerRevolution * microStepResolution; +static double motorTimeUnit = static_cast(1 << 24) / motorfCLK; // t = 2^24/16Mhz static int acquisitionDisplayLength = 200; -static QVector acquisitionAngleList, acquisitionABSAngleList, - acquisitionTurnCountList, acquisitionTmp0List, acquisitionTmp1List, - acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, - graphDataList, graphPostDataList; +static QVector acquisitionAngleList, acquisitionABSAngleList, acquisitionTurnCountList, acquisitionTmp0List, + acquisitionTmp1List, acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, graphDataList, + graphPostDataList; -static const QColor scopyBlueColor = - Style::getColor(json::theme::interactive_primary_idle); +static const QColor scopyBlueColor = Style::getColor(json::theme::interactive_primary_idle); static const QColor sineColor = QColor("#85e94c"); static const QColor cosineColor = QColor("#91e6cf"); static const QColor faultLEDColor = QColor("#c81a28"); -static const QColor gpioLEDColor = - Style::getColor(json::theme::interactive_secondary_idle); +static const QColor gpioLEDColor = Style::getColor(json::theme::interactive_secondary_idle); static const QColor statusLEDColor = QColor("#2e9e6f"); static const QPen scopyBluePen(scopyBlueColor); @@ -107,10 +102,9 @@ static QString deviceName = ""; static QString deviceType = ""; static bool is5V = false; -static double H1_MAG_ANGLE, H2_MAG_ANGLE, H3_MAG_ANGLE, H8_MAG_ANGLE, - H1_PHASE_ANGLE, H2_PHASE_ANGLE, H3_PHASE_ANGLE, H8_PHASE_ANGLE; -static uint32_t H1_MAG_HEX, H2_MAG_HEX, H3_MAG_HEX, H8_MAG_HEX, H1_PHASE_HEX, - H2_PHASE_HEX, H3_PHASE_HEX, H8_PHASE_HEX; +static double H1_MAG_ANGLE, H2_MAG_ANGLE, H3_MAG_ANGLE, H8_MAG_ANGLE, H1_PHASE_ANGLE, H2_PHASE_ANGLE, H3_PHASE_ANGLE, + H8_PHASE_ANGLE; +static uint32_t H1_MAG_HEX, H2_MAG_HEX, H3_MAG_HEX, H8_MAG_HEX, H1_PHASE_HEX, H2_PHASE_HEX, H3_PHASE_HEX, H8_PHASE_HEX; static int acquisitionGraphYMin = 0; static int acquisitionGraphYMax = 360; @@ -136,5200 +130,4619 @@ static int globalSpacingSmall = Style::getDimension(json::global::unit_0_5); static int globalSpacingMedium = Style::getDimension(json::global::unit_1); static map acquisitionDataMap = { - {RADIUS, false}, {ANGLE, false}, {TURNCOUNT, false}, {ABSANGLE, false}, - {SINE, false}, {COSINE, false}, {SECANGLI, false}, {SECANGLQ, false}, - {ANGLESEC, false}, {DIAG1, false}, {DIAG2, false}, {TMP0, false}, - {TMP1, false}, {CNVCNT, false}, {SCRADIUS, false}, {SPIFAULT, false}}; - -HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, - bool isDebug, QWidget *parent) - : QWidget(parent), isDebug(isDebug), m_admtController(m_admtController) { - ADMTStyleHelper::GetInstance()->initColorMap(); - readDeviceProperties(); - initializeADMT(); - initializeMotor(); - readSequence(); - - rotationChannelName = - m_admtController->getChannelId(ADMTController::Channel::ROTATION); - angleChannelName = - m_admtController->getChannelId(ADMTController::Channel::ANGLE); - countChannelName = - m_admtController->getChannelId(ADMTController::Channel::COUNT); - temperatureChannelName = - m_admtController->getChannelId(ADMTController::Channel::TEMPERATURE); - - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - QHBoxLayout *lay = new QHBoxLayout(this); - tabWidget = new QTabWidget(this); - - setLayout(lay); - lay->setMargin(0); - lay->insertWidget(1, tabWidget); - tabWidget->setStyleSheet(""); - tabWidget->tabBar()->setStyleSheet(""); - Style::setStyle(tabWidget, style::properties::admt::tabWidget); - Style::setStyle(tabWidget->tabBar(), style::properties::admt::tabBar); - - tabWidget->addTab(createAcquisitionWidget(), "Acquisition"); - tabWidget->addTab(createCalibrationWidget(), "Calibration"); - tabWidget->addTab(createUtilityWidget(), "Utility"); - tabWidget->addTab(createRegistersWidget(), "Registers"); - - connect(tabWidget, &QTabWidget::currentChanged, [this](int index) { - tabWidget->setCurrentIndex(index); - - if (index == 0 || index == 1) { - startDeviceStatusMonitor(); - startCurrentMotorPositionMonitor(); - } else { - stopDeviceStatusMonitor(); - stopCurrentMotorPositionMonitor(); - } - - if (index == 0) // Acquisition Tab - { - startAcquisitionUITask(); - readSequence(); - updateSequenceWidget(); - updateAcquisitionMotorRPM(); - updateAcquisitionMotorRotationDirection(); - } else { - stopAcquisitionUITask(); - stop(); - } - - if (index == 1) // Calibration Tab - { - startCalibrationUITask(); - updateCalibrationMotorRPM(); - updateCalibrationMotorRotationDirection(); - } else { - stopCalibrationUITask(); - } - - if (index == 2) // Utility Tab - { - readSequence(); - toggleFaultRegisterMode(GENERALRegisterMap.at("Sequence Type")); - toggleMTDiagnostics(GENERALRegisterMap.at("Sequence Type")); - toggleUtilityTask(true); - } else { - toggleUtilityTask(false); - } - - if (index == 3) // Registers Tab - { - readSequence(); - toggleRegisters(GENERALRegisterMap.at("Sequence Type")); - } - }); - - connect(this, &HarmonicCalibration::updateFaultStatusSignal, this, - &HarmonicCalibration::updateFaultStatus); - connect(this, &HarmonicCalibration::motorPositionChanged, this, - &HarmonicCalibration::updateMotorPosition); - - connect(this, &HarmonicCalibration::calibrationLogWriteSignal, this, - &HarmonicCalibration::calibrationLogWrite); - connect(this, &HarmonicCalibration::commandLogWriteSignal, this, - &HarmonicCalibration::commandLogWrite); - connect(this, &HarmonicCalibration::DIGIORegisterChanged, this, - &HarmonicCalibration::updateDIGIOUI); - connect(this, &HarmonicCalibration::FaultRegisterChanged, this, - &HarmonicCalibration::updateFaultRegisterUI); - connect(this, &HarmonicCalibration::DIAG1RegisterChanged, this, - &HarmonicCalibration::updateMTDiagnosticRegisterUI); - connect(this, &HarmonicCalibration::DIAG2RegisterChanged, this, - &HarmonicCalibration::updateMTDiagnosticsUI); - - startAcquisitionUITask(); - startDeviceStatusMonitor(); - startCurrentMotorPositionMonitor(); + {RADIUS, false}, {ANGLE, false}, {TURNCOUNT, false}, {ABSANGLE, false}, {SINE, false}, {COSINE, false}, + {SECANGLI, false}, {SECANGLQ, false}, {ANGLESEC, false}, {DIAG1, false}, {DIAG2, false}, {TMP0, false}, + {TMP1, false}, {CNVCNT, false}, {SCRADIUS, false}, {SPIFAULT, false}}; + +HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool isDebug, QWidget *parent) + : QWidget(parent) + , isDebug(isDebug) + , m_admtController(m_admtController) +{ + ADMTStyleHelper::GetInstance()->initColorMap(); + readDeviceProperties(); + initializeADMT(); + initializeMotor(); + readSequence(); + + rotationChannelName = m_admtController->getChannelId(ADMTController::Channel::ROTATION); + angleChannelName = m_admtController->getChannelId(ADMTController::Channel::ANGLE); + countChannelName = m_admtController->getChannelId(ADMTController::Channel::COUNT); + temperatureChannelName = m_admtController->getChannelId(ADMTController::Channel::TEMPERATURE); + + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + QHBoxLayout *lay = new QHBoxLayout(this); + tabWidget = new QTabWidget(this); + + setLayout(lay); + lay->setMargin(0); + lay->insertWidget(1, tabWidget); + tabWidget->setStyleSheet(""); + tabWidget->tabBar()->setStyleSheet(""); + Style::setStyle(tabWidget, style::properties::admt::tabWidget); + Style::setStyle(tabWidget->tabBar(), style::properties::admt::tabBar); + + tabWidget->addTab(createAcquisitionWidget(), "Acquisition"); + tabWidget->addTab(createCalibrationWidget(), "Calibration"); + tabWidget->addTab(createUtilityWidget(), "Utility"); + tabWidget->addTab(createRegistersWidget(), "Registers"); + + connect(tabWidget, &QTabWidget::currentChanged, [this](int index) { + tabWidget->setCurrentIndex(index); + + if(index == 0 || index == 1) { + startDeviceStatusMonitor(); + startCurrentMotorPositionMonitor(); + } else { + stopDeviceStatusMonitor(); + stopCurrentMotorPositionMonitor(); + } + + if(index == 0) // Acquisition Tab + { + startAcquisitionUITask(); + readSequence(); + updateSequenceWidget(); + updateAcquisitionMotorRPM(); + updateAcquisitionMotorRotationDirection(); + } else { + stopAcquisitionUITask(); + stop(); + } + + if(index == 1) // Calibration Tab + { + startCalibrationUITask(); + updateCalibrationMotorRPM(); + updateCalibrationMotorRotationDirection(); + } else { + stopCalibrationUITask(); + } + + if(index == 2) // Utility Tab + { + readSequence(); + toggleFaultRegisterMode(GENERALRegisterMap.at("Sequence Type")); + toggleMTDiagnostics(GENERALRegisterMap.at("Sequence Type")); + toggleUtilityTask(true); + } else { + toggleUtilityTask(false); + } + + if(index == 3) // Registers Tab + { + readSequence(); + toggleRegisters(GENERALRegisterMap.at("Sequence Type")); + } + }); + + connect(this, &HarmonicCalibration::updateFaultStatusSignal, this, &HarmonicCalibration::updateFaultStatus); + connect(this, &HarmonicCalibration::motorPositionChanged, this, &HarmonicCalibration::updateMotorPosition); + + connect(this, &HarmonicCalibration::calibrationLogWriteSignal, this, &HarmonicCalibration::calibrationLogWrite); + connect(this, &HarmonicCalibration::commandLogWriteSignal, this, &HarmonicCalibration::commandLogWrite); + connect(this, &HarmonicCalibration::DIGIORegisterChanged, this, &HarmonicCalibration::updateDIGIOUI); + connect(this, &HarmonicCalibration::FaultRegisterChanged, this, &HarmonicCalibration::updateFaultRegisterUI); + connect(this, &HarmonicCalibration::DIAG1RegisterChanged, this, + &HarmonicCalibration::updateMTDiagnosticRegisterUI); + connect(this, &HarmonicCalibration::DIAG2RegisterChanged, this, &HarmonicCalibration::updateMTDiagnosticsUI); + + startAcquisitionUITask(); + startDeviceStatusMonitor(); + startCurrentMotorPositionMonitor(); } HarmonicCalibration::~HarmonicCalibration() { requestDisconnect(); } -ToolTemplate *HarmonicCalibration::createAcquisitionWidget() { - tool = new ToolTemplate(this); - openLastMenuButton = new OpenLastMenuBtn( - dynamic_cast(tool->rightContainer()), true, this); - rightMenuButtonGroup = - dynamic_cast(openLastMenuButton)->getButtonGroup(); +ToolTemplate *HarmonicCalibration::createAcquisitionWidget() +{ + tool = new ToolTemplate(this); + openLastMenuButton = new OpenLastMenuBtn(dynamic_cast(tool->rightContainer()), true, this); + rightMenuButtonGroup = dynamic_cast(openLastMenuButton)->getButtonGroup(); - settingsButton = new GearBtn(this); - runButton = new RunBtn(this); + settingsButton = new GearBtn(this); + runButton = new RunBtn(this); - QPushButton *resetGMRButton = new QPushButton(this); - resetGMRButton->setText("GMR Reset"); - Style::setStyle(resetGMRButton, style::properties::button::singleButton); - connect(resetGMRButton, &QPushButton::clicked, this, - &HarmonicCalibration::GMRReset); + QPushButton *resetGMRButton = new QPushButton(this); + resetGMRButton->setText("GMR Reset"); + Style::setStyle(resetGMRButton, style::properties::button::singleButton); + connect(resetGMRButton, &QPushButton::clicked, this, &HarmonicCalibration::GMRReset); - rightMenuButtonGroup->addButton(settingsButton); + rightMenuButtonGroup->addButton(settingsButton); #pragma region Raw Data Widget - QScrollArea *rawDataScroll = new QScrollArea(this); - rawDataScroll->setWidgetResizable(true); - QWidget *rawDataWidget = new QWidget(rawDataScroll); - rawDataScroll->setWidget(rawDataWidget); - QVBoxLayout *rawDataLayout = new QVBoxLayout(rawDataWidget); - rawDataLayout->setMargin(0); - rawDataWidget->setLayout(rawDataLayout); - - MenuSectionWidget *rotationWidget = new MenuSectionWidget(rawDataWidget); - MenuSectionWidget *angleWidget = new MenuSectionWidget(rawDataWidget); - MenuSectionWidget *countWidget = new MenuSectionWidget(rawDataWidget); - MenuSectionWidget *tempWidget = new MenuSectionWidget(rawDataWidget); - Style::setStyle(rotationWidget, style::properties::widget::basicComponent); - Style::setStyle(angleWidget, style::properties::widget::basicComponent); - Style::setStyle(countWidget, style::properties::widget::basicComponent); - Style::setStyle(tempWidget, style::properties::widget::basicComponent); - MenuCollapseSection *rotationSection = new MenuCollapseSection( - "ABS Angle", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - rotationWidget); - MenuCollapseSection *angleSection = new MenuCollapseSection( - "Angle", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, angleWidget); - MenuCollapseSection *countSection = new MenuCollapseSection( - "Count", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, countWidget); - MenuCollapseSection *tempSection = new MenuCollapseSection( - "Temp 0", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, tempWidget); - rotationSection->contentLayout()->setSpacing(globalSpacingSmall); - angleSection->contentLayout()->setSpacing(globalSpacingSmall); - countSection->contentLayout()->setSpacing(globalSpacingSmall); - tempSection->contentLayout()->setSpacing(globalSpacingSmall); - - rotationWidget->contentLayout()->addWidget(rotationSection); - angleWidget->contentLayout()->addWidget(angleSection); - countWidget->contentLayout()->addWidget(countSection); - tempWidget->contentLayout()->addWidget(tempSection); - - rotationValueLabel = new QLabel("--.--°", rotationSection); - angleValueLabel = new QLabel("--.--°", angleSection); - countValueLabel = new QLabel("--", countSection); - tempValueLabel = new QLabel("--.-- °C", tempSection); - - rotationSection->contentLayout()->addWidget(rotationValueLabel); - angleSection->contentLayout()->addWidget(angleValueLabel); - countSection->contentLayout()->addWidget(countValueLabel); - tempSection->contentLayout()->addWidget(tempValueLabel); + QScrollArea *rawDataScroll = new QScrollArea(this); + rawDataScroll->setWidgetResizable(true); + QWidget *rawDataWidget = new QWidget(rawDataScroll); + rawDataScroll->setWidget(rawDataWidget); + QVBoxLayout *rawDataLayout = new QVBoxLayout(rawDataWidget); + rawDataLayout->setMargin(0); + rawDataWidget->setLayout(rawDataLayout); + + MenuSectionWidget *rotationWidget = new MenuSectionWidget(rawDataWidget); + MenuSectionWidget *angleWidget = new MenuSectionWidget(rawDataWidget); + MenuSectionWidget *countWidget = new MenuSectionWidget(rawDataWidget); + MenuSectionWidget *tempWidget = new MenuSectionWidget(rawDataWidget); + Style::setStyle(rotationWidget, style::properties::widget::basicComponent); + Style::setStyle(angleWidget, style::properties::widget::basicComponent); + Style::setStyle(countWidget, style::properties::widget::basicComponent); + Style::setStyle(tempWidget, style::properties::widget::basicComponent); + MenuCollapseSection *rotationSection = + new MenuCollapseSection("ABS Angle", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, rotationWidget); + MenuCollapseSection *angleSection = + new MenuCollapseSection("Angle", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, angleWidget); + MenuCollapseSection *countSection = + new MenuCollapseSection("Count", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, countWidget); + MenuCollapseSection *tempSection = + new MenuCollapseSection("Temp 0", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, tempWidget); + rotationSection->contentLayout()->setSpacing(globalSpacingSmall); + angleSection->contentLayout()->setSpacing(globalSpacingSmall); + countSection->contentLayout()->setSpacing(globalSpacingSmall); + tempSection->contentLayout()->setSpacing(globalSpacingSmall); + + rotationWidget->contentLayout()->addWidget(rotationSection); + angleWidget->contentLayout()->addWidget(angleSection); + countWidget->contentLayout()->addWidget(countSection); + tempWidget->contentLayout()->addWidget(tempSection); + + rotationValueLabel = new QLabel("--.--°", rotationSection); + angleValueLabel = new QLabel("--.--°", angleSection); + countValueLabel = new QLabel("--", countSection); + tempValueLabel = new QLabel("--.-- °C", tempSection); + + rotationSection->contentLayout()->addWidget(rotationValueLabel); + angleSection->contentLayout()->addWidget(angleValueLabel); + countSection->contentLayout()->addWidget(countValueLabel); + tempSection->contentLayout()->addWidget(tempValueLabel); #pragma region Acquisition Motor Control Section Widget - MenuSectionWidget *motorControlSectionWidget = - new MenuSectionWidget(rawDataWidget); - Style::setStyle(motorControlSectionWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection( - "Motor Control", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - motorControlSectionWidget); - motorControlSectionWidget->contentLayout()->addWidget( - motorControlCollapseSection); - - QWidget *motorRPMWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); - motorRPMWidget->setLayout(motorRPMLayout); - motorRPMLayout->setMargin(0); - motorRPMLayout->setSpacing(0); - QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); - acquisitionMotorRPMLineEdit = - new QLineEdit(QString::number(motor_rpm), motorRPMWidget); - connectLineEditToRPM(acquisitionMotorRPMLineEdit, motor_rpm); - motorRPMLayout->addWidget(motorRPMLabel); - motorRPMLayout->addWidget(acquisitionMotorRPMLineEdit); - - QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); - currentPositionWidget->setLayout(currentPositionLayout); - currentPositionLayout->setMargin(0); - currentPositionLayout->setSpacing(0); - QLabel *currentPositionLabel = - new QLabel("Current Position", currentPositionWidget); - acquisitionMotorCurrentPositionLineEdit = - new QLineEdit("--.--", currentPositionWidget); - acquisitionMotorCurrentPositionLineEdit->setReadOnly(true); - connectLineEditToDouble(acquisitionMotorCurrentPositionLineEdit, current_pos); - currentPositionLayout->addWidget(currentPositionLabel); - currentPositionLayout->addWidget(acquisitionMotorCurrentPositionLineEdit); - - QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); - targetPositionWidget->setLayout(targetPositionLayout); - targetPositionLayout->setMargin(0); - targetPositionLayout->setSpacing(0); - QLabel *targetPositionLabel = - new QLabel("Target Position", targetPositionWidget); - motorTargetPositionLineEdit = - new QLineEdit(QString::number(target_pos), targetPositionWidget); - connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, - ADMTController::MotorAttribute::TARGET_POS); - targetPositionLayout->addWidget(targetPositionLabel); - targetPositionLayout->addWidget(motorTargetPositionLineEdit); - - QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); - motorDirectionWidget->setLayout(motorDirectionLayout); - motorDirectionLayout->setMargin(0); - motorDirectionLayout->setSpacing(0); - QLabel *motorDirectionLabel = - new QLabel("Rotation Direction", motorDirectionWidget); - acquisitionMotorDirectionSwitch = - new CustomSwitch("CW", "CCW", motorControlSectionWidget); - acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); - connect(acquisitionMotorDirectionSwitch, &CustomSwitch::toggled, this, - [this](bool b) { isMotorRotationClockwise = b; }); - motorDirectionLayout->addWidget(motorDirectionLabel); - motorDirectionLayout->addWidget(acquisitionMotorDirectionSwitch); - - QPushButton *continuousRotationButton = - new QPushButton("Continuous Rotation", motorControlSectionWidget); - StyleHelper::BasicButton(continuousRotationButton); - connect(continuousRotationButton, &QPushButton::clicked, this, - &HarmonicCalibration::moveMotorContinuous); - - QPushButton *stopMotorButton = - new QPushButton("Stop Motor", motorControlSectionWidget); - StyleHelper::BasicButton(stopMotorButton); - connect(stopMotorButton, &QPushButton::clicked, this, - &HarmonicCalibration::stopMotor); - - motorControlCollapseSection->contentLayout()->setSpacing(globalSpacingSmall); - motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); - motorControlCollapseSection->contentLayout()->addWidget( - currentPositionWidget); - motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); - motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); - motorControlCollapseSection->contentLayout()->addWidget( - continuousRotationButton); - motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); + MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(rawDataWidget); + Style::setStyle(motorControlSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection( + "Motor Control", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorControlSectionWidget); + motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); + + QWidget *motorRPMWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); + motorRPMWidget->setLayout(motorRPMLayout); + motorRPMLayout->setMargin(0); + motorRPMLayout->setSpacing(0); + QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); + acquisitionMotorRPMLineEdit = new QLineEdit(QString::number(motor_rpm), motorRPMWidget); + connectLineEditToRPM(acquisitionMotorRPMLineEdit, motor_rpm); + motorRPMLayout->addWidget(motorRPMLabel); + motorRPMLayout->addWidget(acquisitionMotorRPMLineEdit); + + QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); + currentPositionWidget->setLayout(currentPositionLayout); + currentPositionLayout->setMargin(0); + currentPositionLayout->setSpacing(0); + QLabel *currentPositionLabel = new QLabel("Current Position", currentPositionWidget); + acquisitionMotorCurrentPositionLineEdit = new QLineEdit("--.--", currentPositionWidget); + acquisitionMotorCurrentPositionLineEdit->setReadOnly(true); + connectLineEditToDouble(acquisitionMotorCurrentPositionLineEdit, current_pos); + currentPositionLayout->addWidget(currentPositionLabel); + currentPositionLayout->addWidget(acquisitionMotorCurrentPositionLineEdit); + + QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); + targetPositionWidget->setLayout(targetPositionLayout); + targetPositionLayout->setMargin(0); + targetPositionLayout->setSpacing(0); + QLabel *targetPositionLabel = new QLabel("Target Position", targetPositionWidget); + motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), targetPositionWidget); + connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, + ADMTController::MotorAttribute::TARGET_POS); + targetPositionLayout->addWidget(targetPositionLabel); + targetPositionLayout->addWidget(motorTargetPositionLineEdit); + + QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); + motorDirectionWidget->setLayout(motorDirectionLayout); + motorDirectionLayout->setMargin(0); + motorDirectionLayout->setSpacing(0); + QLabel *motorDirectionLabel = new QLabel("Rotation Direction", motorDirectionWidget); + acquisitionMotorDirectionSwitch = new CustomSwitch("CW", "CCW", motorControlSectionWidget); + acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); + connect(acquisitionMotorDirectionSwitch, &CustomSwitch::toggled, this, + [this](bool b) { isMotorRotationClockwise = b; }); + motorDirectionLayout->addWidget(motorDirectionLabel); + motorDirectionLayout->addWidget(acquisitionMotorDirectionSwitch); + + QPushButton *continuousRotationButton = new QPushButton("Continuous Rotation", motorControlSectionWidget); + StyleHelper::BasicButton(continuousRotationButton); + connect(continuousRotationButton, &QPushButton::clicked, this, &HarmonicCalibration::moveMotorContinuous); + + QPushButton *stopMotorButton = new QPushButton("Stop Motor", motorControlSectionWidget); + StyleHelper::BasicButton(stopMotorButton); + connect(stopMotorButton, &QPushButton::clicked, this, &HarmonicCalibration::stopMotor); + + motorControlCollapseSection->contentLayout()->setSpacing(globalSpacingSmall); + motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); + motorControlCollapseSection->contentLayout()->addWidget(currentPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); + motorControlCollapseSection->contentLayout()->addWidget(continuousRotationButton); + motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); #pragma endregion - rawDataLayout->setSpacing(globalSpacingSmall); - rawDataLayout->addWidget(angleWidget); - rawDataLayout->addWidget(rotationWidget); - rawDataLayout->addWidget(countWidget); - rawDataLayout->addWidget(tempWidget); - rawDataLayout->addWidget(motorControlSectionWidget); - rawDataLayout->addStretch(); + rawDataLayout->setSpacing(globalSpacingSmall); + rawDataLayout->addWidget(angleWidget); + rawDataLayout->addWidget(rotationWidget); + rawDataLayout->addWidget(countWidget); + rawDataLayout->addWidget(tempWidget); + rawDataLayout->addWidget(motorControlSectionWidget); + rawDataLayout->addStretch(); #pragma endregion #pragma region Acquisition Graph Section Widget - MenuSectionWidget *acquisitionGraphSectionWidget = - new MenuSectionWidget(this); - Style::setStyle(acquisitionGraphSectionWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *acquisitionGraphCollapseSection = - new MenuCollapseSection( - "Captured Data", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - acquisitionGraphSectionWidget); - acquisitionGraphSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::MinimumExpanding); - acquisitionGraphSectionWidget->contentLayout()->addWidget( - acquisitionGraphCollapseSection); - acquisitionGraphCollapseSection->contentLayout()->setSpacing(8); - - acquisitionGraphPlotWidget = new PlotWidget(); - acquisitionGraphPlotWidget->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::MinimumExpanding); - - acquisitionXPlotAxis = new PlotAxis( - QwtAxis::XBottom, acquisitionGraphPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); - acquisitionYPlotAxis = new PlotAxis( - QwtAxis::YLeft, acquisitionGraphPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - acquisitionYPlotAxis->setInterval(0, 360); - - acquisitionAnglePlotChannel = new PlotChannel( - "Angle", channel0Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionABSAnglePlotChannel = new PlotChannel( - "ABS Angle", channel1Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionTurnCountPlotChannel = new PlotChannel( - "Turn Count", channel2Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionTmp0PlotChannel = new PlotChannel( - "TMP 0", channel3Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionTmp1PlotChannel = new PlotChannel( - "TMP 1", channel4Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionSinePlotChannel = new PlotChannel( - "Sine", sinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionCosinePlotChannel = new PlotChannel( - "Cosine", cosinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionRadiusPlotChannel = new PlotChannel( - "Radius", channel5Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionSecAnglQPlotChannel = new PlotChannel( - "SECANGLQ", channel6Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionSecAnglIPlotChannel = new PlotChannel( - "SECANGLI", channel7Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - - acquisitionGraphPlotWidget->addPlotChannel(acquisitionAnglePlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionABSAnglePlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionTurnCountPlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp0PlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp1PlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionSinePlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionCosinePlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionRadiusPlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglQPlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglIPlotChannel); - acquisitionAnglePlotChannel->setEnabled(true); - acquisitionABSAnglePlotChannel->setEnabled(true); - acquisitionTurnCountPlotChannel->setEnabled(true); - acquisitionTmp0PlotChannel->setEnabled(true); - acquisitionTmp1PlotChannel->setEnabled(true); - acquisitionSinePlotChannel->setEnabled(true); - acquisitionCosinePlotChannel->setEnabled(true); - acquisitionRadiusPlotChannel->setEnabled(true); - acquisitionSecAnglQPlotChannel->setEnabled(true); - acquisitionSecAnglIPlotChannel->setEnabled(true); - acquisitionGraphPlotWidget->selectChannel(acquisitionAnglePlotChannel); - - acquisitionGraphPlotWidget->setShowXAxisLabels(true); - acquisitionGraphPlotWidget->setShowYAxisLabels(true); - acquisitionGraphPlotWidget->showAxisLabels(); - acquisitionGraphPlotWidget->replot(); + MenuSectionWidget *acquisitionGraphSectionWidget = new MenuSectionWidget(this); + Style::setStyle(acquisitionGraphSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *acquisitionGraphCollapseSection = new MenuCollapseSection( + "Captured Data", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, acquisitionGraphSectionWidget); + acquisitionGraphSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + acquisitionGraphSectionWidget->contentLayout()->addWidget(acquisitionGraphCollapseSection); + acquisitionGraphCollapseSection->contentLayout()->setSpacing(8); + + acquisitionGraphPlotWidget = new PlotWidget(); + acquisitionGraphPlotWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + + acquisitionXPlotAxis = new PlotAxis(QwtAxis::XBottom, acquisitionGraphPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); + acquisitionYPlotAxis = new PlotAxis(QwtAxis::YLeft, acquisitionGraphPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + acquisitionYPlotAxis->setInterval(0, 360); + + acquisitionAnglePlotChannel = new PlotChannel("Angle", channel0Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionABSAnglePlotChannel = + new PlotChannel("ABS Angle", channel1Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTurnCountPlotChannel = + new PlotChannel("Turn Count", channel2Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTmp0PlotChannel = new PlotChannel("TMP 0", channel3Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTmp1PlotChannel = new PlotChannel("TMP 1", channel4Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionSinePlotChannel = new PlotChannel("Sine", sinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionCosinePlotChannel = new PlotChannel("Cosine", cosinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionRadiusPlotChannel = + new PlotChannel("Radius", channel5Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionSecAnglQPlotChannel = + new PlotChannel("SECANGLQ", channel6Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionSecAnglIPlotChannel = + new PlotChannel("SECANGLI", channel7Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + + acquisitionGraphPlotWidget->addPlotChannel(acquisitionAnglePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionABSAnglePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionTurnCountPlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp0PlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp1PlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionSinePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionCosinePlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionRadiusPlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglQPlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglIPlotChannel); + acquisitionAnglePlotChannel->setEnabled(true); + acquisitionABSAnglePlotChannel->setEnabled(true); + acquisitionTurnCountPlotChannel->setEnabled(true); + acquisitionTmp0PlotChannel->setEnabled(true); + acquisitionTmp1PlotChannel->setEnabled(true); + acquisitionSinePlotChannel->setEnabled(true); + acquisitionCosinePlotChannel->setEnabled(true); + acquisitionRadiusPlotChannel->setEnabled(true); + acquisitionSecAnglQPlotChannel->setEnabled(true); + acquisitionSecAnglIPlotChannel->setEnabled(true); + acquisitionGraphPlotWidget->selectChannel(acquisitionAnglePlotChannel); + + acquisitionGraphPlotWidget->setShowXAxisLabels(true); + acquisitionGraphPlotWidget->setShowYAxisLabels(true); + acquisitionGraphPlotWidget->showAxisLabels(); + acquisitionGraphPlotWidget->replot(); #pragma region Channel Selection - QWidget *acquisitionGraphChannelWidget = - new QWidget(acquisitionGraphSectionWidget); - QGridLayout *acquisitionGraphChannelGridLayout = - new QGridLayout(acquisitionGraphChannelWidget); - acquisitionGraphChannelGridLayout->setContentsMargins(16, 8, 8, 16); - acquisitionGraphChannelGridLayout->setSpacing(8); - - QCheckBox *angleCheckBox = - new QCheckBox("Angle", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(angleCheckBox, channel0Pen.color()); - connectCheckBoxToAcquisitionGraph(angleCheckBox, acquisitionAnglePlotChannel, - ANGLE); - angleCheckBox->setChecked(true); - - QCheckBox *absAngleCheckBox = - new QCheckBox("ABS Angle", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(absAngleCheckBox, channel1Pen.color()); - connectCheckBoxToAcquisitionGraph(absAngleCheckBox, - acquisitionABSAnglePlotChannel, ABSANGLE); - - QCheckBox *temp0CheckBox = - new QCheckBox("Temp 0", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(temp0CheckBox, channel3Pen.color()); - connectCheckBoxToAcquisitionGraph(temp0CheckBox, acquisitionTmp0PlotChannel, - TMP0); - - QCheckBox *sineCheckBox = - new QCheckBox("Sine", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(sineCheckBox, sineColor); - connectCheckBoxToAcquisitionGraph(sineCheckBox, acquisitionSinePlotChannel, - SINE); - - QCheckBox *cosineCheckBox = - new QCheckBox("Cosine", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(cosineCheckBox, cosineColor); - connectCheckBoxToAcquisitionGraph(cosineCheckBox, - acquisitionCosinePlotChannel, COSINE); - - QCheckBox *radiusCheckBox = - new QCheckBox("Radius", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(radiusCheckBox, channel5Pen.color()); - connectCheckBoxToAcquisitionGraph(radiusCheckBox, - acquisitionRadiusPlotChannel, RADIUS); - - if (GENERALRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 - { - acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); - acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); - acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); - acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); - acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); - acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); - } else if (GENERALRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 - { - acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); - acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); - acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); - acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); - acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); - acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); - } + QWidget *acquisitionGraphChannelWidget = new QWidget(acquisitionGraphSectionWidget); + QGridLayout *acquisitionGraphChannelGridLayout = new QGridLayout(acquisitionGraphChannelWidget); + acquisitionGraphChannelGridLayout->setContentsMargins(16, 8, 8, 16); + acquisitionGraphChannelGridLayout->setSpacing(8); + + QCheckBox *angleCheckBox = new QCheckBox("Angle", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(angleCheckBox, channel0Pen.color()); + connectCheckBoxToAcquisitionGraph(angleCheckBox, acquisitionAnglePlotChannel, ANGLE); + angleCheckBox->setChecked(true); + + QCheckBox *absAngleCheckBox = new QCheckBox("ABS Angle", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(absAngleCheckBox, channel1Pen.color()); + connectCheckBoxToAcquisitionGraph(absAngleCheckBox, acquisitionABSAnglePlotChannel, ABSANGLE); + + QCheckBox *temp0CheckBox = new QCheckBox("Temp 0", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(temp0CheckBox, channel3Pen.color()); + connectCheckBoxToAcquisitionGraph(temp0CheckBox, acquisitionTmp0PlotChannel, TMP0); + + QCheckBox *sineCheckBox = new QCheckBox("Sine", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(sineCheckBox, sineColor); + connectCheckBoxToAcquisitionGraph(sineCheckBox, acquisitionSinePlotChannel, SINE); + + QCheckBox *cosineCheckBox = new QCheckBox("Cosine", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(cosineCheckBox, cosineColor); + connectCheckBoxToAcquisitionGraph(cosineCheckBox, acquisitionCosinePlotChannel, COSINE); + + QCheckBox *radiusCheckBox = new QCheckBox("Radius", acquisitionGraphChannelWidget); + ADMTStyleHelper::ColoredSquareCheckbox(radiusCheckBox, channel5Pen.color()); + connectCheckBoxToAcquisitionGraph(radiusCheckBox, acquisitionRadiusPlotChannel, RADIUS); + + if(GENERALRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 + { + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); + } else if(GENERALRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 + { + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); + } #pragma endregion - acquisitionGraphCollapseSection->contentLayout()->addWidget( - acquisitionGraphPlotWidget); - acquisitionGraphCollapseSection->contentLayout()->addWidget( - acquisitionGraphChannelWidget); + acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphPlotWidget); + acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphChannelWidget); #pragma endregion #pragma region General Setting - QScrollArea *generalSettingScroll = new QScrollArea(this); - generalSettingScroll->setWidgetResizable(true); - QWidget *generalSettingWidget = new QWidget(generalSettingScroll); - generalSettingScroll->setWidget(generalSettingWidget); - QVBoxLayout *generalSettingLayout = new QVBoxLayout(generalSettingWidget); - generalSettingLayout->setMargin(0); - generalSettingWidget->setLayout(generalSettingLayout); - - header = - new MenuHeaderWidget(deviceName + " " + deviceType, scopyBluePen, this); - Style::setStyle(header, style::properties::widget::basicComponent); - - // General Setting Widget - MenuSectionWidget *generalWidget = - new MenuSectionWidget(generalSettingWidget); - Style::setStyle(generalWidget, style::properties::widget::basicComponent); - MenuCollapseSection *generalSection = new MenuCollapseSection( - "Data Acquisition", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); - generalSection->header()->toggle(); - generalSection->contentLayout()->setSpacing(globalSpacingSmall); - generalWidget->contentLayout()->addWidget(generalSection); - - // Graph Update Interval - QWidget *graphUpdateIntervalWidget = new QWidget(generalSection); - QVBoxLayout *graphUpdateIntervalLayout = - new QVBoxLayout(graphUpdateIntervalWidget); - graphUpdateIntervalWidget->setLayout(graphUpdateIntervalLayout); - graphUpdateIntervalLayout->setMargin(0); - graphUpdateIntervalLayout->setSpacing(0); - QLabel *graphUpdateIntervalLabel = new QLabel(graphUpdateIntervalWidget); - graphUpdateIntervalLabel->setText("Graph Update Interval (ms)"); - graphUpdateIntervalLineEdit = new QLineEdit(graphUpdateIntervalWidget); - graphUpdateIntervalLineEdit->setText( - QString::number(acquisitionGraphSampleRate)); - connectLineEditToNumber(graphUpdateIntervalLineEdit, - acquisitionGraphSampleRate, 1, 5000); - graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLabel); - graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLineEdit); - - // Data Sample Size - QWidget *displayLengthWidget = new QWidget(generalSection); - QVBoxLayout *displayLengthLayout = new QVBoxLayout(displayLengthWidget); - displayLengthWidget->setLayout(displayLengthLayout); - displayLengthLayout->setMargin(0); - displayLengthLayout->setSpacing(0); - QLabel *displayLengthLabel = - new QLabel("Display Length", displayLengthWidget); - displayLengthLineEdit = new QLineEdit(displayLengthWidget); - displayLengthLineEdit->setText(QString::number(acquisitionDisplayLength)); - connectLineEditToNumber(displayLengthLineEdit, acquisitionDisplayLength, 1, - 2048); - displayLengthLayout->addWidget(displayLengthLabel); - displayLengthLayout->addWidget(displayLengthLineEdit); - - QPushButton *resetYAxisButton = - new QPushButton("Reset Y-Axis Scale", generalSection); - StyleHelper::BasicButton(resetYAxisButton); - connect(resetYAxisButton, &QPushButton::clicked, this, - &HarmonicCalibration::resetAcquisitionYAxisScale); - - generalSection->contentLayout()->addWidget(graphUpdateIntervalWidget); - generalSection->contentLayout()->addWidget(displayLengthWidget); - generalSection->contentLayout()->addWidget(resetYAxisButton); - - MenuSectionWidget *sequenceWidget = - new MenuSectionWidget(generalSettingWidget); - Style::setStyle(sequenceWidget, style::properties::widget::basicComponent); - MenuCollapseSection *sequenceSection = new MenuCollapseSection( - "Sequence", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - sequenceWidget); - sequenceWidget->contentLayout()->addWidget(sequenceSection); - sequenceSection->contentLayout()->setSpacing(globalSpacingSmall); - - sequenceTypeMenuCombo = new MenuCombo("Sequence Type", sequenceSection); - QComboBox *sequenceTypeComboBox = sequenceTypeMenuCombo->combo(); - sequenceTypeComboBox->addItem("Mode 1", QVariant(0)); - if (deviceType.toStdString() == "Automotive") { - sequenceTypeComboBox->addItem("Mode 2", QVariant(1)); - } - - conversionTypeMenuCombo = new MenuCombo("Conversion Type", sequenceSection); - QComboBox *conversionTypeComboBox = conversionTypeMenuCombo->combo(); - conversionTypeComboBox->addItem("Continuous conversions", QVariant(0)); - conversionTypeComboBox->addItem("One-shot conversion", QVariant(1)); - - convertSynchronizationMenuCombo = - new MenuCombo("Convert Synchronization", sequenceSection); - QComboBox *convertSynchronizationComboBox = - convertSynchronizationMenuCombo->combo(); - convertSynchronizationComboBox->addItem("Enabled", QVariant(1)); - convertSynchronizationComboBox->addItem("Disabled", QVariant(0)); - - angleFilterMenuCombo = new MenuCombo("Angle Filter", sequenceSection); - QComboBox *angleFilterComboBox = angleFilterMenuCombo->combo(); - angleFilterComboBox->addItem("Enabled", QVariant(1)); - angleFilterComboBox->addItem("Disabled", QVariant(0)); - - eighthHarmonicMenuCombo = new MenuCombo("8th Harmonic", sequenceSection); - QComboBox *eighthHarmonicComboBox = eighthHarmonicMenuCombo->combo(); - eighthHarmonicComboBox->addItem("User-Supplied Values", QVariant(1)); - eighthHarmonicComboBox->addItem("ADI Factory Values", QVariant(0)); - - updateSequenceWidget(); - - applySequenceButton = new QPushButton("Apply", sequenceSection); - StyleHelper::BasicButton(applySequenceButton); - connect(applySequenceButton, &QPushButton::clicked, this, - &HarmonicCalibration::applySequenceAndUpdate); - - sequenceSection->contentLayout()->addWidget(sequenceTypeMenuCombo); - sequenceSection->contentLayout()->addWidget(conversionTypeMenuCombo); - sequenceSection->contentLayout()->addWidget(convertSynchronizationMenuCombo); - sequenceSection->contentLayout()->addWidget(angleFilterMenuCombo); - sequenceSection->contentLayout()->addWidget(eighthHarmonicMenuCombo); - sequenceSection->contentLayout()->addWidget(applySequenceButton); + QScrollArea *generalSettingScroll = new QScrollArea(this); + generalSettingScroll->setWidgetResizable(true); + QWidget *generalSettingWidget = new QWidget(generalSettingScroll); + generalSettingScroll->setWidget(generalSettingWidget); + QVBoxLayout *generalSettingLayout = new QVBoxLayout(generalSettingWidget); + generalSettingLayout->setMargin(0); + generalSettingWidget->setLayout(generalSettingLayout); + + header = new MenuHeaderWidget(deviceName + " " + deviceType, scopyBluePen, this); + Style::setStyle(header, style::properties::widget::basicComponent); + + // General Setting Widget + MenuSectionWidget *generalWidget = new MenuSectionWidget(generalSettingWidget); + Style::setStyle(generalWidget, style::properties::widget::basicComponent); + MenuCollapseSection *generalSection = + new MenuCollapseSection("Data Acquisition", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); + generalSection->header()->toggle(); + generalSection->contentLayout()->setSpacing(globalSpacingSmall); + generalWidget->contentLayout()->addWidget(generalSection); + + // Graph Update Interval + QWidget *graphUpdateIntervalWidget = new QWidget(generalSection); + QVBoxLayout *graphUpdateIntervalLayout = new QVBoxLayout(graphUpdateIntervalWidget); + graphUpdateIntervalWidget->setLayout(graphUpdateIntervalLayout); + graphUpdateIntervalLayout->setMargin(0); + graphUpdateIntervalLayout->setSpacing(0); + QLabel *graphUpdateIntervalLabel = new QLabel(graphUpdateIntervalWidget); + graphUpdateIntervalLabel->setText("Graph Update Interval (ms)"); + graphUpdateIntervalLineEdit = new QLineEdit(graphUpdateIntervalWidget); + graphUpdateIntervalLineEdit->setText(QString::number(acquisitionGraphSampleRate)); + connectLineEditToNumber(graphUpdateIntervalLineEdit, acquisitionGraphSampleRate, 1, 5000); + graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLabel); + graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLineEdit); + + // Data Sample Size + QWidget *displayLengthWidget = new QWidget(generalSection); + QVBoxLayout *displayLengthLayout = new QVBoxLayout(displayLengthWidget); + displayLengthWidget->setLayout(displayLengthLayout); + displayLengthLayout->setMargin(0); + displayLengthLayout->setSpacing(0); + QLabel *displayLengthLabel = new QLabel("Display Length", displayLengthWidget); + displayLengthLineEdit = new QLineEdit(displayLengthWidget); + displayLengthLineEdit->setText(QString::number(acquisitionDisplayLength)); + connectLineEditToNumber(displayLengthLineEdit, acquisitionDisplayLength, 1, 2048); + displayLengthLayout->addWidget(displayLengthLabel); + displayLengthLayout->addWidget(displayLengthLineEdit); + + QPushButton *resetYAxisButton = new QPushButton("Reset Y-Axis Scale", generalSection); + StyleHelper::BasicButton(resetYAxisButton); + connect(resetYAxisButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAcquisitionYAxisScale); + + generalSection->contentLayout()->addWidget(graphUpdateIntervalWidget); + generalSection->contentLayout()->addWidget(displayLengthWidget); + generalSection->contentLayout()->addWidget(resetYAxisButton); + + MenuSectionWidget *sequenceWidget = new MenuSectionWidget(generalSettingWidget); + Style::setStyle(sequenceWidget, style::properties::widget::basicComponent); + MenuCollapseSection *sequenceSection = + new MenuCollapseSection("Sequence", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, sequenceWidget); + sequenceWidget->contentLayout()->addWidget(sequenceSection); + sequenceSection->contentLayout()->setSpacing(globalSpacingSmall); + + sequenceTypeMenuCombo = new MenuCombo("Sequence Type", sequenceSection); + QComboBox *sequenceTypeComboBox = sequenceTypeMenuCombo->combo(); + sequenceTypeComboBox->addItem("Mode 1", QVariant(0)); + if(deviceType.toStdString() == "Automotive") { + sequenceTypeComboBox->addItem("Mode 2", QVariant(1)); + } + + conversionTypeMenuCombo = new MenuCombo("Conversion Type", sequenceSection); + QComboBox *conversionTypeComboBox = conversionTypeMenuCombo->combo(); + conversionTypeComboBox->addItem("Continuous conversions", QVariant(0)); + conversionTypeComboBox->addItem("One-shot conversion", QVariant(1)); + + convertSynchronizationMenuCombo = new MenuCombo("Convert Synchronization", sequenceSection); + QComboBox *convertSynchronizationComboBox = convertSynchronizationMenuCombo->combo(); + convertSynchronizationComboBox->addItem("Enabled", QVariant(1)); + convertSynchronizationComboBox->addItem("Disabled", QVariant(0)); + + angleFilterMenuCombo = new MenuCombo("Angle Filter", sequenceSection); + QComboBox *angleFilterComboBox = angleFilterMenuCombo->combo(); + angleFilterComboBox->addItem("Enabled", QVariant(1)); + angleFilterComboBox->addItem("Disabled", QVariant(0)); + + eighthHarmonicMenuCombo = new MenuCombo("8th Harmonic", sequenceSection); + QComboBox *eighthHarmonicComboBox = eighthHarmonicMenuCombo->combo(); + eighthHarmonicComboBox->addItem("User-Supplied Values", QVariant(1)); + eighthHarmonicComboBox->addItem("ADI Factory Values", QVariant(0)); + + updateSequenceWidget(); + + applySequenceButton = new QPushButton("Apply", sequenceSection); + StyleHelper::BasicButton(applySequenceButton); + connect(applySequenceButton, &QPushButton::clicked, this, &HarmonicCalibration::applySequenceAndUpdate); + + sequenceSection->contentLayout()->addWidget(sequenceTypeMenuCombo); + sequenceSection->contentLayout()->addWidget(conversionTypeMenuCombo); + sequenceSection->contentLayout()->addWidget(convertSynchronizationMenuCombo); + sequenceSection->contentLayout()->addWidget(angleFilterMenuCombo); + sequenceSection->contentLayout()->addWidget(eighthHarmonicMenuCombo); + sequenceSection->contentLayout()->addWidget(applySequenceButton); #pragma region Device Status Widget - MenuSectionWidget *acquisitionDeviceStatusWidget = - new MenuSectionWidget(generalSettingWidget); - Style::setStyle(acquisitionDeviceStatusWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *acquisitionDeviceStatusSection = new MenuCollapseSection( - "Device Status", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); - acquisitionDeviceStatusSection->contentLayout()->setSpacing( - globalSpacingSmall); - acquisitionDeviceStatusWidget->contentLayout()->addWidget( - acquisitionDeviceStatusSection); - - acquisitionFaultRegisterLEDWidget = createStatusLEDWidget( - "Fault Register", "status", false, acquisitionDeviceStatusSection); - acquisitionDeviceStatusSection->contentLayout()->addWidget( - acquisitionFaultRegisterLEDWidget); - - if (deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == - 1) // Automotive & Sequence Mode 2 - { - QCheckBox *acquisitionSPICRCLEDWidget = createStatusLEDWidget( - "SPI CRC", "status", false, acquisitionDeviceStatusSection); - QCheckBox *acquisitionSPIFlagLEDWidget = createStatusLEDWidget( - "SPI Flag", "status", false, acquisitionDeviceStatusSection); - acquisitionDeviceStatusSection->contentLayout()->addWidget( - acquisitionSPICRCLEDWidget); - acquisitionDeviceStatusSection->contentLayout()->addWidget( - acquisitionSPIFlagLEDWidget); - } + MenuSectionWidget *acquisitionDeviceStatusWidget = new MenuSectionWidget(generalSettingWidget); + Style::setStyle(acquisitionDeviceStatusWidget, style::properties::widget::basicComponent); + MenuCollapseSection *acquisitionDeviceStatusSection = + new MenuCollapseSection("Device Status", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); + acquisitionDeviceStatusSection->contentLayout()->setSpacing(globalSpacingSmall); + acquisitionDeviceStatusWidget->contentLayout()->addWidget(acquisitionDeviceStatusSection); + + acquisitionFaultRegisterLEDWidget = + createStatusLEDWidget("Fault Register", "status", false, acquisitionDeviceStatusSection); + acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionFaultRegisterLEDWidget); + + if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 + { + QCheckBox *acquisitionSPICRCLEDWidget = + createStatusLEDWidget("SPI CRC", "status", false, acquisitionDeviceStatusSection); + QCheckBox *acquisitionSPIFlagLEDWidget = + createStatusLEDWidget("SPI Flag", "status", false, acquisitionDeviceStatusSection); + acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPICRCLEDWidget); + acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPIFlagLEDWidget); + } #pragma endregion - generalSettingLayout->setSpacing(globalSpacingSmall); - generalSettingLayout->addWidget(acquisitionDeviceStatusWidget); - generalSettingLayout->addWidget(header); - generalSettingLayout->addWidget(sequenceWidget); - generalSettingLayout->addWidget(generalWidget); - generalSettingLayout->addStretch(); + generalSettingLayout->setSpacing(globalSpacingSmall); + generalSettingLayout->addWidget(acquisitionDeviceStatusWidget); + generalSettingLayout->addWidget(header); + generalSettingLayout->addWidget(sequenceWidget); + generalSettingLayout->addWidget(generalWidget); + generalSettingLayout->addStretch(); #pragma endregion - tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - tool->topContainer()->setVisible(true); - tool->leftContainer()->setVisible(true); - tool->rightContainer()->setVisible(true); - tool->bottomContainer()->setVisible(false); - tool->setLeftContainerWidth(210); - tool->setRightContainerWidth(300); - tool->setTopContainerHeight(100); - tool->openBottomContainerHelper(false); - tool->openTopContainerHelper(false); - tool->addWidgetToTopContainerMenuControlHelper(openLastMenuButton, TTA_RIGHT); - tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); - tool->addWidgetToTopContainerHelper(resetGMRButton, TTA_RIGHT); - tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); - tool->leftStack()->add("rawDataScroll", rawDataScroll); - tool->rightStack()->add("generalSettingScroll", generalSettingScroll); - tool->addWidgetToCentralContainerHelper(acquisitionGraphSectionWidget); - - connect(runButton, &QPushButton::toggled, this, - &HarmonicCalibration::setRunning); - connect(this, &HarmonicCalibration::runningChanged, this, - &HarmonicCalibration::run); - connect(this, &HarmonicCalibration::runningChanged, runButton, - &QAbstractButton::setChecked); - - return tool; -} - -ToolTemplate *HarmonicCalibration::createCalibrationWidget() { - ToolTemplate *tool = new ToolTemplate(this); + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(true); + tool->leftContainer()->setVisible(true); + tool->rightContainer()->setVisible(true); + tool->bottomContainer()->setVisible(false); + tool->setLeftContainerWidth(210); + tool->setRightContainerWidth(300); + tool->setTopContainerHeight(100); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + tool->addWidgetToTopContainerMenuControlHelper(openLastMenuButton, TTA_RIGHT); + tool->addWidgetToTopContainerMenuControlHelper(settingsButton, TTA_LEFT); + tool->addWidgetToTopContainerHelper(resetGMRButton, TTA_RIGHT); + tool->addWidgetToTopContainerHelper(runButton, TTA_RIGHT); + tool->leftStack()->add("rawDataScroll", rawDataScroll); + tool->rightStack()->add("generalSettingScroll", generalSettingScroll); + tool->addWidgetToCentralContainerHelper(acquisitionGraphSectionWidget); + + connect(runButton, &QPushButton::toggled, this, &HarmonicCalibration::setRunning); + connect(this, &HarmonicCalibration::runningChanged, this, &HarmonicCalibration::run); + connect(this, &HarmonicCalibration::runningChanged, runButton, &QAbstractButton::setChecked); + + return tool; +} + +ToolTemplate *HarmonicCalibration::createCalibrationWidget() +{ + ToolTemplate *tool = new ToolTemplate(this); #pragma region Calibration Data Graph Widget - QWidget *calibrationDataGraphWidget = new QWidget(); - QGridLayout *calibrationDataGraphLayout = - new QGridLayout(calibrationDataGraphWidget); - calibrationDataGraphWidget->setLayout(calibrationDataGraphLayout); - calibrationDataGraphLayout->setMargin(0); - calibrationDataGraphLayout->setSpacing(5); - - MenuSectionWidget *calibrationDataGraphSectionWidget = - new MenuSectionWidget(calibrationDataGraphWidget); - Style::setStyle(calibrationDataGraphSectionWidget, - style::properties::widget::basicComponent); - calibrationDataGraphTabWidget = - new QTabWidget(calibrationDataGraphSectionWidget); - calibrationDataGraphTabWidget->tabBar()->setStyleSheet( - "QTabBar::tab { width: 176px; }"); - calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); - calibrationDataGraphSectionWidget->contentLayout()->addWidget( - calibrationDataGraphTabWidget); + QWidget *calibrationDataGraphWidget = new QWidget(); + QGridLayout *calibrationDataGraphLayout = new QGridLayout(calibrationDataGraphWidget); + calibrationDataGraphWidget->setLayout(calibrationDataGraphLayout); + calibrationDataGraphLayout->setMargin(0); + calibrationDataGraphLayout->setSpacing(5); + + MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); + Style::setStyle(calibrationDataGraphSectionWidget, style::properties::widget::basicComponent); + calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); + calibrationDataGraphTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 176px; }"); + calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); + calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); #pragma region Calibration Samples - QWidget *calibrationSamplesWidget = - new QWidget(calibrationDataGraphTabWidget); - Style::setStyle(calibrationSamplesWidget, - style::properties::widget::basicBackground); - QVBoxLayout *calibrationSamplesLayout = - new QVBoxLayout(calibrationSamplesWidget); - calibrationSamplesWidget->setLayout(calibrationSamplesLayout); - calibrationSamplesLayout->setMargin(0); - calibrationSamplesLayout->setSpacing(0); - - calibrationRawDataPlotWidget = new PlotWidget(); - calibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); - - calibrationRawDataXPlotAxis = new PlotAxis( - QwtAxis::XBottom, calibrationRawDataPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - calibrationRawDataXPlotAxis->setMin(0); - calibrationRawDataYPlotAxis = new PlotAxis( - QwtAxis::YLeft, calibrationRawDataPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - calibrationRawDataYPlotAxis->setInterval(0, 360); - - calibrationRawDataPlotChannel = - new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, - calibrationRawDataYPlotAxis); - calibrationSineDataPlotChannel = - new PlotChannel("Sine", sinePen, calibrationRawDataXPlotAxis, - calibrationRawDataYPlotAxis); - calibrationCosineDataPlotChannel = - new PlotChannel("Cosine", cosinePen, calibrationRawDataXPlotAxis, - calibrationRawDataYPlotAxis); - - calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); - calibrationRawDataPlotWidget->addPlotChannel(calibrationSineDataPlotChannel); - calibrationRawDataPlotWidget->addPlotChannel( - calibrationCosineDataPlotChannel); - calibrationSineDataPlotChannel->setEnabled(true); - calibrationCosineDataPlotChannel->setEnabled(true); - calibrationRawDataPlotChannel->setEnabled(true); - calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); - - calibrationRawDataPlotWidget->setShowXAxisLabels(true); - calibrationRawDataPlotWidget->setShowYAxisLabels(true); - calibrationRawDataPlotWidget->showAxisLabels(); - calibrationRawDataPlotWidget->replot(); - - QWidget *calibrationDataGraphChannelsWidget = - new QWidget(calibrationDataGraphTabWidget); - ADMTStyleHelper::UIBackgroundStyle(calibrationDataGraphChannelsWidget); - QHBoxLayout *calibrationDataGraphChannelsLayout = - new QHBoxLayout(calibrationDataGraphChannelsWidget); - calibrationDataGraphChannelsWidget->setLayout( - calibrationDataGraphChannelsLayout); - calibrationDataGraphChannelsLayout->setContentsMargins(20, 13, 20, 5); - calibrationDataGraphChannelsLayout->setSpacing(20); - - MenuControlButton *toggleAngleButton = createChannelToggleWidget( - "Angle", scopyBlueColor, calibrationDataGraphChannelsWidget); - MenuControlButton *toggleSineButton = createChannelToggleWidget( - "Sine", sineColor, calibrationDataGraphChannelsWidget); - MenuControlButton *toggleCosineButton = createChannelToggleWidget( - "Cosine", cosineColor, calibrationDataGraphChannelsWidget); - - calibrationDataGraphChannelsLayout->addWidget(toggleAngleButton); - calibrationDataGraphChannelsLayout->addWidget(toggleSineButton); - calibrationDataGraphChannelsLayout->addWidget(toggleCosineButton); - calibrationDataGraphChannelsLayout->addStretch(); - - calibrationSamplesLayout->addWidget(calibrationRawDataPlotWidget); - calibrationSamplesLayout->addWidget(calibrationDataGraphChannelsWidget); + QWidget *calibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); + Style::setStyle(calibrationSamplesWidget, style::properties::widget::basicBackground); + QVBoxLayout *calibrationSamplesLayout = new QVBoxLayout(calibrationSamplesWidget); + calibrationSamplesWidget->setLayout(calibrationSamplesLayout); + calibrationSamplesLayout->setMargin(0); + calibrationSamplesLayout->setSpacing(0); + + calibrationRawDataPlotWidget = new PlotWidget(); + calibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); + + calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + calibrationRawDataXPlotAxis->setMin(0); + calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + calibrationRawDataYPlotAxis->setInterval(0, 360); + + calibrationRawDataPlotChannel = + new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + calibrationSineDataPlotChannel = + new PlotChannel("Sine", sinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + calibrationCosineDataPlotChannel = + new PlotChannel("Cosine", cosinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + + calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); + calibrationRawDataPlotWidget->addPlotChannel(calibrationSineDataPlotChannel); + calibrationRawDataPlotWidget->addPlotChannel(calibrationCosineDataPlotChannel); + calibrationSineDataPlotChannel->setEnabled(true); + calibrationCosineDataPlotChannel->setEnabled(true); + calibrationRawDataPlotChannel->setEnabled(true); + calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); + + calibrationRawDataPlotWidget->setShowXAxisLabels(true); + calibrationRawDataPlotWidget->setShowYAxisLabels(true); + calibrationRawDataPlotWidget->showAxisLabels(); + calibrationRawDataPlotWidget->replot(); + + QWidget *calibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); + ADMTStyleHelper::UIBackgroundStyle(calibrationDataGraphChannelsWidget); + QHBoxLayout *calibrationDataGraphChannelsLayout = new QHBoxLayout(calibrationDataGraphChannelsWidget); + calibrationDataGraphChannelsWidget->setLayout(calibrationDataGraphChannelsLayout); + calibrationDataGraphChannelsLayout->setContentsMargins(20, 13, 20, 5); + calibrationDataGraphChannelsLayout->setSpacing(20); + + MenuControlButton *toggleAngleButton = + createChannelToggleWidget("Angle", scopyBlueColor, calibrationDataGraphChannelsWidget); + MenuControlButton *toggleSineButton = + createChannelToggleWidget("Sine", sineColor, calibrationDataGraphChannelsWidget); + MenuControlButton *toggleCosineButton = + createChannelToggleWidget("Cosine", cosineColor, calibrationDataGraphChannelsWidget); + + calibrationDataGraphChannelsLayout->addWidget(toggleAngleButton); + calibrationDataGraphChannelsLayout->addWidget(toggleSineButton); + calibrationDataGraphChannelsLayout->addWidget(toggleCosineButton); + calibrationDataGraphChannelsLayout->addStretch(); + + calibrationSamplesLayout->addWidget(calibrationRawDataPlotWidget); + calibrationSamplesLayout->addWidget(calibrationDataGraphChannelsWidget); #pragma endregion #pragma region Post Calibration Samples - QWidget *postCalibrationSamplesWidget = - new QWidget(calibrationDataGraphTabWidget); - Style::setStyle(postCalibrationSamplesWidget, - style::properties::widget::basicBackground); - QVBoxLayout *postCalibrationSamplesLayout = - new QVBoxLayout(postCalibrationSamplesWidget); - postCalibrationSamplesWidget->setLayout(postCalibrationSamplesLayout); - postCalibrationSamplesLayout->setMargin(0); - postCalibrationSamplesLayout->setSpacing(0); - - postCalibrationRawDataPlotWidget = new PlotWidget(); - postCalibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); - - postCalibrationRawDataXPlotAxis = new PlotAxis( - QwtAxis::XBottom, postCalibrationRawDataPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - postCalibrationRawDataXPlotAxis->setMin(0); - postCalibrationRawDataYPlotAxis = new PlotAxis( - QwtAxis::YLeft, postCalibrationRawDataPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - postCalibrationRawDataYPlotAxis->setInterval(0, 360); - - postCalibrationRawDataPlotChannel = - new PlotChannel("Samples", scopyBluePen, postCalibrationRawDataXPlotAxis, - postCalibrationRawDataYPlotAxis); - postCalibrationSineDataPlotChannel = - new PlotChannel("Sine", sinePen, postCalibrationRawDataXPlotAxis, - postCalibrationRawDataYPlotAxis); - postCalibrationCosineDataPlotChannel = - new PlotChannel("Cosine", cosinePen, postCalibrationRawDataXPlotAxis, - postCalibrationRawDataYPlotAxis); - - postCalibrationRawDataPlotWidget->addPlotChannel( - postCalibrationRawDataPlotChannel); - postCalibrationRawDataPlotWidget->addPlotChannel( - postCalibrationSineDataPlotChannel); - postCalibrationRawDataPlotWidget->addPlotChannel( - postCalibrationCosineDataPlotChannel); - - postCalibrationSineDataPlotChannel->setEnabled(true); - postCalibrationCosineDataPlotChannel->setEnabled(true); - postCalibrationRawDataPlotChannel->setEnabled(true); - postCalibrationRawDataPlotWidget->selectChannel( - postCalibrationRawDataPlotChannel); - - postCalibrationRawDataPlotWidget->setShowXAxisLabels(true); - postCalibrationRawDataPlotWidget->setShowYAxisLabels(true); - postCalibrationRawDataPlotWidget->showAxisLabels(); - postCalibrationRawDataPlotWidget->replot(); - - QWidget *postCalibrationDataGraphChannelsWidget = - new QWidget(calibrationDataGraphTabWidget); - QHBoxLayout *postCalibrationDataGraphChannelsLayout = - new QHBoxLayout(postCalibrationDataGraphChannelsWidget); - ADMTStyleHelper::GraphChannelStyle(postCalibrationDataGraphChannelsWidget, - postCalibrationDataGraphChannelsLayout); - - MenuControlButton *togglePostAngleButton = createChannelToggleWidget( - "Angle", scopyBlueColor, postCalibrationDataGraphChannelsWidget); - MenuControlButton *togglePostSineButton = createChannelToggleWidget( - "Sine", sineColor, postCalibrationDataGraphChannelsWidget); - MenuControlButton *togglePostCosineButton = createChannelToggleWidget( - "Cosine", cosineColor, postCalibrationDataGraphChannelsWidget); - - postCalibrationDataGraphChannelsLayout->addWidget(togglePostAngleButton); - postCalibrationDataGraphChannelsLayout->addWidget(togglePostSineButton); - postCalibrationDataGraphChannelsLayout->addWidget(togglePostCosineButton); - postCalibrationDataGraphChannelsLayout->addStretch(); - - postCalibrationSamplesLayout->addWidget(postCalibrationRawDataPlotWidget); - postCalibrationSamplesLayout->addWidget( - postCalibrationDataGraphChannelsWidget); + QWidget *postCalibrationSamplesWidget = new QWidget(calibrationDataGraphTabWidget); + Style::setStyle(postCalibrationSamplesWidget, style::properties::widget::basicBackground); + QVBoxLayout *postCalibrationSamplesLayout = new QVBoxLayout(postCalibrationSamplesWidget); + postCalibrationSamplesWidget->setLayout(postCalibrationSamplesLayout); + postCalibrationSamplesLayout->setMargin(0); + postCalibrationSamplesLayout->setSpacing(0); + + postCalibrationRawDataPlotWidget = new PlotWidget(); + postCalibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); + + postCalibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, postCalibrationRawDataPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + postCalibrationRawDataXPlotAxis->setMin(0); + postCalibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, postCalibrationRawDataPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + postCalibrationRawDataYPlotAxis->setInterval(0, 360); + + postCalibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, postCalibrationRawDataXPlotAxis, + postCalibrationRawDataYPlotAxis); + postCalibrationSineDataPlotChannel = + new PlotChannel("Sine", sinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); + postCalibrationCosineDataPlotChannel = + new PlotChannel("Cosine", cosinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); + + postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationRawDataPlotChannel); + postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationSineDataPlotChannel); + postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationCosineDataPlotChannel); + + postCalibrationSineDataPlotChannel->setEnabled(true); + postCalibrationCosineDataPlotChannel->setEnabled(true); + postCalibrationRawDataPlotChannel->setEnabled(true); + postCalibrationRawDataPlotWidget->selectChannel(postCalibrationRawDataPlotChannel); + + postCalibrationRawDataPlotWidget->setShowXAxisLabels(true); + postCalibrationRawDataPlotWidget->setShowYAxisLabels(true); + postCalibrationRawDataPlotWidget->showAxisLabels(); + postCalibrationRawDataPlotWidget->replot(); + + QWidget *postCalibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); + QHBoxLayout *postCalibrationDataGraphChannelsLayout = new QHBoxLayout(postCalibrationDataGraphChannelsWidget); + ADMTStyleHelper::GraphChannelStyle(postCalibrationDataGraphChannelsWidget, + postCalibrationDataGraphChannelsLayout); + + MenuControlButton *togglePostAngleButton = + createChannelToggleWidget("Angle", scopyBlueColor, postCalibrationDataGraphChannelsWidget); + MenuControlButton *togglePostSineButton = + createChannelToggleWidget("Sine", sineColor, postCalibrationDataGraphChannelsWidget); + MenuControlButton *togglePostCosineButton = + createChannelToggleWidget("Cosine", cosineColor, postCalibrationDataGraphChannelsWidget); + + postCalibrationDataGraphChannelsLayout->addWidget(togglePostAngleButton); + postCalibrationDataGraphChannelsLayout->addWidget(togglePostSineButton); + postCalibrationDataGraphChannelsLayout->addWidget(togglePostCosineButton); + postCalibrationDataGraphChannelsLayout->addStretch(); + + postCalibrationSamplesLayout->addWidget(postCalibrationRawDataPlotWidget); + postCalibrationSamplesLayout->addWidget(postCalibrationDataGraphChannelsWidget); #pragma endregion - calibrationDataGraphTabWidget->addTab(calibrationSamplesWidget, - "Calibration Samples"); - calibrationDataGraphTabWidget->addTab(postCalibrationSamplesWidget, - "Post Calibration Samples"); - - MenuSectionWidget *resultDataSectionWidget = - new MenuSectionWidget(calibrationDataGraphWidget); - Style::setStyle(resultDataSectionWidget, - style::properties::widget::basicComponent); - resultDataTabWidget = new QTabWidget(resultDataSectionWidget); - resultDataTabWidget->tabBar()->setStyleSheet( - "QTabBar::tab { width: 160px; }"); - resultDataSectionWidget->contentLayout()->setSpacing(8); - resultDataSectionWidget->contentLayout()->addWidget(resultDataTabWidget); - - QColor magnitudeColor = Style::getColor(json::global::ch0); - QColor phaseColor = Style::getColor(json::global::ch1); - QPen magnitudePen = QPen(magnitudeColor); - QPen phasePen = QPen(phaseColor); + calibrationDataGraphTabWidget->addTab(calibrationSamplesWidget, "Calibration Samples"); + calibrationDataGraphTabWidget->addTab(postCalibrationSamplesWidget, "Post Calibration Samples"); + + MenuSectionWidget *resultDataSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); + Style::setStyle(resultDataSectionWidget, style::properties::widget::basicComponent); + resultDataTabWidget = new QTabWidget(resultDataSectionWidget); + resultDataTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 160px; }"); + resultDataSectionWidget->contentLayout()->setSpacing(8); + resultDataSectionWidget->contentLayout()->addWidget(resultDataTabWidget); + + QColor magnitudeColor = Style::getColor(json::global::ch0); + QColor phaseColor = Style::getColor(json::global::ch1); + QPen magnitudePen = QPen(magnitudeColor); + QPen phasePen = QPen(phaseColor); #pragma region Angle Error Widget - QWidget *angleErrorWidget = new QWidget(); - Style::setStyle(angleErrorWidget, style::properties::widget::basicBackground); - QVBoxLayout *angleErrorLayout = new QVBoxLayout(angleErrorWidget); - angleErrorWidget->setLayout(angleErrorLayout); - angleErrorLayout->setMargin(0); - angleErrorLayout->setSpacing(0); - - angleErrorPlotWidget = new PlotWidget(); - angleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - angleErrorXPlotAxis = new PlotAxis( - QwtAxis::XBottom, angleErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - angleErrorXPlotAxis->setMin(0); - angleErrorYPlotAxis = new PlotAxis( - QwtAxis::YLeft, angleErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - angleErrorYPlotAxis->setInterval(-4, 4); - - angleErrorPlotChannel = new PlotChannel( - "Angle Error", scopyBluePen, angleErrorXPlotAxis, angleErrorYPlotAxis); - - angleErrorPlotWidget->addPlotChannel(angleErrorPlotChannel); - angleErrorPlotChannel->setEnabled(true); - angleErrorPlotWidget->selectChannel(angleErrorPlotChannel); - - angleErrorPlotWidget->setShowXAxisLabels(true); - angleErrorPlotWidget->setShowYAxisLabels(true); - angleErrorPlotWidget->showAxisLabels(); - angleErrorPlotWidget->replot(); - - angleErrorLayout->addWidget(angleErrorPlotWidget); + QWidget *angleErrorWidget = new QWidget(); + Style::setStyle(angleErrorWidget, style::properties::widget::basicBackground); + QVBoxLayout *angleErrorLayout = new QVBoxLayout(angleErrorWidget); + angleErrorWidget->setLayout(angleErrorLayout); + angleErrorLayout->setMargin(0); + angleErrorLayout->setSpacing(0); + + angleErrorPlotWidget = new PlotWidget(); + angleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + angleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, angleErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + angleErrorXPlotAxis->setMin(0); + angleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, angleErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + angleErrorYPlotAxis->setInterval(-4, 4); + + angleErrorPlotChannel = new PlotChannel("Angle Error", scopyBluePen, angleErrorXPlotAxis, angleErrorYPlotAxis); + + angleErrorPlotWidget->addPlotChannel(angleErrorPlotChannel); + angleErrorPlotChannel->setEnabled(true); + angleErrorPlotWidget->selectChannel(angleErrorPlotChannel); + + angleErrorPlotWidget->setShowXAxisLabels(true); + angleErrorPlotWidget->setShowYAxisLabels(true); + angleErrorPlotWidget->showAxisLabels(); + angleErrorPlotWidget->replot(); + + angleErrorLayout->addWidget(angleErrorPlotWidget); #pragma endregion #pragma region FFT Angle Error Widget - QWidget *FFTAngleErrorWidget = new QWidget(); - Style::setStyle(FFTAngleErrorWidget, - style::properties::widget::basicBackground); - QVBoxLayout *FFTAngleErrorLayout = new QVBoxLayout(FFTAngleErrorWidget); - FFTAngleErrorWidget->setLayout(FFTAngleErrorLayout); - FFTAngleErrorLayout->setMargin(0); - FFTAngleErrorLayout->setSpacing(0); - - FFTAngleErrorPlotWidget = new PlotWidget(); - FFTAngleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - - FFTAngleErrorXPlotAxis = new PlotAxis( - QwtAxis::XBottom, FFTAngleErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTAngleErrorXPlotAxis->setMin(0); - FFTAngleErrorYPlotAxis = new PlotAxis( - QwtAxis::YLeft, FFTAngleErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTAngleErrorYPlotAxis->setInterval(-4, 4); - - FFTAngleErrorMagnitudeChannel = - new PlotChannel("FFT Angle Error Magnitude", magnitudePen, - FFTAngleErrorXPlotAxis, FFTAngleErrorYPlotAxis); - FFTAngleErrorPhaseChannel = - new PlotChannel("FFT Angle Error Phase", phasePen, FFTAngleErrorXPlotAxis, - FFTAngleErrorYPlotAxis); - FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorMagnitudeChannel); - FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorPhaseChannel); - - FFTAngleErrorPhaseChannel->setEnabled(true); - FFTAngleErrorMagnitudeChannel->setEnabled(true); - FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); - - FFTAngleErrorPlotWidget->setShowXAxisLabels(true); - FFTAngleErrorPlotWidget->setShowYAxisLabels(true); - FFTAngleErrorPlotWidget->showAxisLabels(); - FFTAngleErrorPlotWidget->replot(); - - QWidget *FFTAngleErrorChannelsWidget = new QWidget(); - QHBoxLayout *FFTAngleErrorChannelsLayout = - new QHBoxLayout(FFTAngleErrorChannelsWidget); - ADMTStyleHelper::GraphChannelStyle(FFTAngleErrorChannelsWidget, - FFTAngleErrorChannelsLayout); - - MenuControlButton *toggleFFTAngleErrorMagnitudeButton = - createChannelToggleWidget("Magnitude", magnitudeColor, - FFTAngleErrorChannelsWidget); - MenuControlButton *toggleFFTAngleErrorPhaseButton = createChannelToggleWidget( - "Phase", phaseColor, FFTAngleErrorChannelsWidget); - - FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorMagnitudeButton); - FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorPhaseButton); - FFTAngleErrorChannelsLayout->addStretch(); - - FFTAngleErrorLayout->addWidget(FFTAngleErrorPlotWidget); - FFTAngleErrorLayout->addWidget(FFTAngleErrorChannelsWidget); + QWidget *FFTAngleErrorWidget = new QWidget(); + Style::setStyle(FFTAngleErrorWidget, style::properties::widget::basicBackground); + QVBoxLayout *FFTAngleErrorLayout = new QVBoxLayout(FFTAngleErrorWidget); + FFTAngleErrorWidget->setLayout(FFTAngleErrorLayout); + FFTAngleErrorLayout->setMargin(0); + FFTAngleErrorLayout->setSpacing(0); + + FFTAngleErrorPlotWidget = new PlotWidget(); + FFTAngleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + + FFTAngleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTAngleErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + FFTAngleErrorXPlotAxis->setMin(0); + FFTAngleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTAngleErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + FFTAngleErrorYPlotAxis->setInterval(-4, 4); + + FFTAngleErrorMagnitudeChannel = new PlotChannel("FFT Angle Error Magnitude", magnitudePen, + FFTAngleErrorXPlotAxis, FFTAngleErrorYPlotAxis); + FFTAngleErrorPhaseChannel = + new PlotChannel("FFT Angle Error Phase", phasePen, FFTAngleErrorXPlotAxis, FFTAngleErrorYPlotAxis); + FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorMagnitudeChannel); + FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorPhaseChannel); + + FFTAngleErrorPhaseChannel->setEnabled(true); + FFTAngleErrorMagnitudeChannel->setEnabled(true); + FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); + + FFTAngleErrorPlotWidget->setShowXAxisLabels(true); + FFTAngleErrorPlotWidget->setShowYAxisLabels(true); + FFTAngleErrorPlotWidget->showAxisLabels(); + FFTAngleErrorPlotWidget->replot(); + + QWidget *FFTAngleErrorChannelsWidget = new QWidget(); + QHBoxLayout *FFTAngleErrorChannelsLayout = new QHBoxLayout(FFTAngleErrorChannelsWidget); + ADMTStyleHelper::GraphChannelStyle(FFTAngleErrorChannelsWidget, FFTAngleErrorChannelsLayout); + + MenuControlButton *toggleFFTAngleErrorMagnitudeButton = + createChannelToggleWidget("Magnitude", magnitudeColor, FFTAngleErrorChannelsWidget); + MenuControlButton *toggleFFTAngleErrorPhaseButton = + createChannelToggleWidget("Phase", phaseColor, FFTAngleErrorChannelsWidget); + + FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorMagnitudeButton); + FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorPhaseButton); + FFTAngleErrorChannelsLayout->addStretch(); + + FFTAngleErrorLayout->addWidget(FFTAngleErrorPlotWidget); + FFTAngleErrorLayout->addWidget(FFTAngleErrorChannelsWidget); #pragma endregion #pragma region Corrected Error Widget - QWidget *correctedErrorWidget = new QWidget(); - Style::setStyle(correctedErrorWidget, - style::properties::widget::basicBackground); - QVBoxLayout *correctedErrorLayout = new QVBoxLayout(correctedErrorWidget); - correctedErrorWidget->setLayout(correctedErrorLayout); - correctedErrorLayout->setMargin(0); - correctedErrorLayout->setSpacing(0); - - correctedErrorPlotWidget = new PlotWidget(); - correctedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - - correctedErrorXPlotAxis = new PlotAxis( - QwtAxis::XBottom, correctedErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - correctedErrorXPlotAxis->setMin(0); - correctedErrorYPlotAxis = new PlotAxis( - QwtAxis::YLeft, correctedErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - correctedErrorYPlotAxis->setInterval(-4, 4); - - correctedErrorPlotChannel = - new PlotChannel("Corrected Error", scopyBluePen, correctedErrorXPlotAxis, - correctedErrorYPlotAxis); - correctedErrorPlotWidget->addPlotChannel(correctedErrorPlotChannel); - - correctedErrorPlotChannel->setEnabled(true); - correctedErrorPlotWidget->selectChannel(correctedErrorPlotChannel); - - correctedErrorPlotWidget->setShowXAxisLabels(true); - correctedErrorPlotWidget->setShowYAxisLabels(true); - correctedErrorPlotWidget->showAxisLabels(); - correctedErrorPlotWidget->replot(); - - correctedErrorLayout->addWidget(correctedErrorPlotWidget); + QWidget *correctedErrorWidget = new QWidget(); + Style::setStyle(correctedErrorWidget, style::properties::widget::basicBackground); + QVBoxLayout *correctedErrorLayout = new QVBoxLayout(correctedErrorWidget); + correctedErrorWidget->setLayout(correctedErrorLayout); + correctedErrorLayout->setMargin(0); + correctedErrorLayout->setSpacing(0); + + correctedErrorPlotWidget = new PlotWidget(); + correctedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + + correctedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, correctedErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + correctedErrorXPlotAxis->setMin(0); + correctedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, correctedErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + correctedErrorYPlotAxis->setInterval(-4, 4); + + correctedErrorPlotChannel = + new PlotChannel("Corrected Error", scopyBluePen, correctedErrorXPlotAxis, correctedErrorYPlotAxis); + correctedErrorPlotWidget->addPlotChannel(correctedErrorPlotChannel); + + correctedErrorPlotChannel->setEnabled(true); + correctedErrorPlotWidget->selectChannel(correctedErrorPlotChannel); + + correctedErrorPlotWidget->setShowXAxisLabels(true); + correctedErrorPlotWidget->setShowYAxisLabels(true); + correctedErrorPlotWidget->showAxisLabels(); + correctedErrorPlotWidget->replot(); + + correctedErrorLayout->addWidget(correctedErrorPlotWidget); #pragma endregion #pragma region FFT Corrected Error Widget - QWidget *FFTCorrectedErrorWidget = new QWidget(); - Style::setStyle(FFTCorrectedErrorWidget, - style::properties::widget::basicBackground); - QVBoxLayout *FFTCorrectedErrorLayout = - new QVBoxLayout(FFTCorrectedErrorWidget); - FFTCorrectedErrorWidget->setLayout(FFTCorrectedErrorLayout); - FFTCorrectedErrorLayout->setMargin(0); - FFTCorrectedErrorLayout->setSpacing(0); - - FFTCorrectedErrorPlotWidget = new PlotWidget(); - FFTCorrectedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - - FFTCorrectedErrorXPlotAxis = new PlotAxis( - QwtAxis::XBottom, FFTCorrectedErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTCorrectedErrorXPlotAxis->setMin(0); - FFTCorrectedErrorYPlotAxis = new PlotAxis( - QwtAxis::YLeft, FFTCorrectedErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTCorrectedErrorYPlotAxis->setInterval(-4, 4); - - FFTCorrectedErrorMagnitudeChannel = - new PlotChannel("FFT Corrected Error Magnitude", magnitudePen, - FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); - FFTCorrectedErrorPhaseChannel = - new PlotChannel("FFT Corrected Error Phase", phasePen, - FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); - FFTCorrectedErrorPlotWidget->addPlotChannel( - FFTCorrectedErrorMagnitudeChannel); - FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorPhaseChannel); - - FFTCorrectedErrorPhaseChannel->setEnabled(true); - FFTCorrectedErrorMagnitudeChannel->setEnabled(true); - FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); - - FFTCorrectedErrorPlotWidget->setShowXAxisLabels(true); - FFTCorrectedErrorPlotWidget->setShowYAxisLabels(true); - FFTCorrectedErrorPlotWidget->showAxisLabels(); - FFTCorrectedErrorPlotWidget->replot(); - - QWidget *FFTCorrectedErrorChannelsWidget = new QWidget(); - QHBoxLayout *FFTCorrectedErrorChannelsLayout = - new QHBoxLayout(FFTCorrectedErrorChannelsWidget); - ADMTStyleHelper::GraphChannelStyle(FFTCorrectedErrorChannelsWidget, - FFTCorrectedErrorChannelsLayout); - - MenuControlButton *toggleFFTCorrectedErrorMagnitudeButton = - createChannelToggleWidget("Magnitude", magnitudeColor, - FFTCorrectedErrorChannelsWidget); - MenuControlButton *toggleFFTCorrectedErrorPhaseButton = - createChannelToggleWidget("Phase", phaseColor, - FFTCorrectedErrorChannelsWidget); - - FFTCorrectedErrorChannelsLayout->addWidget( - toggleFFTCorrectedErrorMagnitudeButton); - FFTCorrectedErrorChannelsLayout->addWidget( - toggleFFTCorrectedErrorPhaseButton); - FFTCorrectedErrorChannelsLayout->addStretch(); - - FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorPlotWidget); - FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorChannelsWidget); + QWidget *FFTCorrectedErrorWidget = new QWidget(); + Style::setStyle(FFTCorrectedErrorWidget, style::properties::widget::basicBackground); + QVBoxLayout *FFTCorrectedErrorLayout = new QVBoxLayout(FFTCorrectedErrorWidget); + FFTCorrectedErrorWidget->setLayout(FFTCorrectedErrorLayout); + FFTCorrectedErrorLayout->setMargin(0); + FFTCorrectedErrorLayout->setSpacing(0); + + FFTCorrectedErrorPlotWidget = new PlotWidget(); + FFTCorrectedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + + FFTCorrectedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTCorrectedErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + FFTCorrectedErrorXPlotAxis->setMin(0); + FFTCorrectedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTCorrectedErrorPlotWidget, + QPen(Style::getColor(json::theme::interactive_primary_idle))); + FFTCorrectedErrorYPlotAxis->setInterval(-4, 4); + + FFTCorrectedErrorMagnitudeChannel = new PlotChannel("FFT Corrected Error Magnitude", magnitudePen, + FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); + FFTCorrectedErrorPhaseChannel = new PlotChannel("FFT Corrected Error Phase", phasePen, + FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); + FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorMagnitudeChannel); + FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorPhaseChannel); + + FFTCorrectedErrorPhaseChannel->setEnabled(true); + FFTCorrectedErrorMagnitudeChannel->setEnabled(true); + FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); + + FFTCorrectedErrorPlotWidget->setShowXAxisLabels(true); + FFTCorrectedErrorPlotWidget->setShowYAxisLabels(true); + FFTCorrectedErrorPlotWidget->showAxisLabels(); + FFTCorrectedErrorPlotWidget->replot(); + + QWidget *FFTCorrectedErrorChannelsWidget = new QWidget(); + QHBoxLayout *FFTCorrectedErrorChannelsLayout = new QHBoxLayout(FFTCorrectedErrorChannelsWidget); + ADMTStyleHelper::GraphChannelStyle(FFTCorrectedErrorChannelsWidget, FFTCorrectedErrorChannelsLayout); + + MenuControlButton *toggleFFTCorrectedErrorMagnitudeButton = + createChannelToggleWidget("Magnitude", magnitudeColor, FFTCorrectedErrorChannelsWidget); + MenuControlButton *toggleFFTCorrectedErrorPhaseButton = + createChannelToggleWidget("Phase", phaseColor, FFTCorrectedErrorChannelsWidget); + + FFTCorrectedErrorChannelsLayout->addWidget(toggleFFTCorrectedErrorMagnitudeButton); + FFTCorrectedErrorChannelsLayout->addWidget(toggleFFTCorrectedErrorPhaseButton); + FFTCorrectedErrorChannelsLayout->addStretch(); + + FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorPlotWidget); + FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorChannelsWidget); #pragma endregion - resultDataTabWidget->addTab(angleErrorWidget, "Angle Error"); - resultDataTabWidget->addTab(FFTAngleErrorWidget, "FFT Angle Error"); - resultDataTabWidget->addTab(correctedErrorWidget, "Corrected Error"); - resultDataTabWidget->addTab(FFTCorrectedErrorWidget, "FFT Corrected Error"); + resultDataTabWidget->addTab(angleErrorWidget, "Angle Error"); + resultDataTabWidget->addTab(FFTAngleErrorWidget, "FFT Angle Error"); + resultDataTabWidget->addTab(correctedErrorWidget, "Corrected Error"); + resultDataTabWidget->addTab(FFTCorrectedErrorWidget, "FFT Corrected Error"); - calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget, 0, - 0); - calibrationDataGraphLayout->addWidget(resultDataSectionWidget, 1, 0); + calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget, 0, 0); + calibrationDataGraphLayout->addWidget(resultDataSectionWidget, 1, 0); - calibrationDataGraphLayout->setColumnStretch(0, 1); - calibrationDataGraphLayout->setRowStretch(0, 1); - calibrationDataGraphLayout->setRowStretch(1, 1); + calibrationDataGraphLayout->setColumnStretch(0, 1); + calibrationDataGraphLayout->setRowStretch(0, 1); + calibrationDataGraphLayout->setRowStretch(1, 1); #pragma endregion #pragma region Calibration Settings Widget - QWidget *calibrationSettingsGroupWidget = new QWidget(); - QVBoxLayout *calibrationSettingsGroupLayout = - new QVBoxLayout(calibrationSettingsGroupWidget); - calibrationSettingsGroupWidget->setLayout(calibrationSettingsGroupLayout); - calibrationSettingsGroupLayout->setMargin(0); - calibrationSettingsGroupLayout->setSpacing(8); + QWidget *calibrationSettingsGroupWidget = new QWidget(); + QVBoxLayout *calibrationSettingsGroupLayout = new QVBoxLayout(calibrationSettingsGroupWidget); + calibrationSettingsGroupWidget->setLayout(calibrationSettingsGroupLayout); + calibrationSettingsGroupLayout->setMargin(0); + calibrationSettingsGroupLayout->setSpacing(8); #pragma region Device Status Widget - MenuSectionWidget *calibrationDeviceStatusWidget = - new MenuSectionWidget(calibrationSettingsGroupWidget); - Style::setStyle(calibrationDeviceStatusWidget, - style::properties::widget::basicComponent); - calibrationDeviceStatusWidget->contentLayout()->setSpacing(8); - MenuCollapseSection *calibrationDeviceStatusSection = new MenuCollapseSection( - "Device Status", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - calibrationSettingsGroupWidget); - calibrationDeviceStatusSection->contentLayout()->setSpacing(8); - calibrationDeviceStatusWidget->contentLayout()->addWidget( - calibrationDeviceStatusSection); - - calibrationFaultRegisterLEDWidget = createStatusLEDWidget( - "Fault Register", "status", false, calibrationDeviceStatusSection); - calibrationDeviceStatusSection->contentLayout()->addWidget( - calibrationFaultRegisterLEDWidget); - - if (deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == - 1) // Automotive & Sequence Mode 2 - { - QCheckBox *calibrationSPICRCLEDWidget = createStatusLEDWidget( - "SPI CRC", "status", false, calibrationDeviceStatusSection); - QCheckBox *calibrationSPIFlagLEDWidget = createStatusLEDWidget( - "SPI Flag", "status", false, calibrationDeviceStatusSection); - calibrationDeviceStatusSection->contentLayout()->addWidget( - calibrationSPICRCLEDWidget); - calibrationDeviceStatusSection->contentLayout()->addWidget( - calibrationSPIFlagLEDWidget); - } + MenuSectionWidget *calibrationDeviceStatusWidget = new MenuSectionWidget(calibrationSettingsGroupWidget); + Style::setStyle(calibrationDeviceStatusWidget, style::properties::widget::basicComponent); + calibrationDeviceStatusWidget->contentLayout()->setSpacing(8); + MenuCollapseSection *calibrationDeviceStatusSection = new MenuCollapseSection( + "Device Status", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationSettingsGroupWidget); + calibrationDeviceStatusSection->contentLayout()->setSpacing(8); + calibrationDeviceStatusWidget->contentLayout()->addWidget(calibrationDeviceStatusSection); + + calibrationFaultRegisterLEDWidget = + createStatusLEDWidget("Fault Register", "status", false, calibrationDeviceStatusSection); + calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationFaultRegisterLEDWidget); + + if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 + { + QCheckBox *calibrationSPICRCLEDWidget = + createStatusLEDWidget("SPI CRC", "status", false, calibrationDeviceStatusSection); + QCheckBox *calibrationSPIFlagLEDWidget = + createStatusLEDWidget("SPI Flag", "status", false, calibrationDeviceStatusSection); + calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPICRCLEDWidget); + calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPIFlagLEDWidget); + } #pragma endregion #pragma region Acquire Calibration Samples Button - calibrationStartMotorButton = - new QPushButton(" Acquire Samples", calibrationSettingsGroupWidget); - Style::setStyle(calibrationStartMotorButton, - style::properties::admt::fullWidthRunButton); - calibrationStartMotorButton->setCheckable(true); - calibrationStartMotorButton->setChecked(false); - QIcon icon1; - icon1.addPixmap( - Style::getPixmap(":/gui/icons/play.svg", - Style::getColor(json::theme::content_inverse)), - QIcon::Normal, QIcon::Off); - icon1.addPixmap( - Style::getPixmap(":/gui/icons/" + - Style::getAttribute(json::theme::icon_theme_folder) + - "/icons/play_stop.svg", - Style::getColor(json::theme::content_inverse)), - QIcon::Normal, QIcon::On); - calibrationStartMotorButton->setIcon(icon1); - - connect(calibrationStartMotorButton, &QPushButton::toggled, this, - [this](bool toggled) { - calibrationStartMotorButton->setText(toggled ? " Stop Acquisition" - : " Acquire Samples"); - isStartMotor = toggled; - if (toggled) { - isPostCalibration = false; - startCalibration(); - } else { - stopCalibration(); - } - }); + calibrationStartMotorButton = new QPushButton(" Acquire Samples", calibrationSettingsGroupWidget); + Style::setStyle(calibrationStartMotorButton, style::properties::admt::fullWidthRunButton); + calibrationStartMotorButton->setCheckable(true); + calibrationStartMotorButton->setChecked(false); + QIcon icon1; + icon1.addPixmap(Style::getPixmap(":/gui/icons/play.svg", Style::getColor(json::theme::content_inverse)), + QIcon::Normal, QIcon::Off); + icon1.addPixmap(Style::getPixmap(":/gui/icons/" + Style::getAttribute(json::theme::icon_theme_folder) + + "/icons/play_stop.svg", + Style::getColor(json::theme::content_inverse)), + QIcon::Normal, QIcon::On); + calibrationStartMotorButton->setIcon(icon1); + + connect(calibrationStartMotorButton, &QPushButton::toggled, this, [this](bool toggled) { + calibrationStartMotorButton->setText(toggled ? " Stop Acquisition" : " Acquire Samples"); + isStartMotor = toggled; + if(toggled) { + isPostCalibration = false; + startCalibration(); + } else { + stopCalibration(); + } + }); #pragma endregion #pragma region Start Calibration Button - calibrateDataButton = - new QPushButton(" Calibrate", calibrationSettingsGroupWidget); - Style::setStyle(calibrateDataButton, - style::properties::admt::fullWidthRunButton); - calibrateDataButton->setCheckable(true); - calibrateDataButton->setChecked(false); - calibrateDataButton->setEnabled(false); - calibrateDataButton->setIcon(icon1); - - connect(calibrateDataButton, &QPushButton::toggled, this, [this](bool toggled) { - calibrateDataButton->setText(toggled ? " Stop Calibration" : " Calibrate"); - if (toggled) - postCalibrateData(); - else - stopCalibration(); - }); + calibrateDataButton = new QPushButton(" Calibrate", calibrationSettingsGroupWidget); + Style::setStyle(calibrateDataButton, style::properties::admt::fullWidthRunButton); + calibrateDataButton->setCheckable(true); + calibrateDataButton->setChecked(false); + calibrateDataButton->setEnabled(false); + calibrateDataButton->setIcon(icon1); + + connect(calibrateDataButton, &QPushButton::toggled, this, [this](bool toggled) { + calibrateDataButton->setText(toggled ? " Stop Calibration" : " Calibrate"); + if(toggled) + postCalibrateData(); + else + stopCalibration(); + }); #pragma endregion #pragma region Reset Calibration Button - clearCalibrateDataButton = - new QPushButton("Reset Calibration", calibrationSettingsGroupWidget); - StyleHelper::BasicButton(clearCalibrateDataButton); - QIcon resetIcon; - // resetIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/refresh.svg", - // "white", 1), QIcon::Normal, QIcon::Off); - resetIcon.addPixmap( - Style::getPixmap(":/gui/icons/refresh.svg", - Style::getColor(json::theme::content_inverse)), - QIcon::Normal, QIcon::Off); - clearCalibrateDataButton->setIcon(resetIcon); - clearCalibrateDataButton->setIconSize(QSize(26, 26)); + clearCalibrateDataButton = new QPushButton("Reset Calibration", calibrationSettingsGroupWidget); + StyleHelper::BasicButton(clearCalibrateDataButton); + QIcon resetIcon; + // resetIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/refresh.svg", + // "white", 1), QIcon::Normal, QIcon::Off); + resetIcon.addPixmap(Style::getPixmap(":/gui/icons/refresh.svg", Style::getColor(json::theme::content_inverse)), + QIcon::Normal, QIcon::Off); + clearCalibrateDataButton->setIcon(resetIcon); + clearCalibrateDataButton->setIconSize(QSize(26, 26)); #pragma endregion - QScrollArea *calibrationSettingsScrollArea = new QScrollArea(); - QWidget *calibrationSettingsWidget = - new QWidget(calibrationSettingsScrollArea); - QVBoxLayout *calibrationSettingsLayout = - new QVBoxLayout(calibrationSettingsWidget); - calibrationSettingsScrollArea->setWidgetResizable(true); - calibrationSettingsScrollArea->setWidget(calibrationSettingsWidget); - calibrationSettingsWidget->setFixedWidth(260); - calibrationSettingsWidget->setLayout(calibrationSettingsLayout); - - calibrationSettingsGroupLayout->addWidget(calibrationDeviceStatusWidget); - calibrationSettingsGroupLayout->addWidget(calibrationStartMotorButton); - calibrationSettingsGroupLayout->addWidget(calibrateDataButton); - calibrationSettingsGroupLayout->addWidget(clearCalibrateDataButton); - calibrationSettingsGroupLayout->addWidget(calibrationSettingsScrollArea); + QScrollArea *calibrationSettingsScrollArea = new QScrollArea(); + QWidget *calibrationSettingsWidget = new QWidget(calibrationSettingsScrollArea); + QVBoxLayout *calibrationSettingsLayout = new QVBoxLayout(calibrationSettingsWidget); + calibrationSettingsScrollArea->setWidgetResizable(true); + calibrationSettingsScrollArea->setWidget(calibrationSettingsWidget); + calibrationSettingsWidget->setFixedWidth(260); + calibrationSettingsWidget->setLayout(calibrationSettingsLayout); + + calibrationSettingsGroupLayout->addWidget(calibrationDeviceStatusWidget); + calibrationSettingsGroupLayout->addWidget(calibrationStartMotorButton); + calibrationSettingsGroupLayout->addWidget(calibrateDataButton); + calibrationSettingsGroupLayout->addWidget(clearCalibrateDataButton); + calibrationSettingsGroupLayout->addWidget(calibrationSettingsScrollArea); #pragma region Calibration Coefficient Section Widget - MenuSectionWidget *calibrationCoeffSectionWidget = - new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(calibrationCoeffSectionWidget, - style::properties::widget::basicComponent); - QLabel *calibrationDisplayFormatLabel = - new QLabel(calibrationCoeffSectionWidget); - calibrationDisplayFormatLabel->setText("Display Format"); - Style::setStyle(calibrationDisplayFormatLabel, - style::properties::label::menuMedium); - QLabel *calibrationCalculatedCoeffLabel = - new QLabel(calibrationCoeffSectionWidget); - calibrationCalculatedCoeffLabel->setText("Calculated Coefficients"); - Style::setStyle(calibrationCalculatedCoeffLabel, - style::properties::label::menuMedium); - - calibrationDisplayFormatSwitch = new CustomSwitch(); - calibrationDisplayFormatSwitch->setOffText("Hex"); - calibrationDisplayFormatSwitch->setOnText("Angle"); - calibrationDisplayFormatSwitch->setProperty("bigBtn", true); - - QWidget *calibrationCalculatedCoeffWidget = - new QWidget(calibrationCoeffSectionWidget); - QGridLayout *calibrationCalculatedCoeffLayout = - new QGridLayout(calibrationCalculatedCoeffWidget); - - calibrationCalculatedCoeffWidget->setLayout(calibrationCalculatedCoeffLayout); - calibrationCalculatedCoeffLayout->setMargin(0); - calibrationCalculatedCoeffLayout->setVerticalSpacing(4); - Style::setStyle(calibrationCalculatedCoeffWidget, - style::properties::widget::basicBackground); - - QWidget *h1RowContainer = new QWidget(calibrationCalculatedCoeffWidget); - QHBoxLayout *h1RowLayout = new QHBoxLayout(h1RowContainer); - QLabel *calibrationH1Label = - new QLabel("H1", calibrationCalculatedCoeffWidget); - calibrationH1MagLabel = - new QLabel("0x----", calibrationCalculatedCoeffWidget); - calibrationH1PhaseLabel = - new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle( - h1RowContainer, h1RowLayout, calibrationH1Label, calibrationH1MagLabel, - calibrationH1PhaseLabel); - - QWidget *h2RowContainer = new QWidget(calibrationCalculatedCoeffWidget); - QHBoxLayout *h2RowLayout = new QHBoxLayout(h2RowContainer); - QLabel *calibrationH2Label = - new QLabel("H2", calibrationCalculatedCoeffWidget); - calibrationH2MagLabel = - new QLabel("0x----", calibrationCalculatedCoeffWidget); - calibrationH2PhaseLabel = - new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle( - h2RowContainer, h2RowLayout, calibrationH2Label, calibrationH2MagLabel, - calibrationH2PhaseLabel); - - QWidget *h3RowContainer = new QWidget(calibrationCalculatedCoeffWidget); - QHBoxLayout *h3RowLayout = new QHBoxLayout(h3RowContainer); - QLabel *calibrationH3Label = - new QLabel("H3", calibrationCalculatedCoeffWidget); - calibrationH3MagLabel = - new QLabel("0x----", calibrationCalculatedCoeffWidget); - calibrationH3PhaseLabel = - new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle( - h3RowContainer, h3RowLayout, calibrationH3Label, calibrationH3MagLabel, - calibrationH3PhaseLabel); - - QWidget *h8RowContainer = new QWidget(calibrationCalculatedCoeffWidget); - QHBoxLayout *h8RowLayout = new QHBoxLayout(h8RowContainer); - QLabel *calibrationH8Label = - new QLabel("H8", calibrationCalculatedCoeffWidget); - calibrationH8MagLabel = - new QLabel("0x----", calibrationCalculatedCoeffWidget); - calibrationH8PhaseLabel = - new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle( - h8RowContainer, h8RowLayout, calibrationH8Label, calibrationH8MagLabel, - calibrationH8PhaseLabel); - - calibrationCalculatedCoeffLayout->addWidget(h1RowContainer, 0, 0); - calibrationCalculatedCoeffLayout->addWidget(h2RowContainer, 1, 0); - calibrationCalculatedCoeffLayout->addWidget(h3RowContainer, 2, 0); - calibrationCalculatedCoeffLayout->addWidget(h8RowContainer, 3, 0); - - calibrationCoeffSectionWidget->contentLayout()->setSpacing(8); - calibrationCoeffSectionWidget->contentLayout()->addWidget( - calibrationDisplayFormatLabel); - calibrationCoeffSectionWidget->contentLayout()->addWidget( - calibrationDisplayFormatSwitch); - calibrationCoeffSectionWidget->contentLayout()->addWidget( - calibrationCalculatedCoeffLabel); - calibrationCoeffSectionWidget->contentLayout()->addWidget( - calibrationCalculatedCoeffWidget); + MenuSectionWidget *calibrationCoeffSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(calibrationCoeffSectionWidget, style::properties::widget::basicComponent); + QLabel *calibrationDisplayFormatLabel = new QLabel(calibrationCoeffSectionWidget); + calibrationDisplayFormatLabel->setText("Display Format"); + Style::setStyle(calibrationDisplayFormatLabel, style::properties::label::menuMedium); + QLabel *calibrationCalculatedCoeffLabel = new QLabel(calibrationCoeffSectionWidget); + calibrationCalculatedCoeffLabel->setText("Calculated Coefficients"); + Style::setStyle(calibrationCalculatedCoeffLabel, style::properties::label::menuMedium); + + calibrationDisplayFormatSwitch = new CustomSwitch(); + calibrationDisplayFormatSwitch->setOffText("Hex"); + calibrationDisplayFormatSwitch->setOnText("Angle"); + calibrationDisplayFormatSwitch->setProperty("bigBtn", true); + + QWidget *calibrationCalculatedCoeffWidget = new QWidget(calibrationCoeffSectionWidget); + QGridLayout *calibrationCalculatedCoeffLayout = new QGridLayout(calibrationCalculatedCoeffWidget); + + calibrationCalculatedCoeffWidget->setLayout(calibrationCalculatedCoeffLayout); + calibrationCalculatedCoeffLayout->setMargin(0); + calibrationCalculatedCoeffLayout->setVerticalSpacing(4); + Style::setStyle(calibrationCalculatedCoeffWidget, style::properties::widget::basicBackground); + + QWidget *h1RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h1RowLayout = new QHBoxLayout(h1RowContainer); + QLabel *calibrationH1Label = new QLabel("H1", calibrationCalculatedCoeffWidget); + calibrationH1MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH1PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h1RowContainer, h1RowLayout, calibrationH1Label, + calibrationH1MagLabel, calibrationH1PhaseLabel); + + QWidget *h2RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h2RowLayout = new QHBoxLayout(h2RowContainer); + QLabel *calibrationH2Label = new QLabel("H2", calibrationCalculatedCoeffWidget); + calibrationH2MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH2PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h2RowContainer, h2RowLayout, calibrationH2Label, + calibrationH2MagLabel, calibrationH2PhaseLabel); + + QWidget *h3RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h3RowLayout = new QHBoxLayout(h3RowContainer); + QLabel *calibrationH3Label = new QLabel("H3", calibrationCalculatedCoeffWidget); + calibrationH3MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH3PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h3RowContainer, h3RowLayout, calibrationH3Label, + calibrationH3MagLabel, calibrationH3PhaseLabel); + + QWidget *h8RowContainer = new QWidget(calibrationCalculatedCoeffWidget); + QHBoxLayout *h8RowLayout = new QHBoxLayout(h8RowContainer); + QLabel *calibrationH8Label = new QLabel("H8", calibrationCalculatedCoeffWidget); + calibrationH8MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + calibrationH8PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); + ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h8RowContainer, h8RowLayout, calibrationH8Label, + calibrationH8MagLabel, calibrationH8PhaseLabel); + + calibrationCalculatedCoeffLayout->addWidget(h1RowContainer, 0, 0); + calibrationCalculatedCoeffLayout->addWidget(h2RowContainer, 1, 0); + calibrationCalculatedCoeffLayout->addWidget(h3RowContainer, 2, 0); + calibrationCalculatedCoeffLayout->addWidget(h8RowContainer, 3, 0); + + calibrationCoeffSectionWidget->contentLayout()->setSpacing(8); + calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatLabel); + calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatSwitch); + calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffLabel); + calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffWidget); #pragma endregion #pragma region Calibration Dataset Configuration - MenuSectionWidget *calibrationDatasetConfigSectionWidget = - new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(calibrationDatasetConfigSectionWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *calibrationDatasetConfigCollapseSection = - new MenuCollapseSection( - "Dataset Configuration", - MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - calibrationDatasetConfigSectionWidget); - calibrationDatasetConfigSectionWidget->contentLayout()->setSpacing(8); - calibrationDatasetConfigSectionWidget->contentLayout()->addWidget( - calibrationDatasetConfigCollapseSection); + MenuSectionWidget *calibrationDatasetConfigSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(calibrationDatasetConfigSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *calibrationDatasetConfigCollapseSection = new MenuCollapseSection( + "Dataset Configuration", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationDatasetConfigSectionWidget); + calibrationDatasetConfigSectionWidget->contentLayout()->setSpacing(8); + calibrationDatasetConfigSectionWidget->contentLayout()->addWidget(calibrationDatasetConfigCollapseSection); #pragma region Continuous Calibration Toggle - calibrationModeMenuCombo = new MenuCombo( - "Calibration Mode", calibrationDatasetConfigCollapseSection); - auto calibrationModeCombo = calibrationModeMenuCombo->combo(); - calibrationModeCombo->addItem("Continuous", QVariant(0)); - calibrationModeCombo->addItem("One Shot", QVariant(1)); - connectMenuComboToNumber(calibrationModeMenuCombo, calibrationMode); + calibrationModeMenuCombo = new MenuCombo("Calibration Mode", calibrationDatasetConfigCollapseSection); + auto calibrationModeCombo = calibrationModeMenuCombo->combo(); + calibrationModeCombo->addItem("Continuous", QVariant(0)); + calibrationModeCombo->addItem("One Shot", QVariant(1)); + connectMenuComboToNumber(calibrationModeMenuCombo, calibrationMode); #pragma endregion - QWidget *calibrationCycleCountWidget = - new QWidget(calibrationDatasetConfigCollapseSection); - QVBoxLayout *calibrationCycleCountLayout = - new QVBoxLayout(calibrationCycleCountWidget); - calibrationCycleCountWidget->setLayout(calibrationCycleCountLayout); - calibrationCycleCountLayout->setMargin(0); - calibrationCycleCountLayout->setSpacing(0); - QLabel *calibrationCycleCountLabel = - new QLabel("Cycle Count", calibrationCycleCountWidget); - QLineEdit *calibrationCycleCountLineEdit = - new QLineEdit(calibrationCycleCountWidget); - calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); - connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 1000); - calibrationCycleCountLayout->addWidget(calibrationCycleCountLabel); - calibrationCycleCountLayout->addWidget(calibrationCycleCountLineEdit); - - QWidget *calibrationSamplesPerCycleWidget = - new QWidget(calibrationDatasetConfigCollapseSection); - QVBoxLayout *calibrationSamplesPerCycleLayout = - new QVBoxLayout(calibrationSamplesPerCycleWidget); - calibrationSamplesPerCycleWidget->setLayout(calibrationSamplesPerCycleLayout); - calibrationSamplesPerCycleLayout->setMargin(0); - calibrationSamplesPerCycleLayout->setSpacing(0); - QLabel *calibrationSamplesPerCycleLabel = - new QLabel("Samples Per Cycle", calibrationSamplesPerCycleWidget); - QLineEdit *calibrationSamplesPerCycleLineEdit = - new QLineEdit(calibrationSamplesPerCycleWidget); - calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); - connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, - 1, 5000); - calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLabel); - calibrationSamplesPerCycleLayout->addWidget( - calibrationSamplesPerCycleLineEdit); - - calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(8); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget( - calibrationModeMenuCombo); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget( - calibrationCycleCountWidget); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget( - calibrationSamplesPerCycleWidget); + QWidget *calibrationCycleCountWidget = new QWidget(calibrationDatasetConfigCollapseSection); + QVBoxLayout *calibrationCycleCountLayout = new QVBoxLayout(calibrationCycleCountWidget); + calibrationCycleCountWidget->setLayout(calibrationCycleCountLayout); + calibrationCycleCountLayout->setMargin(0); + calibrationCycleCountLayout->setSpacing(0); + QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", calibrationCycleCountWidget); + QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(calibrationCycleCountWidget); + calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); + connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 1000); + calibrationCycleCountLayout->addWidget(calibrationCycleCountLabel); + calibrationCycleCountLayout->addWidget(calibrationCycleCountLineEdit); + + QWidget *calibrationSamplesPerCycleWidget = new QWidget(calibrationDatasetConfigCollapseSection); + QVBoxLayout *calibrationSamplesPerCycleLayout = new QVBoxLayout(calibrationSamplesPerCycleWidget); + calibrationSamplesPerCycleWidget->setLayout(calibrationSamplesPerCycleLayout); + calibrationSamplesPerCycleLayout->setMargin(0); + calibrationSamplesPerCycleLayout->setSpacing(0); + QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", calibrationSamplesPerCycleWidget); + QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationSamplesPerCycleWidget); + calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); + connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, 1, 5000); + calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLabel); + calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLineEdit); + + calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(8); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationModeMenuCombo); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountWidget); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleWidget); #pragma endregion #pragma region Calibration Data Section Widget - MenuSectionWidget *calibrationDataSectionWidget = - new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(calibrationDataSectionWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection( - "Calibration Data", - MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - calibrationDataSectionWidget); - calibrationDataSectionWidget->contentLayout()->setSpacing(8); - calibrationDataSectionWidget->contentLayout()->addWidget( - calibrationDataCollapseSection); - - QPushButton *importSamplesButton = - new QPushButton("Import Samples", calibrationDataCollapseSection); - QPushButton *extractDataButton = - new QPushButton("Save to CSV", calibrationDataCollapseSection); - StyleHelper::BasicButton(importSamplesButton); - StyleHelper::BasicButton(extractDataButton); - - calibrationDataCollapseSection->contentLayout()->setSpacing(8); - calibrationDataCollapseSection->contentLayout()->addWidget( - importSamplesButton); - calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); + MenuSectionWidget *calibrationDataSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(calibrationDataSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection( + "Calibration Data", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationDataSectionWidget); + calibrationDataSectionWidget->contentLayout()->setSpacing(8); + calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); + + QPushButton *importSamplesButton = new QPushButton("Import Samples", calibrationDataCollapseSection); + QPushButton *extractDataButton = new QPushButton("Save to CSV", calibrationDataCollapseSection); + StyleHelper::BasicButton(importSamplesButton); + StyleHelper::BasicButton(extractDataButton); + + calibrationDataCollapseSection->contentLayout()->setSpacing(8); + calibrationDataCollapseSection->contentLayout()->addWidget(importSamplesButton); + calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); #pragma endregion #pragma region Motor Control Section Widget - MenuSectionWidget *motorControlSectionWidget = - new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(motorControlSectionWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection( - "Motor Control", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - motorControlSectionWidget); - motorControlSectionWidget->contentLayout()->setSpacing(8); - motorControlSectionWidget->contentLayout()->addWidget( - motorControlCollapseSection); - - QWidget *motorRPMWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); - motorRPMWidget->setLayout(motorRPMLayout); - motorRPMLayout->setMargin(0); - motorRPMLayout->setSpacing(0); - QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); - calibrationMotorRPMLineEdit = - new QLineEdit(QString::number(motor_rpm), motorRPMWidget); - connectLineEditToRPM(calibrationMotorRPMLineEdit, motor_rpm); - motorRPMLayout->addWidget(motorRPMLabel); - motorRPMLayout->addWidget(calibrationMotorRPMLineEdit); - - QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); - currentPositionWidget->setLayout(currentPositionLayout); - currentPositionLayout->setMargin(0); - currentPositionLayout->setSpacing(0); - QLabel *currentPositionLabel = - new QLabel("Current Position", currentPositionWidget); - calibrationMotorCurrentPositionLineEdit = - new QLineEdit("--.--", currentPositionWidget); - calibrationMotorCurrentPositionLineEdit->setReadOnly(true); - connectLineEditToDouble(calibrationMotorCurrentPositionLineEdit, current_pos); - currentPositionLayout->addWidget(currentPositionLabel); - currentPositionLayout->addWidget(calibrationMotorCurrentPositionLineEdit); - - QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); - targetPositionWidget->setLayout(targetPositionLayout); - targetPositionLayout->setMargin(0); - targetPositionLayout->setSpacing(0); - QLabel *targetPositionLabel = - new QLabel("Target Position", targetPositionWidget); - motorTargetPositionLineEdit = - new QLineEdit(QString::number(target_pos), targetPositionWidget); - connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, - ADMTController::MotorAttribute::TARGET_POS); - targetPositionLayout->addWidget(targetPositionLabel); - targetPositionLayout->addWidget(motorTargetPositionLineEdit); - - QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); - motorDirectionWidget->setLayout(motorDirectionLayout); - motorDirectionLayout->setMargin(0); - motorDirectionLayout->setSpacing(0); - QLabel *motorDirectionLabel = - new QLabel("Rotation Direction", motorDirectionWidget); - calibrationMotorDirectionSwitch = - new CustomSwitch("CW", "CCW", motorControlSectionWidget); - calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); - connect(calibrationMotorDirectionSwitch, &CustomSwitch::toggled, this, - [this](bool b) { isMotorRotationClockwise = b; }); - motorDirectionLayout->addWidget(motorDirectionLabel); - motorDirectionLayout->addWidget(calibrationMotorDirectionSwitch); - - QPushButton *continuousRotationButton = - new QPushButton("Continuous Rotation", motorControlSectionWidget); - StyleHelper::BasicButton(continuousRotationButton); - connect(continuousRotationButton, &QPushButton::clicked, this, - &HarmonicCalibration::moveMotorContinuous); - - QPushButton *stopMotorButton = - new QPushButton("Stop Motor", motorControlSectionWidget); - StyleHelper::BasicButton(stopMotorButton); - connect(stopMotorButton, &QPushButton::clicked, this, - &HarmonicCalibration::stopMotor); - - motorControlCollapseSection->contentLayout()->setSpacing(8); - motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); - motorControlCollapseSection->contentLayout()->addWidget( - currentPositionWidget); - motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); - motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); - motorControlCollapseSection->contentLayout()->addWidget( - continuousRotationButton); - motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); + MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(motorControlSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection( + "Motor Control", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorControlSectionWidget); + motorControlSectionWidget->contentLayout()->setSpacing(8); + motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); + + QWidget *motorRPMWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); + motorRPMWidget->setLayout(motorRPMLayout); + motorRPMLayout->setMargin(0); + motorRPMLayout->setSpacing(0); + QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); + calibrationMotorRPMLineEdit = new QLineEdit(QString::number(motor_rpm), motorRPMWidget); + connectLineEditToRPM(calibrationMotorRPMLineEdit, motor_rpm); + motorRPMLayout->addWidget(motorRPMLabel); + motorRPMLayout->addWidget(calibrationMotorRPMLineEdit); + + QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); + currentPositionWidget->setLayout(currentPositionLayout); + currentPositionLayout->setMargin(0); + currentPositionLayout->setSpacing(0); + QLabel *currentPositionLabel = new QLabel("Current Position", currentPositionWidget); + calibrationMotorCurrentPositionLineEdit = new QLineEdit("--.--", currentPositionWidget); + calibrationMotorCurrentPositionLineEdit->setReadOnly(true); + connectLineEditToDouble(calibrationMotorCurrentPositionLineEdit, current_pos); + currentPositionLayout->addWidget(currentPositionLabel); + currentPositionLayout->addWidget(calibrationMotorCurrentPositionLineEdit); + + QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); + targetPositionWidget->setLayout(targetPositionLayout); + targetPositionLayout->setMargin(0); + targetPositionLayout->setSpacing(0); + QLabel *targetPositionLabel = new QLabel("Target Position", targetPositionWidget); + motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), targetPositionWidget); + connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, + ADMTController::MotorAttribute::TARGET_POS); + targetPositionLayout->addWidget(targetPositionLabel); + targetPositionLayout->addWidget(motorTargetPositionLineEdit); + + QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); + motorDirectionWidget->setLayout(motorDirectionLayout); + motorDirectionLayout->setMargin(0); + motorDirectionLayout->setSpacing(0); + QLabel *motorDirectionLabel = new QLabel("Rotation Direction", motorDirectionWidget); + calibrationMotorDirectionSwitch = new CustomSwitch("CW", "CCW", motorControlSectionWidget); + calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); + connect(calibrationMotorDirectionSwitch, &CustomSwitch::toggled, this, + [this](bool b) { isMotorRotationClockwise = b; }); + motorDirectionLayout->addWidget(motorDirectionLabel); + motorDirectionLayout->addWidget(calibrationMotorDirectionSwitch); + + QPushButton *continuousRotationButton = new QPushButton("Continuous Rotation", motorControlSectionWidget); + StyleHelper::BasicButton(continuousRotationButton); + connect(continuousRotationButton, &QPushButton::clicked, this, &HarmonicCalibration::moveMotorContinuous); + + QPushButton *stopMotorButton = new QPushButton("Stop Motor", motorControlSectionWidget); + StyleHelper::BasicButton(stopMotorButton); + connect(stopMotorButton, &QPushButton::clicked, this, &HarmonicCalibration::stopMotor); + + motorControlCollapseSection->contentLayout()->setSpacing(8); + motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); + motorControlCollapseSection->contentLayout()->addWidget(currentPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); + motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); + motorControlCollapseSection->contentLayout()->addWidget(continuousRotationButton); + motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); #pragma endregion #pragma region Logs Section Widget - MenuSectionWidget *logsSectionWidget = - new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(logsSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *logsCollapseSection = new MenuCollapseSection( - "Logs", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - logsSectionWidget); - logsCollapseSection->header()->toggle(); - logsSectionWidget->contentLayout()->setSpacing(8); - logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); - - logsPlainTextEdit = new QPlainTextEdit(logsSectionWidget); - logsPlainTextEdit->setReadOnly(true); - logsPlainTextEdit->setFixedHeight(320); - logsPlainTextEdit->setStyleSheet("QPlainTextEdit { border: none; }"); - - logsCollapseSection->contentLayout()->setSpacing(8); - logsCollapseSection->contentLayout()->addWidget(logsPlainTextEdit); + MenuSectionWidget *logsSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(logsSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *logsCollapseSection = + new MenuCollapseSection("Logs", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, logsSectionWidget); + logsCollapseSection->header()->toggle(); + logsSectionWidget->contentLayout()->setSpacing(8); + logsSectionWidget->contentLayout()->addWidget(logsCollapseSection); + + logsPlainTextEdit = new QPlainTextEdit(logsSectionWidget); + logsPlainTextEdit->setReadOnly(true); + logsPlainTextEdit->setFixedHeight(320); + logsPlainTextEdit->setStyleSheet("QPlainTextEdit { border: none; }"); + + logsCollapseSection->contentLayout()->setSpacing(8); + logsCollapseSection->contentLayout()->addWidget(logsPlainTextEdit); #pragma endregion - calibrationSettingsLayout->setMargin(0); - calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); - calibrationSettingsLayout->addWidget(motorControlSectionWidget); - calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); - // calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); - calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); - calibrationSettingsLayout->addWidget(logsSectionWidget); - calibrationSettingsLayout->addSpacerItem( - new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + calibrationSettingsLayout->setMargin(0); + calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); + calibrationSettingsLayout->addWidget(motorControlSectionWidget); + calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); + // calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); + calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); + calibrationSettingsLayout->addWidget(logsSectionWidget); + calibrationSettingsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); #pragma endregion - tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - tool->topContainer()->setVisible(false); - tool->topContainerMenuControl()->setVisible(false); - tool->leftContainer()->setVisible(false); - tool->rightContainer()->setVisible(true); - tool->bottomContainer()->setVisible(false); - tool->setLeftContainerWidth(270); - tool->setRightContainerWidth(270); - tool->openBottomContainerHelper(false); - tool->openTopContainerHelper(false); - - tool->addWidgetToCentralContainerHelper(calibrationDataGraphWidget); - tool->rightStack()->add("calibrationSettingsGroupWidget", - calibrationSettingsGroupWidget); - - connect(extractDataButton, &QPushButton::clicked, this, - &HarmonicCalibration::extractCalibrationData); - connect(importSamplesButton, &QPushButton::clicked, this, - &HarmonicCalibration::importCalibrationData); - connect(clearCalibrateDataButton, &QPushButton::clicked, this, - &HarmonicCalibration::resetAllCalibrationState); - connect(toggleAngleButton->checkBox(), &QCheckBox::toggled, this, - [this](bool b) { - calibrationRawDataPlotWidget->selectChannel( - calibrationRawDataPlotChannel); - calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleSineButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { - calibrationRawDataPlotWidget->selectChannel(calibrationSineDataPlotChannel); - calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleCosineButton->checkBox(), &QCheckBox::toggled, this, - [this](bool b) { - calibrationRawDataPlotWidget->selectChannel( - calibrationCosineDataPlotChannel); - calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(togglePostAngleButton->checkBox(), &QCheckBox::toggled, this, - [this](bool b) { - postCalibrationRawDataPlotWidget->selectChannel( - postCalibrationRawDataPlotChannel); - postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(togglePostSineButton->checkBox(), &QCheckBox::toggled, this, - [this](bool b) { - postCalibrationRawDataPlotWidget->selectChannel( - postCalibrationSineDataPlotChannel); - postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(togglePostCosineButton->checkBox(), &QCheckBox::toggled, this, - [this](bool b) { - postCalibrationRawDataPlotWidget->selectChannel( - postCalibrationCosineDataPlotChannel); - postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleFFTAngleErrorMagnitudeButton->checkBox(), &QCheckBox::toggled, - this, [this](bool b) { - FFTAngleErrorPlotWidget->selectChannel( - FFTAngleErrorMagnitudeChannel); - FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleFFTAngleErrorPhaseButton->checkBox(), &QCheckBox::toggled, this, - [this](bool b) { - FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorPhaseChannel); - FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleFFTCorrectedErrorMagnitudeButton->checkBox(), - &QCheckBox::toggled, this, [this](bool b) { - FFTCorrectedErrorPlotWidget->selectChannel( - FFTCorrectedErrorMagnitudeChannel); - FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleFFTCorrectedErrorPhaseButton->checkBox(), &QCheckBox::toggled, - this, [this](bool b) { - FFTCorrectedErrorPlotWidget->selectChannel( - FFTCorrectedErrorPhaseChannel); - FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(calibrationDisplayFormatSwitch, &CustomSwitch::toggled, this, - [this](bool b) { - isAngleDisplayFormat = b; - displayCalculatedCoeff(); - }); - - connect(&m_calibrationWaitVelocityWatcher, &QFutureWatcher::finished, - this, [this]() { - if (isMotorVelocityReached) { - startCalibrationStreamThread(); - } else { - startCurrentMotorPositionMonitor(); - startDeviceStatusMonitor(); - } - }); - - connect(&m_resetMotorToZeroWatcher, &QFutureWatcher::finished, this, - [this]() { startWaitForVelocityReachedThread(1); }); - - connect(&m_calibrationStreamWatcher, &QFutureWatcher::started, [this]() { - QThread *thread = QThread::currentThread(); - thread->setPriority(QThread::TimeCriticalPriority); - }); - - connect(&m_calibrationStreamWatcher, &QFutureWatcher::finished, this, - [this]() { - stopMotor(); - isStartMotor = false; - toggleTabSwitching(true); - toggleCalibrationControls(true); - - QString log = "Calibration Stream Timing: \n"; - for (auto &value : m_admtController->streamBufferedIntervals) { - log += QString::number(value) + "\n"; - } - Q_EMIT calibrationLogWriteSignal(log); - - if (isPostCalibration) { - graphPostDataList = m_admtController->streamBufferedValues; - postCalibrationRawDataPlotChannel->curve()->setSamples( - graphPostDataList); - postCalibrationRawDataPlotWidget->replot(); - if (static_cast(graphPostDataList.size()) == - totalSamplesCount) { - computeSineCosineOfAngles(graphPostDataList); - m_admtController->postcalibrate( - vector(graphPostDataList.begin(), - graphPostDataList.end()), - cycleCount, samplesPerCycle, !isMotorRotationClockwise); - populateCorrectedAngleErrorGraphs(); - isPostCalibration = false; - isStartMotor = false; - resetToZero = true; - toggleCalibrationButtonState(4); - } - } else { - graphDataList = m_admtController->streamBufferedValues; - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotWidget->replot(); - if (static_cast(graphDataList.size()) >= totalSamplesCount) { - computeSineCosineOfAngles(graphDataList); - calibrationLogWrite(m_admtController->calibrate( - vector(graphDataList.begin(), graphDataList.end()), - cycleCount, samplesPerCycle, !isMotorRotationClockwise)); - populateAngleErrorGraphs(); - calculateHarmonicValues(); - toggleCalibrationButtonState(2); - } else { - resetToZero = true; - toggleCalibrationButtonState(0); - } - } - - startCurrentMotorPositionMonitor(); - startDeviceStatusMonitor(); - }); - - return tool; -} - -ToolTemplate *HarmonicCalibration::createRegistersWidget() { - ToolTemplate *tool = new ToolTemplate(this); - - QScrollArea *registerScrollArea = new QScrollArea(); - QWidget *registerWidget = new QWidget(registerScrollArea); - registerWidget->setContentsMargins( - 0, 0, Style::getDimension(json::global::unit_0_5), 0); - QVBoxLayout *registerLayout = new QVBoxLayout(registerWidget); - registerScrollArea->setWidgetResizable(true); - registerScrollArea->setWidget(registerWidget); - registerWidget->setLayout(registerLayout); - registerLayout->setMargin(0); - registerLayout->setSpacing(globalSpacingSmall); - - MenuCollapseSection *registerConfigurationCollapseSection = - new MenuCollapseSection( - "Configuration", MenuCollapseSection::MHCW_ARROW, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - registerWidget); - QWidget *registerConfigurationGridWidget = new QWidget(registerWidget); - QGridLayout *registerConfigurationGridLayout = - new QGridLayout(registerConfigurationGridWidget); - registerConfigurationGridWidget->setLayout(registerConfigurationGridLayout); - registerConfigurationGridLayout->setMargin(0); - registerConfigurationGridLayout->setSpacing(globalSpacingSmall); - registerConfigurationCollapseSection->contentLayout()->addWidget( - registerConfigurationGridWidget); - - MenuCollapseSection *registerSensorDataCollapseSection = - new MenuCollapseSection( - "Sensor Data", MenuCollapseSection::MHCW_ARROW, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - registerWidget); - QWidget *registerSensorDataGridWidget = new QWidget(registerWidget); - QGridLayout *registerSensorDataGridLayout = - new QGridLayout(registerSensorDataGridWidget); - registerSensorDataGridWidget->setLayout(registerSensorDataGridLayout); - registerSensorDataGridLayout->setMargin(0); - registerSensorDataGridLayout->setSpacing(globalSpacingSmall); - registerSensorDataCollapseSection->contentLayout()->addWidget( - registerSensorDataGridWidget); - - MenuCollapseSection *registerDeviceIDCollapseSection = - new MenuCollapseSection( - "Device ID", MenuCollapseSection::MHCW_ARROW, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - registerWidget); - QWidget *registerDeviceIDGridWidget = new QWidget(registerWidget); - QGridLayout *registerDeviceIDGridLayout = - new QGridLayout(registerDeviceIDGridWidget); - registerDeviceIDGridWidget->setLayout(registerDeviceIDGridLayout); - registerDeviceIDGridLayout->setMargin(0); - registerDeviceIDGridLayout->setSpacing(globalSpacingSmall); - registerDeviceIDCollapseSection->contentLayout()->addWidget( - registerDeviceIDGridWidget); - - MenuCollapseSection *registerHarmonicsCollapseSection = - new MenuCollapseSection( - "Harmonics", MenuCollapseSection::MHCW_ARROW, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - registerWidget); - QWidget *registerHarmonicsGridWidget = new QWidget(registerWidget); - QGridLayout *registerHarmonicsGridLayout = - new QGridLayout(registerHarmonicsGridWidget); - registerHarmonicsGridWidget->setLayout(registerHarmonicsGridLayout); - registerHarmonicsGridLayout->setMargin(0); - registerHarmonicsGridLayout->setSpacing(globalSpacingSmall); - registerHarmonicsCollapseSection->contentLayout()->addWidget( - registerHarmonicsGridWidget); - - cnvPageRegisterBlock = new RegisterBlockWidget( - "CNVPAGE", "Convert Start and Page Select", - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::CNVPAGE), - m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::CNVPAGE), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - digIORegisterBlock = new RegisterBlockWidget( - "DIGIO", "Digital Input Output", - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::DIGIO), - m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::DIGIO), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - faultRegisterBlock = new RegisterBlockWidget( - "FAULT", "Fault Register", - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::FAULT), - m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::FAULT), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - generalRegisterBlock = new RegisterBlockWidget( - "GENERAL", "General Device Configuration", - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::GENERAL), - m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::GENERAL), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - digIOEnRegisterBlock = new RegisterBlockWidget( - "DIGIOEN", "Enable Digital Input/Outputs", - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::DIGIOEN), - m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::DIGIOEN), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - angleCkRegisterBlock = new RegisterBlockWidget( - "ANGLECK", "Primary vs Secondary Angle Check", - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::ANGLECK), - m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::ANGLECK), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - eccDcdeRegisterBlock = new RegisterBlockWidget( - "ECCDCDE", "Error Correction Codes", - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::ECCDCDE), - m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::ECCDCDE), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - eccDisRegisterBlock = new RegisterBlockWidget( - "ECCDIS", "Error Correction Code disable", - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::ECCDIS), - m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::ECCDIS), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - - absAngleRegisterBlock = new RegisterBlockWidget( - "ABSANGLE", "Absolute Angle", - m_admtController->getSensorRegister( - ADMTController::SensorRegister::ABSANGLE), - m_admtController->getSensorPage(ADMTController::SensorRegister::ABSANGLE), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - angleRegisterBlock = new RegisterBlockWidget( - "ANGLE", "Angle Register", - m_admtController->getSensorRegister( - ADMTController::SensorRegister::ANGLEREG), - m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLEREG), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - angleSecRegisterBlock = new RegisterBlockWidget( - "ANGLESEC", "Secondary Angle", - m_admtController->getSensorRegister( - ADMTController::SensorRegister::ANGLESEC), - m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLESEC), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - sineRegisterBlock = new RegisterBlockWidget( - "SINE", "Sine Measurement", - m_admtController->getSensorRegister(ADMTController::SensorRegister::SINE), - m_admtController->getSensorPage(ADMTController::SensorRegister::SINE), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - cosineRegisterBlock = new RegisterBlockWidget( - "COSINE", "Cosine Measurement", - m_admtController->getSensorRegister( - ADMTController::SensorRegister::COSINE), - m_admtController->getSensorPage(ADMTController::SensorRegister::COSINE), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - secAnglIRegisterBlock = new RegisterBlockWidget( - "SECANGLI", "In-phase secondary angle measurement", - m_admtController->getSensorRegister( - ADMTController::SensorRegister::SECANGLI), - m_admtController->getSensorPage(ADMTController::SensorRegister::SECANGLI), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - secAnglQRegisterBlock = new RegisterBlockWidget( - "SECANGLQ", "Quadrature phase secondary angle measurement", - m_admtController->getSensorRegister( - ADMTController::SensorRegister::SECANGLQ), - m_admtController->getSensorPage(ADMTController::SensorRegister::SECANGLQ), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - radiusRegisterBlock = new RegisterBlockWidget( - "RADIUS", "Angle measurement radius", - m_admtController->getSensorRegister( - ADMTController::SensorRegister::RADIUS), - m_admtController->getSensorPage(ADMTController::SensorRegister::RADIUS), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - diag1RegisterBlock = new RegisterBlockWidget( - "DIAG1", - "State of the MT reference resistors and AFE fixed input voltage", - m_admtController->getSensorRegister( - ADMTController::SensorRegister::DIAG1), - m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - diag2RegisterBlock = new RegisterBlockWidget( - "DIAG2", "Measurements of two diagnostics resistors of fixed value", - m_admtController->getSensorRegister( - ADMTController::SensorRegister::DIAG2), - m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - tmp0RegisterBlock = new RegisterBlockWidget( - "TMP0", "Primary Temperature Sensor", - m_admtController->getSensorRegister(ADMTController::SensorRegister::TMP0), - m_admtController->getSensorPage(ADMTController::SensorRegister::TMP0), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - tmp1RegisterBlock = new RegisterBlockWidget( - "TMP1", "Secondary Temperature Sensor", - m_admtController->getSensorRegister(ADMTController::SensorRegister::TMP1), - m_admtController->getSensorPage(ADMTController::SensorRegister::TMP1), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - cnvCntRegisterBlock = new RegisterBlockWidget( - "CNVCNT", "Conversion Count", - m_admtController->getSensorRegister( - ADMTController::SensorRegister::CNVCNT), - m_admtController->getSensorPage(ADMTController::SensorRegister::CNVCNT), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - - uniqID0RegisterBlock = new RegisterBlockWidget( - "UNIQID0", "Unique ID Register 0", - m_admtController->getUniqueIdRegister( - ADMTController::UniqueIDRegister::UNIQID0), - m_admtController->getUniqueIdPage( - ADMTController::UniqueIDRegister::UNIQID0), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - uniqID1RegisterBlock = new RegisterBlockWidget( - "UNIQID1", "Unique ID Register 1", - m_admtController->getUniqueIdRegister( - ADMTController::UniqueIDRegister::UNIQID1), - m_admtController->getUniqueIdPage( - ADMTController::UniqueIDRegister::UNIQID1), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - uniqID2RegisterBlock = new RegisterBlockWidget( - "UNIQID2", "Unique ID Register 2", - m_admtController->getUniqueIdRegister( - ADMTController::UniqueIDRegister::UNIQID2), - m_admtController->getUniqueIdPage( - ADMTController::UniqueIDRegister::UNIQID2), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - uniqID3RegisterBlock = new RegisterBlockWidget( - "UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", - m_admtController->getUniqueIdRegister( - ADMTController::UniqueIDRegister::UNIQID3), - m_admtController->getUniqueIdPage( - ADMTController::UniqueIDRegister::UNIQID3), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - - h1MagRegisterBlock = new RegisterBlockWidget( - "H1MAG", "1st Harmonic error magnitude", - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H1MAG), - m_admtController->getHarmonicPage( - ADMTController::HarmonicRegister::H1MAG), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h1PhRegisterBlock = new RegisterBlockWidget( - "H1PH", "1st Harmonic error phase", - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H1PH), - m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1PH), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h2MagRegisterBlock = new RegisterBlockWidget( - "H2MAG", "2nd Harmonic error magnitude", - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H2MAG), - m_admtController->getHarmonicPage( - ADMTController::HarmonicRegister::H2MAG), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h2PhRegisterBlock = new RegisterBlockWidget( - "H2PH", "2nd Harmonic error phase", - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H2PH), - m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H2PH), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h3MagRegisterBlock = new RegisterBlockWidget( - "H3MAG", "3rd Harmonic error magnitude", - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H3MAG), - m_admtController->getHarmonicPage( - ADMTController::HarmonicRegister::H3MAG), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h3PhRegisterBlock = new RegisterBlockWidget( - "H3PH", "3rd Harmonic error phase", - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H3PH), - m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H3PH), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h8MagRegisterBlock = new RegisterBlockWidget( - "H8MAG", "8th Harmonic error magnitude", - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H8MAG), - m_admtController->getHarmonicPage( - ADMTController::HarmonicRegister::H8MAG), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - h8PhRegisterBlock = new RegisterBlockWidget( - "H8PH", "8th Harmonic error phase", - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H8PH), - m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H8PH), - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - - registerConfigurationGridLayout->addWidget(cnvPageRegisterBlock, 0, 0); - registerConfigurationGridLayout->addWidget(digIORegisterBlock, 0, 1); - registerConfigurationGridLayout->addWidget(faultRegisterBlock, 0, 2); - registerConfigurationGridLayout->addWidget(generalRegisterBlock, 0, 3); - registerConfigurationGridLayout->addWidget(digIOEnRegisterBlock, 0, 4); - registerConfigurationGridLayout->addWidget(eccDcdeRegisterBlock, 1, 0); - registerConfigurationGridLayout->addWidget(eccDisRegisterBlock, 1, 1); - registerConfigurationGridLayout->addWidget(angleCkRegisterBlock, 1, 2); - - registerSensorDataGridLayout->addWidget(absAngleRegisterBlock, 0, 0); - registerSensorDataGridLayout->addWidget(angleRegisterBlock, 0, 1); - registerSensorDataGridLayout->addWidget(sineRegisterBlock, 0, 2); - registerSensorDataGridLayout->addWidget(cosineRegisterBlock, 0, 3); - registerSensorDataGridLayout->addWidget(cnvCntRegisterBlock, 0, 4); - registerSensorDataGridLayout->addWidget(tmp0RegisterBlock, 1, 0); - registerSensorDataGridLayout->addWidget(tmp1RegisterBlock, 1, 1); - registerSensorDataGridLayout->addWidget(diag1RegisterBlock, 1, 2); - registerSensorDataGridLayout->addWidget(diag2RegisterBlock, 1, 3); - registerSensorDataGridLayout->addWidget(radiusRegisterBlock, 1, 4); - registerSensorDataGridLayout->addWidget(angleSecRegisterBlock, 2, 0); - registerSensorDataGridLayout->addWidget(secAnglIRegisterBlock, 2, 1); - registerSensorDataGridLayout->addWidget(secAnglQRegisterBlock, 2, 2); - - registerDeviceIDGridLayout->addWidget(uniqID0RegisterBlock, 0, 0); - registerDeviceIDGridLayout->addWidget(uniqID1RegisterBlock, 0, 1); - registerDeviceIDGridLayout->addWidget(uniqID2RegisterBlock, 0, 2); - registerDeviceIDGridLayout->addWidget(uniqID3RegisterBlock, 0, 3); - QSpacerItem *registerDeviceSpacer = - new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred); - registerDeviceIDGridLayout->addItem(registerDeviceSpacer, 0, 4); - - registerHarmonicsGridLayout->addWidget(h1MagRegisterBlock, 0, 0); - registerHarmonicsGridLayout->addWidget(h1PhRegisterBlock, 0, 1); - registerHarmonicsGridLayout->addWidget(h2MagRegisterBlock, 0, 2); - registerHarmonicsGridLayout->addWidget(h2PhRegisterBlock, 0, 3); - registerHarmonicsGridLayout->addWidget(h3MagRegisterBlock, 0, 4); - registerHarmonicsGridLayout->addWidget(h3PhRegisterBlock, 1, 0); - registerHarmonicsGridLayout->addWidget(h8MagRegisterBlock, 1, 1); - registerHarmonicsGridLayout->addWidget(h8PhRegisterBlock, 1, 2); - - for (int c = 0; c < registerConfigurationGridLayout->columnCount(); ++c) - registerConfigurationGridLayout->setColumnStretch(c, 1); - for (int c = 0; c < registerDeviceIDGridLayout->columnCount(); ++c) - registerDeviceIDGridLayout->setColumnStretch(c, 1); - for (int c = 0; c < registerHarmonicsGridLayout->columnCount(); ++c) - registerHarmonicsGridLayout->setColumnStretch(c, 1); - for (int c = 0; c < registerSensorDataGridLayout->columnCount(); ++c) - registerSensorDataGridLayout->setColumnStretch(c, 1); - - QWidget *registerActionsWidget = new QWidget(registerWidget); - QHBoxLayout *registerActionsLayout = new QHBoxLayout(registerActionsWidget); - registerActionsWidget->setLayout(registerActionsLayout); - registerActionsLayout->setMargin(0); - registerActionsLayout->setSpacing(globalSpacingSmall); - readAllRegistersButton = - new QPushButton("Read All Registers", registerWidget); - StyleHelper::BasicButton(readAllRegistersButton); - readAllRegistersButton->setFixedWidth(270); - connect(readAllRegistersButton, &QPushButton::clicked, this, - &HarmonicCalibration::readAllRegisters); - registerActionsLayout->addWidget(readAllRegistersButton); - - registerLayout->addWidget(registerConfigurationCollapseSection); - registerLayout->addWidget(registerSensorDataCollapseSection); - registerLayout->addWidget(registerDeviceIDCollapseSection); - registerLayout->addWidget(registerHarmonicsCollapseSection); - registerLayout->addSpacerItem( - new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); - - tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - tool->topContainer()->setVisible(true); - tool->topContainerMenuControl()->setVisible(false); - tool->leftContainer()->setVisible(false); - tool->rightContainer()->setVisible(false); - tool->bottomContainer()->setVisible(false); - tool->openBottomContainerHelper(false); - tool->openTopContainerHelper(false); - - tool->addWidgetToTopContainerHelper(registerActionsWidget, - ToolTemplateAlignment::TTA_LEFT); - tool->addWidgetToCentralContainerHelper(registerScrollArea); - - tool->layout()->setMargin(0); - tool->layout()->setContentsMargins( - globalSpacingSmall, globalSpacingSmall, - Style::getDimension(json::global::unit_0_5), globalSpacingSmall); - - connectRegisterBlockToRegistry(cnvPageRegisterBlock); - connectRegisterBlockToRegistry(digIORegisterBlock); - connectRegisterBlockToRegistry(faultRegisterBlock); - connectRegisterBlockToRegistry(generalRegisterBlock); - connectRegisterBlockToRegistry(digIOEnRegisterBlock); - connectRegisterBlockToRegistry(angleCkRegisterBlock); - connectRegisterBlockToRegistry(eccDcdeRegisterBlock); - connectRegisterBlockToRegistry(eccDisRegisterBlock); - - connectRegisterBlockToRegistry(absAngleRegisterBlock); - connectRegisterBlockToRegistry(angleRegisterBlock); - connectRegisterBlockToRegistry(angleSecRegisterBlock); - connectRegisterBlockToRegistry(sineRegisterBlock); - connectRegisterBlockToRegistry(cosineRegisterBlock); - connectRegisterBlockToRegistry(secAnglIRegisterBlock); - connectRegisterBlockToRegistry(secAnglQRegisterBlock); - connectRegisterBlockToRegistry(radiusRegisterBlock); - connectRegisterBlockToRegistry(diag1RegisterBlock); - connectRegisterBlockToRegistry(diag2RegisterBlock); - connectRegisterBlockToRegistry(tmp0RegisterBlock); - connectRegisterBlockToRegistry(tmp1RegisterBlock); - connectRegisterBlockToRegistry(cnvCntRegisterBlock); - - connectRegisterBlockToRegistry(uniqID0RegisterBlock); - connectRegisterBlockToRegistry(uniqID1RegisterBlock); - connectRegisterBlockToRegistry(uniqID2RegisterBlock); - connectRegisterBlockToRegistry(uniqID3RegisterBlock); - - connectRegisterBlockToRegistry(h1MagRegisterBlock); - connectRegisterBlockToRegistry(h1PhRegisterBlock); - connectRegisterBlockToRegistry(h2MagRegisterBlock); - connectRegisterBlockToRegistry(h2PhRegisterBlock); - connectRegisterBlockToRegistry(h3MagRegisterBlock); - connectRegisterBlockToRegistry(h3PhRegisterBlock); - connectRegisterBlockToRegistry(h8MagRegisterBlock); - connectRegisterBlockToRegistry(h8PhRegisterBlock); - - return tool; -} - -ToolTemplate *HarmonicCalibration::createUtilityWidget() { - ToolTemplate *tool = new ToolTemplate(this); + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(false); + tool->topContainerMenuControl()->setVisible(false); + tool->leftContainer()->setVisible(false); + tool->rightContainer()->setVisible(true); + tool->bottomContainer()->setVisible(false); + tool->setLeftContainerWidth(270); + tool->setRightContainerWidth(270); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + + tool->addWidgetToCentralContainerHelper(calibrationDataGraphWidget); + tool->rightStack()->add("calibrationSettingsGroupWidget", calibrationSettingsGroupWidget); + + connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); + connect(importSamplesButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); + connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAllCalibrationState); + connect(toggleAngleButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); + calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleSineButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + calibrationRawDataPlotWidget->selectChannel(calibrationSineDataPlotChannel); + calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleCosineButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + calibrationRawDataPlotWidget->selectChannel(calibrationCosineDataPlotChannel); + calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(togglePostAngleButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + postCalibrationRawDataPlotWidget->selectChannel(postCalibrationRawDataPlotChannel); + postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(togglePostSineButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + postCalibrationRawDataPlotWidget->selectChannel(postCalibrationSineDataPlotChannel); + postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(togglePostCosineButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + postCalibrationRawDataPlotWidget->selectChannel(postCalibrationCosineDataPlotChannel); + postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleFFTAngleErrorMagnitudeButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); + FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleFFTAngleErrorPhaseButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorPhaseChannel); + FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleFFTCorrectedErrorMagnitudeButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); + FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(toggleFFTCorrectedErrorPhaseButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorPhaseChannel); + FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); + }); + connect(calibrationDisplayFormatSwitch, &CustomSwitch::toggled, this, [this](bool b) { + isAngleDisplayFormat = b; + displayCalculatedCoeff(); + }); + + connect(&m_calibrationWaitVelocityWatcher, &QFutureWatcher::finished, this, [this]() { + if(isMotorVelocityReached) { + startCalibrationStreamThread(); + } else { + startCurrentMotorPositionMonitor(); + startDeviceStatusMonitor(); + } + }); + + connect(&m_resetMotorToZeroWatcher, &QFutureWatcher::finished, this, + [this]() { startWaitForVelocityReachedThread(1); }); + + connect(&m_calibrationStreamWatcher, &QFutureWatcher::started, [this]() { + QThread *thread = QThread::currentThread(); + thread->setPriority(QThread::TimeCriticalPriority); + }); + + connect(&m_calibrationStreamWatcher, &QFutureWatcher::finished, this, [this]() { + stopMotor(); + isStartMotor = false; + toggleTabSwitching(true); + toggleCalibrationControls(true); + + QString log = "Calibration Stream Timing: \n"; + for(auto &value : m_admtController->streamBufferedIntervals) { + log += QString::number(value) + "\n"; + } + Q_EMIT calibrationLogWriteSignal(log); + + if(isPostCalibration) { + graphPostDataList = m_admtController->streamBufferedValues; + postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); + postCalibrationRawDataPlotWidget->replot(); + if(static_cast(graphPostDataList.size()) == totalSamplesCount) { + computeSineCosineOfAngles(graphPostDataList); + m_admtController->postcalibrate( + vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, + samplesPerCycle, !isMotorRotationClockwise); + populateCorrectedAngleErrorGraphs(); + isPostCalibration = false; + isStartMotor = false; + resetToZero = true; + toggleCalibrationButtonState(4); + } + } else { + graphDataList = m_admtController->streamBufferedValues; + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotWidget->replot(); + if(static_cast(graphDataList.size()) >= totalSamplesCount) { + computeSineCosineOfAngles(graphDataList); + calibrationLogWrite(m_admtController->calibrate( + vector(graphDataList.begin(), graphDataList.end()), cycleCount, + samplesPerCycle, !isMotorRotationClockwise)); + populateAngleErrorGraphs(); + calculateHarmonicValues(); + toggleCalibrationButtonState(2); + } else { + resetToZero = true; + toggleCalibrationButtonState(0); + } + } + + startCurrentMotorPositionMonitor(); + startDeviceStatusMonitor(); + }); + + return tool; +} + +ToolTemplate *HarmonicCalibration::createRegistersWidget() +{ + ToolTemplate *tool = new ToolTemplate(this); + + QScrollArea *registerScrollArea = new QScrollArea(); + QWidget *registerWidget = new QWidget(registerScrollArea); + registerWidget->setContentsMargins(0, 0, Style::getDimension(json::global::unit_0_5), 0); + QVBoxLayout *registerLayout = new QVBoxLayout(registerWidget); + registerScrollArea->setWidgetResizable(true); + registerScrollArea->setWidget(registerWidget); + registerWidget->setLayout(registerLayout); + registerLayout->setMargin(0); + registerLayout->setSpacing(globalSpacingSmall); + + MenuCollapseSection *registerConfigurationCollapseSection = + new MenuCollapseSection("Configuration", MenuCollapseSection::MHCW_ARROW, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); + QWidget *registerConfigurationGridWidget = new QWidget(registerWidget); + QGridLayout *registerConfigurationGridLayout = new QGridLayout(registerConfigurationGridWidget); + registerConfigurationGridWidget->setLayout(registerConfigurationGridLayout); + registerConfigurationGridLayout->setMargin(0); + registerConfigurationGridLayout->setSpacing(globalSpacingSmall); + registerConfigurationCollapseSection->contentLayout()->addWidget(registerConfigurationGridWidget); + + MenuCollapseSection *registerSensorDataCollapseSection = + new MenuCollapseSection("Sensor Data", MenuCollapseSection::MHCW_ARROW, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); + QWidget *registerSensorDataGridWidget = new QWidget(registerWidget); + QGridLayout *registerSensorDataGridLayout = new QGridLayout(registerSensorDataGridWidget); + registerSensorDataGridWidget->setLayout(registerSensorDataGridLayout); + registerSensorDataGridLayout->setMargin(0); + registerSensorDataGridLayout->setSpacing(globalSpacingSmall); + registerSensorDataCollapseSection->contentLayout()->addWidget(registerSensorDataGridWidget); + + MenuCollapseSection *registerDeviceIDCollapseSection = + new MenuCollapseSection("Device ID", MenuCollapseSection::MHCW_ARROW, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); + QWidget *registerDeviceIDGridWidget = new QWidget(registerWidget); + QGridLayout *registerDeviceIDGridLayout = new QGridLayout(registerDeviceIDGridWidget); + registerDeviceIDGridWidget->setLayout(registerDeviceIDGridLayout); + registerDeviceIDGridLayout->setMargin(0); + registerDeviceIDGridLayout->setSpacing(globalSpacingSmall); + registerDeviceIDCollapseSection->contentLayout()->addWidget(registerDeviceIDGridWidget); + + MenuCollapseSection *registerHarmonicsCollapseSection = + new MenuCollapseSection("Harmonics", MenuCollapseSection::MHCW_ARROW, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, registerWidget); + QWidget *registerHarmonicsGridWidget = new QWidget(registerWidget); + QGridLayout *registerHarmonicsGridLayout = new QGridLayout(registerHarmonicsGridWidget); + registerHarmonicsGridWidget->setLayout(registerHarmonicsGridLayout); + registerHarmonicsGridLayout->setMargin(0); + registerHarmonicsGridLayout->setSpacing(globalSpacingSmall); + registerHarmonicsCollapseSection->contentLayout()->addWidget(registerHarmonicsGridWidget); + + cnvPageRegisterBlock = new RegisterBlockWidget( + "CNVPAGE", "Convert Start and Page Select", + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::CNVPAGE), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + digIORegisterBlock = new RegisterBlockWidget( + "DIGIO", "Digital Input Output", + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIO), + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIO), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + faultRegisterBlock = new RegisterBlockWidget( + "FAULT", "Fault Register", + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::FAULT), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + generalRegisterBlock = new RegisterBlockWidget( + "GENERAL", "General Device Configuration", + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL), + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + digIOEnRegisterBlock = new RegisterBlockWidget( + "DIGIOEN", "Enable Digital Input/Outputs", + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + angleCkRegisterBlock = new RegisterBlockWidget( + "ANGLECK", "Primary vs Secondary Angle Check", + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ANGLECK), + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ANGLECK), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + eccDcdeRegisterBlock = new RegisterBlockWidget( + "ECCDCDE", "Error Correction Codes", + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ECCDCDE), + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCDCDE), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + eccDisRegisterBlock = new RegisterBlockWidget( + "ECCDIS", "Error Correction Code disable", + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ECCDIS), + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCDIS), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + + absAngleRegisterBlock = + new RegisterBlockWidget("ABSANGLE", "Absolute Angle", + m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), + m_admtController->getSensorPage(ADMTController::SensorRegister::ABSANGLE), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + angleRegisterBlock = + new RegisterBlockWidget("ANGLE", "Angle Register", + m_admtController->getSensorRegister(ADMTController::SensorRegister::ANGLEREG), + m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLEREG), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + angleSecRegisterBlock = + new RegisterBlockWidget("ANGLESEC", "Secondary Angle", + m_admtController->getSensorRegister(ADMTController::SensorRegister::ANGLESEC), + m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLESEC), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + sineRegisterBlock = new RegisterBlockWidget( + "SINE", "Sine Measurement", m_admtController->getSensorRegister(ADMTController::SensorRegister::SINE), + m_admtController->getSensorPage(ADMTController::SensorRegister::SINE), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + cosineRegisterBlock = + new RegisterBlockWidget("COSINE", "Cosine Measurement", + m_admtController->getSensorRegister(ADMTController::SensorRegister::COSINE), + m_admtController->getSensorPage(ADMTController::SensorRegister::COSINE), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + secAnglIRegisterBlock = + new RegisterBlockWidget("SECANGLI", "In-phase secondary angle measurement", + m_admtController->getSensorRegister(ADMTController::SensorRegister::SECANGLI), + m_admtController->getSensorPage(ADMTController::SensorRegister::SECANGLI), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + secAnglQRegisterBlock = + new RegisterBlockWidget("SECANGLQ", "Quadrature phase secondary angle measurement", + m_admtController->getSensorRegister(ADMTController::SensorRegister::SECANGLQ), + m_admtController->getSensorPage(ADMTController::SensorRegister::SECANGLQ), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + radiusRegisterBlock = + new RegisterBlockWidget("RADIUS", "Angle measurement radius", + m_admtController->getSensorRegister(ADMTController::SensorRegister::RADIUS), + m_admtController->getSensorPage(ADMTController::SensorRegister::RADIUS), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + diag1RegisterBlock = + new RegisterBlockWidget("DIAG1", "State of the MT reference resistors and AFE fixed input voltage", + m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1), + m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + diag2RegisterBlock = + new RegisterBlockWidget("DIAG2", "Measurements of two diagnostics resistors of fixed value", + m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG2), + m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + tmp0RegisterBlock = + new RegisterBlockWidget("TMP0", "Primary Temperature Sensor", + m_admtController->getSensorRegister(ADMTController::SensorRegister::TMP0), + m_admtController->getSensorPage(ADMTController::SensorRegister::TMP0), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + tmp1RegisterBlock = + new RegisterBlockWidget("TMP1", "Secondary Temperature Sensor", + m_admtController->getSensorRegister(ADMTController::SensorRegister::TMP1), + m_admtController->getSensorPage(ADMTController::SensorRegister::TMP1), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + cnvCntRegisterBlock = + new RegisterBlockWidget("CNVCNT", "Conversion Count", + m_admtController->getSensorRegister(ADMTController::SensorRegister::CNVCNT), + m_admtController->getSensorPage(ADMTController::SensorRegister::CNVCNT), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + + uniqID0RegisterBlock = new RegisterBlockWidget( + "UNIQID0", "Unique ID Register 0", + m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID0), + m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID0), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID1RegisterBlock = new RegisterBlockWidget( + "UNIQID1", "Unique ID Register 1", + m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID1), + m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID1), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID2RegisterBlock = new RegisterBlockWidget( + "UNIQID2", "Unique ID Register 2", + m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID2), + m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID2), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + uniqID3RegisterBlock = new RegisterBlockWidget( + "UNIQID3", "Product, voltage supply. ASIL and ASIC revision identifiers", + m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID3), + m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + + h1MagRegisterBlock = + new RegisterBlockWidget("H1MAG", "1st Harmonic error magnitude", + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1MAG), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h1PhRegisterBlock = + new RegisterBlockWidget("H1PH", "1st Harmonic error phase", + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1PH), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h2MagRegisterBlock = + new RegisterBlockWidget("H2MAG", "2nd Harmonic error magnitude", + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H2MAG), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h2PhRegisterBlock = + new RegisterBlockWidget("H2PH", "2nd Harmonic error phase", + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H2PH), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h3MagRegisterBlock = + new RegisterBlockWidget("H3MAG", "3rd Harmonic error magnitude", + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H3MAG), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h3PhRegisterBlock = + new RegisterBlockWidget("H3PH", "3rd Harmonic error phase", + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H3PH), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h8MagRegisterBlock = + new RegisterBlockWidget("H8MAG", "8th Harmonic error magnitude", + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H8MAG), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + h8PhRegisterBlock = + new RegisterBlockWidget("H8PH", "8th Harmonic error phase", + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), + m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H8PH), + RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); + + registerConfigurationGridLayout->addWidget(cnvPageRegisterBlock, 0, 0); + registerConfigurationGridLayout->addWidget(digIORegisterBlock, 0, 1); + registerConfigurationGridLayout->addWidget(faultRegisterBlock, 0, 2); + registerConfigurationGridLayout->addWidget(generalRegisterBlock, 0, 3); + registerConfigurationGridLayout->addWidget(digIOEnRegisterBlock, 0, 4); + registerConfigurationGridLayout->addWidget(eccDcdeRegisterBlock, 1, 0); + registerConfigurationGridLayout->addWidget(eccDisRegisterBlock, 1, 1); + registerConfigurationGridLayout->addWidget(angleCkRegisterBlock, 1, 2); + + registerSensorDataGridLayout->addWidget(absAngleRegisterBlock, 0, 0); + registerSensorDataGridLayout->addWidget(angleRegisterBlock, 0, 1); + registerSensorDataGridLayout->addWidget(sineRegisterBlock, 0, 2); + registerSensorDataGridLayout->addWidget(cosineRegisterBlock, 0, 3); + registerSensorDataGridLayout->addWidget(cnvCntRegisterBlock, 0, 4); + registerSensorDataGridLayout->addWidget(tmp0RegisterBlock, 1, 0); + registerSensorDataGridLayout->addWidget(tmp1RegisterBlock, 1, 1); + registerSensorDataGridLayout->addWidget(diag1RegisterBlock, 1, 2); + registerSensorDataGridLayout->addWidget(diag2RegisterBlock, 1, 3); + registerSensorDataGridLayout->addWidget(radiusRegisterBlock, 1, 4); + registerSensorDataGridLayout->addWidget(angleSecRegisterBlock, 2, 0); + registerSensorDataGridLayout->addWidget(secAnglIRegisterBlock, 2, 1); + registerSensorDataGridLayout->addWidget(secAnglQRegisterBlock, 2, 2); + + registerDeviceIDGridLayout->addWidget(uniqID0RegisterBlock, 0, 0); + registerDeviceIDGridLayout->addWidget(uniqID1RegisterBlock, 0, 1); + registerDeviceIDGridLayout->addWidget(uniqID2RegisterBlock, 0, 2); + registerDeviceIDGridLayout->addWidget(uniqID3RegisterBlock, 0, 3); + QSpacerItem *registerDeviceSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred); + registerDeviceIDGridLayout->addItem(registerDeviceSpacer, 0, 4); + + registerHarmonicsGridLayout->addWidget(h1MagRegisterBlock, 0, 0); + registerHarmonicsGridLayout->addWidget(h1PhRegisterBlock, 0, 1); + registerHarmonicsGridLayout->addWidget(h2MagRegisterBlock, 0, 2); + registerHarmonicsGridLayout->addWidget(h2PhRegisterBlock, 0, 3); + registerHarmonicsGridLayout->addWidget(h3MagRegisterBlock, 0, 4); + registerHarmonicsGridLayout->addWidget(h3PhRegisterBlock, 1, 0); + registerHarmonicsGridLayout->addWidget(h8MagRegisterBlock, 1, 1); + registerHarmonicsGridLayout->addWidget(h8PhRegisterBlock, 1, 2); + + for(int c = 0; c < registerConfigurationGridLayout->columnCount(); ++c) + registerConfigurationGridLayout->setColumnStretch(c, 1); + for(int c = 0; c < registerDeviceIDGridLayout->columnCount(); ++c) + registerDeviceIDGridLayout->setColumnStretch(c, 1); + for(int c = 0; c < registerHarmonicsGridLayout->columnCount(); ++c) + registerHarmonicsGridLayout->setColumnStretch(c, 1); + for(int c = 0; c < registerSensorDataGridLayout->columnCount(); ++c) + registerSensorDataGridLayout->setColumnStretch(c, 1); + + QWidget *registerActionsWidget = new QWidget(registerWidget); + QHBoxLayout *registerActionsLayout = new QHBoxLayout(registerActionsWidget); + registerActionsWidget->setLayout(registerActionsLayout); + registerActionsLayout->setMargin(0); + registerActionsLayout->setSpacing(globalSpacingSmall); + readAllRegistersButton = new QPushButton("Read All Registers", registerWidget); + StyleHelper::BasicButton(readAllRegistersButton); + readAllRegistersButton->setFixedWidth(270); + connect(readAllRegistersButton, &QPushButton::clicked, this, &HarmonicCalibration::readAllRegisters); + registerActionsLayout->addWidget(readAllRegistersButton); + + registerLayout->addWidget(registerConfigurationCollapseSection); + registerLayout->addWidget(registerSensorDataCollapseSection); + registerLayout->addWidget(registerDeviceIDCollapseSection); + registerLayout->addWidget(registerHarmonicsCollapseSection); + registerLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(true); + tool->topContainerMenuControl()->setVisible(false); + tool->leftContainer()->setVisible(false); + tool->rightContainer()->setVisible(false); + tool->bottomContainer()->setVisible(false); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + + tool->addWidgetToTopContainerHelper(registerActionsWidget, ToolTemplateAlignment::TTA_LEFT); + tool->addWidgetToCentralContainerHelper(registerScrollArea); + + tool->layout()->setMargin(0); + tool->layout()->setContentsMargins(globalSpacingSmall, globalSpacingSmall, + Style::getDimension(json::global::unit_0_5), globalSpacingSmall); + + connectRegisterBlockToRegistry(cnvPageRegisterBlock); + connectRegisterBlockToRegistry(digIORegisterBlock); + connectRegisterBlockToRegistry(faultRegisterBlock); + connectRegisterBlockToRegistry(generalRegisterBlock); + connectRegisterBlockToRegistry(digIOEnRegisterBlock); + connectRegisterBlockToRegistry(angleCkRegisterBlock); + connectRegisterBlockToRegistry(eccDcdeRegisterBlock); + connectRegisterBlockToRegistry(eccDisRegisterBlock); + + connectRegisterBlockToRegistry(absAngleRegisterBlock); + connectRegisterBlockToRegistry(angleRegisterBlock); + connectRegisterBlockToRegistry(angleSecRegisterBlock); + connectRegisterBlockToRegistry(sineRegisterBlock); + connectRegisterBlockToRegistry(cosineRegisterBlock); + connectRegisterBlockToRegistry(secAnglIRegisterBlock); + connectRegisterBlockToRegistry(secAnglQRegisterBlock); + connectRegisterBlockToRegistry(radiusRegisterBlock); + connectRegisterBlockToRegistry(diag1RegisterBlock); + connectRegisterBlockToRegistry(diag2RegisterBlock); + connectRegisterBlockToRegistry(tmp0RegisterBlock); + connectRegisterBlockToRegistry(tmp1RegisterBlock); + connectRegisterBlockToRegistry(cnvCntRegisterBlock); + + connectRegisterBlockToRegistry(uniqID0RegisterBlock); + connectRegisterBlockToRegistry(uniqID1RegisterBlock); + connectRegisterBlockToRegistry(uniqID2RegisterBlock); + connectRegisterBlockToRegistry(uniqID3RegisterBlock); + + connectRegisterBlockToRegistry(h1MagRegisterBlock); + connectRegisterBlockToRegistry(h1PhRegisterBlock); + connectRegisterBlockToRegistry(h2MagRegisterBlock); + connectRegisterBlockToRegistry(h2PhRegisterBlock); + connectRegisterBlockToRegistry(h3MagRegisterBlock); + connectRegisterBlockToRegistry(h3PhRegisterBlock); + connectRegisterBlockToRegistry(h8MagRegisterBlock); + connectRegisterBlockToRegistry(h8PhRegisterBlock); + + return tool; +} + +ToolTemplate *HarmonicCalibration::createUtilityWidget() +{ + ToolTemplate *tool = new ToolTemplate(this); #pragma region Left Utility Widget - QWidget *leftUtilityWidget = new QWidget(this); - QVBoxLayout *leftUtilityLayout = new QVBoxLayout(leftUtilityWidget); - leftUtilityWidget->setLayout(leftUtilityLayout); - leftUtilityLayout->setMargin(0); - leftUtilityLayout->setSpacing(8); + QWidget *leftUtilityWidget = new QWidget(this); + QVBoxLayout *leftUtilityLayout = new QVBoxLayout(leftUtilityWidget); + leftUtilityWidget->setLayout(leftUtilityLayout); + leftUtilityLayout->setMargin(0); + leftUtilityLayout->setSpacing(8); #pragma region Command Log Widget - MenuSectionWidget *commandLogSectionWidget = - new MenuSectionWidget(leftUtilityWidget); - Style::setStyle(commandLogSectionWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *commandLogCollapseSection = new MenuCollapseSection( - "Command Log", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - commandLogSectionWidget); - commandLogSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::MinimumExpanding); - commandLogSectionWidget->contentLayout()->addWidget( - commandLogCollapseSection); - commandLogCollapseSection->contentLayout()->setSpacing(8); - - commandLogPlainTextEdit = new QPlainTextEdit(commandLogSectionWidget); - commandLogPlainTextEdit->setReadOnly(true); - commandLogPlainTextEdit->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::MinimumExpanding); - commandLogPlainTextEdit->setStyleSheet("QPlainTextEdit { border: none; }"); - - clearCommandLogButton = - new QPushButton("Clear Command Logs", commandLogSectionWidget); - StyleHelper::BasicButton(clearCommandLogButton); - connect(clearCommandLogButton, &QPushButton::clicked, this, - &HarmonicCalibration::clearCommandLog); - - commandLogCollapseSection->contentLayout()->addWidget( - commandLogPlainTextEdit); - commandLogCollapseSection->contentLayout()->addWidget(clearCommandLogButton); - - leftUtilityLayout->addWidget(commandLogSectionWidget, 1); - leftUtilityLayout->addStretch(); + MenuSectionWidget *commandLogSectionWidget = new MenuSectionWidget(leftUtilityWidget); + Style::setStyle(commandLogSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *commandLogCollapseSection = new MenuCollapseSection( + "Command Log", MenuCollapseSection::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, commandLogSectionWidget); + commandLogSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + commandLogSectionWidget->contentLayout()->addWidget(commandLogCollapseSection); + commandLogCollapseSection->contentLayout()->setSpacing(8); + + commandLogPlainTextEdit = new QPlainTextEdit(commandLogSectionWidget); + commandLogPlainTextEdit->setReadOnly(true); + commandLogPlainTextEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + commandLogPlainTextEdit->setStyleSheet("QPlainTextEdit { border: none; }"); + + clearCommandLogButton = new QPushButton("Clear Command Logs", commandLogSectionWidget); + StyleHelper::BasicButton(clearCommandLogButton); + connect(clearCommandLogButton, &QPushButton::clicked, this, &HarmonicCalibration::clearCommandLog); + + commandLogCollapseSection->contentLayout()->addWidget(commandLogPlainTextEdit); + commandLogCollapseSection->contentLayout()->addWidget(clearCommandLogButton); + + leftUtilityLayout->addWidget(commandLogSectionWidget, 1); + leftUtilityLayout->addStretch(); #pragma endregion #pragma endregion #pragma region Center Utility Widget - QWidget *centerUtilityWidget = new QWidget(this); - QHBoxLayout *centerUtilityLayout = new QHBoxLayout(centerUtilityWidget); - centerUtilityWidget->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::MinimumExpanding); - centerUtilityWidget->setContentsMargins(2, 0, 2, 0); - centerUtilityWidget->setLayout(centerUtilityLayout); - centerUtilityLayout->setMargin(0); - centerUtilityLayout->setSpacing(8); - - QScrollArea *DIGIOScrollArea = new QScrollArea(centerUtilityWidget); - QWidget *DIGIOWidget = new QWidget(DIGIOScrollArea); - DIGIOScrollArea->setWidget(DIGIOWidget); - DIGIOScrollArea->setWidgetResizable(true); - QVBoxLayout *DIGIOLayout = new QVBoxLayout(DIGIOWidget); - DIGIOWidget->setLayout(DIGIOLayout); - DIGIOLayout->setMargin(0); - DIGIOLayout->setSpacing(8); + QWidget *centerUtilityWidget = new QWidget(this); + QHBoxLayout *centerUtilityLayout = new QHBoxLayout(centerUtilityWidget); + centerUtilityWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + centerUtilityWidget->setContentsMargins(2, 0, 2, 0); + centerUtilityWidget->setLayout(centerUtilityLayout); + centerUtilityLayout->setMargin(0); + centerUtilityLayout->setSpacing(8); + + QScrollArea *DIGIOScrollArea = new QScrollArea(centerUtilityWidget); + QWidget *DIGIOWidget = new QWidget(DIGIOScrollArea); + DIGIOScrollArea->setWidget(DIGIOWidget); + DIGIOScrollArea->setWidgetResizable(true); + QVBoxLayout *DIGIOLayout = new QVBoxLayout(DIGIOWidget); + DIGIOWidget->setLayout(DIGIOLayout); + DIGIOLayout->setMargin(0); + DIGIOLayout->setSpacing(8); #pragma region DIGIO Monitor - MenuSectionWidget *DIGIOMonitorSectionWidget = - new MenuSectionWidget(DIGIOWidget); - Style::setStyle(DIGIOMonitorSectionWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection( - "DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - DIGIOMonitorSectionWidget); - DIGIOMonitorSectionWidget->contentLayout()->addWidget( - DIGIOMonitorCollapseSection); - DIGIOMonitorCollapseSection->contentLayout()->setSpacing(8); - - DIGIOBusyStatusLED = createStatusLEDWidget("BUSY (Output)", "digio", false, - DIGIOMonitorCollapseSection); - DIGIOCNVStatusLED = createStatusLEDWidget("CNV (Input)", "digio", false, - DIGIOMonitorCollapseSection); - DIGIOSENTStatusLED = createStatusLEDWidget("SENT (Output)", "digio", false, - DIGIOMonitorCollapseSection); - DIGIOACALCStatusLED = createStatusLEDWidget("ACALC (Output)", "digio", false, - DIGIOMonitorCollapseSection); - DIGIOFaultStatusLED = createStatusLEDWidget("FAULT (Output)", "digio", false, - DIGIOMonitorCollapseSection); - DIGIOBootloaderStatusLED = createStatusLEDWidget( - "BOOTLOADER (Output)", "digio", false, DIGIOMonitorCollapseSection); - - DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBusyStatusLED); - DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOCNVStatusLED); - DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOSENTStatusLED); - DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOACALCStatusLED); - DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOFaultStatusLED); - DIGIOMonitorCollapseSection->contentLayout()->addWidget( - DIGIOBootloaderStatusLED); + MenuSectionWidget *DIGIOMonitorSectionWidget = new MenuSectionWidget(DIGIOWidget); + Style::setStyle(DIGIOMonitorSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *DIGIOMonitorCollapseSection = new MenuCollapseSection( + "DIGIO Monitor", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOMonitorSectionWidget); + DIGIOMonitorSectionWidget->contentLayout()->addWidget(DIGIOMonitorCollapseSection); + DIGIOMonitorCollapseSection->contentLayout()->setSpacing(8); + + DIGIOBusyStatusLED = createStatusLEDWidget("BUSY (Output)", "digio", false, DIGIOMonitorCollapseSection); + DIGIOCNVStatusLED = createStatusLEDWidget("CNV (Input)", "digio", false, DIGIOMonitorCollapseSection); + DIGIOSENTStatusLED = createStatusLEDWidget("SENT (Output)", "digio", false, DIGIOMonitorCollapseSection); + DIGIOACALCStatusLED = createStatusLEDWidget("ACALC (Output)", "digio", false, DIGIOMonitorCollapseSection); + DIGIOFaultStatusLED = createStatusLEDWidget("FAULT (Output)", "digio", false, DIGIOMonitorCollapseSection); + DIGIOBootloaderStatusLED = + createStatusLEDWidget("BOOTLOADER (Output)", "digio", false, DIGIOMonitorCollapseSection); + + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBusyStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOCNVStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOSENTStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOACALCStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOFaultStatusLED); + DIGIOMonitorCollapseSection->contentLayout()->addWidget(DIGIOBootloaderStatusLED); #pragma endregion #pragma region DIGIO Control - MenuSectionWidget *DIGIOControlSectionWidget = - new MenuSectionWidget(DIGIOWidget); - Style::setStyle(DIGIOControlSectionWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *DIGIOControlCollapseSection = new MenuCollapseSection( - "DIGIO Control", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - DIGIOControlSectionWidget); - DIGIOControlCollapseSection->contentLayout()->setSpacing(8); - DIGIOControlSectionWidget->contentLayout()->addWidget( - DIGIOControlCollapseSection); - - QWidget *DIGIOControlGridWidget = new QWidget(DIGIOControlCollapseSection); - QGridLayout *DIGIOControlGridLayout = new QGridLayout(DIGIOControlGridWidget); - DIGIOControlGridWidget->setLayout(DIGIOControlGridLayout); - DIGIOControlGridLayout->setMargin(0); - DIGIOControlGridLayout->setSpacing(8); - - QLabel *DIGIO0Label = new QLabel("DIGIO0", DIGIOControlGridWidget); - QLabel *DIGIO1Label = new QLabel("DIGIO1", DIGIOControlGridWidget); - QLabel *DIGIO2Label = new QLabel("DIGIO2", DIGIOControlGridWidget); - QLabel *DIGIO3Label = new QLabel("DIGIO3", DIGIOControlGridWidget); - QLabel *DIGIO4Label = new QLabel("DIGIO4", DIGIOControlGridWidget); - QLabel *DIGIO5Label = new QLabel("DIGIO5", DIGIOControlGridWidget); - QLabel *DIGIOFunctionLabel = - new QLabel("DIGIO Function", DIGIOControlGridWidget); - QLabel *GPIOModeLabel = new QLabel("GPIO Mode", DIGIOControlGridWidget); - - DIGIO0ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Output", "Input"); - connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("DIGIO0EN", value); }); - - DIGIO0FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO0FNCToggleSwitch, "GPIO0", "BUSY"); - connect(DIGIO0FNCToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("BUSY", value); }); - - DIGIO1ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO1ENToggleSwitch, "Output", "Input"); - connect(DIGIO1ENToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("DIGIO1EN", value); }); - - DIGIO1FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO1FNCToggleSwitch, "GPIO1", "CNV"); - connect(DIGIO1FNCToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("CNV", value); }); - - DIGIO2ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO2ENToggleSwitch, "Output", "Input"); - connect(DIGIO2ENToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("DIGIO2EN", value); }); - - DIGIO2FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO2FNCToggleSwitch, "GPIO2", "SENT"); - connect(DIGIO2FNCToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("SENT", value); }); - - DIGIO3ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO3ENToggleSwitch, "Output", "Input"); - connect(DIGIO3ENToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("DIGIO3EN", value); }); - - DIGIO3FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO3FNCToggleSwitch, "GPIO3", "ACALC"); - connect(DIGIO3FNCToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("ACALC", value); }); - - DIGIO4ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO4ENToggleSwitch, "Output", "Input"); - connect(DIGIO4ENToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("DIGIO4EN", value); }); - - DIGIO4FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO4FNCToggleSwitch, "GPIO4", "FAULT"); - connect(DIGIO4FNCToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("FAULT", value); }); - - DIGIO5ENToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO5ENToggleSwitch, "Output", "Input"); - connect(DIGIO5ENToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("DIGIO5EN", value); }); - - DIGIO5FNCToggleSwitch = new CustomSwitch(); - changeCustomSwitchLabel(DIGIO5FNCToggleSwitch, "GPIO5", "BOOT"); - connect(DIGIO5FNCToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("BOOTLOAD", value); }); - - QPushButton *DIGIOResetButton = - new QPushButton("Reset DIGIO", DIGIOControlGridWidget); - DIGIOResetButton->setFixedWidth(100); - StyleHelper::BasicButton(DIGIOResetButton); - connect(DIGIOResetButton, &QPushButton::clicked, [this] { - toggleUtilityTask(false); - resetDIGIO(); - toggleUtilityTask(true); - }); - - DIGIOControlGridLayout->addWidget(DIGIOFunctionLabel, 0, 1); - DIGIOControlGridLayout->addWidget(GPIOModeLabel, 0, 2); - - DIGIOControlGridLayout->addWidget(DIGIO0Label, 1, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO0FNCToggleSwitch, 1, 1); - DIGIOControlGridLayout->addWidget(DIGIO0ENToggleSwitch, 1, 2); - - DIGIOControlGridLayout->addWidget(DIGIO1Label, 2, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO1FNCToggleSwitch, 2, 1); - DIGIOControlGridLayout->addWidget(DIGIO1ENToggleSwitch, 2, 2); - - DIGIOControlGridLayout->addWidget(DIGIO2Label, 3, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO2FNCToggleSwitch, 3, 1); - DIGIOControlGridLayout->addWidget(DIGIO2ENToggleSwitch, 3, 2); - - DIGIOControlGridLayout->addWidget(DIGIO3Label, 4, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO3FNCToggleSwitch, 4, 1); - DIGIOControlGridLayout->addWidget(DIGIO3ENToggleSwitch, 4, 2); - - DIGIOControlGridLayout->addWidget(DIGIO4Label, 5, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO4FNCToggleSwitch, 5, 1); - DIGIOControlGridLayout->addWidget(DIGIO4ENToggleSwitch, 5, 2); - - DIGIOControlGridLayout->addWidget(DIGIO5Label, 6, 0, Qt::AlignLeft); - DIGIOControlGridLayout->addWidget(DIGIO5FNCToggleSwitch, 6, 1); - DIGIOControlGridLayout->addWidget(DIGIO5ENToggleSwitch, 6, 2); - - DIGIOControlGridLayout->setColumnStretch(0, 1); - - DIGIOControlCollapseSection->contentLayout()->addWidget( - DIGIOControlGridWidget); - DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOResetButton); - - if (GENERALRegisterMap.at("Sequence Type") == 0) { - DIGIO2FNCToggleSwitch->setVisible(false); - DIGIO4FNCToggleSwitch->setVisible(false); - } + MenuSectionWidget *DIGIOControlSectionWidget = new MenuSectionWidget(DIGIOWidget); + Style::setStyle(DIGIOControlSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *DIGIOControlCollapseSection = new MenuCollapseSection( + "DIGIO Control", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, DIGIOControlSectionWidget); + DIGIOControlCollapseSection->contentLayout()->setSpacing(8); + DIGIOControlSectionWidget->contentLayout()->addWidget(DIGIOControlCollapseSection); + + QWidget *DIGIOControlGridWidget = new QWidget(DIGIOControlCollapseSection); + QGridLayout *DIGIOControlGridLayout = new QGridLayout(DIGIOControlGridWidget); + DIGIOControlGridWidget->setLayout(DIGIOControlGridLayout); + DIGIOControlGridLayout->setMargin(0); + DIGIOControlGridLayout->setSpacing(8); + + QLabel *DIGIO0Label = new QLabel("DIGIO0", DIGIOControlGridWidget); + QLabel *DIGIO1Label = new QLabel("DIGIO1", DIGIOControlGridWidget); + QLabel *DIGIO2Label = new QLabel("DIGIO2", DIGIOControlGridWidget); + QLabel *DIGIO3Label = new QLabel("DIGIO3", DIGIOControlGridWidget); + QLabel *DIGIO4Label = new QLabel("DIGIO4", DIGIOControlGridWidget); + QLabel *DIGIO5Label = new QLabel("DIGIO5", DIGIOControlGridWidget); + QLabel *DIGIOFunctionLabel = new QLabel("DIGIO Function", DIGIOControlGridWidget); + QLabel *GPIOModeLabel = new QLabel("GPIO Mode", DIGIOControlGridWidget); + + DIGIO0ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Output", "Input"); + connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO0EN", value); }); + + DIGIO0FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO0FNCToggleSwitch, "GPIO0", "BUSY"); + connect(DIGIO0FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("BUSY", value); }); + + DIGIO1ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO1ENToggleSwitch, "Output", "Input"); + connect(DIGIO1ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO1EN", value); }); + + DIGIO1FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO1FNCToggleSwitch, "GPIO1", "CNV"); + connect(DIGIO1FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("CNV", value); }); + + DIGIO2ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO2ENToggleSwitch, "Output", "Input"); + connect(DIGIO2ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO2EN", value); }); + + DIGIO2FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO2FNCToggleSwitch, "GPIO2", "SENT"); + connect(DIGIO2FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("SENT", value); }); + + DIGIO3ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO3ENToggleSwitch, "Output", "Input"); + connect(DIGIO3ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO3EN", value); }); + + DIGIO3FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO3FNCToggleSwitch, "GPIO3", "ACALC"); + connect(DIGIO3FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("ACALC", value); }); + + DIGIO4ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO4ENToggleSwitch, "Output", "Input"); + connect(DIGIO4ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO4EN", value); }); + + DIGIO4FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO4FNCToggleSwitch, "GPIO4", "FAULT"); + connect(DIGIO4FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("FAULT", value); }); + + DIGIO5ENToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO5ENToggleSwitch, "Output", "Input"); + connect(DIGIO5ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO5EN", value); }); + + DIGIO5FNCToggleSwitch = new CustomSwitch(); + changeCustomSwitchLabel(DIGIO5FNCToggleSwitch, "GPIO5", "BOOT"); + connect(DIGIO5FNCToggleSwitch, &CustomSwitch::clicked, + [this](bool value) { toggleDIGIOEN("BOOTLOAD", value); }); + + QPushButton *DIGIOResetButton = new QPushButton("Reset DIGIO", DIGIOControlGridWidget); + DIGIOResetButton->setFixedWidth(100); + StyleHelper::BasicButton(DIGIOResetButton); + connect(DIGIOResetButton, &QPushButton::clicked, [this] { + toggleUtilityTask(false); + resetDIGIO(); + toggleUtilityTask(true); + }); + + DIGIOControlGridLayout->addWidget(DIGIOFunctionLabel, 0, 1); + DIGIOControlGridLayout->addWidget(GPIOModeLabel, 0, 2); + + DIGIOControlGridLayout->addWidget(DIGIO0Label, 1, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO0FNCToggleSwitch, 1, 1); + DIGIOControlGridLayout->addWidget(DIGIO0ENToggleSwitch, 1, 2); + + DIGIOControlGridLayout->addWidget(DIGIO1Label, 2, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO1FNCToggleSwitch, 2, 1); + DIGIOControlGridLayout->addWidget(DIGIO1ENToggleSwitch, 2, 2); + + DIGIOControlGridLayout->addWidget(DIGIO2Label, 3, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO2FNCToggleSwitch, 3, 1); + DIGIOControlGridLayout->addWidget(DIGIO2ENToggleSwitch, 3, 2); + + DIGIOControlGridLayout->addWidget(DIGIO3Label, 4, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO3FNCToggleSwitch, 4, 1); + DIGIOControlGridLayout->addWidget(DIGIO3ENToggleSwitch, 4, 2); + + DIGIOControlGridLayout->addWidget(DIGIO4Label, 5, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO4FNCToggleSwitch, 5, 1); + DIGIOControlGridLayout->addWidget(DIGIO4ENToggleSwitch, 5, 2); + + DIGIOControlGridLayout->addWidget(DIGIO5Label, 6, 0, Qt::AlignLeft); + DIGIOControlGridLayout->addWidget(DIGIO5FNCToggleSwitch, 6, 1); + DIGIOControlGridLayout->addWidget(DIGIO5ENToggleSwitch, 6, 2); + + DIGIOControlGridLayout->setColumnStretch(0, 1); + + DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOControlGridWidget); + DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOResetButton); + + if(GENERALRegisterMap.at("Sequence Type") == 0) { + DIGIO2FNCToggleSwitch->setVisible(false); + DIGIO4FNCToggleSwitch->setVisible(false); + } #pragma endregion - DIGIOLayout->addWidget(DIGIOMonitorSectionWidget); - DIGIOLayout->addWidget(DIGIOControlSectionWidget); - DIGIOLayout->addStretch(); + DIGIOLayout->addWidget(DIGIOMonitorSectionWidget); + DIGIOLayout->addWidget(DIGIOControlSectionWidget); + DIGIOLayout->addStretch(); #pragma region MTDIAG1 Widget - MenuSectionWidget *MTDIAG1SectionWidget = - new MenuSectionWidget(centerUtilityWidget); - Style::setStyle(MTDIAG1SectionWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *MTDIAG1CollapseSection = new MenuCollapseSection( - "MT Diagnostic Register", - MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - MTDIAG1SectionWidget); - MTDIAG1SectionWidget->contentLayout()->addWidget(MTDIAG1CollapseSection); - MTDIAG1CollapseSection->contentLayout()->setSpacing(8); - - R0StatusLED = - createStatusLEDWidget("R0", "mtdiag", false, MTDIAG1SectionWidget); - R1StatusLED = - createStatusLEDWidget("R1", "mtdiag", false, MTDIAG1SectionWidget); - R2StatusLED = - createStatusLEDWidget("R2", "mtdiag", false, MTDIAG1SectionWidget); - R3StatusLED = - createStatusLEDWidget("R3", "mtdiag", false, MTDIAG1SectionWidget); - R4StatusLED = - createStatusLEDWidget("R4", "mtdiag", false, MTDIAG1SectionWidget); - R5StatusLED = - createStatusLEDWidget("R5", "mtdiag", false, MTDIAG1SectionWidget); - R6StatusLED = - createStatusLEDWidget("R6", "mtdiag", false, MTDIAG1SectionWidget); - R7StatusLED = - createStatusLEDWidget("R7", "mtdiag", false, MTDIAG1SectionWidget); - - MTDIAG1CollapseSection->contentLayout()->addWidget(R0StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R1StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R2StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R3StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R4StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R5StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R6StatusLED); - MTDIAG1CollapseSection->contentLayout()->addWidget(R7StatusLED); + MenuSectionWidget *MTDIAG1SectionWidget = new MenuSectionWidget(centerUtilityWidget); + Style::setStyle(MTDIAG1SectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *MTDIAG1CollapseSection = new MenuCollapseSection( + "MT Diagnostic Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, MTDIAG1SectionWidget); + MTDIAG1SectionWidget->contentLayout()->addWidget(MTDIAG1CollapseSection); + MTDIAG1CollapseSection->contentLayout()->setSpacing(8); + + R0StatusLED = createStatusLEDWidget("R0", "mtdiag", false, MTDIAG1SectionWidget); + R1StatusLED = createStatusLEDWidget("R1", "mtdiag", false, MTDIAG1SectionWidget); + R2StatusLED = createStatusLEDWidget("R2", "mtdiag", false, MTDIAG1SectionWidget); + R3StatusLED = createStatusLEDWidget("R3", "mtdiag", false, MTDIAG1SectionWidget); + R4StatusLED = createStatusLEDWidget("R4", "mtdiag", false, MTDIAG1SectionWidget); + R5StatusLED = createStatusLEDWidget("R5", "mtdiag", false, MTDIAG1SectionWidget); + R6StatusLED = createStatusLEDWidget("R6", "mtdiag", false, MTDIAG1SectionWidget); + R7StatusLED = createStatusLEDWidget("R7", "mtdiag", false, MTDIAG1SectionWidget); + + MTDIAG1CollapseSection->contentLayout()->addWidget(R0StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R1StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R2StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R3StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R4StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R5StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R6StatusLED); + MTDIAG1CollapseSection->contentLayout()->addWidget(R7StatusLED); #pragma endregion #pragma region MT Diagnostics - MTDiagnosticsScrollArea = new QScrollArea(centerUtilityWidget); - QWidget *MTDiagnosticsWidget = new QWidget(MTDiagnosticsScrollArea); - MTDiagnosticsScrollArea->setWidget(MTDiagnosticsWidget); - MTDiagnosticsScrollArea->setWidgetResizable(true); - QVBoxLayout *MTDiagnosticsLayout = new QVBoxLayout(MTDiagnosticsWidget); - MTDiagnosticsWidget->setLayout(MTDiagnosticsLayout); - MTDiagnosticsLayout->setMargin(0); - MTDiagnosticsLayout->setSpacing(8); - - MenuSectionWidget *MTDiagnosticsSectionWidget = - new MenuSectionWidget(centerUtilityWidget); - Style::setStyle(MTDiagnosticsSectionWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *MTDiagnosticsCollapseSection = new MenuCollapseSection( - "MT Diagnostics", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - MTDiagnosticsSectionWidget); - MTDiagnosticsSectionWidget->contentLayout()->addWidget( - MTDiagnosticsCollapseSection); - MTDiagnosticsCollapseSection->contentLayout()->setSpacing(8); - - QLabel *AFEDIAG0Label = new QLabel("AFEDIAG0 (%)"); - Style::setStyle(AFEDIAG0Label, style::properties::label::menuSmall); - QLabel *AFEDIAG1Label = new QLabel("AFEDIAG1 (%)"); - Style::setStyle(AFEDIAG1Label, style::properties::label::menuSmall); - QLabel *AFEDIAG2Label = new QLabel("AFEDIAG2 (V)"); - Style::setStyle(AFEDIAG2Label, style::properties::label::menuSmall); - - AFEDIAG0LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); - AFEDIAG1LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); - AFEDIAG2LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); - AFEDIAG0LineEdit->setReadOnly(true); - AFEDIAG1LineEdit->setReadOnly(true); - AFEDIAG2LineEdit->setReadOnly(true); - connectLineEditToNumber(AFEDIAG0LineEdit, afeDiag0, "V"); - connectLineEditToNumber(AFEDIAG1LineEdit, afeDiag1, "V"); - connectLineEditToNumber(AFEDIAG2LineEdit, afeDiag2, "V"); - - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0Label); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0LineEdit); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1Label); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1LineEdit); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2Label); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2LineEdit); - - MTDiagnosticsLayout->addWidget(MTDiagnosticsSectionWidget); - MTDiagnosticsLayout->addWidget(MTDIAG1SectionWidget); - MTDiagnosticsLayout->addStretch(); + MTDiagnosticsScrollArea = new QScrollArea(centerUtilityWidget); + QWidget *MTDiagnosticsWidget = new QWidget(MTDiagnosticsScrollArea); + MTDiagnosticsScrollArea->setWidget(MTDiagnosticsWidget); + MTDiagnosticsScrollArea->setWidgetResizable(true); + QVBoxLayout *MTDiagnosticsLayout = new QVBoxLayout(MTDiagnosticsWidget); + MTDiagnosticsWidget->setLayout(MTDiagnosticsLayout); + MTDiagnosticsLayout->setMargin(0); + MTDiagnosticsLayout->setSpacing(8); + + MenuSectionWidget *MTDiagnosticsSectionWidget = new MenuSectionWidget(centerUtilityWidget); + Style::setStyle(MTDiagnosticsSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *MTDiagnosticsCollapseSection = new MenuCollapseSection( + "MT Diagnostics", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, MTDiagnosticsSectionWidget); + MTDiagnosticsSectionWidget->contentLayout()->addWidget(MTDiagnosticsCollapseSection); + MTDiagnosticsCollapseSection->contentLayout()->setSpacing(8); + + QLabel *AFEDIAG0Label = new QLabel("AFEDIAG0 (%)"); + Style::setStyle(AFEDIAG0Label, style::properties::label::menuSmall); + QLabel *AFEDIAG1Label = new QLabel("AFEDIAG1 (%)"); + Style::setStyle(AFEDIAG1Label, style::properties::label::menuSmall); + QLabel *AFEDIAG2Label = new QLabel("AFEDIAG2 (V)"); + Style::setStyle(AFEDIAG2Label, style::properties::label::menuSmall); + + AFEDIAG0LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); + AFEDIAG1LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); + AFEDIAG2LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); + AFEDIAG0LineEdit->setReadOnly(true); + AFEDIAG1LineEdit->setReadOnly(true); + AFEDIAG2LineEdit->setReadOnly(true); + connectLineEditToNumber(AFEDIAG0LineEdit, afeDiag0, "V"); + connectLineEditToNumber(AFEDIAG1LineEdit, afeDiag1, "V"); + connectLineEditToNumber(AFEDIAG2LineEdit, afeDiag2, "V"); + + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0Label); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0LineEdit); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1Label); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1LineEdit); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2Label); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2LineEdit); + + MTDiagnosticsLayout->addWidget(MTDiagnosticsSectionWidget); + MTDiagnosticsLayout->addWidget(MTDIAG1SectionWidget); + MTDiagnosticsLayout->addStretch(); #pragma endregion - centerUtilityLayout->addWidget(DIGIOScrollArea); - centerUtilityLayout->addWidget(MTDiagnosticsScrollArea); + centerUtilityLayout->addWidget(DIGIOScrollArea); + centerUtilityLayout->addWidget(MTDiagnosticsScrollArea); #pragma endregion #pragma region Right Utility Widget - QScrollArea *rightUtilityScrollArea = new QScrollArea(this); - QWidget *rightUtilityWidget = new QWidget(rightUtilityScrollArea); - rightUtilityScrollArea->setWidget(rightUtilityWidget); - rightUtilityScrollArea->setWidgetResizable(true); - QVBoxLayout *rightUtilityLayout = new QVBoxLayout(rightUtilityWidget); - rightUtilityWidget->setLayout(rightUtilityLayout); - rightUtilityLayout->setMargin(0); - rightUtilityLayout->setSpacing(8); - - MenuSectionWidget *faultRegisterSectionWidget = - new MenuSectionWidget(rightUtilityWidget); - Style::setStyle(faultRegisterSectionWidget, - style::properties::widget::basicComponent); - MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection( - "Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, - faultRegisterSectionWidget); - faultRegisterSectionWidget->contentLayout()->addWidget( - faultRegisterCollapseSection); - faultRegisterCollapseSection->contentLayout()->setSpacing(8); - - VDDUnderVoltageStatusLED = createStatusLEDWidget( - "VDD Under Voltage", "fault", false, faultRegisterCollapseSection); - VDDOverVoltageStatusLED = createStatusLEDWidget( - "VDD Over Voltage", "fault", false, faultRegisterCollapseSection); - VDRIVEUnderVoltageStatusLED = createStatusLEDWidget( - "VDRIVE Under Voltage", "fault", false, faultRegisterCollapseSection); - VDRIVEOverVoltageStatusLED = createStatusLEDWidget( - "VDRIVE Over Voltage", "fault", false, faultRegisterCollapseSection); - AFEDIAGStatusLED = createStatusLEDWidget("AFEDIAG", "fault", false, - faultRegisterCollapseSection); - NVMCRCFaultStatusLED = createStatusLEDWidget("NVM CRC Fault", "fault", false, - faultRegisterCollapseSection); - ECCDoubleBitErrorStatusLED = createStatusLEDWidget( - "ECC Double Bit Error", "fault", false, faultRegisterCollapseSection); - OscillatorDriftStatusLED = createStatusLEDWidget( - "Oscillator Drift", "fault", false, faultRegisterCollapseSection); - CountSensorFalseStateStatusLED = createStatusLEDWidget( - "Count Sensor False State", "fault", false, faultRegisterCollapseSection); - AngleCrossCheckStatusLED = createStatusLEDWidget( - "Angle Cross Check", "fault", false, faultRegisterCollapseSection); - TurnCountSensorLevelsStatusLED = createStatusLEDWidget( - "Turn Count Sensor Levels", "fault", false, faultRegisterCollapseSection); - MTDIAGStatusLED = createStatusLEDWidget("MTDIAG", "fault", false, - faultRegisterCollapseSection); - TurnCounterCrossCheckStatusLED = createStatusLEDWidget( - "Turn Counter Cross Check", "fault", false, faultRegisterCollapseSection); - RadiusCheckStatusLED = createStatusLEDWidget("Radius Check", "fault", false, - faultRegisterCollapseSection); - SequencerWatchdogStatusLED = createStatusLEDWidget( - "Sequencer Watchdog", "fault", false, faultRegisterCollapseSection); - - faultRegisterCollapseSection->contentLayout()->addWidget( - VDDUnderVoltageStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - VDDOverVoltageStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - VDRIVEUnderVoltageStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - VDRIVEOverVoltageStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(AFEDIAGStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - NVMCRCFaultStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - ECCDoubleBitErrorStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - OscillatorDriftStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - CountSensorFalseStateStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - AngleCrossCheckStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - TurnCountSensorLevelsStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget(MTDIAGStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - TurnCounterCrossCheckStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - RadiusCheckStatusLED); - faultRegisterCollapseSection->contentLayout()->addWidget( - SequencerWatchdogStatusLED); - - rightUtilityLayout->addWidget(faultRegisterSectionWidget); - rightUtilityLayout->addSpacerItem( - new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + QScrollArea *rightUtilityScrollArea = new QScrollArea(this); + QWidget *rightUtilityWidget = new QWidget(rightUtilityScrollArea); + rightUtilityScrollArea->setWidget(rightUtilityWidget); + rightUtilityScrollArea->setWidgetResizable(true); + QVBoxLayout *rightUtilityLayout = new QVBoxLayout(rightUtilityWidget); + rightUtilityWidget->setLayout(rightUtilityLayout); + rightUtilityLayout->setMargin(0); + rightUtilityLayout->setSpacing(8); + + MenuSectionWidget *faultRegisterSectionWidget = new MenuSectionWidget(rightUtilityWidget); + Style::setStyle(faultRegisterSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *faultRegisterCollapseSection = new MenuCollapseSection( + "Fault Register", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, faultRegisterSectionWidget); + faultRegisterSectionWidget->contentLayout()->addWidget(faultRegisterCollapseSection); + faultRegisterCollapseSection->contentLayout()->setSpacing(8); + + VDDUnderVoltageStatusLED = + createStatusLEDWidget("VDD Under Voltage", "fault", false, faultRegisterCollapseSection); + VDDOverVoltageStatusLED = + createStatusLEDWidget("VDD Over Voltage", "fault", false, faultRegisterCollapseSection); + VDRIVEUnderVoltageStatusLED = + createStatusLEDWidget("VDRIVE Under Voltage", "fault", false, faultRegisterCollapseSection); + VDRIVEOverVoltageStatusLED = + createStatusLEDWidget("VDRIVE Over Voltage", "fault", false, faultRegisterCollapseSection); + AFEDIAGStatusLED = createStatusLEDWidget("AFEDIAG", "fault", false, faultRegisterCollapseSection); + NVMCRCFaultStatusLED = createStatusLEDWidget("NVM CRC Fault", "fault", false, faultRegisterCollapseSection); + ECCDoubleBitErrorStatusLED = + createStatusLEDWidget("ECC Double Bit Error", "fault", false, faultRegisterCollapseSection); + OscillatorDriftStatusLED = + createStatusLEDWidget("Oscillator Drift", "fault", false, faultRegisterCollapseSection); + CountSensorFalseStateStatusLED = + createStatusLEDWidget("Count Sensor False State", "fault", false, faultRegisterCollapseSection); + AngleCrossCheckStatusLED = + createStatusLEDWidget("Angle Cross Check", "fault", false, faultRegisterCollapseSection); + TurnCountSensorLevelsStatusLED = + createStatusLEDWidget("Turn Count Sensor Levels", "fault", false, faultRegisterCollapseSection); + MTDIAGStatusLED = createStatusLEDWidget("MTDIAG", "fault", false, faultRegisterCollapseSection); + TurnCounterCrossCheckStatusLED = + createStatusLEDWidget("Turn Counter Cross Check", "fault", false, faultRegisterCollapseSection); + RadiusCheckStatusLED = createStatusLEDWidget("Radius Check", "fault", false, faultRegisterCollapseSection); + SequencerWatchdogStatusLED = + createStatusLEDWidget("Sequencer Watchdog", "fault", false, faultRegisterCollapseSection); + + faultRegisterCollapseSection->contentLayout()->addWidget(VDDUnderVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(VDDOverVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(VDRIVEUnderVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(VDRIVEOverVoltageStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(AFEDIAGStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(NVMCRCFaultStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(ECCDoubleBitErrorStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(OscillatorDriftStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(CountSensorFalseStateStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(AngleCrossCheckStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(TurnCountSensorLevelsStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(MTDIAGStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(TurnCounterCrossCheckStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(RadiusCheckStatusLED); + faultRegisterCollapseSection->contentLayout()->addWidget(SequencerWatchdogStatusLED); + + rightUtilityLayout->addWidget(faultRegisterSectionWidget); + rightUtilityLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); #pragma endregion - tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - tool->topContainer()->setVisible(false); - tool->topContainerMenuControl()->setVisible(false); - tool->leftContainer()->setVisible(true); - tool->rightContainer()->setVisible(true); - tool->bottomContainer()->setVisible(false); - tool->setLeftContainerWidth(240); - tool->setRightContainerWidth(224); - tool->openBottomContainerHelper(false); - tool->openTopContainerHelper(false); - - tool->leftStack()->addWidget(leftUtilityWidget); - tool->addWidgetToCentralContainerHelper(centerUtilityWidget); - tool->rightStack()->addWidget(rightUtilityScrollArea); - - return tool; -} - -void HarmonicCalibration::readDeviceProperties() { - uint32_t *uniqId3RegisterValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t page = m_admtController->getUniqueIdPage( - ADMTController::UniqueIDRegister::UNIQID3); - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::CNVPAGE); - - bool success = false; - - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, page) != -1) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, cnvPageRegValue) != -1) { - if (*cnvPageRegValue == page) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getUniqueIdRegister( - ADMTController::UniqueIDRegister::UNIQID3), - uniqId3RegisterValue) != -1) { - deviceRegisterMap = m_admtController->getUNIQID3RegisterMapping( - static_cast(*uniqId3RegisterValue)); - - if (deviceRegisterMap.at("Supply ID") == "5V") { - is5V = true; - } else if (deviceRegisterMap.at("Supply ID") == "3.3V") { - is5V = false; - } else { - is5V = false; - } - - deviceName = - QString::fromStdString(deviceRegisterMap.at("Product ID")); - - if (deviceRegisterMap.at("ASIL ID") == "ASIL QM") { - deviceType = QString::fromStdString("Industrial"); - } else if (deviceRegisterMap.at("ASIL ID") == "ASIL B") { - deviceType = QString::fromStdString("Automotive"); - } else { - deviceType = - QString::fromStdString(deviceRegisterMap.at("ASIL ID")); - } - - success = true; - } - } - } - } - - if (!success) { - StatusBarManager::pushMessage("Failed to read device properties"); - } -} - -void HarmonicCalibration::initializeADMT() { - bool success = resetDIGIO(); - success = resetGENERAL(); - - if (!success) { - StatusBarManager::pushMessage("Failed initialize ADMT"); - } -} - -bool HarmonicCalibration::readSequence() { - uint32_t *generalRegValue = new uint32_t; - uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::GENERAL); - uint32_t generalRegisterPage = m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::GENERAL); - - bool success = false; - - if (changeCNVPage(generalRegisterPage)) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - generalRegisterAddress, generalRegValue) != -1) { - if (*generalRegValue != UINT32_MAX) { - GENERALRegisterMap = m_admtController->getGeneralRegisterBitMapping( - static_cast(*generalRegValue)); - success = true; - } - } - } - - return success; -} - -bool HarmonicCalibration::writeSequence(const map &settings) { - uint32_t *generalRegValue = new uint32_t; - uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::GENERAL); - - bool success = false; - - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - generalRegisterAddress, generalRegValue) != -1) { - - uint32_t newGeneralRegValue = - m_admtController->setGeneralRegisterBitMapping(*generalRegValue, - settings); - uint32_t generalRegisterPage = m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::GENERAL); - - if (changeCNVPage(generalRegisterPage)) { - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - generalRegisterAddress, newGeneralRegValue) != -1) { - if (readSequence()) { - if (settings.at("Convert Synchronization") == - GENERALRegisterMap.at("Convert Synchronization") && - settings.at("Angle Filter") == - GENERALRegisterMap.at("Angle Filter") && - settings.at("8th Harmonic") == - GENERALRegisterMap.at("8th Harmonic") && - settings.at("Sequence Type") == - GENERALRegisterMap.at("Sequence Type") && - settings.at("Conversion Type") == - GENERALRegisterMap.at("Conversion Type")) { - success = true; - } - } - } - } - } - - return success; -} - -void HarmonicCalibration::applySequence() { - toggleWidget(applySequenceButton, false); - applySequenceButton->setText("Writing..."); - QTimer::singleShot(1000, this, [this]() { - this->toggleWidget(applySequenceButton, true); - applySequenceButton->setText("Apply"); - }); - uint32_t *generalRegValue = new uint32_t; - uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::GENERAL); - map settings; - - bool success = false; - - settings["Sequence Type"] = qvariant_cast( - sequenceTypeMenuCombo->combo()->currentData()); // sequenceType; - settings["Conversion Type"] = qvariant_cast( - conversionTypeMenuCombo->combo()->currentData()); // conversionType; - settings["Convert Synchronization"] = qvariant_cast( - convertSynchronizationMenuCombo->combo()->currentData()); // convertSync; - settings["Angle Filter"] = qvariant_cast( - angleFilterMenuCombo->combo()->currentData()); // angleFilter; - settings["8th Harmonic"] = qvariant_cast( - eighthHarmonicMenuCombo->combo()->currentData()); // eighthHarmonic; - - success = writeSequence(settings); - if (!success) - StatusBarManager::pushMessage("Failed to apply sequence settings"); - else - StatusBarManager::pushMessage("Sequence settings applied successfully"); -} - -bool HarmonicCalibration::changeCNVPage(uint32_t page) { - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::CNVPAGE); - - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, page) != -1) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, cnvPageRegValue) != -1) { - if (*cnvPageRegValue == page) { - return true; - } - } - } - - return false; -} - -void HarmonicCalibration::initializeMotor() { - motor_rpm = 60; - rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(motor_rpm)); - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, - rotate_vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - - amax = convertAccelTimetoAMAX(motorAccelTime); - writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - - dmax = 3000; - writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); - - ramp_mode = 0; - writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, - ramp_mode); - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - - target_pos = 0; - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, - target_pos); - - current_pos = 0; - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, - current_pos); -} - -void HarmonicCalibration::startDeviceStatusMonitor() { - if (!m_deviceStatusThread.isRunning()) { - isDeviceStatusMonitor = true; - m_deviceStatusThread = - QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, - deviceStatusMonitorRate); - m_deviceStatusWatcher.setFuture(m_deviceStatusThread); - } -} - -void HarmonicCalibration::stopDeviceStatusMonitor() { - isDeviceStatusMonitor = false; - if (m_deviceStatusThread.isRunning()) { - m_deviceStatusThread.cancel(); - m_deviceStatusWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) { - uint32_t *readValue = new uint32_t; - bool registerFault = false; - while (isDeviceStatusMonitor) { - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::FAULT), - 0) == 0) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::FAULT), - readValue) == 0) { - registerFault = m_admtController->checkRegisterFault( - static_cast(*readValue), - GENERALRegisterMap.at("Sequence Type") == 0 ? true : false); - Q_EMIT updateFaultStatusSignal(registerFault); - } else { - Q_EMIT updateFaultStatusSignal(true); - } - } else { - Q_EMIT updateFaultStatusSignal(true); - } - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::requestDisconnect() { - stopAcquisition(); - - stopAcquisitionUITask(); - stopCalibrationUITask(); - stopUtilityTask(); - - stopCalibrationStreamThread(); - - stopDeviceStatusMonitor(); - stopCurrentMotorPositionMonitor(); -} - -void HarmonicCalibration::startCurrentMotorPositionMonitor() { - if (!m_currentMotorPositionThread.isRunning()) { - isMotorPositionMonitor = true; - m_currentMotorPositionThread = - QtConcurrent::run(this, &HarmonicCalibration::currentMotorPositionTask, - motorPositionMonitorRate); - m_currentMotorPositionWatcher.setFuture(m_currentMotorPositionThread); - } -} - -void HarmonicCalibration::stopCurrentMotorPositionMonitor() { - isMotorPositionMonitor = false; - if (m_currentMotorPositionThread.isRunning()) { - m_currentMotorPositionThread.cancel(); - m_currentMotorPositionWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::currentMotorPositionTask(int sampleRate) { - double motorPosition = 0; - while (isMotorPositionMonitor) { - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, - motorPosition); - - Q_EMIT motorPositionChanged(motorPosition); - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::updateMotorPosition(double position) { - current_pos = position; - if (isAcquisitionTab) - updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); - else if (isCalibrationTab) - updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); -} - -bool HarmonicCalibration::resetGENERAL() { - bool success = false; - - uint32_t resetValue = 0x0000; - if (deviceRegisterMap.at("ASIL ID") == "ASIL QM") { - resetValue = 0x1231; - } // Industrial or ASIL QM - else if (deviceRegisterMap.at("ASIL ID") == "ASIL B") { - resetValue = 0x1200; - } // Automotive or ASIL B - - if (resetValue != 0x0000) { - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::GENERAL), - resetValue) == 0) { - success = true; - } - } - - return success; + tool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tool->topContainer()->setVisible(false); + tool->topContainerMenuControl()->setVisible(false); + tool->leftContainer()->setVisible(true); + tool->rightContainer()->setVisible(true); + tool->bottomContainer()->setVisible(false); + tool->setLeftContainerWidth(240); + tool->setRightContainerWidth(224); + tool->openBottomContainerHelper(false); + tool->openTopContainerHelper(false); + + tool->leftStack()->addWidget(leftUtilityWidget); + tool->addWidgetToCentralContainerHelper(centerUtilityWidget); + tool->rightStack()->addWidget(rightUtilityScrollArea); + + return tool; +} + +void HarmonicCalibration::readDeviceProperties() +{ + uint32_t *uniqId3RegisterValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t page = m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3); + uint32_t cnvPageAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + bool success = false; + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, page) != -1) { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) != -1) { + if(*cnvPageRegValue == page) { + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getUniqueIdRegister( + ADMTController::UniqueIDRegister::UNIQID3), + uniqId3RegisterValue) != -1) { + deviceRegisterMap = m_admtController->getUNIQID3RegisterMapping( + static_cast(*uniqId3RegisterValue)); + + if(deviceRegisterMap.at("Supply ID") == "5V") { + is5V = true; + } else if(deviceRegisterMap.at("Supply ID") == "3.3V") { + is5V = false; + } else { + is5V = false; + } + + deviceName = QString::fromStdString(deviceRegisterMap.at("Product ID")); + + if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { + deviceType = QString::fromStdString("Industrial"); + } else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { + deviceType = QString::fromStdString("Automotive"); + } else { + deviceType = QString::fromStdString(deviceRegisterMap.at("ASIL ID")); + } + + success = true; + } + } + } + } + + if(!success) { + StatusBarManager::pushMessage("Failed to read device properties"); + } +} + +void HarmonicCalibration::initializeADMT() +{ + bool success = resetDIGIO(); + success = resetGENERAL(); + + if(!success) { + StatusBarManager::pushMessage("Failed initialize ADMT"); + } +} + +bool HarmonicCalibration::readSequence() +{ + uint32_t *generalRegValue = new uint32_t; + uint32_t generalRegisterAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); + uint32_t generalRegisterPage = + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); + + bool success = false; + + if(changeCNVPage(generalRegisterPage)) { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + generalRegisterAddress, generalRegValue) != -1) { + if(*generalRegValue != UINT32_MAX) { + GENERALRegisterMap = m_admtController->getGeneralRegisterBitMapping( + static_cast(*generalRegValue)); + success = true; + } + } + } + + return success; +} + +bool HarmonicCalibration::writeSequence(const map &settings) +{ + uint32_t *generalRegValue = new uint32_t; + uint32_t generalRegisterAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); + + bool success = false; + + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + generalRegisterAddress, generalRegValue) != -1) { + + uint32_t newGeneralRegValue = + m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings); + uint32_t generalRegisterPage = + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); + + if(changeCNVPage(generalRegisterPage)) { + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + generalRegisterAddress, newGeneralRegValue) != -1) { + if(readSequence()) { + if(settings.at("Convert Synchronization") == + GENERALRegisterMap.at("Convert Synchronization") && + settings.at("Angle Filter") == GENERALRegisterMap.at("Angle Filter") && + settings.at("8th Harmonic") == GENERALRegisterMap.at("8th Harmonic") && + settings.at("Sequence Type") == GENERALRegisterMap.at("Sequence Type") && + settings.at("Conversion Type") == GENERALRegisterMap.at("Conversion Type")) { + success = true; + } + } + } + } + } + + return success; +} + +void HarmonicCalibration::applySequence() +{ + toggleWidget(applySequenceButton, false); + applySequenceButton->setText("Writing..."); + QTimer::singleShot(1000, this, [this]() { + this->toggleWidget(applySequenceButton, true); + applySequenceButton->setText("Apply"); + }); + uint32_t *generalRegValue = new uint32_t; + uint32_t generalRegisterAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); + map settings; + + bool success = false; + + settings["Sequence Type"] = qvariant_cast(sequenceTypeMenuCombo->combo()->currentData()); // sequenceType; + settings["Conversion Type"] = + qvariant_cast(conversionTypeMenuCombo->combo()->currentData()); // conversionType; + settings["Convert Synchronization"] = + qvariant_cast(convertSynchronizationMenuCombo->combo()->currentData()); // convertSync; + settings["Angle Filter"] = qvariant_cast(angleFilterMenuCombo->combo()->currentData()); // angleFilter; + settings["8th Harmonic"] = + qvariant_cast(eighthHarmonicMenuCombo->combo()->currentData()); // eighthHarmonic; + + success = writeSequence(settings); + if(!success) + StatusBarManager::pushMessage("Failed to apply sequence settings"); + else + StatusBarManager::pushMessage("Sequence settings applied successfully"); +} + +bool HarmonicCalibration::changeCNVPage(uint32_t page) +{ + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t cnvPageAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, page) != -1) { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) != -1) { + if(*cnvPageRegValue == page) { + return true; + } + } + } + + return false; +} + +void HarmonicCalibration::initializeMotor() +{ + motor_rpm = 60; + rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(motor_rpm)); + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + + amax = convertAccelTimetoAMAX(motorAccelTime); + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + readMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + + dmax = 3000; + writeMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); + readMotorAttributeValue(ADMTController::MotorAttribute::DMAX, dmax); + + ramp_mode = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + + target_pos = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); + + current_pos = 0; + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); +} + +void HarmonicCalibration::startDeviceStatusMonitor() +{ + if(!m_deviceStatusThread.isRunning()) { + isDeviceStatusMonitor = true; + m_deviceStatusThread = + QtConcurrent::run(this, &HarmonicCalibration::getDeviceFaultStatus, deviceStatusMonitorRate); + m_deviceStatusWatcher.setFuture(m_deviceStatusThread); + } +} + +void HarmonicCalibration::stopDeviceStatusMonitor() +{ + isDeviceStatusMonitor = false; + if(m_deviceStatusThread.isRunning()) { + m_deviceStatusThread.cancel(); + m_deviceStatusWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) +{ + uint32_t *readValue = new uint32_t; + bool registerFault = false; + while(isDeviceStatusMonitor) { + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), + 0) == 0) { + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::FAULT), + readValue) == 0) { + registerFault = m_admtController->checkRegisterFault( + static_cast(*readValue), + GENERALRegisterMap.at("Sequence Type") == 0 ? true : false); + Q_EMIT updateFaultStatusSignal(registerFault); + } else { + Q_EMIT updateFaultStatusSignal(true); + } + } else { + Q_EMIT updateFaultStatusSignal(true); + } + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::requestDisconnect() +{ + stopAcquisition(); + + stopAcquisitionUITask(); + stopCalibrationUITask(); + stopUtilityTask(); + + stopCalibrationStreamThread(); + + stopDeviceStatusMonitor(); + stopCurrentMotorPositionMonitor(); +} + +void HarmonicCalibration::startCurrentMotorPositionMonitor() +{ + if(!m_currentMotorPositionThread.isRunning()) { + isMotorPositionMonitor = true; + m_currentMotorPositionThread = QtConcurrent::run(this, &HarmonicCalibration::currentMotorPositionTask, + motorPositionMonitorRate); + m_currentMotorPositionWatcher.setFuture(m_currentMotorPositionThread); + } +} + +void HarmonicCalibration::stopCurrentMotorPositionMonitor() +{ + isMotorPositionMonitor = false; + if(m_currentMotorPositionThread.isRunning()) { + m_currentMotorPositionThread.cancel(); + m_currentMotorPositionWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::currentMotorPositionTask(int sampleRate) +{ + double motorPosition = 0; + while(isMotorPositionMonitor) { + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, motorPosition); + + Q_EMIT motorPositionChanged(motorPosition); + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::updateMotorPosition(double position) +{ + current_pos = position; + if(isAcquisitionTab) + updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); + else if(isCalibrationTab) + updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); +} + +bool HarmonicCalibration::resetGENERAL() +{ + bool success = false; + + uint32_t resetValue = 0x0000; + if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { + resetValue = 0x1231; + } // Industrial or ASIL QM + else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { + resetValue = 0x1200; + } // Automotive or ASIL B + + if(resetValue != 0x0000) { + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL), + resetValue) == 0) { + success = true; + } + } + + return success; } #pragma region Acquisition Methods -bool HarmonicCalibration::updateChannelValues() { - bool success = false; - rotation = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - rotationChannelName, bufferSize); - if (rotation == static_cast(UINT64_MAX)) { - return false; - } - angle = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - angleChannelName, bufferSize); - if (angle == static_cast(UINT64_MAX)) { - return false; - } - updateCountValue(); - if (count == static_cast(UINT64_MAX)) { - return false; - } - temp = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - temperatureChannelName, bufferSize); - if (temp == static_cast(UINT64_MAX)) { - return false; - } - return success = true; -} - -void HarmonicCalibration::updateCountValue() { - uint32_t *absAngleRegValue = new uint32_t; - bool success = false; - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::CNVPAGE), - 0x0000) == 0) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister( - ADMTController::SensorRegister::ABSANGLE), - absAngleRegValue) == 0) { - count = m_admtController->getAbsAngleTurnCount( - static_cast(*absAngleRegValue)); - success = true; - } - } - if (!success) { - count = static_cast(UINT64_MAX); - } -} - -void HarmonicCalibration::updateLineEditValues() { - if (rotation == static_cast(UINT64_MAX)) { - rotationValueLabel->setText("N/A"); - } else { - rotationValueLabel->setText(QString::number(rotation) + "°"); - } - if (angle == static_cast(UINT64_MAX)) { - angleValueLabel->setText("N/A"); - } else { - angleValueLabel->setText(QString::number(angle) + "°"); - } - if (count == static_cast(UINT64_MAX)) { - countValueLabel->setText("N/A"); - } else { - countValueLabel->setText(QString::number(count)); - } - if (temp == static_cast(UINT64_MAX)) { - tempValueLabel->setText("N/A"); - } else { - tempValueLabel->setText(QString::number(temp) + " °C"); - } -} - -void HarmonicCalibration::startAcquisition() { - isStartAcquisition = true; - acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); - - m_acquisitionDataThread = QtConcurrent::run( - this, &HarmonicCalibration::getAcquisitionSamples, acquisitionSampleRate); - m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); - m_acquisitionGraphThread = - QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, - acquisitionGraphSampleRate); - m_acquisitionGraphWatcher.setFuture(m_acquisitionGraphThread); -} - -void HarmonicCalibration::stopAcquisition() { - isStartAcquisition = false; - if (m_acquisitionDataThread.isRunning()) { - m_acquisitionDataThread.cancel(); - m_acquisitionDataWatcher.waitForFinished(); - } - if (m_acquisitionGraphThread.isRunning()) { - m_acquisitionGraphThread.cancel(); - m_acquisitionGraphWatcher.waitForFinished(); - } - - stopCurrentMotorPositionMonitor(); -} - -void HarmonicCalibration::updateFaultStatus(bool status) { - bool isChanged = (deviceStatusFault != status); - if (isChanged) { - deviceStatusFault = status; - acquisitionFaultRegisterLEDWidget->setChecked(deviceStatusFault); - calibrationFaultRegisterLEDWidget->setChecked(deviceStatusFault); - } -} - -void HarmonicCalibration::updateAcquisitionMotorRPM() { - acquisitionMotorRPMLineEdit->setText(QString::number(motor_rpm)); -} - -void HarmonicCalibration::updateAcquisitionMotorRotationDirection() { - acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); -} - -void HarmonicCalibration::getAcquisitionSamples(int sampleRate) { - while (isStartAcquisition) { - if (!updateChannelValues()) { - break; - } - - if (acquisitionDataMap.at(ANGLE) == false && - acquisitionAngleList.size() > 0) - acquisitionAngleList.clear(); - if (acquisitionDataMap.at(ABSANGLE) == false && - acquisitionABSAngleList.size() > 0) - acquisitionABSAngleList.clear(); - if (acquisitionDataMap.at(TURNCOUNT) == false && - acquisitionTurnCountList.size() > 0) - acquisitionTurnCountList.clear(); - if (acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) - acquisitionTmp0List.clear(); - if (acquisitionDataMap.at(SINE) == false && acquisitionSineList.size() > 0) - acquisitionSineList.clear(); - if (acquisitionDataMap.at(COSINE) == false && - acquisitionCosineList.size() > 0) - acquisitionCosineList.clear(); - if (acquisitionDataMap.at(RADIUS) == false && - acquisitionRadiusList.size() > 0) - acquisitionRadiusList.clear(); - - if (acquisitionDataMap.at(ANGLE)) - prependAcquisitionData(angle, acquisitionAngleList); - if (acquisitionDataMap.at(ABSANGLE)) - prependAcquisitionData(rotation, acquisitionABSAngleList); - if (acquisitionDataMap.at(TURNCOUNT)) - prependAcquisitionData(count, acquisitionTurnCountList); - if (acquisitionDataMap.at(TMP0)) - prependAcquisitionData(temp, acquisitionTmp0List); - if (acquisitionDataMap.at(SINE)) - prependAcquisitionData(getAcquisitionParameterValue(SINE), - acquisitionSineList); - if (acquisitionDataMap.at(COSINE)) - prependAcquisitionData(getAcquisitionParameterValue(COSINE), - acquisitionCosineList); - if (acquisitionDataMap.at(RADIUS)) - prependAcquisitionData(getAcquisitionParameterValue(RADIUS), - acquisitionRadiusList); - - QThread::msleep(sampleRate); - } -} - -double HarmonicCalibration::getAcquisitionParameterValue( - const AcquisitionDataKey &key) { - uint32_t *readValue = new uint32_t; - switch (key) { - case SINE: { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister( - ADMTController::SensorRegister::SINE), - readValue) == -1) - return qQNaN(); - map sineRegisterMap = - m_admtController->getSineRegisterBitMapping( - static_cast(*readValue)); - return sineRegisterMap.at("SINE"); - break; - } - case COSINE: { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister( - ADMTController::SensorRegister::COSINE), - readValue) == -1) - return qQNaN(); - map cosineRegisterMap = - m_admtController->getCosineRegisterBitMapping( - static_cast(*readValue)); - return cosineRegisterMap.at("COSINE"); - break; - } - case RADIUS: { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister( - ADMTController::SensorRegister::RADIUS), - readValue) == -1) - return qQNaN(); - map radiusRegisterMap = - m_admtController->getRadiusRegisterBitMapping( - static_cast(*readValue)); - return radiusRegisterMap.at("RADIUS"); - break; - } - default: - return qQNaN(); - break; - } -} - -void HarmonicCalibration::plotAcquisition(QVector &list, - PlotChannel *channel) { - channel->curve()->setSamples(list); - auto result = minmax_element(list.begin(), list.end()); - if (*result.first < acquisitionGraphYMin) - acquisitionGraphYMin = *result.first; - if (*result.second > acquisitionGraphYMax) - acquisitionGraphYMax = *result.second; -} - -void HarmonicCalibration::prependAcquisitionData(const double &data, - QVector &list) { - list.prepend(data); - if (list.size() >= acquisitionDisplayLength) { - list.resize(acquisitionDisplayLength); - list.squeeze(); - } -} - -void HarmonicCalibration::resetAcquisitionYAxisScale() { - acquisitionGraphYMin = 0; - acquisitionGraphYMax = 360; - acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); - acquisitionGraphPlotWidget->replot(); -} - -void HarmonicCalibration::acquisitionPlotTask(int sampleRate) { - while (isStartAcquisition) { - if (acquisitionDataMap.at(ANGLE)) - plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel); - if (acquisitionDataMap.at(ABSANGLE)) - plotAcquisition(acquisitionABSAngleList, acquisitionABSAnglePlotChannel); - if (acquisitionDataMap.at(TURNCOUNT)) - plotAcquisition(acquisitionTurnCountList, - acquisitionTurnCountPlotChannel); - if (acquisitionDataMap.at(TMP0)) - plotAcquisition(acquisitionTmp0List, acquisitionTmp0PlotChannel); - if (acquisitionDataMap.at(SINE)) - plotAcquisition(acquisitionSineList, acquisitionSinePlotChannel); - if (acquisitionDataMap.at(COSINE)) - plotAcquisition(acquisitionCosineList, acquisitionCosinePlotChannel); - if (acquisitionDataMap.at(RADIUS)) - plotAcquisition(acquisitionRadiusList, acquisitionRadiusPlotChannel); - - acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, - acquisitionGraphYMax); - acquisitionGraphPlotWidget->replot(); - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::acquisitionUITask(int sampleRate) { - while (isAcquisitionTab) { - if (isStartAcquisition) - updateLineEditValues(); - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::startAcquisitionUITask() { - if (!m_acquisitionUIThread.isRunning()) { - isAcquisitionTab = true; - m_acquisitionUIThread = QtConcurrent::run( - this, &HarmonicCalibration::acquisitionUITask, acquisitionUITimerRate); - m_acquisitionUIWatcher.setFuture(m_acquisitionUIThread); - } -} - -void HarmonicCalibration::stopAcquisitionUITask() { - isAcquisitionTab = false; - if (m_acquisitionUIThread.isRunning()) { - m_acquisitionUIThread.cancel(); - m_acquisitionUIWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::updateSequenceWidget() { - if (GENERALRegisterMap.at("Sequence Type") == -1) { - sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); - } else { - sequenceTypeMenuCombo->combo()->setCurrentIndex( - sequenceTypeMenuCombo->combo()->findData( - GENERALRegisterMap.at("Sequence Type"))); - } - conversionTypeMenuCombo->combo()->setCurrentIndex( - conversionTypeMenuCombo->combo()->findData( - GENERALRegisterMap.at("Conversion Type"))); - if (GENERALRegisterMap.at("Convert Synchronization") == -1) { - convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); - } else { - convertSynchronizationMenuCombo->combo()->setCurrentIndex( - convertSynchronizationMenuCombo->combo()->findData( - GENERALRegisterMap.at("Convert Synchronization"))); - } - angleFilterMenuCombo->combo()->setCurrentIndex( - angleFilterMenuCombo->combo()->findData( - GENERALRegisterMap.at("Angle Filter"))); - eighthHarmonicMenuCombo->combo()->setCurrentIndex( - eighthHarmonicMenuCombo->combo()->findData( - GENERALRegisterMap.at("8th Harmonic"))); -} - -void HarmonicCalibration::applySequenceAndUpdate() { - applySequence(); - updateSequenceWidget(); -} - -void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { - graphUpdateIntervalLineEdit->setEnabled(value); - displayLengthLineEdit->setEnabled(value); -} - -void HarmonicCalibration::connectCheckBoxToAcquisitionGraph( - QCheckBox *widget, PlotChannel *channel, AcquisitionDataKey key) { - connect(widget, &QCheckBox::stateChanged, [this, channel, key](int state) { - if (state == Qt::Checked) { - channel->setEnabled(true); - acquisitionDataMap[key] = true; - } else { - channel->setEnabled(false); - acquisitionDataMap[key] = false; - } - }); -} - -void HarmonicCalibration::GMRReset() { - // Set Motor Angle to 315 degrees - target_pos = 0; - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, - target_pos); - - // Write 1 to ADMT IIO Attribute coil_rs - m_admtController->setDeviceAttributeValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getDeviceAttribute( - ADMTController::DeviceAttribute::SDP_COIL_RS), - 1); - - // Write 0xc000 to CNVPAGE - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::CNVPAGE), - 0xc000) != -1) { - // Write 0x0000 to CNVPAGE - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::CNVPAGE), - 0x0000) != -1) { - // Read ABSANGLE - - StatusBarManager::pushMessage("GMR Reset Done"); - } else { - StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); - } - } else { - StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); - } -} - -void HarmonicCalibration::restart() { - if (m_running) { - run(false); - run(true); - } +bool HarmonicCalibration::updateChannelValues() +{ + bool success = false; + rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + rotationChannelName, bufferSize); + if(rotation == static_cast(UINT64_MAX)) { + return false; + } + angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + angleChannelName, bufferSize); + if(angle == static_cast(UINT64_MAX)) { + return false; + } + updateCountValue(); + if(count == static_cast(UINT64_MAX)) { + return false; + } + temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + temperatureChannelName, bufferSize); + if(temp == static_cast(UINT64_MAX)) { + return false; + } + return success = true; +} + +void HarmonicCalibration::updateCountValue() +{ + uint32_t *absAngleRegValue = new uint32_t; + bool success = false; + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), + 0x0000) == 0) { + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), + absAngleRegValue) == 0) { + count = m_admtController->getAbsAngleTurnCount(static_cast(*absAngleRegValue)); + success = true; + } + } + if(!success) { + count = static_cast(UINT64_MAX); + } +} + +void HarmonicCalibration::updateLineEditValues() +{ + if(rotation == static_cast(UINT64_MAX)) { + rotationValueLabel->setText("N/A"); + } else { + rotationValueLabel->setText(QString::number(rotation) + "°"); + } + if(angle == static_cast(UINT64_MAX)) { + angleValueLabel->setText("N/A"); + } else { + angleValueLabel->setText(QString::number(angle) + "°"); + } + if(count == static_cast(UINT64_MAX)) { + countValueLabel->setText("N/A"); + } else { + countValueLabel->setText(QString::number(count)); + } + if(temp == static_cast(UINT64_MAX)) { + tempValueLabel->setText("N/A"); + } else { + tempValueLabel->setText(QString::number(temp) + " °C"); + } +} + +void HarmonicCalibration::startAcquisition() +{ + isStartAcquisition = true; + acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); + + m_acquisitionDataThread = + QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples, acquisitionSampleRate); + m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); + m_acquisitionGraphThread = + QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, acquisitionGraphSampleRate); + m_acquisitionGraphWatcher.setFuture(m_acquisitionGraphThread); +} + +void HarmonicCalibration::stopAcquisition() +{ + isStartAcquisition = false; + if(m_acquisitionDataThread.isRunning()) { + m_acquisitionDataThread.cancel(); + m_acquisitionDataWatcher.waitForFinished(); + } + if(m_acquisitionGraphThread.isRunning()) { + m_acquisitionGraphThread.cancel(); + m_acquisitionGraphWatcher.waitForFinished(); + } + + stopCurrentMotorPositionMonitor(); +} + +void HarmonicCalibration::updateFaultStatus(bool status) +{ + bool isChanged = (deviceStatusFault != status); + if(isChanged) { + deviceStatusFault = status; + acquisitionFaultRegisterLEDWidget->setChecked(deviceStatusFault); + calibrationFaultRegisterLEDWidget->setChecked(deviceStatusFault); + } +} + +void HarmonicCalibration::updateAcquisitionMotorRPM() +{ + acquisitionMotorRPMLineEdit->setText(QString::number(motor_rpm)); +} + +void HarmonicCalibration::updateAcquisitionMotorRotationDirection() +{ + acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); +} + +void HarmonicCalibration::getAcquisitionSamples(int sampleRate) +{ + while(isStartAcquisition) { + if(!updateChannelValues()) { + break; + } + + if(acquisitionDataMap.at(ANGLE) == false && acquisitionAngleList.size() > 0) + acquisitionAngleList.clear(); + if(acquisitionDataMap.at(ABSANGLE) == false && acquisitionABSAngleList.size() > 0) + acquisitionABSAngleList.clear(); + if(acquisitionDataMap.at(TURNCOUNT) == false && acquisitionTurnCountList.size() > 0) + acquisitionTurnCountList.clear(); + if(acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) + acquisitionTmp0List.clear(); + if(acquisitionDataMap.at(SINE) == false && acquisitionSineList.size() > 0) + acquisitionSineList.clear(); + if(acquisitionDataMap.at(COSINE) == false && acquisitionCosineList.size() > 0) + acquisitionCosineList.clear(); + if(acquisitionDataMap.at(RADIUS) == false && acquisitionRadiusList.size() > 0) + acquisitionRadiusList.clear(); + + if(acquisitionDataMap.at(ANGLE)) + prependAcquisitionData(angle, acquisitionAngleList); + if(acquisitionDataMap.at(ABSANGLE)) + prependAcquisitionData(rotation, acquisitionABSAngleList); + if(acquisitionDataMap.at(TURNCOUNT)) + prependAcquisitionData(count, acquisitionTurnCountList); + if(acquisitionDataMap.at(TMP0)) + prependAcquisitionData(temp, acquisitionTmp0List); + if(acquisitionDataMap.at(SINE)) + prependAcquisitionData(getAcquisitionParameterValue(SINE), acquisitionSineList); + if(acquisitionDataMap.at(COSINE)) + prependAcquisitionData(getAcquisitionParameterValue(COSINE), acquisitionCosineList); + if(acquisitionDataMap.at(RADIUS)) + prependAcquisitionData(getAcquisitionParameterValue(RADIUS), acquisitionRadiusList); + + QThread::msleep(sampleRate); + } +} + +double HarmonicCalibration::getAcquisitionParameterValue(const AcquisitionDataKey &key) +{ + uint32_t *readValue = new uint32_t; + switch(key) { + case SINE: { + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(ADMTController::SensorRegister::SINE), readValue) == -1) + return qQNaN(); + map sineRegisterMap = + m_admtController->getSineRegisterBitMapping(static_cast(*readValue)); + return sineRegisterMap.at("SINE"); + break; + } + case COSINE: { + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(ADMTController::SensorRegister::COSINE), + readValue) == -1) + return qQNaN(); + map cosineRegisterMap = + m_admtController->getCosineRegisterBitMapping(static_cast(*readValue)); + return cosineRegisterMap.at("COSINE"); + break; + } + case RADIUS: { + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(ADMTController::SensorRegister::RADIUS), + readValue) == -1) + return qQNaN(); + map radiusRegisterMap = + m_admtController->getRadiusRegisterBitMapping(static_cast(*readValue)); + return radiusRegisterMap.at("RADIUS"); + break; + } + default: + return qQNaN(); + break; + } +} + +void HarmonicCalibration::plotAcquisition(QVector &list, PlotChannel *channel) +{ + channel->curve()->setSamples(list); + auto result = minmax_element(list.begin(), list.end()); + if(*result.first < acquisitionGraphYMin) + acquisitionGraphYMin = *result.first; + if(*result.second > acquisitionGraphYMax) + acquisitionGraphYMax = *result.second; +} + +void HarmonicCalibration::prependAcquisitionData(const double &data, QVector &list) +{ + list.prepend(data); + if(list.size() >= acquisitionDisplayLength) { + list.resize(acquisitionDisplayLength); + list.squeeze(); + } +} + +void HarmonicCalibration::resetAcquisitionYAxisScale() +{ + acquisitionGraphYMin = 0; + acquisitionGraphYMax = 360; + acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); + acquisitionGraphPlotWidget->replot(); +} + +void HarmonicCalibration::acquisitionPlotTask(int sampleRate) +{ + while(isStartAcquisition) { + if(acquisitionDataMap.at(ANGLE)) + plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel); + if(acquisitionDataMap.at(ABSANGLE)) + plotAcquisition(acquisitionABSAngleList, acquisitionABSAnglePlotChannel); + if(acquisitionDataMap.at(TURNCOUNT)) + plotAcquisition(acquisitionTurnCountList, acquisitionTurnCountPlotChannel); + if(acquisitionDataMap.at(TMP0)) + plotAcquisition(acquisitionTmp0List, acquisitionTmp0PlotChannel); + if(acquisitionDataMap.at(SINE)) + plotAcquisition(acquisitionSineList, acquisitionSinePlotChannel); + if(acquisitionDataMap.at(COSINE)) + plotAcquisition(acquisitionCosineList, acquisitionCosinePlotChannel); + if(acquisitionDataMap.at(RADIUS)) + plotAcquisition(acquisitionRadiusList, acquisitionRadiusPlotChannel); + + acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); + acquisitionGraphPlotWidget->replot(); + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::acquisitionUITask(int sampleRate) +{ + while(isAcquisitionTab) { + if(isStartAcquisition) + updateLineEditValues(); + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::startAcquisitionUITask() +{ + if(!m_acquisitionUIThread.isRunning()) { + isAcquisitionTab = true; + m_acquisitionUIThread = + QtConcurrent::run(this, &HarmonicCalibration::acquisitionUITask, acquisitionUITimerRate); + m_acquisitionUIWatcher.setFuture(m_acquisitionUIThread); + } +} + +void HarmonicCalibration::stopAcquisitionUITask() +{ + isAcquisitionTab = false; + if(m_acquisitionUIThread.isRunning()) { + m_acquisitionUIThread.cancel(); + m_acquisitionUIWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::updateSequenceWidget() +{ + if(GENERALRegisterMap.at("Sequence Type") == -1) { + sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); + } else { + sequenceTypeMenuCombo->combo()->setCurrentIndex( + sequenceTypeMenuCombo->combo()->findData(GENERALRegisterMap.at("Sequence Type"))); + } + conversionTypeMenuCombo->combo()->setCurrentIndex( + conversionTypeMenuCombo->combo()->findData(GENERALRegisterMap.at("Conversion Type"))); + if(GENERALRegisterMap.at("Convert Synchronization") == -1) { + convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); + } else { + convertSynchronizationMenuCombo->combo()->setCurrentIndex( + convertSynchronizationMenuCombo->combo()->findData( + GENERALRegisterMap.at("Convert Synchronization"))); + } + angleFilterMenuCombo->combo()->setCurrentIndex( + angleFilterMenuCombo->combo()->findData(GENERALRegisterMap.at("Angle Filter"))); + eighthHarmonicMenuCombo->combo()->setCurrentIndex( + eighthHarmonicMenuCombo->combo()->findData(GENERALRegisterMap.at("8th Harmonic"))); +} + +void HarmonicCalibration::applySequenceAndUpdate() +{ + applySequence(); + updateSequenceWidget(); +} + +void HarmonicCalibration::updateGeneralSettingEnabled(bool value) +{ + graphUpdateIntervalLineEdit->setEnabled(value); + displayLengthLineEdit->setEnabled(value); +} + +void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, + AcquisitionDataKey key) +{ + connect(widget, &QCheckBox::stateChanged, [this, channel, key](int state) { + if(state == Qt::Checked) { + channel->setEnabled(true); + acquisitionDataMap[key] = true; + } else { + channel->setEnabled(false); + acquisitionDataMap[key] = false; + } + }); +} + +void HarmonicCalibration::GMRReset() +{ + // Set Motor Angle to 315 degrees + target_pos = 0; + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, target_pos); + + // Write 1 to ADMT IIO Attribute coil_rs + m_admtController->setDeviceAttributeValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getDeviceAttribute(ADMTController::DeviceAttribute::SDP_COIL_RS), 1); + + // Write 0xc000 to CNVPAGE + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), + 0xc000) != -1) { + // Write 0x0000 to CNVPAGE + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), + 0x0000) != -1) { + // Read ABSANGLE + + StatusBarManager::pushMessage("GMR Reset Done"); + } else { + StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); + } + } else { + StatusBarManager::pushMessage("Failed to write CNVPAGE Register"); + } +} + +void HarmonicCalibration::restart() +{ + if(m_running) { + run(false); + run(true); + } } bool HarmonicCalibration::running() const { return m_running; } -void HarmonicCalibration::setRunning(bool newRunning) { - if (m_running == newRunning) - return; - m_running = newRunning; - Q_EMIT runningChanged(newRunning); +void HarmonicCalibration::setRunning(bool newRunning) +{ + if(m_running == newRunning) + return; + m_running = newRunning; + Q_EMIT runningChanged(newRunning); } void HarmonicCalibration::start() { run(true); } void HarmonicCalibration::stop() { run(false); } -void HarmonicCalibration::run(bool b) { - qInfo() << b; - QElapsedTimer tim; - tim.start(); +void HarmonicCalibration::run(bool b) +{ + qInfo() << b; + QElapsedTimer tim; + tim.start(); - if (!b) { - isStartAcquisition = false; - runButton->setChecked(false); - } else { - startAcquisition(); - } + if(!b) { + isStartAcquisition = false; + runButton->setChecked(false); + } else { + startAcquisition(); + } - updateGeneralSettingEnabled(!b); + updateGeneralSettingEnabled(!b); } #pragma endregion #pragma region Calibration Methods -void HarmonicCalibration::startCalibrationUITask() { - if (!m_calibrationUIThread.isRunning()) { - isCalibrationTab = true; - m_calibrationUIThread = QtConcurrent::run( - this, &HarmonicCalibration::calibrationUITask, calibrationUITimerRate); - m_calibrationUIWatcher.setFuture(m_calibrationUIThread); - } -} - -void HarmonicCalibration::stopCalibrationUITask() { - isCalibrationTab = false; - if (m_calibrationUIThread.isRunning()) { - m_calibrationUIThread.cancel(); - m_calibrationUIWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::calibrationUITask(int sampleRate) { - while (isCalibrationTab) { - if (isStartMotor) { - if (isPostCalibration) { - postCalibrationRawDataPlotChannel->curve()->setSamples( - graphPostDataList); - postCalibrationRawDataPlotWidget->replot(); - } else { - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotWidget->replot(); - } - } - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::updateCalibrationMotorRPM() { - calibrationMotorRPMLineEdit->setText(QString::number(motor_rpm)); -} - -void HarmonicCalibration::updateCalibrationMotorRotationDirection() { - calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); -} - -void HarmonicCalibration::getCalibrationSamples() { - if (resetCurrentPositionToZero()) { - double step = 0; - if (isMotorRotationClockwise) - step = motorFullStepPerRevolution; - else - step = -motorFullStepPerRevolution; - if (isPostCalibration) { - int currentSamplesCount = graphPostDataList.size(); - while (isStartMotor && currentSamplesCount < totalSamplesCount) { - target_pos = current_pos + step; - moveMotorToPosition(target_pos, true); - updateChannelValue(ADMTController::Channel::ANGLE); - graphPostDataList.append(angle); - currentSamplesCount++; - } - } else { - int currentSamplesCount = graphDataList.size(); - while (isStartMotor && currentSamplesCount < totalSamplesCount) { - target_pos = current_pos + step; - if (moveMotorToPosition(target_pos, true) == false) { - m_admtController->disconnectADMT(); - } - if (updateChannelValue(ADMTController::Channel::ANGLE)) { - break; - } - graphDataList.append(angle); - currentSamplesCount++; - } - } - } - - stopMotor(); -} - -void HarmonicCalibration::startCalibration() { - totalSamplesCount = cycleCount * samplesPerCycle; - graphPostDataList.reserve(totalSamplesCount); - graphPostDataList.squeeze(); - graphDataList.reserve(totalSamplesCount); - graphDataList.squeeze(); - - // configureConversionType(calibrationMode); // TODO uncomment when conversion - // type is okay - configureCalibrationSequenceSettings(); - clearHarmonicRegisters(); - - toggleTabSwitching(false); - toggleCalibrationControls(false); - - calibrationDataGraphTabWidget->setCurrentIndex(0); - calibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); - - toggleCalibrationButtonState(1); - if (calibrationMode == 0) - startContinuousCalibration(); - else - startOneShotCalibration(); -} - -void HarmonicCalibration::stopCalibration() { - isStartMotor = false; - if (calibrationMode == 0) { - stopContinuousCalibration(); - } - - toggleTabSwitching(true); - toggleCalibrationControls(true); -} - -void HarmonicCalibration::startContinuousCalibration() { - stopCurrentMotorPositionMonitor(); - stopDeviceStatusMonitor(); - - if (isPostCalibration) - StatusBarManager::pushMessage( - "Acquiring Post Calibration Samples, Please Wait..."); - else - StatusBarManager::pushMessage( - "Acquiring Calibration Samples, Please Wait..."); - startResetMotorToZero(); -} - -void HarmonicCalibration::stopContinuousCalibration() { - stopMotor(); - stopWaitForVelocityReachedThread(); - stopCalibrationStreamThread(); - - startCurrentMotorPositionMonitor(); - startDeviceStatusMonitor(); -} - -void HarmonicCalibration::startResetMotorToZero() { - isResetMotorToZero = true; - if (!m_resetMotorToZeroThread.isRunning()) { - m_resetMotorToZeroThread = - QtConcurrent::run(this, &HarmonicCalibration::resetMotorToZero); - m_resetMotorToZeroWatcher.setFuture(m_resetMotorToZeroThread); - } -} - -void HarmonicCalibration::stopResetMotorToZero() { - isResetMotorToZero = false; - if (m_resetMotorToZeroThread.isRunning()) { - m_resetMotorToZeroThread.cancel(); - m_resetMotorToZeroWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::resetMotorToZero() { - if (readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, - current_pos) == 0) { - if (current_pos != 0) { - writeMotorAttributeValue( - ADMTController::MotorAttribute::ROTATE_VMAX, - convertRPStoVMAX(convertRPMtoRPS(fast_motor_rpm))); - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, - current_pos); - while (isResetMotorToZero && current_pos != 0) { - if (readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, - current_pos) != 0) - break; - QThread::msleep(readMotorDebounce); - } - if (current_pos == 0) { - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, - rotate_vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); - } - } - } -} - -void HarmonicCalibration::startCalibrationStreamThread() { - if (!m_calibrationStreamThread.isRunning()) { - m_admtController->stopStream = false; - - continuousCalibrationSampleRate = calculateContinuousCalibrationSampleRate( - convertVMAXtoRPS(rotate_vmax), samplesPerCycle); - m_calibrationStreamThread = QtConcurrent::run([this]() { - m_admtController->bufferedStreamIO(totalSamplesCount, - continuousCalibrationSampleRate); - }); - m_calibrationStreamWatcher.setFuture(m_calibrationStreamThread); - } -} - -void HarmonicCalibration::stopCalibrationStreamThread() { - m_admtController->stopStream = true; - if (m_calibrationStreamThread.isRunning()) { - m_calibrationStreamThread.cancel(); - m_calibrationStreamWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::startWaitForVelocityReachedThread(int mode) { - if (!m_calibrationWaitVelocityWatcher.isRunning()) { - isMotorVelocityCheck = true; - m_calibrationWaitVelocityThread = - QtConcurrent::run(this, &HarmonicCalibration::waitForVelocityReached, - mode, motorWaitVelocityReachedSampleRate); - m_calibrationWaitVelocityWatcher.setFuture(m_calibrationWaitVelocityThread); - } -} - -void HarmonicCalibration::stopWaitForVelocityReachedThread() { - isMotorVelocityCheck = false; - if (m_calibrationWaitVelocityWatcher.isRunning()) { - m_calibrationWaitVelocityThread.cancel(); - m_calibrationWaitVelocityWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::waitForVelocityReached(int mode, int sampleRate) { - isMotorVelocityReached = false; - if (mode == 0) { - QThread::msleep(floor(convertAMAXtoAccelTime(amax) * 1000)); - isMotorVelocityReached = true; - } else if (mode == 1) { - moveMotorContinuous(); - uint32_t *registerValue = new uint32_t; - while (isMotorVelocityCheck && !isMotorVelocityReached) { - if (readMotorRegisterValue( - m_admtController->getRampGeneratorDriverFeatureControlRegister( - ADMTController::RampGeneratorDriverFeatureControlRegister:: - RAMP_STAT), - registerValue) == 0) { - isMotorVelocityReached = m_admtController->checkVelocityReachedFlag( - static_cast(*registerValue)); - } - - QThread::msleep(sampleRate); - } - - delete registerValue; - } -} - -int HarmonicCalibration::calculateContinuousCalibrationSampleRate( - double motorRPS, int samplesPerCycle) { - return static_cast(floor(1 / motorRPS / samplesPerCycle * 1000 * 1000 * - 1000)); // In nanoseconds -} - -void HarmonicCalibration::configureConversionType(int mode) { - readSequence(); - GENERALRegisterMap.at("Conversion Type") = mode; - writeSequence(GENERALRegisterMap); -} - -void HarmonicCalibration::configureCalibrationSequenceSettings() { - readSequence(); - GENERALRegisterMap.at("8th Harmonic") = 1; // User-supplied 8th Harmonic - writeSequence(GENERALRegisterMap); -} - -void HarmonicCalibration::getStreamedCalibrationSamples(int microSampleRate) { - int currentSamplesCount = graphDataList.size(); - moveMotorContinuous(); - while (isStartMotor && currentSamplesCount < totalSamplesCount) { - graphDataList.append(m_admtController->streamedValue); - // graphPostDataList.append(m_admtController->streamedValue); - currentSamplesCount = graphDataList.size(); - // currentSamplesCount = graphDataPostList.size(); - - QThread::usleep(microSampleRate); - } -} - -void HarmonicCalibration::startOneShotCalibration() { - if (resetToZero && !isPostCalibration) { - clearCalibrationSamples(); - clearPostCalibrationSamples(); - clearAngleErrorGraphs(); - clearCorrectedAngleErrorGraphs(); - } else if (resetToZero) { - clearPostCalibrationSamples(); - } - - QFuture future = - QtConcurrent::run(this, &HarmonicCalibration::getCalibrationSamples); - QFutureWatcher *watcher = new QFutureWatcher(this); - - connect(watcher, &QFutureWatcher::finished, this, [this]() { - toggleTabSwitching(true); - toggleCalibrationControls(true); - - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotChannel->xAxis()->setMax(graphDataList.size()); - calibrationRawDataPlotWidget->replot(); - isStartMotor = false; - - if (isPostCalibration) { - if (static_cast(graphPostDataList.size()) == totalSamplesCount) { - computeSineCosineOfAngles(graphPostDataList); - m_admtController->postcalibrate( - vector(graphPostDataList.begin(), graphPostDataList.end()), - cycleCount, samplesPerCycle, !isMotorRotationClockwise); - populateCorrectedAngleErrorGraphs(); - isPostCalibration = false; - isStartMotor = false; - resetToZero = true; - toggleCalibrationButtonState(4); - } else - toggleCalibrationButtonState(2); - } else { - if (static_cast(graphDataList.size()) == totalSamplesCount) { - computeSineCosineOfAngles(graphDataList); - calibrationLogWrite(m_admtController->calibrate( - vector(graphDataList.begin(), graphDataList.end()), - cycleCount, samplesPerCycle, !isMotorRotationClockwise)); - populateAngleErrorGraphs(); - calculateHarmonicValues(); - toggleCalibrationButtonState(2); - } else { - resetToZero = true; - toggleCalibrationButtonState(0); - } - } - }); - connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater())); - watcher->setFuture(future); -} - -void HarmonicCalibration::postCalibrateData() { - calibrationLogWrite("==== Post Calibration Start ====\n"); - flashHarmonicValues(); - isPostCalibration = true; - isStartMotor = true; - resetToZero = true; - - toggleTabSwitching(false); - toggleCalibrationControls(false); - - calibrationDataGraphTabWidget->setCurrentIndex(1); - postCalibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); - - toggleCalibrationButtonState(3); - if (calibrationMode == 0) - startContinuousCalibration(); - else - startOneShotCalibration(); -} - -void HarmonicCalibration::resetAllCalibrationState() { - clearCalibrationSamples(); - clearPostCalibrationSamples(); - calibrationDataGraphTabWidget->setCurrentIndex(0); - - clearAngleErrorGraphs(); - clearCorrectedAngleErrorGraphs(); - resultDataTabWidget->setCurrentIndex(0); - - toggleCalibrationButtonState(0); - - isPostCalibration = false; - isCalculatedCoeff = false; - resetToZero = true; - displayCalculatedCoeff(); -} - -void HarmonicCalibration::computeSineCosineOfAngles( - QVector graphDataList) { - m_admtController->computeSineCosineOfAngles( - vector(graphDataList.begin(), graphDataList.end())); - if (isPostCalibration) { - postCalibrationSineDataPlotChannel->curve()->setSamples( - m_admtController->calibration_samples_sine_scaled.data(), - m_admtController->calibration_samples_sine_scaled.size()); - postCalibrationCosineDataPlotChannel->curve()->setSamples( - m_admtController->calibration_samples_cosine_scaled.data(), - m_admtController->calibration_samples_cosine_scaled.size()); - postCalibrationRawDataPlotWidget->replot(); - } else { - calibrationSineDataPlotChannel->curve()->setSamples( - m_admtController->calibration_samples_sine_scaled.data(), - m_admtController->calibration_samples_sine_scaled.size()); - calibrationCosineDataPlotChannel->curve()->setSamples( - m_admtController->calibration_samples_cosine_scaled.data(), - m_admtController->calibration_samples_cosine_scaled.size()); - calibrationRawDataPlotWidget->replot(); - } -} - -void HarmonicCalibration::populateAngleErrorGraphs() { - QVector angleError = QVector( - m_admtController->angleError.begin(), m_admtController->angleError.end()); - QVector FFTAngleErrorMagnitude = - QVector(m_admtController->FFTAngleErrorMagnitude.begin(), - m_admtController->FFTAngleErrorMagnitude.end()); - QVector FFTAngleErrorPhase = - QVector(m_admtController->FFTAngleErrorPhase.begin(), - m_admtController->FFTAngleErrorPhase.end()); - - angleErrorPlotChannel->curve()->setSamples(angleError); - auto angleErrorMinMax = minmax_element(angleError.begin(), angleError.end()); - angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, - *angleErrorMinMax.second); - angleErrorXPlotAxis->setInterval(0, angleError.size()); - angleErrorPlotWidget->replot(); - - FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); - FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); - auto angleErrorMagnitudeMinMax = minmax_element( - FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); - auto angleErrorPhaseMinMax = - minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); - double FFTAngleErrorPlotMin = - *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first - ? *angleErrorMagnitudeMinMax.first - : *angleErrorPhaseMinMax.first; - double FFTAngleErrorPlotMax = - *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second - ? *angleErrorMagnitudeMinMax.second - : *angleErrorPhaseMinMax.second; - FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, - FFTAngleErrorPlotMax); - FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); - FFTAngleErrorPlotWidget->replot(); - - resultDataTabWidget->setCurrentIndex(0); // Set tab to Angle Error -} - -void HarmonicCalibration::populateCorrectedAngleErrorGraphs() { - QVector correctedError(m_admtController->correctedError.begin(), - m_admtController->correctedError.end()); - QVector FFTCorrectedErrorMagnitude( - m_admtController->FFTCorrectedErrorMagnitude.begin(), - m_admtController->FFTCorrectedErrorMagnitude.end()); - QVector FFTCorrectedErrorPhase( - m_admtController->FFTCorrectedErrorPhase.begin(), - m_admtController->FFTCorrectedErrorPhase.end()); - - correctedErrorPlotChannel->curve()->setSamples(correctedError); - auto correctedErrorMagnitudeMinMax = - minmax_element(correctedError.begin(), correctedError.end()); - correctedErrorYPlotAxis->setInterval(*correctedErrorMagnitudeMinMax.first, - *correctedErrorMagnitudeMinMax.second); - correctedErrorXPlotAxis->setMax(correctedError.size()); - correctedErrorPlotWidget->replot(); - - FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); - FFTCorrectedErrorMagnitudeChannel->curve()->setSamples( - FFTCorrectedErrorMagnitude); - auto FFTCorrectedErrorMagnitudeMinMax = minmax_element( - FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); - auto FFTCorrectedErrorPhaseMinMax = minmax_element( - FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); - double FFTCorrectedErrorPlotMin = - *FFTCorrectedErrorMagnitudeMinMax.first < - *FFTCorrectedErrorPhaseMinMax.first - ? *FFTCorrectedErrorMagnitudeMinMax.first - : *FFTCorrectedErrorPhaseMinMax.first; - double FFTCorrectedErrorPlotMax = - *FFTCorrectedErrorMagnitudeMinMax.second > - *FFTCorrectedErrorPhaseMinMax.second - ? *FFTCorrectedErrorMagnitudeMinMax.second - : *FFTCorrectedErrorPhaseMinMax.second; - FFTCorrectedErrorYPlotAxis->setInterval(FFTCorrectedErrorPlotMin, - FFTCorrectedErrorPlotMax); - FFTCorrectedErrorXPlotAxis->setMax(FFTCorrectedErrorMagnitude.size()); - FFTCorrectedErrorPlotWidget->replot(); - - resultDataTabWidget->setCurrentIndex(2); // Set tab to Angle Error -} - -void HarmonicCalibration::clearHarmonicRegisters() { - bool success = false; - uint32_t value = 0x0; - uint32_t harmonicCNVPage = m_admtController->getHarmonicPage( - ADMTController::HarmonicRegister::H1MAG); - if (changeCNVPage(harmonicCNVPage)) { - success = - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H1MAG), - value) == 0 - ? true - : false; - success = - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H1PH), - value) == 0 - ? true - : false; - success = - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H2MAG), - value) == 0 - ? true - : false; - success = - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H2PH), - value) == 0 - ? true - : false; - success = - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H3MAG), - value) == 0 - ? true - : false; - success = - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H3PH), - value) == 0 - ? true - : false; - success = - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H8MAG), - value) == 0 - ? true - : false; - success = - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H8PH), - value) == 0 - ? true - : false; - } - - if (!success) { - calibrationLogWrite("Unable to clear Harmonic Registers!"); - } -} - -void HarmonicCalibration::flashHarmonicValues() { - if (changeCNVPage(0x02)) { - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), 0x01, - 0x02); - - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H1MAG), - H1_MAG_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H1PH), - H1_PHASE_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H2MAG), - H2_MAG_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H2PH), - H2_PHASE_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H3MAG), - H3_MAG_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H3PH), - H3_PHASE_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H8MAG), - H8_MAG_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H8PH), - H8_PHASE_HEX); - - isCalculatedCoeff = true; - displayCalculatedCoeff(); - } else { - calibrationLogWrite("Unabled to flash Harmonic Registers!"); - } -} - -void HarmonicCalibration::calculateHarmonicValues() { - uint32_t *h1MagCurrent = new uint32_t, *h1PhaseCurrent = new uint32_t, - *h2MagCurrent = new uint32_t, *h2PhaseCurrent = new uint32_t, - *h3MagCurrent = new uint32_t, *h3PhaseCurrent = new uint32_t, - *h8MagCurrent = new uint32_t, *h8PhaseCurrent = new uint32_t; - - if (changeCNVPage(0x02)) { - // Read and store current harmonic values - m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H1MAG), - h1MagCurrent); - m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H2MAG), - h2MagCurrent); - m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H3MAG), - h3MagCurrent); - m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H8MAG), - h8MagCurrent); - m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H1PH), - h1PhaseCurrent); - m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H2PH), - h2PhaseCurrent); - m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H3PH), - h3PhaseCurrent); - m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister( - ADMTController::HarmonicRegister::H8PH), - h8PhaseCurrent); - - // Calculate harmonic coefficients (Hex) - H1_MAG_HEX = static_cast( - m_admtController->calculateHarmonicCoefficientMagnitude( - static_cast(m_admtController->HAR_MAG_1), - static_cast(*h1MagCurrent), "h1")); - H2_MAG_HEX = static_cast( - m_admtController->calculateHarmonicCoefficientMagnitude( - static_cast(m_admtController->HAR_MAG_2), - static_cast(*h2MagCurrent), "h2")); - H3_MAG_HEX = static_cast( - m_admtController->calculateHarmonicCoefficientMagnitude( - static_cast(m_admtController->HAR_MAG_3), - static_cast(*h3MagCurrent), "h3")); - H8_MAG_HEX = static_cast( - m_admtController->calculateHarmonicCoefficientMagnitude( - static_cast(m_admtController->HAR_MAG_8), - static_cast(*h8MagCurrent), "h8")); - H1_PHASE_HEX = static_cast( - m_admtController->calculateHarmonicCoefficientPhase( - static_cast(m_admtController->HAR_PHASE_1), - static_cast(*h1PhaseCurrent))); - H2_PHASE_HEX = static_cast( - m_admtController->calculateHarmonicCoefficientPhase( - static_cast(m_admtController->HAR_PHASE_2), - static_cast(*h2PhaseCurrent))); - H3_PHASE_HEX = static_cast( - m_admtController->calculateHarmonicCoefficientPhase( - static_cast(m_admtController->HAR_PHASE_3), - static_cast(*h3PhaseCurrent))); - H8_PHASE_HEX = static_cast( - m_admtController->calculateHarmonicCoefficientPhase( - static_cast(m_admtController->HAR_PHASE_8), - static_cast(*h8PhaseCurrent))); - - calibrationLogWrite(); - calibrationLogWrite( - QString("Calculated H1 Mag (Hex): 0x%1") - .arg(QString::number(H1_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite( - QString("Calculated H1 Phase (Hex): 0x%1") - .arg(QString::number(H1_PHASE_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite( - QString("Calculated H2 Mag (Hex): 0x%1") - .arg(QString::number(H2_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite( - QString("Calculated H2 Phase (Hex): 0x%1") - .arg(QString::number(H2_PHASE_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite( - QString("Calculated H3 Mag (Hex): 0x%1") - .arg(QString::number(H3_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite( - QString("Calculated H3 Phase (Hex): 0x%1") - .arg(QString::number(H3_PHASE_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite( - QString("Calculated H8 Mag (Hex): 0x%1") - .arg(QString::number(H8_MAG_HEX, 16).rightJustified(4, '0'))); - calibrationLogWrite( - QString("Calculated H8 Phase (Hex): 0x%1") - .arg(QString::number(H8_PHASE_HEX, 16).rightJustified(4, '0'))); - - // Get actual harmonic values from hex - H1_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue( - static_cast(H1_MAG_HEX), "h1mag"); - H1_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue( - static_cast(H1_PHASE_HEX), "h1phase"); - H2_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue( - static_cast(H2_MAG_HEX), "h2mag"); - H2_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue( - static_cast(H2_PHASE_HEX), "h2phase"); - H3_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue( - static_cast(H3_MAG_HEX), "h3mag"); - H3_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue( - static_cast(H3_PHASE_HEX), "h3phase"); - H8_MAG_ANGLE = m_admtController->getActualHarmonicRegisterValue( - static_cast(H8_MAG_HEX), "h8mag"); - H8_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue( - static_cast(H8_PHASE_HEX), "h8phase"); - - calibrationLogWrite(); - calibrationLogWrite(QString("Calculated H1 Mag (Angle): %1°") - .arg(QString::number(H1_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H1 Phase (Angle): %1°") - .arg(QString::number(H1_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H2 Mag (Angle): %1°") - .arg(QString::number(H2_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H2 Phase (Angle): %1°") - .arg(QString::number(H2_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H3 Mag (Angle): %1°") - .arg(QString::number(H3_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H3 Phase (Angle): %1°") - .arg(QString::number(H3_PHASE_ANGLE))); - calibrationLogWrite(QString("Calculated H8 Mag (Angle): %1°") - .arg(QString::number(H8_MAG_ANGLE))); - calibrationLogWrite(QString("Calculated H8 Phase (Angle): %1°") - .arg(QString::number(H8_PHASE_ANGLE))); - - if (isAngleDisplayFormat) - updateCalculatedCoeffAngle(); - else - updateCalculatedCoeffHex(); - isCalculatedCoeff = true; - } -} - -void HarmonicCalibration::updateCalculatedCoeffAngle() { - calibrationH1MagLabel->setText(QString::number(H1_MAG_ANGLE, 'f', 2) + "°"); - calibrationH2MagLabel->setText(QString::number(H2_MAG_ANGLE, 'f', 2) + "°"); - calibrationH3MagLabel->setText(QString::number(H3_MAG_ANGLE, 'f', 2) + "°"); - calibrationH8MagLabel->setText(QString::number(H8_MAG_ANGLE, 'f', 2) + "°"); - calibrationH1PhaseLabel->setText("Φ " + - QString::number(H1_PHASE_ANGLE, 'f', 2)); - calibrationH2PhaseLabel->setText("Φ " + - QString::number(H2_PHASE_ANGLE, 'f', 2)); - calibrationH3PhaseLabel->setText("Φ " + - QString::number(H3_PHASE_ANGLE, 'f', 2)); - calibrationH8PhaseLabel->setText("Φ " + - QString::number(H8_PHASE_ANGLE, 'f', 2)); -} - -void HarmonicCalibration::updateCalculatedCoeffHex() { - calibrationH1MagLabel->setText( - QString("0x%1").arg(H1_MAG_HEX, 4, 16, QChar('0'))); - calibrationH2MagLabel->setText( - QString("0x%1").arg(H2_MAG_HEX, 4, 16, QChar('0'))); - calibrationH3MagLabel->setText( - QString("0x%1").arg(H3_MAG_HEX, 4, 16, QChar('0'))); - calibrationH8MagLabel->setText( - QString("0x%1").arg(H8_MAG_HEX, 4, 16, QChar('0'))); - calibrationH1PhaseLabel->setText( - QString("0x%1").arg(H1_PHASE_HEX, 4, 16, QChar('0'))); - calibrationH2PhaseLabel->setText( - QString("0x%1").arg(H2_PHASE_HEX, 4, 16, QChar('0'))); - calibrationH3PhaseLabel->setText( - QString("0x%1").arg(H3_PHASE_HEX, 4, 16, QChar('0'))); - calibrationH8PhaseLabel->setText( - QString("0x%1").arg(H8_PHASE_HEX, 4, 16, QChar('0'))); -} - -void HarmonicCalibration::resetCalculatedCoeffAngle() { - calibrationH1MagLabel->setText("--.--°"); - calibrationH2MagLabel->setText("--.--°"); - calibrationH3MagLabel->setText("--.--°"); - calibrationH8MagLabel->setText("--.--°"); - calibrationH1PhaseLabel->setText("Φ --.--"); - calibrationH2PhaseLabel->setText("Φ --.--"); - calibrationH3PhaseLabel->setText("Φ --.--"); - calibrationH8PhaseLabel->setText("Φ --.--"); -} - -void HarmonicCalibration::resetCalculatedCoeffHex() { - calibrationH1MagLabel->setText("0x----"); - calibrationH2MagLabel->setText("0x----"); - calibrationH3MagLabel->setText("0x----"); - calibrationH8MagLabel->setText("0x----"); - calibrationH1PhaseLabel->setText("0x----"); - calibrationH2PhaseLabel->setText("0x----"); - calibrationH3PhaseLabel->setText("0x----"); - calibrationH8PhaseLabel->setText("0x----"); -} - -void HarmonicCalibration::displayCalculatedCoeff() { - if (isAngleDisplayFormat) { - if (isCalculatedCoeff) { - updateCalculatedCoeffAngle(); - } else { - resetCalculatedCoeffAngle(); - } - } else { - if (isCalculatedCoeff) { - updateCalculatedCoeffHex(); - } else { - resetCalculatedCoeffHex(); - } - } -} - -void HarmonicCalibration::calibrationLogWrite(QString message) { - logsPlainTextEdit->appendPlainText(message); -} - -void HarmonicCalibration::importCalibrationData() { - QString fileName = - QFileDialog::getOpenFileName(this, tr("Import"), "", - tr("Comma-separated values files (*.csv);;" - "Tab-delimited values files (*.txt)"), - nullptr, QFileDialog::Options()); - - FileManager fm("HarmonicCalibration"); - - try { - fm.open(fileName, FileManager::IMPORT); - - graphDataList = fm.read(0); - if (graphDataList.size() > 0) { - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataXPlotAxis->setInterval(0, graphDataList.size()); - calibrationRawDataPlotWidget->replot(); - - computeSineCosineOfAngles(graphDataList); - calibrationLogWrite(m_admtController->calibrate( - vector(graphDataList.begin(), graphDataList.end()), - cycleCount, samplesPerCycle, false)); // TODO: Hard-coded Clockwise - populateAngleErrorGraphs(); - toggleCalibrationButtonState(2); - } - } catch (FileManagerException &ex) { - calibrationLogWrite(QString(ex.what())); - } -} - -void HarmonicCalibration::extractCalibrationData() { - QStringList filter; - filter += QString(tr("Comma-separated values files (*.csv)")); - filter += QString(tr("Tab-delimited values files (*.txt)")); - filter += QString(tr("All Files(*)")); - - QString selectedFilter = filter[0]; - - QString fileName = - QFileDialog::getSaveFileName(this, tr("Export"), "", filter.join(";;"), - &selectedFilter, QFileDialog::Options()); - - if (fileName.split(".").size() <= 1) { - QString ext = selectedFilter.split(".")[1].split(")")[0]; - fileName += "." + ext; - } - - if (!fileName.isEmpty()) { - bool withScopyHeader = false; - FileManager fm("HarmonicCalibration"); - fm.open(fileName, FileManager::EXPORT); - - QVector preCalibrationAngleErrorsFFTMagnitude( - m_admtController->angle_errors_fft_pre.begin(), - m_admtController->angle_errors_fft_pre.end()); - QVector preCalibrationAngleErrorsFFTPhase( - m_admtController->angle_errors_fft_phase_pre.begin(), - m_admtController->angle_errors_fft_phase_pre.end()); - - QVector h1Mag = {H1_MAG_ANGLE}; - QVector h2Mag = {H2_MAG_ANGLE}; - QVector h3Mag = {H3_MAG_ANGLE}; - QVector h8Mag = {H8_MAG_ANGLE}; - QVector h1Phase = {H1_PHASE_ANGLE}; - QVector h2Phase = {H2_PHASE_ANGLE}; - QVector h3Phase = {H3_PHASE_ANGLE}; - QVector h8Phase = {H8_PHASE_ANGLE}; - - fm.save(graphDataList, "Raw Data"); - fm.save(preCalibrationAngleErrorsFFTMagnitude, - "Pre-Calibration Angle Errors FFT Magnitude"); - fm.save(preCalibrationAngleErrorsFFTPhase, - "Pre-Calibration Angle Errors FFT Phase"); - fm.save(h1Mag, "H1 Mag"); - fm.save(h2Mag, "H2 Mag"); - fm.save(h3Mag, "H3 Mag"); - fm.save(h8Mag, "H8 Mag"); - fm.save(h1Phase, "H1 Phase"); - fm.save(h2Phase, "H2 Phase"); - fm.save(h3Phase, "H3 Phase"); - fm.save(h8Phase, "H8 Phase"); - - fm.performWrite(withScopyHeader); - } -} - -void HarmonicCalibration::toggleTabSwitching(bool value) { - tabWidget->setTabEnabled(0, value); - tabWidget->setTabEnabled(2, value); - tabWidget->setTabEnabled(3, value); -} - -void HarmonicCalibration::toggleCalibrationButtonState(int state) { - switch (state) { - case 0: // Idle - calibrationStartMotorButton->setEnabled(true); - calibrationStartMotorButton->setChecked(false); - calibrateDataButton->setEnabled(false); - calibrateDataButton->setChecked(false); - clearCalibrateDataButton->setEnabled(true); - break; - case 1: // Start Motor - calibrationStartMotorButton->setEnabled(true); - calibrateDataButton->setEnabled(false); - clearCalibrateDataButton->setEnabled(false); - break; - case 2: // After Start Motor - calibrationStartMotorButton->setEnabled(false); - calibrateDataButton->setEnabled(true); - calibrateDataButton->setChecked(false); - clearCalibrateDataButton->setEnabled(true); - break; - case 3: // Post-Calibration - calibrationStartMotorButton->setEnabled(false); - calibrateDataButton->setEnabled(true); - clearCalibrateDataButton->setEnabled(false); - break; - case 4: // After Post-Calibration - calibrationStartMotorButton->setEnabled(false); - calibrateDataButton->setEnabled(false); - clearCalibrateDataButton->setEnabled(true); - break; - } -} - -void HarmonicCalibration::canStartMotor(bool value) { - calibrationStartMotorButton->setEnabled(value); -} - -void HarmonicCalibration::canCalibrate(bool value) { - calibrateDataButton->setEnabled(value); -} - -void HarmonicCalibration::toggleCalibrationControls(bool value) { - // motorMaxVelocitySpinBox->setEnabled(value); - // motorAccelTimeSpinBox->setEnabled(value); - // motorMaxDisplacementSpinBox->setEnabled(value); - // m_calibrationMotorRampModeMenuCombo->setEnabled(value); - motorTargetPositionLineEdit->setEnabled(value); - calibrationModeMenuCombo->setEnabled(value); -} - -void HarmonicCalibration::clearCalibrationSamples() { - graphDataList.clear(); - calibrationRawDataPlotChannel->curve()->setData(nullptr); - calibrationSineDataPlotChannel->curve()->setData(nullptr); - calibrationCosineDataPlotChannel->curve()->setData(nullptr); - calibrationRawDataPlotWidget->replot(); -} - -void HarmonicCalibration::clearCalibrationSineCosine() { - calibrationSineDataPlotChannel->curve()->setData(nullptr); - calibrationCosineDataPlotChannel->curve()->setData(nullptr); - calibrationRawDataPlotWidget->replot(); -} - -void HarmonicCalibration::clearPostCalibrationSamples() { - graphPostDataList.clear(); - postCalibrationRawDataPlotChannel->curve()->setData(nullptr); - postCalibrationSineDataPlotChannel->curve()->setData(nullptr); - postCalibrationCosineDataPlotChannel->curve()->setData(nullptr); - postCalibrationRawDataPlotWidget->replot(); -} - -void HarmonicCalibration::clearAngleErrorGraphs() { - angleErrorPlotChannel->curve()->setData(nullptr); - angleErrorPlotWidget->replot(); - FFTAngleErrorMagnitudeChannel->curve()->setData(nullptr); - FFTAngleErrorPhaseChannel->curve()->setData(nullptr); - FFTAngleErrorPlotWidget->replot(); -} - -void HarmonicCalibration::clearCorrectedAngleErrorGraphs() { - correctedErrorPlotChannel->curve()->setData(nullptr); - correctedErrorPlotWidget->replot(); - FFTCorrectedErrorMagnitudeChannel->curve()->setData(nullptr); - FFTCorrectedErrorPhaseChannel->curve()->setData(nullptr); - FFTCorrectedErrorPlotWidget->replot(); +void HarmonicCalibration::startCalibrationUITask() +{ + if(!m_calibrationUIThread.isRunning()) { + isCalibrationTab = true; + m_calibrationUIThread = + QtConcurrent::run(this, &HarmonicCalibration::calibrationUITask, calibrationUITimerRate); + m_calibrationUIWatcher.setFuture(m_calibrationUIThread); + } +} + +void HarmonicCalibration::stopCalibrationUITask() +{ + isCalibrationTab = false; + if(m_calibrationUIThread.isRunning()) { + m_calibrationUIThread.cancel(); + m_calibrationUIWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::calibrationUITask(int sampleRate) +{ + while(isCalibrationTab) { + if(isStartMotor) { + if(isPostCalibration) { + postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); + postCalibrationRawDataPlotWidget->replot(); + } else { + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotWidget->replot(); + } + } + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::updateCalibrationMotorRPM() +{ + calibrationMotorRPMLineEdit->setText(QString::number(motor_rpm)); +} + +void HarmonicCalibration::updateCalibrationMotorRotationDirection() +{ + calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); +} + +void HarmonicCalibration::getCalibrationSamples() +{ + if(resetCurrentPositionToZero()) { + double step = 0; + if(isMotorRotationClockwise) + step = motorFullStepPerRevolution; + else + step = -motorFullStepPerRevolution; + if(isPostCalibration) { + int currentSamplesCount = graphPostDataList.size(); + while(isStartMotor && currentSamplesCount < totalSamplesCount) { + target_pos = current_pos + step; + moveMotorToPosition(target_pos, true); + updateChannelValue(ADMTController::Channel::ANGLE); + graphPostDataList.append(angle); + currentSamplesCount++; + } + } else { + int currentSamplesCount = graphDataList.size(); + while(isStartMotor && currentSamplesCount < totalSamplesCount) { + target_pos = current_pos + step; + if(moveMotorToPosition(target_pos, true) == false) { + m_admtController->disconnectADMT(); + } + if(updateChannelValue(ADMTController::Channel::ANGLE)) { + break; + } + graphDataList.append(angle); + currentSamplesCount++; + } + } + } + + stopMotor(); +} + +void HarmonicCalibration::startCalibration() +{ + totalSamplesCount = cycleCount * samplesPerCycle; + graphPostDataList.reserve(totalSamplesCount); + graphPostDataList.squeeze(); + graphDataList.reserve(totalSamplesCount); + graphDataList.squeeze(); + + // configureConversionType(calibrationMode); // TODO uncomment when conversion + // type is okay + configureCalibrationSequenceSettings(); + clearHarmonicRegisters(); + + toggleTabSwitching(false); + toggleCalibrationControls(false); + + calibrationDataGraphTabWidget->setCurrentIndex(0); + calibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); + + toggleCalibrationButtonState(1); + if(calibrationMode == 0) + startContinuousCalibration(); + else + startOneShotCalibration(); +} + +void HarmonicCalibration::stopCalibration() +{ + isStartMotor = false; + if(calibrationMode == 0) { + stopContinuousCalibration(); + } + + toggleTabSwitching(true); + toggleCalibrationControls(true); +} + +void HarmonicCalibration::startContinuousCalibration() +{ + stopCurrentMotorPositionMonitor(); + stopDeviceStatusMonitor(); + + if(isPostCalibration) + StatusBarManager::pushMessage("Acquiring Post Calibration Samples, Please Wait..."); + else + StatusBarManager::pushMessage("Acquiring Calibration Samples, Please Wait..."); + startResetMotorToZero(); +} + +void HarmonicCalibration::stopContinuousCalibration() +{ + stopMotor(); + stopWaitForVelocityReachedThread(); + stopCalibrationStreamThread(); + + startCurrentMotorPositionMonitor(); + startDeviceStatusMonitor(); +} + +void HarmonicCalibration::startResetMotorToZero() +{ + isResetMotorToZero = true; + if(!m_resetMotorToZeroThread.isRunning()) { + m_resetMotorToZeroThread = QtConcurrent::run(this, &HarmonicCalibration::resetMotorToZero); + m_resetMotorToZeroWatcher.setFuture(m_resetMotorToZeroThread); + } +} + +void HarmonicCalibration::stopResetMotorToZero() +{ + isResetMotorToZero = false; + if(m_resetMotorToZeroThread.isRunning()) { + m_resetMotorToZeroThread.cancel(); + m_resetMotorToZeroWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::resetMotorToZero() +{ + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) { + if(current_pos != 0) { + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, + convertRPStoVMAX(convertRPMtoRPS(fast_motor_rpm))); + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + while(isResetMotorToZero && current_pos != 0) { + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) != + 0) + break; + QThread::msleep(readMotorDebounce); + } + if(current_pos == 0) { + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); + } + } + } +} + +void HarmonicCalibration::startCalibrationStreamThread() +{ + if(!m_calibrationStreamThread.isRunning()) { + m_admtController->stopStream = false; + + continuousCalibrationSampleRate = + calculateContinuousCalibrationSampleRate(convertVMAXtoRPS(rotate_vmax), samplesPerCycle); + m_calibrationStreamThread = QtConcurrent::run([this]() { + m_admtController->bufferedStreamIO(totalSamplesCount, continuousCalibrationSampleRate); + }); + m_calibrationStreamWatcher.setFuture(m_calibrationStreamThread); + } +} + +void HarmonicCalibration::stopCalibrationStreamThread() +{ + m_admtController->stopStream = true; + if(m_calibrationStreamThread.isRunning()) { + m_calibrationStreamThread.cancel(); + m_calibrationStreamWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::startWaitForVelocityReachedThread(int mode) +{ + if(!m_calibrationWaitVelocityWatcher.isRunning()) { + isMotorVelocityCheck = true; + m_calibrationWaitVelocityThread = QtConcurrent::run(this, &HarmonicCalibration::waitForVelocityReached, + mode, motorWaitVelocityReachedSampleRate); + m_calibrationWaitVelocityWatcher.setFuture(m_calibrationWaitVelocityThread); + } +} + +void HarmonicCalibration::stopWaitForVelocityReachedThread() +{ + isMotorVelocityCheck = false; + if(m_calibrationWaitVelocityWatcher.isRunning()) { + m_calibrationWaitVelocityThread.cancel(); + m_calibrationWaitVelocityWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::waitForVelocityReached(int mode, int sampleRate) +{ + isMotorVelocityReached = false; + if(mode == 0) { + QThread::msleep(floor(convertAMAXtoAccelTime(amax) * 1000)); + isMotorVelocityReached = true; + } else if(mode == 1) { + moveMotorContinuous(); + uint32_t *registerValue = new uint32_t; + while(isMotorVelocityCheck && !isMotorVelocityReached) { + if(readMotorRegisterValue( + m_admtController->getRampGeneratorDriverFeatureControlRegister( + ADMTController::RampGeneratorDriverFeatureControlRegister::RAMP_STAT), + registerValue) == 0) { + isMotorVelocityReached = m_admtController->checkVelocityReachedFlag( + static_cast(*registerValue)); + } + + QThread::msleep(sampleRate); + } + + delete registerValue; + } +} + +int HarmonicCalibration::calculateContinuousCalibrationSampleRate(double motorRPS, int samplesPerCycle) +{ + return static_cast(floor(1 / motorRPS / samplesPerCycle * 1000 * 1000 * 1000)); // In nanoseconds +} + +void HarmonicCalibration::configureConversionType(int mode) +{ + readSequence(); + GENERALRegisterMap.at("Conversion Type") = mode; + writeSequence(GENERALRegisterMap); +} + +void HarmonicCalibration::configureCalibrationSequenceSettings() +{ + readSequence(); + GENERALRegisterMap.at("8th Harmonic") = 1; // User-supplied 8th Harmonic + writeSequence(GENERALRegisterMap); +} + +void HarmonicCalibration::getStreamedCalibrationSamples(int microSampleRate) +{ + int currentSamplesCount = graphDataList.size(); + moveMotorContinuous(); + while(isStartMotor && currentSamplesCount < totalSamplesCount) { + graphDataList.append(m_admtController->streamedValue); + // graphPostDataList.append(m_admtController->streamedValue); + currentSamplesCount = graphDataList.size(); + // currentSamplesCount = graphDataPostList.size(); + + QThread::usleep(microSampleRate); + } +} + +void HarmonicCalibration::startOneShotCalibration() +{ + if(resetToZero && !isPostCalibration) { + clearCalibrationSamples(); + clearPostCalibrationSamples(); + clearAngleErrorGraphs(); + clearCorrectedAngleErrorGraphs(); + } else if(resetToZero) { + clearPostCalibrationSamples(); + } + + QFuture future = QtConcurrent::run(this, &HarmonicCalibration::getCalibrationSamples); + QFutureWatcher *watcher = new QFutureWatcher(this); + + connect(watcher, &QFutureWatcher::finished, this, [this]() { + toggleTabSwitching(true); + toggleCalibrationControls(true); + + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotChannel->xAxis()->setMax(graphDataList.size()); + calibrationRawDataPlotWidget->replot(); + isStartMotor = false; + + if(isPostCalibration) { + if(static_cast(graphPostDataList.size()) == totalSamplesCount) { + computeSineCosineOfAngles(graphPostDataList); + m_admtController->postcalibrate( + vector(graphPostDataList.begin(), graphPostDataList.end()), cycleCount, + samplesPerCycle, !isMotorRotationClockwise); + populateCorrectedAngleErrorGraphs(); + isPostCalibration = false; + isStartMotor = false; + resetToZero = true; + toggleCalibrationButtonState(4); + } else + toggleCalibrationButtonState(2); + } else { + if(static_cast(graphDataList.size()) == totalSamplesCount) { + computeSineCosineOfAngles(graphDataList); + calibrationLogWrite(m_admtController->calibrate( + vector(graphDataList.begin(), graphDataList.end()), cycleCount, + samplesPerCycle, !isMotorRotationClockwise)); + populateAngleErrorGraphs(); + calculateHarmonicValues(); + toggleCalibrationButtonState(2); + } else { + resetToZero = true; + toggleCalibrationButtonState(0); + } + } + }); + connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater())); + watcher->setFuture(future); +} + +void HarmonicCalibration::postCalibrateData() +{ + calibrationLogWrite("==== Post Calibration Start ====\n"); + flashHarmonicValues(); + isPostCalibration = true; + isStartMotor = true; + resetToZero = true; + + toggleTabSwitching(false); + toggleCalibrationControls(false); + + calibrationDataGraphTabWidget->setCurrentIndex(1); + postCalibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); + + toggleCalibrationButtonState(3); + if(calibrationMode == 0) + startContinuousCalibration(); + else + startOneShotCalibration(); +} + +void HarmonicCalibration::resetAllCalibrationState() +{ + clearCalibrationSamples(); + clearPostCalibrationSamples(); + calibrationDataGraphTabWidget->setCurrentIndex(0); + + clearAngleErrorGraphs(); + clearCorrectedAngleErrorGraphs(); + resultDataTabWidget->setCurrentIndex(0); + + toggleCalibrationButtonState(0); + + isPostCalibration = false; + isCalculatedCoeff = false; + resetToZero = true; + displayCalculatedCoeff(); +} + +void HarmonicCalibration::computeSineCosineOfAngles(QVector graphDataList) +{ + m_admtController->computeSineCosineOfAngles(vector(graphDataList.begin(), graphDataList.end())); + if(isPostCalibration) { + postCalibrationSineDataPlotChannel->curve()->setSamples( + m_admtController->calibration_samples_sine_scaled.data(), + m_admtController->calibration_samples_sine_scaled.size()); + postCalibrationCosineDataPlotChannel->curve()->setSamples( + m_admtController->calibration_samples_cosine_scaled.data(), + m_admtController->calibration_samples_cosine_scaled.size()); + postCalibrationRawDataPlotWidget->replot(); + } else { + calibrationSineDataPlotChannel->curve()->setSamples( + m_admtController->calibration_samples_sine_scaled.data(), + m_admtController->calibration_samples_sine_scaled.size()); + calibrationCosineDataPlotChannel->curve()->setSamples( + m_admtController->calibration_samples_cosine_scaled.data(), + m_admtController->calibration_samples_cosine_scaled.size()); + calibrationRawDataPlotWidget->replot(); + } +} + +void HarmonicCalibration::populateAngleErrorGraphs() +{ + QVector angleError = + QVector(m_admtController->angleError.begin(), m_admtController->angleError.end()); + QVector FFTAngleErrorMagnitude = QVector(m_admtController->FFTAngleErrorMagnitude.begin(), + m_admtController->FFTAngleErrorMagnitude.end()); + QVector FFTAngleErrorPhase = QVector(m_admtController->FFTAngleErrorPhase.begin(), + m_admtController->FFTAngleErrorPhase.end()); + + angleErrorPlotChannel->curve()->setSamples(angleError); + auto angleErrorMinMax = minmax_element(angleError.begin(), angleError.end()); + angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, *angleErrorMinMax.second); + angleErrorXPlotAxis->setInterval(0, angleError.size()); + angleErrorPlotWidget->replot(); + + FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); + FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); + auto angleErrorMagnitudeMinMax = minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); + auto angleErrorPhaseMinMax = minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); + double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first + ? *angleErrorMagnitudeMinMax.first + : *angleErrorPhaseMinMax.first; + double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second + ? *angleErrorMagnitudeMinMax.second + : *angleErrorPhaseMinMax.second; + FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); + FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); + FFTAngleErrorPlotWidget->replot(); + + resultDataTabWidget->setCurrentIndex(0); // Set tab to Angle Error +} + +void HarmonicCalibration::populateCorrectedAngleErrorGraphs() +{ + QVector correctedError(m_admtController->correctedError.begin(), + m_admtController->correctedError.end()); + QVector FFTCorrectedErrorMagnitude(m_admtController->FFTCorrectedErrorMagnitude.begin(), + m_admtController->FFTCorrectedErrorMagnitude.end()); + QVector FFTCorrectedErrorPhase(m_admtController->FFTCorrectedErrorPhase.begin(), + m_admtController->FFTCorrectedErrorPhase.end()); + + correctedErrorPlotChannel->curve()->setSamples(correctedError); + auto correctedErrorMagnitudeMinMax = minmax_element(correctedError.begin(), correctedError.end()); + correctedErrorYPlotAxis->setInterval(*correctedErrorMagnitudeMinMax.first, + *correctedErrorMagnitudeMinMax.second); + correctedErrorXPlotAxis->setMax(correctedError.size()); + correctedErrorPlotWidget->replot(); + + FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); + FFTCorrectedErrorMagnitudeChannel->curve()->setSamples(FFTCorrectedErrorMagnitude); + auto FFTCorrectedErrorMagnitudeMinMax = + minmax_element(FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); + auto FFTCorrectedErrorPhaseMinMax = + minmax_element(FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); + double FFTCorrectedErrorPlotMin = *FFTCorrectedErrorMagnitudeMinMax.first < *FFTCorrectedErrorPhaseMinMax.first + ? *FFTCorrectedErrorMagnitudeMinMax.first + : *FFTCorrectedErrorPhaseMinMax.first; + double FFTCorrectedErrorPlotMax = + *FFTCorrectedErrorMagnitudeMinMax.second > *FFTCorrectedErrorPhaseMinMax.second + ? *FFTCorrectedErrorMagnitudeMinMax.second + : *FFTCorrectedErrorPhaseMinMax.second; + FFTCorrectedErrorYPlotAxis->setInterval(FFTCorrectedErrorPlotMin, FFTCorrectedErrorPlotMax); + FFTCorrectedErrorXPlotAxis->setMax(FFTCorrectedErrorMagnitude.size()); + FFTCorrectedErrorPlotWidget->replot(); + + resultDataTabWidget->setCurrentIndex(2); // Set tab to Angle Error +} + +void HarmonicCalibration::clearHarmonicRegisters() +{ + bool success = false; + uint32_t value = 0x0; + uint32_t harmonicCNVPage = m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1MAG); + if(changeCNVPage(harmonicCNVPage)) { + success = m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), + value) == 0 + ? true + : false; + success = m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), + value) == 0 + ? true + : false; + success = m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), + value) == 0 + ? true + : false; + success = m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), + value) == 0 + ? true + : false; + success = m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), + value) == 0 + ? true + : false; + success = m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), + value) == 0 + ? true + : false; + success = m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), + value) == 0 + ? true + : false; + success = m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), + value) == 0 + ? true + : false; + } + + if(!success) { + calibrationLogWrite("Unable to clear Harmonic Registers!"); + } +} + +void HarmonicCalibration::flashHarmonicValues() +{ + if(changeCNVPage(0x02)) { + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + 0x01, 0x02); + + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), H1_MAG_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), H1_PHASE_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), H2_MAG_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), H2_PHASE_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), H3_MAG_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), H3_PHASE_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), H8_MAG_HEX); + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), H8_PHASE_HEX); + + isCalculatedCoeff = true; + displayCalculatedCoeff(); + } else { + calibrationLogWrite("Unabled to flash Harmonic Registers!"); + } +} + +void HarmonicCalibration::calculateHarmonicValues() +{ + uint32_t *h1MagCurrent = new uint32_t, *h1PhaseCurrent = new uint32_t, *h2MagCurrent = new uint32_t, + *h2PhaseCurrent = new uint32_t, *h3MagCurrent = new uint32_t, *h3PhaseCurrent = new uint32_t, + *h8MagCurrent = new uint32_t, *h8PhaseCurrent = new uint32_t; + + if(changeCNVPage(0x02)) { + // Read and store current harmonic values + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), h1MagCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), h2MagCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), h3MagCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), h8MagCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), h1PhaseCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), h2PhaseCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), h3PhaseCurrent); + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), h8PhaseCurrent); + + // Calculate harmonic coefficients (Hex) + H1_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude( + static_cast(m_admtController->HAR_MAG_1), static_cast(*h1MagCurrent), + "h1")); + H2_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude( + static_cast(m_admtController->HAR_MAG_2), static_cast(*h2MagCurrent), + "h2")); + H3_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude( + static_cast(m_admtController->HAR_MAG_3), static_cast(*h3MagCurrent), + "h3")); + H8_MAG_HEX = static_cast(m_admtController->calculateHarmonicCoefficientMagnitude( + static_cast(m_admtController->HAR_MAG_8), static_cast(*h8MagCurrent), + "h8")); + H1_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase( + static_cast(m_admtController->HAR_PHASE_1), static_cast(*h1PhaseCurrent))); + H2_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase( + static_cast(m_admtController->HAR_PHASE_2), static_cast(*h2PhaseCurrent))); + H3_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase( + static_cast(m_admtController->HAR_PHASE_3), static_cast(*h3PhaseCurrent))); + H8_PHASE_HEX = static_cast(m_admtController->calculateHarmonicCoefficientPhase( + static_cast(m_admtController->HAR_PHASE_8), static_cast(*h8PhaseCurrent))); + + calibrationLogWrite(); + calibrationLogWrite(QString("Calculated H1 Mag (Hex): 0x%1") + .arg(QString::number(H1_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H1 Phase (Hex): 0x%1") + .arg(QString::number(H1_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H2 Mag (Hex): 0x%1") + .arg(QString::number(H2_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H2 Phase (Hex): 0x%1") + .arg(QString::number(H2_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H3 Mag (Hex): 0x%1") + .arg(QString::number(H3_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H3 Phase (Hex): 0x%1") + .arg(QString::number(H3_PHASE_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H8 Mag (Hex): 0x%1") + .arg(QString::number(H8_MAG_HEX, 16).rightJustified(4, '0'))); + calibrationLogWrite(QString("Calculated H8 Phase (Hex): 0x%1") + .arg(QString::number(H8_PHASE_HEX, 16).rightJustified(4, '0'))); + + // Get actual harmonic values from hex + H1_MAG_ANGLE = + m_admtController->getActualHarmonicRegisterValue(static_cast(H1_MAG_HEX), "h1mag"); + H1_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H1_PHASE_HEX), + "h1phase"); + H2_MAG_ANGLE = + m_admtController->getActualHarmonicRegisterValue(static_cast(H2_MAG_HEX), "h2mag"); + H2_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H2_PHASE_HEX), + "h2phase"); + H3_MAG_ANGLE = + m_admtController->getActualHarmonicRegisterValue(static_cast(H3_MAG_HEX), "h3mag"); + H3_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H3_PHASE_HEX), + "h3phase"); + H8_MAG_ANGLE = + m_admtController->getActualHarmonicRegisterValue(static_cast(H8_MAG_HEX), "h8mag"); + H8_PHASE_ANGLE = m_admtController->getActualHarmonicRegisterValue(static_cast(H8_PHASE_HEX), + "h8phase"); + + calibrationLogWrite(); + calibrationLogWrite(QString("Calculated H1 Mag (Angle): %1°").arg(QString::number(H1_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H1 Phase (Angle): %1°").arg(QString::number(H1_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H2 Mag (Angle): %1°").arg(QString::number(H2_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H2 Phase (Angle): %1°").arg(QString::number(H2_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H3 Mag (Angle): %1°").arg(QString::number(H3_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H3 Phase (Angle): %1°").arg(QString::number(H3_PHASE_ANGLE))); + calibrationLogWrite(QString("Calculated H8 Mag (Angle): %1°").arg(QString::number(H8_MAG_ANGLE))); + calibrationLogWrite(QString("Calculated H8 Phase (Angle): %1°").arg(QString::number(H8_PHASE_ANGLE))); + + if(isAngleDisplayFormat) + updateCalculatedCoeffAngle(); + else + updateCalculatedCoeffHex(); + isCalculatedCoeff = true; + } +} + +void HarmonicCalibration::updateCalculatedCoeffAngle() +{ + calibrationH1MagLabel->setText(QString::number(H1_MAG_ANGLE, 'f', 2) + "°"); + calibrationH2MagLabel->setText(QString::number(H2_MAG_ANGLE, 'f', 2) + "°"); + calibrationH3MagLabel->setText(QString::number(H3_MAG_ANGLE, 'f', 2) + "°"); + calibrationH8MagLabel->setText(QString::number(H8_MAG_ANGLE, 'f', 2) + "°"); + calibrationH1PhaseLabel->setText("Φ " + QString::number(H1_PHASE_ANGLE, 'f', 2)); + calibrationH2PhaseLabel->setText("Φ " + QString::number(H2_PHASE_ANGLE, 'f', 2)); + calibrationH3PhaseLabel->setText("Φ " + QString::number(H3_PHASE_ANGLE, 'f', 2)); + calibrationH8PhaseLabel->setText("Φ " + QString::number(H8_PHASE_ANGLE, 'f', 2)); +} + +void HarmonicCalibration::updateCalculatedCoeffHex() +{ + calibrationH1MagLabel->setText(QString("0x%1").arg(H1_MAG_HEX, 4, 16, QChar('0'))); + calibrationH2MagLabel->setText(QString("0x%1").arg(H2_MAG_HEX, 4, 16, QChar('0'))); + calibrationH3MagLabel->setText(QString("0x%1").arg(H3_MAG_HEX, 4, 16, QChar('0'))); + calibrationH8MagLabel->setText(QString("0x%1").arg(H8_MAG_HEX, 4, 16, QChar('0'))); + calibrationH1PhaseLabel->setText(QString("0x%1").arg(H1_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH2PhaseLabel->setText(QString("0x%1").arg(H2_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH3PhaseLabel->setText(QString("0x%1").arg(H3_PHASE_HEX, 4, 16, QChar('0'))); + calibrationH8PhaseLabel->setText(QString("0x%1").arg(H8_PHASE_HEX, 4, 16, QChar('0'))); +} + +void HarmonicCalibration::resetCalculatedCoeffAngle() +{ + calibrationH1MagLabel->setText("--.--°"); + calibrationH2MagLabel->setText("--.--°"); + calibrationH3MagLabel->setText("--.--°"); + calibrationH8MagLabel->setText("--.--°"); + calibrationH1PhaseLabel->setText("Φ --.--"); + calibrationH2PhaseLabel->setText("Φ --.--"); + calibrationH3PhaseLabel->setText("Φ --.--"); + calibrationH8PhaseLabel->setText("Φ --.--"); +} + +void HarmonicCalibration::resetCalculatedCoeffHex() +{ + calibrationH1MagLabel->setText("0x----"); + calibrationH2MagLabel->setText("0x----"); + calibrationH3MagLabel->setText("0x----"); + calibrationH8MagLabel->setText("0x----"); + calibrationH1PhaseLabel->setText("0x----"); + calibrationH2PhaseLabel->setText("0x----"); + calibrationH3PhaseLabel->setText("0x----"); + calibrationH8PhaseLabel->setText("0x----"); +} + +void HarmonicCalibration::displayCalculatedCoeff() +{ + if(isAngleDisplayFormat) { + if(isCalculatedCoeff) { + updateCalculatedCoeffAngle(); + } else { + resetCalculatedCoeffAngle(); + } + } else { + if(isCalculatedCoeff) { + updateCalculatedCoeffHex(); + } else { + resetCalculatedCoeffHex(); + } + } +} + +void HarmonicCalibration::calibrationLogWrite(QString message) { logsPlainTextEdit->appendPlainText(message); } + +void HarmonicCalibration::importCalibrationData() +{ + QString fileName = QFileDialog::getOpenFileName(this, tr("Import"), "", + tr("Comma-separated values files (*.csv);;" + "Tab-delimited values files (*.txt)"), + nullptr, QFileDialog::Options()); + + FileManager fm("HarmonicCalibration"); + + try { + fm.open(fileName, FileManager::IMPORT); + + graphDataList = fm.read(0); + if(graphDataList.size() > 0) { + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataXPlotAxis->setInterval(0, graphDataList.size()); + calibrationRawDataPlotWidget->replot(); + + computeSineCosineOfAngles(graphDataList); + calibrationLogWrite(m_admtController->calibrate( + vector(graphDataList.begin(), graphDataList.end()), cycleCount, samplesPerCycle, + false)); // TODO: Hard-coded Clockwise + populateAngleErrorGraphs(); + toggleCalibrationButtonState(2); + } + } catch(FileManagerException &ex) { + calibrationLogWrite(QString(ex.what())); + } +} + +void HarmonicCalibration::extractCalibrationData() +{ + QStringList filter; + filter += QString(tr("Comma-separated values files (*.csv)")); + filter += QString(tr("Tab-delimited values files (*.txt)")); + filter += QString(tr("All Files(*)")); + + QString selectedFilter = filter[0]; + + QString fileName = QFileDialog::getSaveFileName(this, tr("Export"), "", filter.join(";;"), &selectedFilter, + QFileDialog::Options()); + + if(fileName.split(".").size() <= 1) { + QString ext = selectedFilter.split(".")[1].split(")")[0]; + fileName += "." + ext; + } + + if(!fileName.isEmpty()) { + bool withScopyHeader = false; + FileManager fm("HarmonicCalibration"); + fm.open(fileName, FileManager::EXPORT); + + QVector preCalibrationAngleErrorsFFTMagnitude(m_admtController->angle_errors_fft_pre.begin(), + m_admtController->angle_errors_fft_pre.end()); + QVector preCalibrationAngleErrorsFFTPhase(m_admtController->angle_errors_fft_phase_pre.begin(), + m_admtController->angle_errors_fft_phase_pre.end()); + + QVector h1Mag = {H1_MAG_ANGLE}; + QVector h2Mag = {H2_MAG_ANGLE}; + QVector h3Mag = {H3_MAG_ANGLE}; + QVector h8Mag = {H8_MAG_ANGLE}; + QVector h1Phase = {H1_PHASE_ANGLE}; + QVector h2Phase = {H2_PHASE_ANGLE}; + QVector h3Phase = {H3_PHASE_ANGLE}; + QVector h8Phase = {H8_PHASE_ANGLE}; + + fm.save(graphDataList, "Raw Data"); + fm.save(preCalibrationAngleErrorsFFTMagnitude, "Pre-Calibration Angle Errors FFT Magnitude"); + fm.save(preCalibrationAngleErrorsFFTPhase, "Pre-Calibration Angle Errors FFT Phase"); + fm.save(h1Mag, "H1 Mag"); + fm.save(h2Mag, "H2 Mag"); + fm.save(h3Mag, "H3 Mag"); + fm.save(h8Mag, "H8 Mag"); + fm.save(h1Phase, "H1 Phase"); + fm.save(h2Phase, "H2 Phase"); + fm.save(h3Phase, "H3 Phase"); + fm.save(h8Phase, "H8 Phase"); + + fm.performWrite(withScopyHeader); + } +} + +void HarmonicCalibration::toggleTabSwitching(bool value) +{ + tabWidget->setTabEnabled(0, value); + tabWidget->setTabEnabled(2, value); + tabWidget->setTabEnabled(3, value); +} + +void HarmonicCalibration::toggleCalibrationButtonState(int state) +{ + switch(state) { + case 0: // Idle + calibrationStartMotorButton->setEnabled(true); + calibrationStartMotorButton->setChecked(false); + calibrateDataButton->setEnabled(false); + calibrateDataButton->setChecked(false); + clearCalibrateDataButton->setEnabled(true); + break; + case 1: // Start Motor + calibrationStartMotorButton->setEnabled(true); + calibrateDataButton->setEnabled(false); + clearCalibrateDataButton->setEnabled(false); + break; + case 2: // After Start Motor + calibrationStartMotorButton->setEnabled(false); + calibrateDataButton->setEnabled(true); + calibrateDataButton->setChecked(false); + clearCalibrateDataButton->setEnabled(true); + break; + case 3: // Post-Calibration + calibrationStartMotorButton->setEnabled(false); + calibrateDataButton->setEnabled(true); + clearCalibrateDataButton->setEnabled(false); + break; + case 4: // After Post-Calibration + calibrationStartMotorButton->setEnabled(false); + calibrateDataButton->setEnabled(false); + clearCalibrateDataButton->setEnabled(true); + break; + } +} + +void HarmonicCalibration::canStartMotor(bool value) { calibrationStartMotorButton->setEnabled(value); } + +void HarmonicCalibration::canCalibrate(bool value) { calibrateDataButton->setEnabled(value); } + +void HarmonicCalibration::toggleCalibrationControls(bool value) +{ + // motorMaxVelocitySpinBox->setEnabled(value); + // motorAccelTimeSpinBox->setEnabled(value); + // motorMaxDisplacementSpinBox->setEnabled(value); + // m_calibrationMotorRampModeMenuCombo->setEnabled(value); + motorTargetPositionLineEdit->setEnabled(value); + calibrationModeMenuCombo->setEnabled(value); +} + +void HarmonicCalibration::clearCalibrationSamples() +{ + graphDataList.clear(); + calibrationRawDataPlotChannel->curve()->setData(nullptr); + calibrationSineDataPlotChannel->curve()->setData(nullptr); + calibrationCosineDataPlotChannel->curve()->setData(nullptr); + calibrationRawDataPlotWidget->replot(); +} + +void HarmonicCalibration::clearCalibrationSineCosine() +{ + calibrationSineDataPlotChannel->curve()->setData(nullptr); + calibrationCosineDataPlotChannel->curve()->setData(nullptr); + calibrationRawDataPlotWidget->replot(); +} + +void HarmonicCalibration::clearPostCalibrationSamples() +{ + graphPostDataList.clear(); + postCalibrationRawDataPlotChannel->curve()->setData(nullptr); + postCalibrationSineDataPlotChannel->curve()->setData(nullptr); + postCalibrationCosineDataPlotChannel->curve()->setData(nullptr); + postCalibrationRawDataPlotWidget->replot(); +} + +void HarmonicCalibration::clearAngleErrorGraphs() +{ + angleErrorPlotChannel->curve()->setData(nullptr); + angleErrorPlotWidget->replot(); + FFTAngleErrorMagnitudeChannel->curve()->setData(nullptr); + FFTAngleErrorPhaseChannel->curve()->setData(nullptr); + FFTAngleErrorPlotWidget->replot(); +} + +void HarmonicCalibration::clearCorrectedAngleErrorGraphs() +{ + correctedErrorPlotChannel->curve()->setData(nullptr); + correctedErrorPlotWidget->replot(); + FFTCorrectedErrorMagnitudeChannel->curve()->setData(nullptr); + FFTCorrectedErrorPhaseChannel->curve()->setData(nullptr); + FFTCorrectedErrorPlotWidget->replot(); } #pragma endregion #pragma region Motor Methods -bool HarmonicCalibration::moveMotorToPosition(double &position, bool validate) { - bool success = false; - bool canRead = true; - if (writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, - position) == 0) { - if (validate) { - if (readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, - current_pos) == 0) { - while (target_pos != current_pos && canRead) { - canRead = - readMotorAttributeValue( - ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0 - ? true - : false; - } - if (canRead) - success = true; - } - } - } - - return success; -} - -void HarmonicCalibration::moveMotorContinuous() { - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, - rotate_vmax); - setRampMode(isMotorRotationClockwise); -} - -bool HarmonicCalibration::resetCurrentPositionToZero() { - bool success = false; - if (readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, - current_pos) == 0) { - if (current_pos != 0 && - writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, - 0) == 0 && - readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, - current_pos) == 0) { - while (current_pos != 0) { - if (readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, - current_pos) != 0) - break; - QThread::msleep(readMotorDebounce); - } - if (current_pos == 0) { - resetToZero = false; - success = true; - } - } else { - success = true; - } - } - - return success; -} - -void HarmonicCalibration::stopMotor() { - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); -} - -int HarmonicCalibration::readMotorAttributeValue( - ADMTController::MotorAttribute attribute, double &value) { - int result = -1; - if (!isDebug) { - result = m_admtController->getDeviceAttributeValue( - m_admtController->getDeviceId(ADMTController::Device::TMC5240), - m_admtController->getMotorAttribute(attribute), &value); - } - return result; -} - -int HarmonicCalibration::writeMotorAttributeValue( - ADMTController::MotorAttribute attribute, double value) { - int result = -1; - if (!isDebug) { - result = m_admtController->setDeviceAttributeValue( - m_admtController->getDeviceId(ADMTController::Device::TMC5240), - m_admtController->getMotorAttribute(attribute), value); - } - return result; -} - -int HarmonicCalibration::readMotorRegisterValue(uint32_t address, - uint32_t *value) { - int result = -1; - result = m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::TMC5240), address, - value); - return result; -} - -void HarmonicCalibration::setRampMode(bool motorRotationClockwise) { - // Ramp Mode 1: Clockwise, Ramp Mode 2: Counter-Clockwise - isMotorRotationClockwise = motorRotationClockwise; - int mode = isMotorRotationClockwise ? 1 : 2; - writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, mode); -} - -void HarmonicCalibration::getRampMode() { - readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); - // Ramp Mode 1: Counter-Clockwise, Ramp Mode 2: Clockwise - if (ramp_mode == 1) - isMotorRotationClockwise = false; - else if (ramp_mode == 2) - isMotorRotationClockwise = true; +bool HarmonicCalibration::moveMotorToPosition(double &position, bool validate) +{ + bool success = false; + bool canRead = true; + if(writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, position) == 0) { + if(validate) { + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) { + while(target_pos != current_pos && canRead) { + canRead = readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, + current_pos) == 0 + ? true + : false; + } + if(canRead) + success = true; + } + } + } + + return success; +} + +void HarmonicCalibration::moveMotorContinuous() +{ + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + setRampMode(isMotorRotationClockwise); +} + +bool HarmonicCalibration::resetCurrentPositionToZero() +{ + bool success = false; + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) { + if(current_pos != 0 && writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0) == 0 && + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) { + while(current_pos != 0) { + if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) != + 0) + break; + QThread::msleep(readMotorDebounce); + } + if(current_pos == 0) { + resetToZero = false; + success = true; + } + } else { + success = true; + } + } + + return success; +} + +void HarmonicCalibration::stopMotor() { writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); } + +int HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute attribute, double &value) +{ + int result = -1; + if(!isDebug) { + result = m_admtController->getDeviceAttributeValue( + m_admtController->getDeviceId(ADMTController::Device::TMC5240), + m_admtController->getMotorAttribute(attribute), &value); + } + return result; +} + +int HarmonicCalibration::writeMotorAttributeValue(ADMTController::MotorAttribute attribute, double value) +{ + int result = -1; + if(!isDebug) { + result = m_admtController->setDeviceAttributeValue( + m_admtController->getDeviceId(ADMTController::Device::TMC5240), + m_admtController->getMotorAttribute(attribute), value); + } + return result; +} + +int HarmonicCalibration::readMotorRegisterValue(uint32_t address, uint32_t *value) +{ + int result = -1; + result = m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::TMC5240), + address, value); + return result; +} + +void HarmonicCalibration::setRampMode(bool motorRotationClockwise) +{ + // Ramp Mode 1: Clockwise, Ramp Mode 2: Counter-Clockwise + isMotorRotationClockwise = motorRotationClockwise; + int mode = isMotorRotationClockwise ? 1 : 2; + writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, mode); +} + +void HarmonicCalibration::getRampMode() +{ + readMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, ramp_mode); + // Ramp Mode 1: Counter-Clockwise, Ramp Mode 2: Clockwise + if(ramp_mode == 1) + isMotorRotationClockwise = false; + else if(ramp_mode == 2) + isMotorRotationClockwise = true; } #pragma endregion #pragma region Utility Methods -void HarmonicCalibration::startUtilityTask() { - if (!m_utilityThread.isRunning()) { - isUtilityTab = true; - m_utilityThread = QtConcurrent::run(this, &HarmonicCalibration::utilityTask, - utilityUITimerRate); - m_utilityWatcher.setFuture(m_utilityThread); - } -} - -void HarmonicCalibration::stopUtilityTask() { - isUtilityTab = false; - if (m_utilityThread.isRunning()) { - m_utilityThread.cancel(); - m_utilityWatcher.waitForFinished(); - } -} - -void HarmonicCalibration::utilityTask(int sampleRate) { - while (isUtilityTab) { - getDIGIOENRegister(); - getFAULTRegister(); - if (hasMTDiagnostics) { - getDIAG1Register(); - getDIAG2Register(); - } - - Q_EMIT commandLogWriteSignal(""); - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::toggleUtilityTask(bool run) { - if (run) { - startUtilityTask(); - } else { - stopUtilityTask(); - } -} - -void HarmonicCalibration::getDIGIOENRegister() { - uint32_t *digioRegValue = new uint32_t; - uint32_t digioEnPage = m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::DIGIOEN); - if (changeCNVPage(digioEnPage)) { - uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::DIGIOEN); - - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - digioRegisterAddress, digioRegValue) != -1) { - uint16_t *digioRegValue16 = new uint16_t; - *digioRegValue16 = static_cast(*digioRegValue); - - Q_EMIT DIGIORegisterChanged(digioRegValue16); - - Q_EMIT commandLogWriteSignal( - "DIGIOEN: 0b" + - QString::number(*digioRegValue, 2).rightJustified(16, '0')); - - delete digioRegValue16; - } else { - Q_EMIT commandLogWriteSignal("Failed to read DIGIOEN Register"); - } - } - - delete digioRegValue; -} - -void HarmonicCalibration::updateDIGIOUI(uint16_t *registerValue) { - DIGIOENRegisterMap = - m_admtController->getDIGIOENRegisterBitMapping(*registerValue); - updateDIGIOMonitorUI(); - updateDIGIOControlUI(); -} - -void HarmonicCalibration::updateDIGIOMonitorUI() { - map registerMap = DIGIOENRegisterMap; - DIGIOBusyStatusLED->setChecked(registerMap.at("BUSY")); - DIGIOCNVStatusLED->setChecked(registerMap.at("CNV")); - DIGIOSENTStatusLED->setChecked(registerMap.at("SENT")); - DIGIOACALCStatusLED->setChecked(registerMap.at("ACALC")); - DIGIOFaultStatusLED->setChecked(registerMap.at("FAULT")); - DIGIOBootloaderStatusLED->setChecked(registerMap.at("BOOTLOAD")); - - if (!registerMap.at("BUSY")) - DIGIOBusyStatusLED->setText("BUSY (Output)"); - else { - if (registerMap.at("DIGIO0EN")) - DIGIOBusyStatusLED->setText("GPIO0 (Output)"); - else - DIGIOBusyStatusLED->setText("GPIO0 (Input)"); - } - - if (!registerMap.at("CNV")) - DIGIOCNVStatusLED->setText("CNV (Input)"); - else { - if (registerMap.at("DIGIO1EN")) - DIGIOCNVStatusLED->setText("GPIO1 (Output)"); - else - DIGIOCNVStatusLED->setText("GPIO1 (Input)"); - } - - if (!registerMap.at("SENT")) - DIGIOSENTStatusLED->setText("SENT (Output)"); - else { - if (registerMap.at("DIGIO2EN")) - DIGIOSENTStatusLED->setText("GPIO2 (Output)"); - else - DIGIOSENTStatusLED->setText("GPIO2 (Input)"); - } - - if (!registerMap.at("ACALC")) - DIGIOACALCStatusLED->setText("ACALC (Output)"); - else { - if (registerMap.at("DIGIO3EN")) - DIGIOACALCStatusLED->setText("GPIO3 (Output)"); - else - DIGIOACALCStatusLED->setText("GPIO3 (Input)"); - } - - if (!registerMap.at("FAULT")) - DIGIOFaultStatusLED->setText("FAULT (Output)"); - else { - if (registerMap.at("DIGIO4EN")) - DIGIOFaultStatusLED->setText("GPIO4 (Output)"); - else - DIGIOFaultStatusLED->setText("GPIO4 (Input)"); - } - - if (!registerMap.at("BOOTLOAD")) - DIGIOBootloaderStatusLED->setText("BOOTLOAD (Output)"); - else { - if (registerMap.at("DIGIO5EN")) - DIGIOBootloaderStatusLED->setText("GPIO5 (Output)"); - else - DIGIOBootloaderStatusLED->setText("GPIO5 (Input)"); - } -} - -void HarmonicCalibration::updateDIGIOControlUI() { - map registerMap = DIGIOENRegisterMap; - - DIGIO0ENToggleSwitch->setChecked(registerMap.at("DIGIO0EN")); - DIGIO1ENToggleSwitch->setChecked(registerMap.at("DIGIO1EN")); - DIGIO2ENToggleSwitch->setChecked(registerMap.at("DIGIO2EN")); - DIGIO3ENToggleSwitch->setChecked(registerMap.at("DIGIO3EN")); - DIGIO4ENToggleSwitch->setChecked(registerMap.at("DIGIO4EN")); - DIGIO5ENToggleSwitch->setChecked(registerMap.at("DIGIO5EN")); - DIGIO0FNCToggleSwitch->setChecked(registerMap.at("BUSY")); - DIGIO1FNCToggleSwitch->setChecked(registerMap.at("CNV")); - DIGIO2FNCToggleSwitch->setChecked(registerMap.at("SENT")); - DIGIO3FNCToggleSwitch->setChecked(registerMap.at("ACALC")); - DIGIO4FNCToggleSwitch->setChecked(registerMap.at("FAULT")); - DIGIO5FNCToggleSwitch->setChecked(registerMap.at("BOOTLOAD")); -} - -void HarmonicCalibration::getDIAG2Register() { - uint32_t *mtDiag2RegValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t mtDiag2RegisterAddress = m_admtController->getSensorRegister( - ADMTController::SensorRegister::DIAG2); - uint32_t mtDiag2PageValue = - m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2); - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::CNVPAGE); - - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, mtDiag2PageValue) != -1) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, cnvPageRegValue) != -1) { - if (*cnvPageRegValue == mtDiag2PageValue) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - mtDiag2RegisterAddress, mtDiag2RegValue) != -1) { - uint16_t *mtDiag2RegValue16 = new uint16_t; - *mtDiag2RegValue16 = static_cast(*mtDiag2RegValue); - - Q_EMIT DIAG2RegisterChanged(mtDiag2RegValue16); - - Q_EMIT commandLogWriteSignal( - "DIAG2: 0b" + - QString::number(*mtDiag2RegValue, 2).rightJustified(16, '0')); - - delete mtDiag2RegValue16; - } else { - Q_EMIT commandLogWriteSignal( - "Failed to read MT Diagnostic 2 Register"); - } - } else { - Q_EMIT commandLogWriteSignal( - "CNVPAGE for MT Diagnostic 2 is a different value, abort reading"); - } - } else { - Q_EMIT commandLogWriteSignal( - "Failed to read CNVPAGE for MT Diagnostic 2"); - } - } else { - Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 2"); - } - - delete mtDiag2RegValue, cnvPageRegValue; -} - -void HarmonicCalibration::updateMTDiagnosticsUI(uint16_t *registerValue) { - DIAG2RegisterMap = - m_admtController->getDiag2RegisterBitMapping(*registerValue); - - map regmap = DIAG2RegisterMap; - afeDiag0 = regmap.at("AFE Diagnostic 0 (-57%)"); - afeDiag1 = regmap.at("AFE Diagnostic 1 (+57%)"); - AFEDIAG0LineEdit->setText(QString::number(afeDiag0) + " V"); - AFEDIAG1LineEdit->setText(QString::number(afeDiag1) + " V"); -} - -void HarmonicCalibration::getDIAG1Register() { - uint32_t *mtDiag1RegValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister( - ADMTController::SensorRegister::DIAG1); - uint32_t mtDiag1PageValue = - m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); - uint32_t cnvPageAddress = m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::CNVPAGE); - - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, mtDiag1PageValue) != -1) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, cnvPageRegValue) != -1) { - if (*cnvPageRegValue == mtDiag1PageValue) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - mtDiag1RegisterAddress, mtDiag1RegValue) != -1) { - uint16_t *mtDiag1RegValue16 = new uint16_t; - *mtDiag1RegValue16 = static_cast(*mtDiag1RegValue); - Q_EMIT DIAG1RegisterChanged(mtDiag1RegValue16); - - Q_EMIT commandLogWriteSignal( - "DIAG1: 0b" + - QString::number(*mtDiag1RegValue16, 2).rightJustified(16, '0')); - - delete mtDiag1RegValue16; - } else { - Q_EMIT commandLogWriteSignal( - "Failed to read MT Diagnostic 1 Register"); - } - } else { - Q_EMIT commandLogWriteSignal( - "CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); - } - } else { - Q_EMIT commandLogWriteSignal( - "Failed to read CNVPAGE for MT Diagnostic 1"); - } - } else { - Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 1"); - } - - delete mtDiag1RegValue, cnvPageRegValue; -} - -void HarmonicCalibration::updateMTDiagnosticRegisterUI( - uint16_t *registerValue) { - DIAG1RegisterMap = - m_admtController->getDiag1RegisterBitMapping_Register(*registerValue); - DIAG1AFERegisterMap = - m_admtController->getDiag1RegisterBitMapping_Afe(*registerValue, is5V); - - map regmap = DIAG1RegisterMap; - map afeRegmap = DIAG1AFERegisterMap; - R0StatusLED->setChecked(regmap.at("R0")); - R1StatusLED->setChecked(regmap.at("R1")); - R2StatusLED->setChecked(regmap.at("R2")); - R3StatusLED->setChecked(regmap.at("R3")); - R4StatusLED->setChecked(regmap.at("R4")); - R5StatusLED->setChecked(regmap.at("R5")); - R6StatusLED->setChecked(regmap.at("R6")); - R7StatusLED->setChecked(regmap.at("R7")); - afeDiag2 = afeRegmap.at("AFE Diagnostic 2"); - AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); -} - -void HarmonicCalibration::getFAULTRegister() { - uint32_t *faultRegValue = new uint32_t; - uint32_t faultRegisterAddress = m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::FAULT); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - faultRegisterAddress, 0); // Write all zeros to fault before read - - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - faultRegisterAddress, faultRegValue) != -1) { - uint16_t *faultRegValue16 = new uint16_t; - *faultRegValue16 = static_cast(*faultRegValue); - - Q_EMIT FaultRegisterChanged(faultRegValue16); - - Q_EMIT commandLogWriteSignal( - "FAULT: 0b" + - QString::number(*faultRegValue, 2).rightJustified(16, '0')); - - delete faultRegValue16; - } else { - Q_EMIT commandLogWriteSignal("Failed to read FAULT Register"); - } - - delete faultRegValue; -} - -void HarmonicCalibration::updateFaultRegisterUI(uint16_t *faultRegValue) { - FAULTRegisterMap = - m_admtController->getFaultRegisterBitMapping(*faultRegValue); - - map regmap = FAULTRegisterMap; - VDDUnderVoltageStatusLED->setChecked(regmap.at("VDD Under Voltage")); - VDDOverVoltageStatusLED->setChecked(regmap.at("VDD Over Voltage")); - VDRIVEUnderVoltageStatusLED->setChecked(regmap.at("VDRIVE Under Voltage")); - VDRIVEOverVoltageStatusLED->setChecked(regmap.at("VDRIVE Over Voltage")); - AFEDIAGStatusLED->setChecked(regmap.at("AFE Diagnostic")); - NVMCRCFaultStatusLED->setChecked(regmap.at("NVM CRC Fault")); - ECCDoubleBitErrorStatusLED->setChecked(regmap.at("ECC Double Bit Error")); - OscillatorDriftStatusLED->setChecked(regmap.at("Oscillator Drift")); - CountSensorFalseStateStatusLED->setChecked( - regmap.at("Count Sensor False State")); - AngleCrossCheckStatusLED->setChecked(regmap.at("Angle Cross Check")); - TurnCountSensorLevelsStatusLED->setChecked( - regmap.at("Turn Count Sensor Levels")); - MTDIAGStatusLED->setChecked(regmap.at("MT Diagnostic")); - TurnCounterCrossCheckStatusLED->setChecked( - regmap.at("Turn Counter Cross Check")); - RadiusCheckStatusLED->setChecked(regmap.at("AMR Radius Check")); - SequencerWatchdogStatusLED->setChecked(regmap.at("Sequencer Watchdog")); -} - -void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) { - toggleUtilityTask(false); - - uint32_t *DIGIOENRegisterValue = new uint32_t; - uint32_t DIGIOENPage = m_admtController->getConfigurationPage( - ADMTController::ConfigurationRegister::DIGIOEN); - - if (changeCNVPage(DIGIOENPage)) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) { - map DIGIOSettings = - m_admtController->getDIGIOENRegisterBitMapping( - static_cast(*DIGIOENRegisterValue)); - - DIGIOSettings.at(DIGIOENName) = value; - - uint16_t newRegisterValue = - m_admtController->setDIGIOENRegisterBitMapping( - static_cast(*DIGIOENRegisterValue), DIGIOSettings); - - if (changeCNVPage(DIGIOENPage)) { - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::DIGIOEN), - static_cast(newRegisterValue)) != -1) { - updateDIGIOControlUI(); - } - } - } - } - - toggleUtilityTask(true); -} - -void HarmonicCalibration::toggleMTDiagnostics(int mode) { - switch (mode) { - case 0: - MTDiagnosticsScrollArea->hide(); - hasMTDiagnostics = false; - break; - case 1: - MTDiagnosticsScrollArea->show(); - hasMTDiagnostics = true; - break; - } -} - -void HarmonicCalibration::toggleFaultRegisterMode(int mode) { - switch (mode) { - case 0: - AFEDIAGStatusLED->hide(); - OscillatorDriftStatusLED->hide(); - AngleCrossCheckStatusLED->hide(); - TurnCountSensorLevelsStatusLED->hide(); - MTDIAGStatusLED->hide(); - SequencerWatchdogStatusLED->hide(); - break; - case 1: - AFEDIAGStatusLED->show(); - OscillatorDriftStatusLED->show(); - AngleCrossCheckStatusLED->show(); - TurnCountSensorLevelsStatusLED->show(); - MTDIAGStatusLED->show(); - SequencerWatchdogStatusLED->show(); - break; - } -} - -bool HarmonicCalibration::resetDIGIO() { - return (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::DIGIOEN), - 0x241b) == 0 - ? true - : false); -} - -void HarmonicCalibration::commandLogWrite(QString message) { - commandLogPlainTextEdit->appendPlainText(message); -} - -void HarmonicCalibration::clearCommandLog() { - commandLogPlainTextEdit->clear(); -} +void HarmonicCalibration::startUtilityTask() +{ + if(!m_utilityThread.isRunning()) { + isUtilityTab = true; + m_utilityThread = QtConcurrent::run(this, &HarmonicCalibration::utilityTask, utilityUITimerRate); + m_utilityWatcher.setFuture(m_utilityThread); + } +} + +void HarmonicCalibration::stopUtilityTask() +{ + isUtilityTab = false; + if(m_utilityThread.isRunning()) { + m_utilityThread.cancel(); + m_utilityWatcher.waitForFinished(); + } +} + +void HarmonicCalibration::utilityTask(int sampleRate) +{ + while(isUtilityTab) { + getDIGIOENRegister(); + getFAULTRegister(); + if(hasMTDiagnostics) { + getDIAG1Register(); + getDIAG2Register(); + } + + Q_EMIT commandLogWriteSignal(""); + + QThread::msleep(sampleRate); + } +} + +void HarmonicCalibration::toggleUtilityTask(bool run) +{ + if(run) { + startUtilityTask(); + } else { + stopUtilityTask(); + } +} + +void HarmonicCalibration::getDIGIOENRegister() +{ + uint32_t *digioRegValue = new uint32_t; + uint32_t digioEnPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + if(changeCNVPage(digioEnPage)) { + uint32_t digioRegisterAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN); + + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + digioRegisterAddress, digioRegValue) != -1) { + uint16_t *digioRegValue16 = new uint16_t; + *digioRegValue16 = static_cast(*digioRegValue); + + Q_EMIT DIGIORegisterChanged(digioRegValue16); + + Q_EMIT commandLogWriteSignal("DIGIOEN: 0b" + + QString::number(*digioRegValue, 2).rightJustified(16, '0')); + + delete digioRegValue16; + } else { + Q_EMIT commandLogWriteSignal("Failed to read DIGIOEN Register"); + } + } + + delete digioRegValue; +} + +void HarmonicCalibration::updateDIGIOUI(uint16_t *registerValue) +{ + DIGIOENRegisterMap = m_admtController->getDIGIOENRegisterBitMapping(*registerValue); + updateDIGIOMonitorUI(); + updateDIGIOControlUI(); +} + +void HarmonicCalibration::updateDIGIOMonitorUI() +{ + map registerMap = DIGIOENRegisterMap; + DIGIOBusyStatusLED->setChecked(registerMap.at("BUSY")); + DIGIOCNVStatusLED->setChecked(registerMap.at("CNV")); + DIGIOSENTStatusLED->setChecked(registerMap.at("SENT")); + DIGIOACALCStatusLED->setChecked(registerMap.at("ACALC")); + DIGIOFaultStatusLED->setChecked(registerMap.at("FAULT")); + DIGIOBootloaderStatusLED->setChecked(registerMap.at("BOOTLOAD")); + + if(!registerMap.at("BUSY")) + DIGIOBusyStatusLED->setText("BUSY (Output)"); + else { + if(registerMap.at("DIGIO0EN")) + DIGIOBusyStatusLED->setText("GPIO0 (Output)"); + else + DIGIOBusyStatusLED->setText("GPIO0 (Input)"); + } + + if(!registerMap.at("CNV")) + DIGIOCNVStatusLED->setText("CNV (Input)"); + else { + if(registerMap.at("DIGIO1EN")) + DIGIOCNVStatusLED->setText("GPIO1 (Output)"); + else + DIGIOCNVStatusLED->setText("GPIO1 (Input)"); + } + + if(!registerMap.at("SENT")) + DIGIOSENTStatusLED->setText("SENT (Output)"); + else { + if(registerMap.at("DIGIO2EN")) + DIGIOSENTStatusLED->setText("GPIO2 (Output)"); + else + DIGIOSENTStatusLED->setText("GPIO2 (Input)"); + } + + if(!registerMap.at("ACALC")) + DIGIOACALCStatusLED->setText("ACALC (Output)"); + else { + if(registerMap.at("DIGIO3EN")) + DIGIOACALCStatusLED->setText("GPIO3 (Output)"); + else + DIGIOACALCStatusLED->setText("GPIO3 (Input)"); + } + + if(!registerMap.at("FAULT")) + DIGIOFaultStatusLED->setText("FAULT (Output)"); + else { + if(registerMap.at("DIGIO4EN")) + DIGIOFaultStatusLED->setText("GPIO4 (Output)"); + else + DIGIOFaultStatusLED->setText("GPIO4 (Input)"); + } + + if(!registerMap.at("BOOTLOAD")) + DIGIOBootloaderStatusLED->setText("BOOTLOAD (Output)"); + else { + if(registerMap.at("DIGIO5EN")) + DIGIOBootloaderStatusLED->setText("GPIO5 (Output)"); + else + DIGIOBootloaderStatusLED->setText("GPIO5 (Input)"); + } +} + +void HarmonicCalibration::updateDIGIOControlUI() +{ + map registerMap = DIGIOENRegisterMap; + + DIGIO0ENToggleSwitch->setChecked(registerMap.at("DIGIO0EN")); + DIGIO1ENToggleSwitch->setChecked(registerMap.at("DIGIO1EN")); + DIGIO2ENToggleSwitch->setChecked(registerMap.at("DIGIO2EN")); + DIGIO3ENToggleSwitch->setChecked(registerMap.at("DIGIO3EN")); + DIGIO4ENToggleSwitch->setChecked(registerMap.at("DIGIO4EN")); + DIGIO5ENToggleSwitch->setChecked(registerMap.at("DIGIO5EN")); + DIGIO0FNCToggleSwitch->setChecked(registerMap.at("BUSY")); + DIGIO1FNCToggleSwitch->setChecked(registerMap.at("CNV")); + DIGIO2FNCToggleSwitch->setChecked(registerMap.at("SENT")); + DIGIO3FNCToggleSwitch->setChecked(registerMap.at("ACALC")); + DIGIO4FNCToggleSwitch->setChecked(registerMap.at("FAULT")); + DIGIO5FNCToggleSwitch->setChecked(registerMap.at("BOOTLOAD")); +} + +void HarmonicCalibration::getDIAG2Register() +{ + uint32_t *mtDiag2RegValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t mtDiag2RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG2); + uint32_t mtDiag2PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2); + uint32_t cnvPageAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, mtDiag2PageValue) != -1) { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) != -1) { + if(*cnvPageRegValue == mtDiag2PageValue) { + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + mtDiag2RegisterAddress, mtDiag2RegValue) != -1) { + uint16_t *mtDiag2RegValue16 = new uint16_t; + *mtDiag2RegValue16 = static_cast(*mtDiag2RegValue); + + Q_EMIT DIAG2RegisterChanged(mtDiag2RegValue16); + + Q_EMIT commandLogWriteSignal( + "DIAG2: 0b" + + QString::number(*mtDiag2RegValue, 2).rightJustified(16, '0')); + + delete mtDiag2RegValue16; + } else { + Q_EMIT commandLogWriteSignal("Failed to read MT Diagnostic 2 Register"); + } + } else { + Q_EMIT commandLogWriteSignal( + "CNVPAGE for MT Diagnostic 2 is a different value, abort reading"); + } + } else { + Q_EMIT commandLogWriteSignal("Failed to read CNVPAGE for MT Diagnostic 2"); + } + } else { + Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 2"); + } + + delete mtDiag2RegValue, cnvPageRegValue; +} + +void HarmonicCalibration::updateMTDiagnosticsUI(uint16_t *registerValue) +{ + DIAG2RegisterMap = m_admtController->getDiag2RegisterBitMapping(*registerValue); + + map regmap = DIAG2RegisterMap; + afeDiag0 = regmap.at("AFE Diagnostic 0 (-57%)"); + afeDiag1 = regmap.at("AFE Diagnostic 1 (+57%)"); + AFEDIAG0LineEdit->setText(QString::number(afeDiag0) + " V"); + AFEDIAG1LineEdit->setText(QString::number(afeDiag1) + " V"); +} + +void HarmonicCalibration::getDIAG1Register() +{ + uint32_t *mtDiag1RegValue = new uint32_t; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1); + uint32_t mtDiag1PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); + uint32_t cnvPageAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, mtDiag1PageValue) != -1) { + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) != -1) { + if(*cnvPageRegValue == mtDiag1PageValue) { + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + mtDiag1RegisterAddress, mtDiag1RegValue) != -1) { + uint16_t *mtDiag1RegValue16 = new uint16_t; + *mtDiag1RegValue16 = static_cast(*mtDiag1RegValue); + Q_EMIT DIAG1RegisterChanged(mtDiag1RegValue16); + + Q_EMIT commandLogWriteSignal( + "DIAG1: 0b" + + QString::number(*mtDiag1RegValue16, 2).rightJustified(16, '0')); + + delete mtDiag1RegValue16; + } else { + Q_EMIT commandLogWriteSignal("Failed to read MT Diagnostic 1 Register"); + } + } else { + Q_EMIT commandLogWriteSignal( + "CNVPAGE for MT Diagnostic 1 is a different value, abort reading"); + } + } else { + Q_EMIT commandLogWriteSignal("Failed to read CNVPAGE for MT Diagnostic 1"); + } + } else { + Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 1"); + } + + delete mtDiag1RegValue, cnvPageRegValue; +} + +void HarmonicCalibration::updateMTDiagnosticRegisterUI(uint16_t *registerValue) +{ + DIAG1RegisterMap = m_admtController->getDiag1RegisterBitMapping_Register(*registerValue); + DIAG1AFERegisterMap = m_admtController->getDiag1RegisterBitMapping_Afe(*registerValue, is5V); + + map regmap = DIAG1RegisterMap; + map afeRegmap = DIAG1AFERegisterMap; + R0StatusLED->setChecked(regmap.at("R0")); + R1StatusLED->setChecked(regmap.at("R1")); + R2StatusLED->setChecked(regmap.at("R2")); + R3StatusLED->setChecked(regmap.at("R3")); + R4StatusLED->setChecked(regmap.at("R4")); + R5StatusLED->setChecked(regmap.at("R5")); + R6StatusLED->setChecked(regmap.at("R6")); + R7StatusLED->setChecked(regmap.at("R7")); + afeDiag2 = afeRegmap.at("AFE Diagnostic 2"); + AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); +} + +void HarmonicCalibration::getFAULTRegister() +{ + uint32_t *faultRegValue = new uint32_t; + uint32_t faultRegisterAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT); + m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + faultRegisterAddress, 0); // Write all zeros to fault before read + + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + faultRegisterAddress, faultRegValue) != -1) { + uint16_t *faultRegValue16 = new uint16_t; + *faultRegValue16 = static_cast(*faultRegValue); + + Q_EMIT FaultRegisterChanged(faultRegValue16); + + Q_EMIT commandLogWriteSignal("FAULT: 0b" + QString::number(*faultRegValue, 2).rightJustified(16, '0')); + + delete faultRegValue16; + } else { + Q_EMIT commandLogWriteSignal("Failed to read FAULT Register"); + } + + delete faultRegValue; +} + +void HarmonicCalibration::updateFaultRegisterUI(uint16_t *faultRegValue) +{ + FAULTRegisterMap = m_admtController->getFaultRegisterBitMapping(*faultRegValue); + + map regmap = FAULTRegisterMap; + VDDUnderVoltageStatusLED->setChecked(regmap.at("VDD Under Voltage")); + VDDOverVoltageStatusLED->setChecked(regmap.at("VDD Over Voltage")); + VDRIVEUnderVoltageStatusLED->setChecked(regmap.at("VDRIVE Under Voltage")); + VDRIVEOverVoltageStatusLED->setChecked(regmap.at("VDRIVE Over Voltage")); + AFEDIAGStatusLED->setChecked(regmap.at("AFE Diagnostic")); + NVMCRCFaultStatusLED->setChecked(regmap.at("NVM CRC Fault")); + ECCDoubleBitErrorStatusLED->setChecked(regmap.at("ECC Double Bit Error")); + OscillatorDriftStatusLED->setChecked(regmap.at("Oscillator Drift")); + CountSensorFalseStateStatusLED->setChecked(regmap.at("Count Sensor False State")); + AngleCrossCheckStatusLED->setChecked(regmap.at("Angle Cross Check")); + TurnCountSensorLevelsStatusLED->setChecked(regmap.at("Turn Count Sensor Levels")); + MTDIAGStatusLED->setChecked(regmap.at("MT Diagnostic")); + TurnCounterCrossCheckStatusLED->setChecked(regmap.at("Turn Counter Cross Check")); + RadiusCheckStatusLED->setChecked(regmap.at("AMR Radius Check")); + SequencerWatchdogStatusLED->setChecked(regmap.at("Sequencer Watchdog")); +} + +void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) +{ + toggleUtilityTask(false); + + uint32_t *DIGIOENRegisterValue = new uint32_t; + uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + + if(changeCNVPage(DIGIOENPage)) { + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != -1) { + map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping( + static_cast(*DIGIOENRegisterValue)); + + DIGIOSettings.at(DIGIOENName) = value; + + uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping( + static_cast(*DIGIOENRegisterValue), DIGIOSettings); + + if(changeCNVPage(DIGIOENPage)) { + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::DIGIOEN), + static_cast(newRegisterValue)) != -1) { + updateDIGIOControlUI(); + } + } + } + } + + toggleUtilityTask(true); +} + +void HarmonicCalibration::toggleMTDiagnostics(int mode) +{ + switch(mode) { + case 0: + MTDiagnosticsScrollArea->hide(); + hasMTDiagnostics = false; + break; + case 1: + MTDiagnosticsScrollArea->show(); + hasMTDiagnostics = true; + break; + } +} + +void HarmonicCalibration::toggleFaultRegisterMode(int mode) +{ + switch(mode) { + case 0: + AFEDIAGStatusLED->hide(); + OscillatorDriftStatusLED->hide(); + AngleCrossCheckStatusLED->hide(); + TurnCountSensorLevelsStatusLED->hide(); + MTDIAGStatusLED->hide(); + SequencerWatchdogStatusLED->hide(); + break; + case 1: + AFEDIAGStatusLED->show(); + OscillatorDriftStatusLED->show(); + AngleCrossCheckStatusLED->show(); + TurnCountSensorLevelsStatusLED->show(); + MTDIAGStatusLED->show(); + SequencerWatchdogStatusLED->show(); + break; + } +} + +bool HarmonicCalibration::resetDIGIO() +{ + return (m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + 0x241b) == 0 + ? true + : false); +} + +void HarmonicCalibration::commandLogWrite(QString message) { commandLogPlainTextEdit->appendPlainText(message); } + +void HarmonicCalibration::clearCommandLog() { commandLogPlainTextEdit->clear(); } #pragma endregion #pragma region Register Methods -void HarmonicCalibration::readAllRegisters() { - readAllRegistersButton->setEnabled(false); - readAllRegistersButton->setText(QString("Reading Registers...")); - QTimer::singleShot(1000, this, [this]() { - readAllRegistersButton->setEnabled(true); - readAllRegistersButton->setText(QString("Read All Registers")); - }); - - cnvPageRegisterBlock->readButton()->click(); - digIORegisterBlock->readButton()->click(); - faultRegisterBlock->readButton()->click(); - generalRegisterBlock->readButton()->click(); - digIOEnRegisterBlock->readButton()->click(); - eccDcdeRegisterBlock->readButton()->click(); - eccDisRegisterBlock->readButton()->click(); - absAngleRegisterBlock->readButton()->click(); - angleRegisterBlock->readButton()->click(); - sineRegisterBlock->readButton()->click(); - cosineRegisterBlock->readButton()->click(); - tmp0RegisterBlock->readButton()->click(); - cnvCntRegisterBlock->readButton()->click(); - uniqID0RegisterBlock->readButton()->click(); - uniqID1RegisterBlock->readButton()->click(); - uniqID2RegisterBlock->readButton()->click(); - uniqID3RegisterBlock->readButton()->click(); - h1MagRegisterBlock->readButton()->click(); - h1PhRegisterBlock->readButton()->click(); - h2MagRegisterBlock->readButton()->click(); - h2PhRegisterBlock->readButton()->click(); - h3MagRegisterBlock->readButton()->click(); - h3PhRegisterBlock->readButton()->click(); - h8MagRegisterBlock->readButton()->click(); - h8PhRegisterBlock->readButton()->click(); - - if (GENERALRegisterMap.at("Sequence Type") == 1) { - angleSecRegisterBlock->readButton()->click(); - secAnglIRegisterBlock->readButton()->click(); - secAnglQRegisterBlock->readButton()->click(); - tmp1RegisterBlock->readButton()->click(); - angleCkRegisterBlock->readButton()->click(); - radiusRegisterBlock->readButton()->click(); - diag1RegisterBlock->readButton()->click(); - diag2RegisterBlock->readButton()->click(); - } -} - -void HarmonicCalibration::toggleRegisters(int mode) { - switch (mode) { - case 0: - angleSecRegisterBlock->hide(); - secAnglIRegisterBlock->hide(); - secAnglQRegisterBlock->hide(); - tmp1RegisterBlock->hide(); - angleCkRegisterBlock->hide(); - radiusRegisterBlock->hide(); - diag1RegisterBlock->hide(); - diag2RegisterBlock->hide(); - break; - case 1: - angleSecRegisterBlock->show(); - secAnglIRegisterBlock->show(); - secAnglQRegisterBlock->show(); - tmp1RegisterBlock->show(); - angleCkRegisterBlock->show(); - radiusRegisterBlock->show(); - diag1RegisterBlock->show(); - diag2RegisterBlock->show(); - break; - } +void HarmonicCalibration::readAllRegisters() +{ + readAllRegistersButton->setEnabled(false); + readAllRegistersButton->setText(QString("Reading Registers...")); + QTimer::singleShot(1000, this, [this]() { + readAllRegistersButton->setEnabled(true); + readAllRegistersButton->setText(QString("Read All Registers")); + }); + + cnvPageRegisterBlock->readButton()->click(); + digIORegisterBlock->readButton()->click(); + faultRegisterBlock->readButton()->click(); + generalRegisterBlock->readButton()->click(); + digIOEnRegisterBlock->readButton()->click(); + eccDcdeRegisterBlock->readButton()->click(); + eccDisRegisterBlock->readButton()->click(); + absAngleRegisterBlock->readButton()->click(); + angleRegisterBlock->readButton()->click(); + sineRegisterBlock->readButton()->click(); + cosineRegisterBlock->readButton()->click(); + tmp0RegisterBlock->readButton()->click(); + cnvCntRegisterBlock->readButton()->click(); + uniqID0RegisterBlock->readButton()->click(); + uniqID1RegisterBlock->readButton()->click(); + uniqID2RegisterBlock->readButton()->click(); + uniqID3RegisterBlock->readButton()->click(); + h1MagRegisterBlock->readButton()->click(); + h1PhRegisterBlock->readButton()->click(); + h2MagRegisterBlock->readButton()->click(); + h2PhRegisterBlock->readButton()->click(); + h3MagRegisterBlock->readButton()->click(); + h3PhRegisterBlock->readButton()->click(); + h8MagRegisterBlock->readButton()->click(); + h8PhRegisterBlock->readButton()->click(); + + if(GENERALRegisterMap.at("Sequence Type") == 1) { + angleSecRegisterBlock->readButton()->click(); + secAnglIRegisterBlock->readButton()->click(); + secAnglQRegisterBlock->readButton()->click(); + tmp1RegisterBlock->readButton()->click(); + angleCkRegisterBlock->readButton()->click(); + radiusRegisterBlock->readButton()->click(); + diag1RegisterBlock->readButton()->click(); + diag2RegisterBlock->readButton()->click(); + } +} + +void HarmonicCalibration::toggleRegisters(int mode) +{ + switch(mode) { + case 0: + angleSecRegisterBlock->hide(); + secAnglIRegisterBlock->hide(); + secAnglQRegisterBlock->hide(); + tmp1RegisterBlock->hide(); + angleCkRegisterBlock->hide(); + radiusRegisterBlock->hide(); + diag1RegisterBlock->hide(); + diag2RegisterBlock->hide(); + break; + case 1: + angleSecRegisterBlock->show(); + secAnglIRegisterBlock->show(); + secAnglQRegisterBlock->show(); + tmp1RegisterBlock->show(); + angleCkRegisterBlock->show(); + radiusRegisterBlock->show(); + diag1RegisterBlock->show(); + diag2RegisterBlock->show(); + break; + } } #pragma endregion #pragma region UI Helper Methods -void HarmonicCalibration::updateLabelValue(QLabel *label, int channelIndex) { - switch (channelIndex) { - case ADMTController::Channel::ROTATION: - label->setText(QString("%1").arg(rotation, 0, 'f', 2) + "°"); - break; - case ADMTController::Channel::ANGLE: - label->setText(QString("%1").arg(angle, 0, 'f', 2) + "°"); - break; - case ADMTController::Channel::COUNT: - label->setText(QString::number(count)); - break; - case ADMTController::Channel::TEMPERATURE: - label->setText(QString("%1").arg(temp, 0, 'f', 2) + "°C"); - break; - } -} - -void HarmonicCalibration::updateLabelValue( - QLabel *label, ADMTController::MotorAttribute attribute) { - switch (attribute) { - case ADMTController::MotorAttribute::AMAX: - label->setText(QString::number(amax)); - break; - case ADMTController::MotorAttribute::ROTATE_VMAX: - label->setText(QString::number(rotate_vmax)); - break; - case ADMTController::MotorAttribute::DMAX: - label->setText(QString::number(dmax)); - break; - case ADMTController::MotorAttribute::DISABLE: - label->setText(QString::number(disable)); - break; - case ADMTController::MotorAttribute::TARGET_POS: - label->setText(QString::number(target_pos)); - break; - case ADMTController::MotorAttribute::CURRENT_POS: - label->setText(QString::number(current_pos)); - break; - case ADMTController::MotorAttribute::RAMP_MODE: - label->setText(QString::number(ramp_mode)); - break; - } -} - -bool HarmonicCalibration::updateChannelValue(int channelIndex) { - bool success = false; - switch (channelIndex) { - case ADMTController::Channel::ROTATION: - rotation = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - rotationChannelName, 1); - if (rotation == static_cast(UINT64_MAX)) { - success = false; - } - break; - case ADMTController::Channel::ANGLE: - angle = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - angleChannelName, 1); - if (angle == static_cast(UINT64_MAX)) { - success = false; - } - break; - case ADMTController::Channel::COUNT: - count = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - countChannelName, 1); - if (count == static_cast(UINT64_MAX)) { - success = false; - } - break; - case ADMTController::Channel::TEMPERATURE: - temp = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - temperatureChannelName, 1); - if (temp == static_cast(UINT64_MAX)) { - success = false; - } - break; - } - return success; -} - -void HarmonicCalibration::updateLineEditValue(QLineEdit *lineEdit, - double value) { - if (value == static_cast(UINT64_MAX)) { - lineEdit->setText("N/A"); - } else { - lineEdit->setText(QString::number(value)); - } -} - -void HarmonicCalibration::toggleWidget(QPushButton *widget, bool value) { - widget->setEnabled(value); -} - -void HarmonicCalibration::changeCustomSwitchLabel(CustomSwitch *customSwitch, - QString onLabel, - QString offLabel) { - customSwitch->setOnText(onLabel); - customSwitch->setOffText(offLabel); -} - -QCheckBox *HarmonicCalibration::createStatusLEDWidget(const QString &text, - QVariant variant, - bool checked, - QWidget *parent) { - QCheckBox *checkBox = new QCheckBox(text, parent); - Style::setStyle(checkBox, style::properties::admt::checkBoxLED, variant, - true); - checkBox->setChecked(checked); - checkBox->setEnabled(false); - return checkBox; -} - -MenuControlButton * -HarmonicCalibration::createChannelToggleWidget(const QString title, - QColor color, QWidget *parent) { - MenuControlButton *menuControlButton = new MenuControlButton(parent); - menuControlButton->setName(title); - menuControlButton->setCheckBoxStyle( - MenuControlButton::CheckboxStyle::CS_CIRCLE); - menuControlButton->setOpenMenuChecksThis(true); - menuControlButton->setDoubleClickToOpenMenu(true); - menuControlButton->setColor(color); - menuControlButton->button()->setVisible(false); - menuControlButton->setCheckable(false); - menuControlButton->checkBox()->setChecked(true); - menuControlButton->layout()->setMargin(0); - return menuControlButton; +void HarmonicCalibration::updateLabelValue(QLabel *label, int channelIndex) +{ + switch(channelIndex) { + case ADMTController::Channel::ROTATION: + label->setText(QString("%1").arg(rotation, 0, 'f', 2) + "°"); + break; + case ADMTController::Channel::ANGLE: + label->setText(QString("%1").arg(angle, 0, 'f', 2) + "°"); + break; + case ADMTController::Channel::COUNT: + label->setText(QString::number(count)); + break; + case ADMTController::Channel::TEMPERATURE: + label->setText(QString("%1").arg(temp, 0, 'f', 2) + "°C"); + break; + } +} + +void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute) +{ + switch(attribute) { + case ADMTController::MotorAttribute::AMAX: + label->setText(QString::number(amax)); + break; + case ADMTController::MotorAttribute::ROTATE_VMAX: + label->setText(QString::number(rotate_vmax)); + break; + case ADMTController::MotorAttribute::DMAX: + label->setText(QString::number(dmax)); + break; + case ADMTController::MotorAttribute::DISABLE: + label->setText(QString::number(disable)); + break; + case ADMTController::MotorAttribute::TARGET_POS: + label->setText(QString::number(target_pos)); + break; + case ADMTController::MotorAttribute::CURRENT_POS: + label->setText(QString::number(current_pos)); + break; + case ADMTController::MotorAttribute::RAMP_MODE: + label->setText(QString::number(ramp_mode)); + break; + } +} + +bool HarmonicCalibration::updateChannelValue(int channelIndex) +{ + bool success = false; + switch(channelIndex) { + case ADMTController::Channel::ROTATION: + rotation = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, 1); + if(rotation == static_cast(UINT64_MAX)) { + success = false; + } + break; + case ADMTController::Channel::ANGLE: + angle = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, 1); + if(angle == static_cast(UINT64_MAX)) { + success = false; + } + break; + case ADMTController::Channel::COUNT: + count = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, 1); + if(count == static_cast(UINT64_MAX)) { + success = false; + } + break; + case ADMTController::Channel::TEMPERATURE: + temp = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, 1); + if(temp == static_cast(UINT64_MAX)) { + success = false; + } + break; + } + return success; +} + +void HarmonicCalibration::updateLineEditValue(QLineEdit *lineEdit, double value) +{ + if(value == static_cast(UINT64_MAX)) { + lineEdit->setText("N/A"); + } else { + lineEdit->setText(QString::number(value)); + } +} + +void HarmonicCalibration::toggleWidget(QPushButton *widget, bool value) { widget->setEnabled(value); } + +void HarmonicCalibration::changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel) +{ + customSwitch->setOnText(onLabel); + customSwitch->setOffText(offLabel); +} + +QCheckBox *HarmonicCalibration::createStatusLEDWidget(const QString &text, QVariant variant, bool checked, + QWidget *parent) +{ + QCheckBox *checkBox = new QCheckBox(text, parent); + Style::setStyle(checkBox, style::properties::admt::checkBoxLED, variant, true); + checkBox->setChecked(checked); + checkBox->setEnabled(false); + return checkBox; +} + +MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString title, QColor color, QWidget *parent) +{ + MenuControlButton *menuControlButton = new MenuControlButton(parent); + menuControlButton->setName(title); + menuControlButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); + menuControlButton->setOpenMenuChecksThis(true); + menuControlButton->setDoubleClickToOpenMenu(true); + menuControlButton->setColor(color); + menuControlButton->button()->setVisible(false); + menuControlButton->setCheckable(false); + menuControlButton->checkBox()->setChecked(true); + menuControlButton->layout()->setMargin(0); + return menuControlButton; } #pragma endregion #pragma region Connect Methods -void HarmonicCalibration::connectLineEditToNumber(QLineEdit *lineEdit, - int &variable, int min, - int max) { - QIntValidator *validator = new QIntValidator(min, max, this); - lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, this, - [&variable, lineEdit, min, max]() { - bool ok; - int value = lineEdit->text().toInt(&ok); - if (ok && value >= min && value <= max) { - variable = value; - } else { - lineEdit->setText(QString::number(variable)); - } - }); -} - -void HarmonicCalibration::connectLineEditToNumber(QLineEdit *lineEdit, - double &variable, - QString unit) { - connect(lineEdit, &QLineEdit::editingFinished, this, - [&variable, lineEdit, unit]() { - bool ok; - double value = - lineEdit->text().replace(unit, "").trimmed().toDouble(&ok); - if (ok) { - variable = value; - - } else { - lineEdit->setText(QString::number(variable) + " " + unit); - } - }); -} - -void HarmonicCalibration::connectLineEditToDouble(QLineEdit *lineEdit, - double &variable) { - QDoubleValidator *validator = new QDoubleValidator(this); - validator->setNotation(QDoubleValidator::StandardNotation); - lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { - bool ok; - double value = lineEdit->text().toDouble(&ok); - if (ok) { - variable = value; - } else { - lineEdit->setText(QString::number(variable)); - } - }); -} - -void HarmonicCalibration::connectLineEditToNumberWrite( - QLineEdit *lineEdit, double &variable, - ADMTController::MotorAttribute attribute) { - QDoubleValidator *validator = new QDoubleValidator(this); - validator->setNotation(QDoubleValidator::StandardNotation); - lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, attribute, &variable]() { - bool ok; - double value = lineEdit->text().toDouble(&ok); - if (ok) { - variable = value; - writeMotorAttributeValue(attribute, variable); - - } else { - lineEdit->setText(QString::number(variable)); - } - }); -} - -void HarmonicCalibration::connectMenuComboToNumber(MenuCombo *menuCombo, - double &variable) { - QComboBox *combo = menuCombo->combo(); - connect(combo, QOverload::of(&QComboBox::currentIndexChanged), - [this, &combo, &variable]() { - variable = qvariant_cast(combo->currentData()); - }); -} - -void HarmonicCalibration::connectMenuComboToNumber(MenuCombo *menuCombo, - int &variable) { - QComboBox *combo = menuCombo->combo(); - connect(combo, QOverload::of(&QComboBox::currentIndexChanged), - [this, combo, &variable]() { - variable = qvariant_cast(combo->currentData()); - }); -} - -void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit *lineEdit, - double &vmax) { - connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, &vmax]() { - bool ok; - double rps = lineEdit->text().toDouble(&ok); - if (ok) { - vmax = convertRPStoVMAX(rps); - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, - vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - amax = convertAccelTimetoAMAX(motorAccelTime); - writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - // StatusBarManager::pushMessage("Applied VMAX: " + - // QString::number(vmax)); StatusBarManager::pushMessage("Applied AMAX: " - // + QString::number(amax)); - } else { - lineEdit->setText(QString::number(convertVMAXtoRPS(vmax))); - } - }); -} - -void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit *lineEdit, - double &amax) { - connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, &amax]() { - bool ok; - double accelTime = lineEdit->text().toDouble(&ok); - if (ok) { - amax = convertAccelTimetoAMAX(accelTime); - // StatusBarManager::pushMessage("Applied AMAX: " + - // QString::number(amax)); - } else { - lineEdit->setText(QString::number(convertAMAXtoAccelTime(amax))); - } - }); -} - -void HarmonicCalibration::connectRegisterBlockToRegistry( - RegisterBlockWidget *widget) { - uint32_t *readValue = new uint32_t; - connect(widget->readButton(), &QPushButton::clicked, this, [this, widget, readValue] { - bool ok = false, success = false; - - if (widget->getCnvPage() != UINT32_MAX) { - ok = this->changeCNVPage(widget->getCnvPage()); - } else { - ok = true; - } - - if (ok) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - widget->getAddress(), readValue) == 0) { - widget->setValue(*readValue); - } - } else { - StatusBarManager::pushMessage("Failed to read registry"); - } - }); - if (widget->getAccessPermission() == - RegisterBlockWidget::ACCESS_PERMISSION::READWRITE || - widget->getAccessPermission() == - RegisterBlockWidget::ACCESS_PERMISSION::WRITE) { - connect(widget->writeButton(), &QPushButton::clicked, this, [this, widget, readValue] { - bool ok = false, success = false; - - if (widget->getCnvPage() != UINT32_MAX) { - ok = this->changeCNVPage(widget->getCnvPage()); - } else { - ok = true; - } - - if (ok) { - if (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - widget->getAddress(), widget->getValue()) == 0) { - if (m_admtController->readDeviceRegistry( - m_admtController->getDeviceId( - ADMTController::Device::ADMT4000), - widget->getAddress(), readValue) == 0) { - widget->setValue(*readValue); - success = true; - } - } - } - - if (!success) { - StatusBarManager::pushMessage("Failed to write to registry"); - } - }); - } -} - -void HarmonicCalibration::connectLineEditToRPM(QLineEdit *lineEdit, - double &variable) { - QDoubleValidator *validator = new QDoubleValidator(this); - validator->setNotation(QDoubleValidator::StandardNotation); - lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, this, [this, lineEdit, &variable]() { - bool ok; - double value = lineEdit->text().toDouble(&ok); - if (ok) { - variable = value; - rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(variable)); - writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, - rotate_vmax); - writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); - amax = convertAccelTimetoAMAX(motorAccelTime); - writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); - } else { - lineEdit->setText(QString::number(variable)); - } - }); +void HarmonicCalibration::connectLineEditToNumber(QLineEdit *lineEdit, int &variable, int min, int max) +{ + QIntValidator *validator = new QIntValidator(min, max, this); + lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, min, max]() { + bool ok; + int value = lineEdit->text().toInt(&ok); + if(ok && value >= min && value <= max) { + variable = value; + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + +void HarmonicCalibration::connectLineEditToNumber(QLineEdit *lineEdit, double &variable, QString unit) +{ + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, unit]() { + bool ok; + double value = lineEdit->text().replace(unit, "").trimmed().toDouble(&ok); + if(ok) { + variable = value; + + } else { + lineEdit->setText(QString::number(variable) + " " + unit); + } + }); +} + +void HarmonicCalibration::connectLineEditToDouble(QLineEdit *lineEdit, double &variable) +{ + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if(ok) { + variable = value; + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + +void HarmonicCalibration::connectLineEditToNumberWrite(QLineEdit *lineEdit, double &variable, + ADMTController::MotorAttribute attribute) +{ + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, attribute, &variable]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if(ok) { + variable = value; + writeMotorAttributeValue(attribute, variable); + + } else { + lineEdit->setText(QString::number(variable)); + } + }); +} + +void HarmonicCalibration::connectMenuComboToNumber(MenuCombo *menuCombo, double &variable) +{ + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), + [this, &combo, &variable]() { variable = qvariant_cast(combo->currentData()); }); +} + +void HarmonicCalibration::connectMenuComboToNumber(MenuCombo *menuCombo, int &variable) +{ + QComboBox *combo = menuCombo->combo(); + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), + [this, combo, &variable]() { variable = qvariant_cast(combo->currentData()); }); +} + +void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit *lineEdit, double &vmax) +{ + connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, &vmax]() { + bool ok; + double rps = lineEdit->text().toDouble(&ok); + if(ok) { + vmax = convertRPStoVMAX(rps); + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + amax = convertAccelTimetoAMAX(motorAccelTime); + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + // StatusBarManager::pushMessage("Applied VMAX: " + + // QString::number(vmax)); StatusBarManager::pushMessage("Applied AMAX: " + // + QString::number(amax)); + } else { + lineEdit->setText(QString::number(convertVMAXtoRPS(vmax))); + } + }); +} + +void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit *lineEdit, double &amax) +{ + connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, &amax]() { + bool ok; + double accelTime = lineEdit->text().toDouble(&ok); + if(ok) { + amax = convertAccelTimetoAMAX(accelTime); + // StatusBarManager::pushMessage("Applied AMAX: " + + // QString::number(amax)); + } else { + lineEdit->setText(QString::number(convertAMAXtoAccelTime(amax))); + } + }); +} + +void HarmonicCalibration::connectRegisterBlockToRegistry(RegisterBlockWidget *widget) +{ + uint32_t *readValue = new uint32_t; + connect(widget->readButton(), &QPushButton::clicked, this, [this, widget, readValue] { + bool ok = false, success = false; + + if(widget->getCnvPage() != UINT32_MAX) { + ok = this->changeCNVPage(widget->getCnvPage()); + } else { + ok = true; + } + + if(ok) { + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + widget->getAddress(), readValue) == 0) { + widget->setValue(*readValue); + } + } else { + StatusBarManager::pushMessage("Failed to read registry"); + } + }); + if(widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::READWRITE || + widget->getAccessPermission() == RegisterBlockWidget::ACCESS_PERMISSION::WRITE) { + connect(widget->writeButton(), &QPushButton::clicked, this, [this, widget, readValue] { + bool ok = false, success = false; + + if(widget->getCnvPage() != UINT32_MAX) { + ok = this->changeCNVPage(widget->getCnvPage()); + } else { + ok = true; + } + + if(ok) { + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + widget->getAddress(), widget->getValue()) == 0) { + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + widget->getAddress(), readValue) == 0) { + widget->setValue(*readValue); + success = true; + } + } + } + + if(!success) { + StatusBarManager::pushMessage("Failed to write to registry"); + } + }); + } +} + +void HarmonicCalibration::connectLineEditToRPM(QLineEdit *lineEdit, double &variable) +{ + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + lineEdit->setValidator(validator); + connect(lineEdit, &QLineEdit::editingFinished, this, [this, lineEdit, &variable]() { + bool ok; + double value = lineEdit->text().toDouble(&ok); + if(ok) { + variable = value; + rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(variable)); + writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); + amax = convertAccelTimetoAMAX(motorAccelTime); + writeMotorAttributeValue(ADMTController::MotorAttribute::AMAX, amax); + } else { + lineEdit->setText(QString::number(variable)); + } + }); } #pragma endregion #pragma region Convert Methods -double HarmonicCalibration::convertRPStoVMAX(double rps) { - return (rps * motorMicrostepPerRevolution * motorTimeUnit); -} +double HarmonicCalibration::convertRPStoVMAX(double rps) { return (rps * motorMicrostepPerRevolution * motorTimeUnit); } -double HarmonicCalibration::convertVMAXtoRPS(double vmax) { - return (vmax / motorMicrostepPerRevolution / motorTimeUnit); +double HarmonicCalibration::convertVMAXtoRPS(double vmax) +{ + return (vmax / motorMicrostepPerRevolution / motorTimeUnit); } -double HarmonicCalibration::convertAccelTimetoAMAX(double accelTime) { - return (rotate_vmax * static_cast(1 << 17) / accelTime / - motorfCLK); // 1 << 17 = 2^17 = 131072 +double HarmonicCalibration::convertAccelTimetoAMAX(double accelTime) +{ + return (rotate_vmax * static_cast(1 << 17) / accelTime / motorfCLK); // 1 << 17 = 2^17 = 131072 } -double HarmonicCalibration::convertAMAXtoAccelTime(double amax) { - return ((rotate_vmax * static_cast(1 << 17)) / - (amax * motorfCLK)); // 1 << 17 = 2^17 = 131072 +double HarmonicCalibration::convertAMAXtoAccelTime(double amax) +{ + return ((rotate_vmax * static_cast(1 << 17)) / (amax * motorfCLK)); // 1 << 17 = 2^17 = 131072 } double HarmonicCalibration::convertRPMtoRPS(double rpm) { return (rpm / 60); } @@ -5338,17 +4751,16 @@ double HarmonicCalibration::convertRPStoRPM(double rps) { return (rps * 60); } #pragma endregion #pragma region Debug Methods -QString HarmonicCalibration::readRegmapDumpAttributeValue() { - QString output = ""; - char value[1024]; - int result = -1; - result = m_admtController->getDeviceAttributeValueString( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getDeviceAttribute( - ADMTController::DeviceAttribute::REGMAP_DUMP), - value, 1024); - output = QString(value); - return output; +QString HarmonicCalibration::readRegmapDumpAttributeValue() +{ + QString output = ""; + char value[1024]; + int result = -1; + result = m_admtController->getDeviceAttributeValueString( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getDeviceAttribute(ADMTController::DeviceAttribute::REGMAP_DUMP), value, 1024); + output = QString(value); + return output; } #pragma endregion #include "moc_harmoniccalibration.cpp" diff --git a/plugins/admt/src/widgets/horizontalspinbox.cpp b/plugins/admt/src/widgets/horizontalspinbox.cpp index 1df7333ed9..4ed9421251 100644 --- a/plugins/admt/src/widgets/horizontalspinbox.cpp +++ b/plugins/admt/src/widgets/horizontalspinbox.cpp @@ -25,107 +25,112 @@ using namespace scopy::admt; -HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, - QString unit, QWidget *parent) - : QWidget(parent), m_value(initialValue), m_unit(unit) { - QVBoxLayout *container = new QVBoxLayout(this); - setLayout(container); - container->setMargin(0); - container->setSpacing(4); - - if (header != "") { - QLabel *headerLabel = new QLabel(header, this); - Style::setStyle(headerLabel, style::properties::label::menuSmall); - container->addWidget(headerLabel); - } - - QWidget *controlWidget = new QWidget(this); - QHBoxLayout *controlLayout = new QHBoxLayout(controlWidget); - controlWidget->setLayout(controlLayout); - controlLayout->setMargin(0); - controlLayout->setSpacing(2); - - m_lineEdit = new QLineEdit(controlWidget); - QDoubleValidator *validator = new QDoubleValidator(this); - validator->setNotation(QDoubleValidator::StandardNotation); - m_lineEdit->setValidator(validator); - applyLineEditStyle(m_lineEdit); - - if (QString::compare(m_unit, "") != 0) { - QWidget *lineEditContainer = new QWidget(controlWidget); - QHBoxLayout *lineEditLayout = new QHBoxLayout(lineEditContainer); - lineEditContainer->setLayout(lineEditLayout); - lineEditLayout->setMargin(0); - lineEditLayout->setSpacing(0); - - m_unitLabel = new QLabel(m_unit, controlWidget); - applyUnitLabelStyle(m_unitLabel); - - m_lineEdit->setTextMargins(12, 4, 0, 4); - - lineEditLayout->addWidget(m_lineEdit); - lineEditLayout->addWidget(m_unitLabel); - controlLayout->addWidget(lineEditContainer); - } else { - controlLayout->addWidget(m_lineEdit); - } - - m_minusButton = new QPushButton(controlWidget); - m_minusButton->setIcon(QIcon(":/admt/minus.svg")); - applyPushButtonStyle(m_minusButton); - - m_plusButton = new QPushButton(controlWidget); - m_plusButton->setIcon(QIcon(":/admt/plus.svg")); - applyPushButtonStyle(m_plusButton, 0, 4, 0, 4); - - controlLayout->addWidget(m_minusButton); - controlLayout->addWidget(m_plusButton); - - container->addWidget(controlWidget); - - setValue(m_value); - connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(onLineEditTextEdited())); - connect(m_minusButton, SIGNAL(clicked()), SLOT(onMinusButtonPressed())); - connect(m_plusButton, SIGNAL(clicked()), SLOT(onPlusButtonPressed())); +HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, QString unit, QWidget *parent) + : QWidget(parent) + , m_value(initialValue) + , m_unit(unit) +{ + QVBoxLayout *container = new QVBoxLayout(this); + setLayout(container); + container->setMargin(0); + container->setSpacing(4); + + if(header != "") { + QLabel *headerLabel = new QLabel(header, this); + Style::setStyle(headerLabel, style::properties::label::menuSmall); + container->addWidget(headerLabel); + } + + QWidget *controlWidget = new QWidget(this); + QHBoxLayout *controlLayout = new QHBoxLayout(controlWidget); + controlWidget->setLayout(controlLayout); + controlLayout->setMargin(0); + controlLayout->setSpacing(2); + + m_lineEdit = new QLineEdit(controlWidget); + QDoubleValidator *validator = new QDoubleValidator(this); + validator->setNotation(QDoubleValidator::StandardNotation); + m_lineEdit->setValidator(validator); + applyLineEditStyle(m_lineEdit); + + if(QString::compare(m_unit, "") != 0) { + QWidget *lineEditContainer = new QWidget(controlWidget); + QHBoxLayout *lineEditLayout = new QHBoxLayout(lineEditContainer); + lineEditContainer->setLayout(lineEditLayout); + lineEditLayout->setMargin(0); + lineEditLayout->setSpacing(0); + + m_unitLabel = new QLabel(m_unit, controlWidget); + applyUnitLabelStyle(m_unitLabel); + + m_lineEdit->setTextMargins(12, 4, 0, 4); + + lineEditLayout->addWidget(m_lineEdit); + lineEditLayout->addWidget(m_unitLabel); + controlLayout->addWidget(lineEditContainer); + } else { + controlLayout->addWidget(m_lineEdit); + } + + m_minusButton = new QPushButton(controlWidget); + m_minusButton->setIcon(QIcon(":/admt/minus.svg")); + applyPushButtonStyle(m_minusButton); + + m_plusButton = new QPushButton(controlWidget); + m_plusButton->setIcon(QIcon(":/admt/plus.svg")); + applyPushButtonStyle(m_plusButton, 0, 4, 0, 4); + + controlLayout->addWidget(m_minusButton); + controlLayout->addWidget(m_plusButton); + + container->addWidget(controlWidget); + + setValue(m_value); + connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(onLineEditTextEdited())); + connect(m_minusButton, SIGNAL(clicked()), SLOT(onMinusButtonPressed())); + connect(m_plusButton, SIGNAL(clicked()), SLOT(onPlusButtonPressed())); } -void HorizontalSpinBox::onMinusButtonPressed() { - m_value--; - setValue(m_value); - Q_EMIT m_lineEdit->editingFinished(); +void HorizontalSpinBox::onMinusButtonPressed() +{ + m_value--; + setValue(m_value); + Q_EMIT m_lineEdit->editingFinished(); } -void HorizontalSpinBox::onPlusButtonPressed() { - m_value++; - setValue(m_value); - Q_EMIT m_lineEdit->editingFinished(); +void HorizontalSpinBox::onPlusButtonPressed() +{ + m_value++; + setValue(m_value); + Q_EMIT m_lineEdit->editingFinished(); } -void HorizontalSpinBox::onLineEditTextEdited() { - QLineEdit *lineEdit = static_cast(QObject::sender()); - bool ok; - double value = lineEdit->text().toDouble(&ok); - if (ok) { - m_value = value; - } - setValue(m_value); +void HorizontalSpinBox::onLineEditTextEdited() +{ + QLineEdit *lineEdit = static_cast(QObject::sender()); + bool ok; + double value = lineEdit->text().toDouble(&ok); + if(ok) { + m_value = value; + } + setValue(m_value); } -void HorizontalSpinBox::setValue(double value) { - m_lineEdit->setText(QString::number(value)); -} +void HorizontalSpinBox::setValue(double value) { m_lineEdit->setText(QString::number(value)); } -void HorizontalSpinBox::setEnabled(double value) { - m_lineEdit->setEnabled(value); - m_minusButton->setEnabled(value); - m_plusButton->setEnabled(value); - if (QString::compare(m_unit, "") != 0) { - applyUnitLabelStyle(m_unitLabel, value); - } +void HorizontalSpinBox::setEnabled(double value) +{ + m_lineEdit->setEnabled(value); + m_minusButton->setEnabled(value); + m_plusButton->setEnabled(value); + if(QString::compare(m_unit, "") != 0) { + applyUnitLabelStyle(m_unitLabel, value); + } } -void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) { - QString style = QString(R"css( +void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) +{ + QString style = QString(R"css( QLineEdit { font-family: Open Sans; font-size: 16px; @@ -145,21 +150,18 @@ void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) { color: #9c4600; } )css"); - style = style.replace(QString("&&colorname&&"), - Style::getAttribute(json::global::ch0)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setAlignment(Qt::AlignRight); - widget->setContentsMargins(0, 0, 0, 0); - widget->setTextMargins(6, 4, 6, 4); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setAlignment(Qt::AlignRight); + widget->setContentsMargins(0, 0, 0, 0); + widget->setTextMargins(6, 4, 6, 4); } -void HorizontalSpinBox::applyPushButtonStyle(QPushButton *widget, - int topLeftBorderRadius, - int topRightBorderRadius, - int bottomLeftBorderRadius, - int bottomRightBorderRadius) { - QString style = QString(R"css( +void HorizontalSpinBox::applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius, int topRightBorderRadius, + int bottomLeftBorderRadius, int bottomRightBorderRadius) +{ + QString style = QString(R"css( QPushButton{ background-color: black; font-family: Open Sans; @@ -177,24 +179,19 @@ void HorizontalSpinBox::applyPushButtonStyle(QPushButton *widget, color: #2d3d9c; } )css"); - style = - style.replace(QString("&&colorname&&"), - Style::getAttribute(json::theme::interactive_primary_idle)); - style = style.replace(QString("&&topLeftBorderRadius&&"), - QString::number(topLeftBorderRadius)); - style = style.replace(QString("&&topRightBorderRadius&&"), - QString::number(topRightBorderRadius)); - style = style.replace(QString("&&bottomLeftBorderRadius&&"), - QString::number(bottomLeftBorderRadius)); - style = style.replace(QString("&&bottomRightBorderRadius&&"), - QString::number(bottomRightBorderRadius)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setFixedWidth(38); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::interactive_primary_idle)); + style = style.replace(QString("&&topLeftBorderRadius&&"), QString::number(topLeftBorderRadius)); + style = style.replace(QString("&&topRightBorderRadius&&"), QString::number(topRightBorderRadius)); + style = style.replace(QString("&&bottomLeftBorderRadius&&"), QString::number(bottomLeftBorderRadius)); + style = style.replace(QString("&&bottomRightBorderRadius&&"), QString::number(bottomRightBorderRadius)); + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setFixedWidth(38); } -void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget, bool isEnabled) { - QString style = QString(R"css( +void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget, bool isEnabled) +{ + QString style = QString(R"css( background-color: &&backgroundcolor&&; font-family: Open Sans; font-size: 16px; @@ -202,18 +199,17 @@ void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget, bool isEnabled) { color: &&colorname&&; border: none; )css"); - if (isEnabled) { - style = style.replace(QString("&&backgroundcolor&&"), "black"); - style = style.replace(QString("&&colorname&&"), - Style::getAttribute(json::global::ch0)); - } else { - style = style.replace(QString("&&backgroundcolor&&"), "#18181d"); - style = style.replace(QString("&&colorname&&"), "#9c4600"); - } - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setAlignment(Qt::AlignRight); - widget->setContentsMargins(0, 4, 12, 4); + if(isEnabled) { + style = style.replace(QString("&&backgroundcolor&&"), "black"); + style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); + } else { + style = style.replace(QString("&&backgroundcolor&&"), "#18181d"); + style = style.replace(QString("&&colorname&&"), "#9c4600"); + } + widget->setStyleSheet(style); + widget->setFixedHeight(30); + widget->setAlignment(Qt::AlignRight); + widget->setContentsMargins(0, 4, 12, 4); } QLineEdit *HorizontalSpinBox::lineEdit() { return m_lineEdit; } diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp index 04c8c435bb..35377a073b 100644 --- a/plugins/admt/src/widgets/registerblockwidget.cpp +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -27,117 +27,113 @@ using namespace scopy; using namespace scopy::admt; -RegisterBlockWidget::RegisterBlockWidget( - QString header, QString description, uint32_t address, uint32_t cnvPage, - RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent) - : QWidget(parent), m_address(address), m_cnvPage(cnvPage), - m_accessPermission(accessPermission) { - QVBoxLayout *container = new QVBoxLayout(this); - setLayout(container); - container->setMargin(0); - container->setSpacing(0); - MenuSectionWidget *menuSectionWidget = new MenuSectionWidget(this); - Style::setStyle(menuSectionWidget, style::properties::widget::basicComponent); - QLabel *headerLabel = new QLabel(header, menuSectionWidget); - Style::setStyle(headerLabel, style::properties::label::menuMedium); - menuSectionWidget->setFixedHeight(180); - menuSectionWidget->contentLayout()->setSpacing( - Style::getDimension(json::global::unit_0_5)); - - QLabel *descriptionLabel = new QLabel(description, menuSectionWidget); - descriptionLabel->setWordWrap(true); - descriptionLabel->setMinimumHeight(24); - descriptionLabel->setAlignment(Qt::AlignTop); - descriptionLabel->setSizePolicy(QSizePolicy::Preferred, - QSizePolicy::MinimumExpanding); - - m_spinBox = new PaddedSpinBox(menuSectionWidget); - Style::setStyle(m_spinBox, style::properties::admt::spinBox); - m_spinBox->setButtonSymbols(m_spinBox->ButtonSymbols::NoButtons); - - m_value = 0x00; - m_spinBox->setValue(m_value); - - QWidget *buttonsWidget = new QWidget(menuSectionWidget); - QHBoxLayout *buttonsContainer = new QHBoxLayout(buttonsWidget); - buttonsWidget->setLayout(buttonsContainer); - - buttonsContainer->setMargin(0); - buttonsContainer->setSpacing(Style::getDimension(json::global::unit_0_5)); - switch (m_accessPermission) { - case ACCESS_PERMISSION::READWRITE: - addReadButton(buttonsWidget); - addWriteButton(buttonsWidget); - break; - case ACCESS_PERMISSION::WRITE: - addWriteButton(buttonsWidget); - break; - case ACCESS_PERMISSION::READ: - addReadButton(buttonsWidget); - m_spinBox->setReadOnly(true); - break; - } - - menuSectionWidget->contentLayout()->addWidget(headerLabel); - menuSectionWidget->contentLayout()->addWidget(descriptionLabel); - menuSectionWidget->contentLayout()->addWidget(m_spinBox); - menuSectionWidget->contentLayout()->addWidget(buttonsWidget); - - container->addWidget(menuSectionWidget); - container->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, - QSizePolicy::Preferred)); - - connect(m_spinBox, QOverload::of(&QSpinBox::valueChanged), this, - &RegisterBlockWidget::onValueChanged); +RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t cnvPage, + RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent) + : QWidget(parent) + , m_address(address) + , m_cnvPage(cnvPage) + , m_accessPermission(accessPermission) +{ + QVBoxLayout *container = new QVBoxLayout(this); + setLayout(container); + container->setMargin(0); + container->setSpacing(0); + MenuSectionWidget *menuSectionWidget = new MenuSectionWidget(this); + Style::setStyle(menuSectionWidget, style::properties::widget::basicComponent); + QLabel *headerLabel = new QLabel(header, menuSectionWidget); + Style::setStyle(headerLabel, style::properties::label::menuMedium); + menuSectionWidget->setFixedHeight(180); + menuSectionWidget->contentLayout()->setSpacing(Style::getDimension(json::global::unit_0_5)); + + QLabel *descriptionLabel = new QLabel(description, menuSectionWidget); + descriptionLabel->setWordWrap(true); + descriptionLabel->setMinimumHeight(24); + descriptionLabel->setAlignment(Qt::AlignTop); + descriptionLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); + + m_spinBox = new PaddedSpinBox(menuSectionWidget); + Style::setStyle(m_spinBox, style::properties::admt::spinBox); + m_spinBox->setButtonSymbols(m_spinBox->ButtonSymbols::NoButtons); + + m_value = 0x00; + m_spinBox->setValue(m_value); + + QWidget *buttonsWidget = new QWidget(menuSectionWidget); + QHBoxLayout *buttonsContainer = new QHBoxLayout(buttonsWidget); + buttonsWidget->setLayout(buttonsContainer); + + buttonsContainer->setMargin(0); + buttonsContainer->setSpacing(Style::getDimension(json::global::unit_0_5)); + switch(m_accessPermission) { + case ACCESS_PERMISSION::READWRITE: + addReadButton(buttonsWidget); + addWriteButton(buttonsWidget); + break; + case ACCESS_PERMISSION::WRITE: + addWriteButton(buttonsWidget); + break; + case ACCESS_PERMISSION::READ: + addReadButton(buttonsWidget); + m_spinBox->setReadOnly(true); + break; + } + + menuSectionWidget->contentLayout()->addWidget(headerLabel); + menuSectionWidget->contentLayout()->addWidget(descriptionLabel); + menuSectionWidget->contentLayout()->addWidget(m_spinBox); + menuSectionWidget->contentLayout()->addWidget(buttonsWidget); + + container->addWidget(menuSectionWidget); + container->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Preferred)); + + connect(m_spinBox, QOverload::of(&QSpinBox::valueChanged), this, &RegisterBlockWidget::onValueChanged); } RegisterBlockWidget::~RegisterBlockWidget() {} -void RegisterBlockWidget::onValueChanged(int newValue) { - m_value = static_cast(newValue); -} +void RegisterBlockWidget::onValueChanged(int newValue) { m_value = static_cast(newValue); } uint32_t RegisterBlockWidget::getValue() { return m_value; } -void RegisterBlockWidget::setValue(uint32_t value) { - m_value = value; - m_spinBox->setValue(m_value); +void RegisterBlockWidget::setValue(uint32_t value) +{ + m_value = value; + m_spinBox->setValue(m_value); } uint32_t RegisterBlockWidget::getAddress() { return m_address; } uint32_t RegisterBlockWidget::getCnvPage() { return m_cnvPage; } -RegisterBlockWidget::ACCESS_PERMISSION -RegisterBlockWidget::getAccessPermission() { - return m_accessPermission; -} +RegisterBlockWidget::ACCESS_PERMISSION RegisterBlockWidget::getAccessPermission() { return m_accessPermission; } -void RegisterBlockWidget::addReadButton(QWidget *parent) { - m_readButton = new QPushButton("Read", parent); - Style::setStyle(m_readButton, style::properties::button::basicButton); - parent->layout()->addWidget(m_readButton); +void RegisterBlockWidget::addReadButton(QWidget *parent) +{ + m_readButton = new QPushButton("Read", parent); + Style::setStyle(m_readButton, style::properties::button::basicButton); + parent->layout()->addWidget(m_readButton); } QPushButton *RegisterBlockWidget::readButton() { return m_readButton; } -void RegisterBlockWidget::addWriteButton(QWidget *parent) { - m_writeButton = new QPushButton("Write", parent); - Style::setStyle(m_writeButton, style::properties::button::basicButton); - parent->layout()->addWidget(m_writeButton); +void RegisterBlockWidget::addWriteButton(QWidget *parent) +{ + m_writeButton = new QPushButton("Write", parent); + Style::setStyle(m_writeButton, style::properties::button::basicButton); + parent->layout()->addWidget(m_writeButton); } QPushButton *RegisterBlockWidget::writeButton() { return m_writeButton; } -PaddedSpinBox::PaddedSpinBox(QWidget *parent) : QSpinBox(parent) { - setDisplayIntegerBase(16); - setMinimum(0); - setMaximum(INT_MAX); +PaddedSpinBox::PaddedSpinBox(QWidget *parent) + : QSpinBox(parent) +{ + setDisplayIntegerBase(16); + setMinimum(0); + setMaximum(INT_MAX); } PaddedSpinBox::~PaddedSpinBox() {} -QString PaddedSpinBox::textFromValue(int value) const { - return QString("0x%1").arg(value, 4, 16, QChar('0')); -} +QString PaddedSpinBox::textFromValue(int value) const { return QString("0x%1").arg(value, 4, 16, QChar('0')); } #include "moc_registerblockwidget.cpp" diff --git a/plugins/admt/test/tst_pluginloader.cpp b/plugins/admt/test/tst_pluginloader.cpp index 8ed3b7c047..ee227af7db 100644 --- a/plugins/admt/test/tst_pluginloader.cpp +++ b/plugins/admt/test/tst_pluginloader.cpp @@ -27,94 +27,104 @@ using namespace scopy; -class TST_ADMTPlugin : public QObject { - Q_OBJECT +class TST_ADMTPlugin : public QObject +{ + Q_OBJECT private Q_SLOTS: - void fileExists(); - void isLibrary(); - void loaded(); - void className(); - void instanceNotNull(); - void multipleInstances(); - void qobjectcast_to_plugin(); - void clone(); - void name(); - void metadata(); + void fileExists(); + void isLibrary(); + void loaded(); + void className(); + void instanceNotNull(); + void multipleInstances(); + void qobjectcast_to_plugin(); + void clone(); + void name(); + void metadata(); }; #define PLUGIN_LOCATION "../../plugins" #define FILENAME PLUGIN_LOCATION "/libscopy-admtplugin.so" -void TST_ADMTPlugin::fileExists() { - QFile f(FILENAME); - bool ret; - ret = f.open(QIODevice::ReadOnly); - if (ret) - f.close(); - QVERIFY(ret); +void TST_ADMTPlugin::fileExists() +{ + QFile f(FILENAME); + bool ret; + ret = f.open(QIODevice::ReadOnly); + if(ret) + f.close(); + QVERIFY(ret); } void TST_ADMTPlugin::isLibrary() { QVERIFY(QLibrary::isLibrary(FILENAME)); } -void TST_ADMTPlugin::className() { - QPluginLoader qp(FILENAME, this); - QVERIFY(qp.metaData().value("className") == "ADMTPlugin"); +void TST_ADMTPlugin::className() +{ + QPluginLoader qp(FILENAME, this); + QVERIFY(qp.metaData().value("className") == "ADMTPlugin"); } -void TST_ADMTPlugin::loaded() { - QPluginLoader qp(FILENAME, this); - qp.load(); - QVERIFY(qp.isLoaded()); +void TST_ADMTPlugin::loaded() +{ + QPluginLoader qp(FILENAME, this); + qp.load(); + QVERIFY(qp.isLoaded()); } -void TST_ADMTPlugin::instanceNotNull() { - QPluginLoader qp(FILENAME, this); - QVERIFY(qp.instance() != nullptr); +void TST_ADMTPlugin::instanceNotNull() +{ + QPluginLoader qp(FILENAME, this); + QVERIFY(qp.instance() != nullptr); } -void TST_ADMTPlugin::multipleInstances() { - QPluginLoader qp1(FILENAME, this); - QPluginLoader qp2(FILENAME, this); +void TST_ADMTPlugin::multipleInstances() +{ + QPluginLoader qp1(FILENAME, this); + QPluginLoader qp2(FILENAME, this); - QVERIFY(qp1.instance() == qp2.instance()); + QVERIFY(qp1.instance() == qp2.instance()); } -void TST_ADMTPlugin::qobjectcast_to_plugin() { - QPluginLoader qp(FILENAME, this); - auto instance = qobject_cast(qp.instance()); - QVERIFY(instance != nullptr); +void TST_ADMTPlugin::qobjectcast_to_plugin() +{ + QPluginLoader qp(FILENAME, this); + auto instance = qobject_cast(qp.instance()); + QVERIFY(instance != nullptr); } -void TST_ADMTPlugin::clone() { - QPluginLoader qp(FILENAME, this); - - Plugin *p1 = nullptr, *p2 = nullptr; - auto original = qobject_cast(qp.instance()); - p1 = original->clone(); - QVERIFY(p1 != nullptr); - p2 = original->clone(); - QVERIFY(p2 != nullptr); - QVERIFY(p1 != p2); +void TST_ADMTPlugin::clone() +{ + QPluginLoader qp(FILENAME, this); + + Plugin *p1 = nullptr, *p2 = nullptr; + auto original = qobject_cast(qp.instance()); + p1 = original->clone(); + QVERIFY(p1 != nullptr); + p2 = original->clone(); + QVERIFY(p2 != nullptr); + QVERIFY(p1 != p2); } -void TST_ADMTPlugin::name() { - QPluginLoader qp(FILENAME, this); +void TST_ADMTPlugin::name() +{ + QPluginLoader qp(FILENAME, this); - Plugin *p1 = nullptr, *p2 = nullptr; - auto original = qobject_cast(qp.instance()); - p1 = original->clone(); - qDebug() << p1->name(); + Plugin *p1 = nullptr, *p2 = nullptr; + auto original = qobject_cast(qp.instance()); + p1 = original->clone(); + qDebug() << p1->name(); } -void TST_ADMTPlugin::metadata() { - QPluginLoader qp(FILENAME, this); +void TST_ADMTPlugin::metadata() +{ + QPluginLoader qp(FILENAME, this); - Plugin *p1 = nullptr, *p2 = nullptr; - auto original = qobject_cast(qp.instance()); - original->initMetadata(); - p1 = original->clone(); - qDebug() << p1->metadata(); - QVERIFY(!p1->metadata().isEmpty()); + Plugin *p1 = nullptr, *p2 = nullptr; + auto original = qobject_cast(qp.instance()); + original->initMetadata(); + p1 = original->clone(); + qDebug() << p1->metadata(); + QVERIFY(!p1->metadata().isEmpty()); } QTEST_MAIN(TST_ADMTPlugin) From ebd1329b9ebe973236fd2599d60a6a05a0867082 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 7 Mar 2025 16:54:41 +0800 Subject: [PATCH 092/112] admt: Styles cleanup - Added sequence mode 2 graph checkboxes - Updated calibration graphs to align with styles infrastructure - Added formatter for graphs - Added colored checkbox - Disabled SPI CRC and Flag - Set default motor RPM to 30 - Changed uint16_t to quint16 for slot and signals Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 66 +- plugins/admt/src/harmoniccalibration.cpp | 1018 +++++++++++------ .../qss/properties/admt/coloredCheckBox.qss | 31 + 3 files changed, 709 insertions(+), 406 deletions(-) create mode 100644 plugins/admt/style/qss/properties/admt/coloredCheckBox.qss diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index acd4ecffb2..6a5859b472 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -76,24 +76,21 @@ #include #include -enum AcquisitionDataKey +enum SensorDataKey { - RADIUS, - ANGLE, - TURNCOUNT, ABSANGLE, + ANGLE, + ANGLESEC, SINE, COSINE, SECANGLI, SECANGLQ, - ANGLESEC, + RADIUS, DIAG1, DIAG2, TMP0, TMP1, - CNVCNT, - SCRADIUS, - SPIFAULT + CNVCNT }; namespace scopy { @@ -117,10 +114,10 @@ public Q_SLOTS: void commandLogWrite(QString message = ""); void updateFaultStatus(bool value); void updateMotorPosition(double position); - void updateDIGIOUI(uint16_t *registerValue); - void updateFaultRegisterUI(uint16_t *registerValue); - void updateMTDiagnosticRegisterUI(uint16_t *registerValue); - void updateMTDiagnosticsUI(uint16_t *registerValue); + void updateDIGIOUI(quint16 registerValue); + void updateFaultRegisterUI(quint16 registerValue); + void updateMTDiagnosticRegisterUI(quint16 registerValue); + void updateMTDiagnosticsUI(quint16 registerValue); Q_SIGNALS: void runningChanged(bool); void canCalibrateChanged(bool); @@ -129,10 +126,10 @@ public Q_SLOTS: void commandLogWriteSignal(QString message); void updateFaultStatusSignal(bool value); void motorPositionChanged(double position); - void DIGIORegisterChanged(uint16_t *registerValue); - void FaultRegisterChanged(uint16_t *registerValue); - void DIAG1RegisterChanged(uint16_t *registerValue); - void DIAG2RegisterChanged(uint16_t *registerValue); + void DIGIORegisterChanged(quint16 registerValue); + void FaultRegisterChanged(quint16 registerValue); + void DIAG1RegisterChanged(quint16 registerValue); + void DIAG2RegisterChanged(quint16 registerValue); private: ADMTController *m_admtController; @@ -181,7 +178,9 @@ public Q_SLOTS: QPlainTextEdit *logsPlainTextEdit, *commandLogPlainTextEdit; - QCheckBox *acquisitionFaultRegisterLEDWidget, *calibrationFaultRegisterLEDWidget, *DIGIOBusyStatusLED, + QCheckBox *angleCheckBox, *absAngleCheckBox, *temp0CheckBox, *sineCheckBox, *cosineCheckBox, *radiusCheckBox, + *angleSecCheckBox, *secAnglQCheckBox, *secAnglICheckBox, *temp1CheckBox, + *acquisitionFaultRegisterLEDWidget, *calibrationFaultRegisterLEDWidget, *DIGIOBusyStatusLED, *DIGIOCNVStatusLED, *DIGIOSENTStatusLED, *DIGIOACALCStatusLED, *DIGIOFaultStatusLED, *DIGIOBootloaderStatusLED, *R0StatusLED, *R1StatusLED, *R2StatusLED, *R3StatusLED, *R4StatusLED, *R5StatusLED, *R6StatusLED, *R7StatusLED, *VDDUnderVoltageStatusLED, *VDDOverVoltageStatusLED, @@ -192,18 +191,25 @@ public Q_SLOTS: QScrollArea *MTDiagnosticsScrollArea; + QWidget *acquisitionGraphChannelWidget; + + QGridLayout *acquisitionGraphChannelGridLayout; + PlotWidget *acquisitionGraphPlotWidget, *angleErrorPlotWidget, *calibrationRawDataPlotWidget, - *FFTAngleErrorPlotWidget, *correctedErrorPlotWidget, *postCalibrationRawDataPlotWidget, - *FFTCorrectedErrorPlotWidget; + *FFTAngleErrorMagnitudePlotWidget, *FFTAngleErrorPhasePlotWidget, *correctedErrorPlotWidget, + *postCalibrationRawDataPlotWidget, *FFTCorrectedErrorMagnitudePlotWidget, + *FFTCorrectedErrorPhasePlotWidget; PlotAxis *acquisitionXPlotAxis, *acquisitionYPlotAxis, *calibrationRawDataXPlotAxis, - *calibrationRawDataYPlotAxis, *angleErrorXPlotAxis, *angleErrorYPlotAxis, *FFTAngleErrorXPlotAxis, - *FFTAngleErrorYPlotAxis, *correctedErrorXPlotAxis, *correctedErrorYPlotAxis, - *FFTCorrectedErrorXPlotAxis, *FFTCorrectedErrorYPlotAxis, *postCalibrationRawDataXPlotAxis, + *calibrationRawDataYPlotAxis, *angleErrorXPlotAxis, *angleErrorYPlotAxis, + *FFTAngleErrorMagnitudeXPlotAxis, *FFTAngleErrorMagnitudeYPlotAxis, *FFTAngleErrorPhaseXPlotAxis, + *FFTAngleErrorPhaseYPlotAxis, *correctedErrorXPlotAxis, *correctedErrorYPlotAxis, + *FFTCorrectedErrorMagnitudeXPlotAxis, *FFTCorrectedErrorMagnitudeYPlotAxis, + *FFTCorrectedErrorPhaseXPlotAxis, *FFTCorrectedErrorPhaseYPlotAxis, *postCalibrationRawDataXPlotAxis, *postCalibrationRawDataYPlotAxis; - PlotChannel *acquisitionAnglePlotChannel, *acquisitionABSAnglePlotChannel, *acquisitionTurnCountPlotChannel, - *acquisitionTmp0PlotChannel, *acquisitionTmp1PlotChannel, *acquisitionSinePlotChannel, - *acquisitionCosinePlotChannel, *acquisitionRadiusPlotChannel, *acquisitionSecAnglQPlotChannel, - *acquisitionSecAnglIPlotChannel, *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, + PlotChannel *acquisitionAnglePlotChannel, *acquisitionABSAnglePlotChannel, *acquisitionTmp0PlotChannel, + *acquisitionTmp1PlotChannel, *acquisitionSinePlotChannel, *acquisitionCosinePlotChannel, + *acquisitionRadiusPlotChannel, *acquisitionSecAnglQPlotChannel, *acquisitionSecAnglIPlotChannel, + *acquisitionAngleSecPlotChannel, *angleErrorPlotChannel, *preCalibrationFFTPhasePlotChannel, *calibrationRawDataPlotChannel, *calibrationSineDataPlotChannel, *calibrationCosineDataPlotChannel, *FFTAngleErrorMagnitudeChannel, *FFTAngleErrorPhaseChannel, *correctedErrorPlotChannel, *postCalibrationRawDataPlotChannel, *postCalibrationSineDataPlotChannel, @@ -266,7 +272,7 @@ public Q_SLOTS: void updateAcquisitionMotorRPM(); void updateAcquisitionMotorRotationDirection(); void getAcquisitionSamples(int sampleRate); - double getAcquisitionParameterValue(const AcquisitionDataKey &key); + double getSensorDataAcquisitionValue(const ADMTController::SensorRegister &key); void plotAcquisition(QVector &list, PlotChannel *channel); void prependAcquisitionData(const double &data, QVector &list); void resetAcquisitionYAxisScale(); @@ -275,9 +281,10 @@ public Q_SLOTS: void startAcquisitionUITask(); void stopAcquisitionUITask(); void updateSequenceWidget(); + void updateCapturedDataCheckBoxes(); void applySequenceAndUpdate(); void updateGeneralSettingEnabled(bool value); - void connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, AcquisitionDataKey key); + void connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, SensorDataKey key); void GMRReset(); #pragma endregion @@ -326,7 +333,7 @@ public Q_SLOTS: void clearCalibrationSineCosine(); void clearPostCalibrationSamples(); void clearAngleErrorGraphs(); - void clearCorrectedAngleErrorGraphs(); + void clearFFTAngleErrorGraphs(); #pragma endregion #pragma region Motor Methods @@ -376,7 +383,6 @@ public Q_SLOTS: void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel); QCheckBox *createStatusLEDWidget(const QString &text, QVariant variant = true, bool checked = false, QWidget *parent = nullptr); - MenuControlButton *createChannelToggleWidget(const QString title, QColor color, QWidget *parent = nullptr); #pragma endregion #pragma region Connect Methods diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 34de97d74a..e42bb1b61c 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -55,8 +55,9 @@ static bool isAngleDisplayFormat = false; static bool resetToZero = true; static bool hasMTDiagnostics = false; static bool isMotorRotationClockwise = true; -static double fast_motor_rpm = 300; +static double default_motor_rpm = 30; +static double fast_motor_rpm = 300; static double motorFullStepAngle = 0.9; // TODO input as configuration static double microStepResolution = 256; // TODO input as configuration static int motorfCLK = 12500000; // 12.5 Mhz, TODO input as configuration @@ -67,28 +68,21 @@ static double motorMicrostepPerRevolution = motorFullStepPerRevolution * microSt static double motorTimeUnit = static_cast(1 << 24) / motorfCLK; // t = 2^24/16Mhz static int acquisitionDisplayLength = 200; -static QVector acquisitionAngleList, acquisitionABSAngleList, acquisitionTurnCountList, acquisitionTmp0List, - acquisitionTmp1List, acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, graphDataList, - graphPostDataList; +static QVector acquisitionAngleList, acquisitionABSAngleList, acquisitionTmp0List, acquisitionTmp1List, + acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, acquisitionAngleSecList, + acquisitionSecAnglIList, acquisitionSecAnglQList, graphDataList, graphPostDataList; static const QColor scopyBlueColor = Style::getColor(json::theme::interactive_primary_idle); -static const QColor sineColor = QColor("#85e94c"); -static const QColor cosineColor = QColor("#91e6cf"); -static const QColor faultLEDColor = QColor("#c81a28"); -static const QColor gpioLEDColor = Style::getColor(json::theme::interactive_secondary_idle); -static const QColor statusLEDColor = QColor("#2e9e6f"); static const QPen scopyBluePen(scopyBlueColor); -static const QPen channel0Pen(Style::getAttribute(json::global::ch0)); -static const QPen channel1Pen(Style::getAttribute(json::global::ch1)); -static const QPen channel2Pen(Style::getAttribute(json::global::ch2)); -static const QPen channel3Pen(Style::getAttribute(json::global::ch3)); -static const QPen channel4Pen(Style::getAttribute(json::global::ch4)); -static const QPen channel5Pen(Style::getAttribute(json::global::ch5)); -static const QPen channel6Pen(Style::getAttribute(json::global::ch6)); -static const QPen channel7Pen(Style::getAttribute(json::global::ch7)); -static const QPen sinePen(sineColor); -static const QPen cosinePen(cosineColor); +static const QPen channel0Pen(StyleHelper::getChannelColor(0)); +static const QPen channel1Pen(StyleHelper::getChannelColor(1)); +static const QPen channel2Pen(StyleHelper::getChannelColor(2)); +static const QPen channel3Pen(StyleHelper::getChannelColor(3)); +static const QPen channel4Pen(StyleHelper::getChannelColor(4)); +static const QPen channel5Pen(StyleHelper::getChannelColor(5)); +static const QPen channel6Pen(StyleHelper::getChannelColor(6)); +static const QPen channel7Pen(StyleHelper::getChannelColor(7)); static map deviceRegisterMap; static map GENERALRegisterMap; @@ -129,10 +123,26 @@ static int calibrationMode = 0; static int globalSpacingSmall = Style::getDimension(json::global::unit_0_5); static int globalSpacingMedium = Style::getDimension(json::global::unit_1); -static map acquisitionDataMap = { - {RADIUS, false}, {ANGLE, false}, {TURNCOUNT, false}, {ABSANGLE, false}, {SINE, false}, {COSINE, false}, - {SECANGLI, false}, {SECANGLQ, false}, {ANGLESEC, false}, {DIAG1, false}, {DIAG2, false}, {TMP0, false}, - {TMP1, false}, {CNVCNT, false}, {SCRADIUS, false}, {SPIFAULT, false}}; +static double defaultAngleErrorGraphMin = -3; +static double defaultAngleErrorGraphMax = 3; +static double currentAngleErrorGraphMin = defaultAngleErrorGraphMin; +static double currentAngleErrorGraphMax = defaultAngleErrorGraphMax; + +static double defaultMagnitudeGraphMin = 0; +static double defaultMagnitudeGraphMax = 1.2; +static double currentMagnitudeGraphMin = defaultMagnitudeGraphMin; +static double currentMagnitudeGraphMax = defaultMagnitudeGraphMax; + +static double defaultPhaseGraphMin = -4; +static double defaultPhaseGraphMax = 4; +static double currentPhaseGraphMin = defaultPhaseGraphMin; +static double currentPhaseGraphMax = defaultPhaseGraphMax; + +static map acquisitionDataMap = { + {ABSANGLE, false}, {ANGLE, false}, {ANGLESEC, false}, {SINE, false}, {COSINE, false}, + {SECANGLI, false}, {SECANGLQ, false}, {RADIUS, false}, {DIAG1, false}, {DIAG2, false}, + {TMP0, false}, {TMP1, false}, {CNVCNT, false}, +}; HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool isDebug, QWidget *parent) : QWidget(parent) @@ -384,59 +394,69 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() #pragma region Acquisition Graph Section Widget MenuSectionWidget *acquisitionGraphSectionWidget = new MenuSectionWidget(this); Style::setStyle(acquisitionGraphSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *acquisitionGraphCollapseSection = new MenuCollapseSection( - "Captured Data", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, acquisitionGraphSectionWidget); acquisitionGraphSectionWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - acquisitionGraphSectionWidget->contentLayout()->addWidget(acquisitionGraphCollapseSection); - acquisitionGraphCollapseSection->contentLayout()->setSpacing(8); + acquisitionGraphSectionWidget->contentLayout()->setSpacing(globalSpacingSmall); + + QLabel *acquisitionGraphLabel = new QLabel("Captured Data", acquisitionGraphSectionWidget); + Style::setStyle(acquisitionGraphLabel, style::properties::label::menuMedium); acquisitionGraphPlotWidget = new PlotWidget(); acquisitionGraphPlotWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - acquisitionXPlotAxis = new PlotAxis(QwtAxis::XBottom, acquisitionGraphPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); + acquisitionXPlotAxis = new PlotAxis(QwtAxis::XBottom, acquisitionGraphPlotWidget, scopyBluePen); + PrefixFormatter *acquisitionXFormatter = new PrefixFormatter({{" ", 1E0}}, acquisitionXPlotAxis); + acquisitionXFormatter->setTrimZeroes(true); + acquisitionXPlotAxis->setFormatter(acquisitionXFormatter); acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); - acquisitionYPlotAxis = new PlotAxis(QwtAxis::YLeft, acquisitionGraphPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); + acquisitionXPlotAxis->scaleDraw()->setFloatPrecision(0); + + acquisitionYPlotAxis = new PlotAxis(QwtAxis::YLeft, acquisitionGraphPlotWidget, scopyBluePen); + PrefixFormatter *acquisitionYFormatter = new PrefixFormatter({{" ", 1E0}}, acquisitionYPlotAxis); + acquisitionYFormatter->setTrimZeroes(true); + acquisitionYPlotAxis->setFormatter(acquisitionYFormatter); acquisitionYPlotAxis->setInterval(0, 360); acquisitionAnglePlotChannel = new PlotChannel("Angle", channel0Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionABSAnglePlotChannel = - new PlotChannel("ABS Angle", channel1Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionTurnCountPlotChannel = - new PlotChannel("Turn Count", channel2Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionTmp0PlotChannel = new PlotChannel("TMP 0", channel3Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionTmp1PlotChannel = new PlotChannel("TMP 1", channel4Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionSinePlotChannel = new PlotChannel("Sine", sinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionCosinePlotChannel = new PlotChannel("Cosine", cosinePen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionSinePlotChannel = new PlotChannel("Sine", channel1Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionCosinePlotChannel = + new PlotChannel("Cosine", channel2Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); acquisitionRadiusPlotChannel = - new PlotChannel("Radius", channel5Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + new PlotChannel("Radius", channel3Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionABSAnglePlotChannel = + new PlotChannel("ABS Angle", channel4Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTmp0PlotChannel = new PlotChannel("TMP 0", channel5Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionAngleSecPlotChannel = + new PlotChannel("SEC Angle", channel6Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); acquisitionSecAnglQPlotChannel = - new PlotChannel("SECANGLQ", channel6Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + new PlotChannel("SECANGLQ", channel7Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); acquisitionSecAnglIPlotChannel = - new PlotChannel("SECANGLI", channel7Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + new PlotChannel("SECANGLI", channel0Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTmp1PlotChannel = new PlotChannel("TMP 1", channel4Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); acquisitionGraphPlotWidget->addPlotChannel(acquisitionAnglePlotChannel); acquisitionGraphPlotWidget->addPlotChannel(acquisitionABSAnglePlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionTurnCountPlotChannel); acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp0PlotChannel); - acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp1PlotChannel); acquisitionGraphPlotWidget->addPlotChannel(acquisitionSinePlotChannel); acquisitionGraphPlotWidget->addPlotChannel(acquisitionCosinePlotChannel); acquisitionGraphPlotWidget->addPlotChannel(acquisitionRadiusPlotChannel); + + acquisitionGraphPlotWidget->addPlotChannel(acquisitionAngleSecPlotChannel); acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglQPlotChannel); acquisitionGraphPlotWidget->addPlotChannel(acquisitionSecAnglIPlotChannel); + acquisitionGraphPlotWidget->addPlotChannel(acquisitionTmp1PlotChannel); + // Industrial acquisitionAnglePlotChannel->setEnabled(true); - acquisitionABSAnglePlotChannel->setEnabled(true); - acquisitionTurnCountPlotChannel->setEnabled(true); - acquisitionTmp0PlotChannel->setEnabled(true); - acquisitionTmp1PlotChannel->setEnabled(true); - acquisitionSinePlotChannel->setEnabled(true); - acquisitionCosinePlotChannel->setEnabled(true); - acquisitionRadiusPlotChannel->setEnabled(true); - acquisitionSecAnglQPlotChannel->setEnabled(true); - acquisitionSecAnglIPlotChannel->setEnabled(true); + acquisitionABSAnglePlotChannel->setEnabled(false); + acquisitionTmp0PlotChannel->setEnabled(false); + acquisitionSinePlotChannel->setEnabled(false); + acquisitionCosinePlotChannel->setEnabled(false); + acquisitionRadiusPlotChannel->setEnabled(false); + // Automotive + acquisitionAngleSecPlotChannel->setEnabled(false); + acquisitionSecAnglQPlotChannel->setEnabled(false); + acquisitionSecAnglIPlotChannel->setEnabled(false); + acquisitionTmp1PlotChannel->setEnabled(false); + acquisitionGraphPlotWidget->selectChannel(acquisitionAnglePlotChannel); acquisitionGraphPlotWidget->setShowXAxisLabels(true); @@ -445,35 +465,53 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() acquisitionGraphPlotWidget->replot(); #pragma region Channel Selection - QWidget *acquisitionGraphChannelWidget = new QWidget(acquisitionGraphSectionWidget); - QGridLayout *acquisitionGraphChannelGridLayout = new QGridLayout(acquisitionGraphChannelWidget); - acquisitionGraphChannelGridLayout->setContentsMargins(16, 8, 8, 16); - acquisitionGraphChannelGridLayout->setSpacing(8); - - QCheckBox *angleCheckBox = new QCheckBox("Angle", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(angleCheckBox, channel0Pen.color()); + acquisitionGraphChannelWidget = new QWidget(acquisitionGraphSectionWidget); + Style::setStyle(acquisitionGraphChannelWidget, style::properties::widget::basicBackground); + acquisitionGraphChannelGridLayout = new QGridLayout(acquisitionGraphChannelWidget); + acquisitionGraphChannelGridLayout->setContentsMargins(globalSpacingSmall, globalSpacingSmall, + globalSpacingSmall, globalSpacingSmall); + acquisitionGraphChannelGridLayout->setSpacing(globalSpacingSmall); + + angleCheckBox = new QCheckBox("Angle", acquisitionGraphChannelWidget); + Style::setStyle(angleCheckBox, style::properties::admt::coloredCheckBox, "ch0"); connectCheckBoxToAcquisitionGraph(angleCheckBox, acquisitionAnglePlotChannel, ANGLE); angleCheckBox->setChecked(true); - QCheckBox *absAngleCheckBox = new QCheckBox("ABS Angle", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(absAngleCheckBox, channel1Pen.color()); + sineCheckBox = new QCheckBox("Sine", acquisitionGraphChannelWidget); + Style::setStyle(sineCheckBox, style::properties::admt::coloredCheckBox, "ch1"); + connectCheckBoxToAcquisitionGraph(sineCheckBox, acquisitionSinePlotChannel, SINE); + + cosineCheckBox = new QCheckBox("Cosine", acquisitionGraphChannelWidget); + Style::setStyle(cosineCheckBox, style::properties::admt::coloredCheckBox, "ch2"); + connectCheckBoxToAcquisitionGraph(cosineCheckBox, acquisitionCosinePlotChannel, COSINE); + + radiusCheckBox = new QCheckBox("Radius", acquisitionGraphChannelWidget); + Style::setStyle(radiusCheckBox, style::properties::admt::coloredCheckBox, "ch3"); + connectCheckBoxToAcquisitionGraph(radiusCheckBox, acquisitionRadiusPlotChannel, RADIUS); + + absAngleCheckBox = new QCheckBox("ABS Angle", acquisitionGraphChannelWidget); + Style::setStyle(absAngleCheckBox, style::properties::admt::coloredCheckBox, "ch4"); connectCheckBoxToAcquisitionGraph(absAngleCheckBox, acquisitionABSAnglePlotChannel, ABSANGLE); - QCheckBox *temp0CheckBox = new QCheckBox("Temp 0", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(temp0CheckBox, channel3Pen.color()); + temp0CheckBox = new QCheckBox("Temp 0", acquisitionGraphChannelWidget); + Style::setStyle(temp0CheckBox, style::properties::admt::coloredCheckBox, "ch5"); connectCheckBoxToAcquisitionGraph(temp0CheckBox, acquisitionTmp0PlotChannel, TMP0); - QCheckBox *sineCheckBox = new QCheckBox("Sine", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(sineCheckBox, sineColor); - connectCheckBoxToAcquisitionGraph(sineCheckBox, acquisitionSinePlotChannel, SINE); + angleSecCheckBox = new QCheckBox("SEC Angle", acquisitionGraphChannelWidget); + Style::setStyle(angleSecCheckBox, style::properties::admt::coloredCheckBox, "ch6"); + connectCheckBoxToAcquisitionGraph(angleSecCheckBox, acquisitionAngleSecPlotChannel, ANGLESEC); - QCheckBox *cosineCheckBox = new QCheckBox("Cosine", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(cosineCheckBox, cosineColor); - connectCheckBoxToAcquisitionGraph(cosineCheckBox, acquisitionCosinePlotChannel, COSINE); + secAnglQCheckBox = new QCheckBox("SECANGLQ", acquisitionGraphChannelWidget); + Style::setStyle(secAnglQCheckBox, style::properties::admt::coloredCheckBox, "ch7"); + connectCheckBoxToAcquisitionGraph(secAnglQCheckBox, acquisitionSecAnglQPlotChannel, SECANGLQ); - QCheckBox *radiusCheckBox = new QCheckBox("Radius", acquisitionGraphChannelWidget); - ADMTStyleHelper::ColoredSquareCheckbox(radiusCheckBox, channel5Pen.color()); - connectCheckBoxToAcquisitionGraph(radiusCheckBox, acquisitionRadiusPlotChannel, RADIUS); + secAnglICheckBox = new QCheckBox("SECANGLI", acquisitionGraphChannelWidget); + Style::setStyle(secAnglICheckBox, style::properties::admt::coloredCheckBox, "ch0"); + connectCheckBoxToAcquisitionGraph(secAnglICheckBox, acquisitionSecAnglIPlotChannel, SECANGLI); + + temp1CheckBox = new QCheckBox("Temp 1", acquisitionGraphChannelWidget); + Style::setStyle(temp1CheckBox, style::properties::admt::coloredCheckBox, "ch1"); + connectCheckBoxToAcquisitionGraph(temp1CheckBox, acquisitionTmp1PlotChannel, TMP1); if(GENERALRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 { @@ -488,14 +526,19 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); - acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); - acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); - acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); + acquisitionGraphChannelGridLayout->addWidget(angleSecCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(secAnglQCheckBox, 0, 4); + acquisitionGraphChannelGridLayout->addWidget(secAnglICheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 1, 1); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 2); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 3); + acquisitionGraphChannelGridLayout->addWidget(temp1CheckBox, 1, 4); } #pragma endregion - acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphPlotWidget); - acquisitionGraphCollapseSection->contentLayout()->addWidget(acquisitionGraphChannelWidget); + acquisitionGraphSectionWidget->contentLayout()->addWidget(acquisitionGraphLabel); + acquisitionGraphSectionWidget->contentLayout()->addWidget(acquisitionGraphPlotWidget); + acquisitionGraphSectionWidget->contentLayout()->addWidget(acquisitionGraphChannelWidget); #pragma endregion #pragma region General Setting @@ -616,15 +659,15 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() createStatusLEDWidget("Fault Register", "status", false, acquisitionDeviceStatusSection); acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionFaultRegisterLEDWidget); - if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 - { - QCheckBox *acquisitionSPICRCLEDWidget = - createStatusLEDWidget("SPI CRC", "status", false, acquisitionDeviceStatusSection); - QCheckBox *acquisitionSPIFlagLEDWidget = - createStatusLEDWidget("SPI Flag", "status", false, acquisitionDeviceStatusSection); - acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPICRCLEDWidget); - acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPIFlagLEDWidget); - } + // if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 + // { + // QCheckBox *acquisitionSPICRCLEDWidget = + // createStatusLEDWidget("SPI CRC", "status", false, acquisitionDeviceStatusSection); + // QCheckBox *acquisitionSPIFlagLEDWidget = + // createStatusLEDWidget("SPI Flag", "status", false, acquisitionDeviceStatusSection); + // acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPICRCLEDWidget); + // acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPIFlagLEDWidget); + // } #pragma endregion generalSettingLayout->setSpacing(globalSpacingSmall); @@ -669,13 +712,14 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() QGridLayout *calibrationDataGraphLayout = new QGridLayout(calibrationDataGraphWidget); calibrationDataGraphWidget->setLayout(calibrationDataGraphLayout); calibrationDataGraphLayout->setMargin(0); - calibrationDataGraphLayout->setSpacing(5); + calibrationDataGraphLayout->setSpacing(globalSpacingSmall); MenuSectionWidget *calibrationDataGraphSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); Style::setStyle(calibrationDataGraphSectionWidget, style::properties::widget::basicComponent); calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); calibrationDataGraphTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 176px; }"); - calibrationDataGraphSectionWidget->contentLayout()->setSpacing(8); + calibrationDataGraphSectionWidget->contentLayout()->setContentsMargins(globalSpacingSmall, 1, + globalSpacingSmall, globalSpacingSmall); calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); #pragma region Calibration Samples @@ -684,31 +728,39 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() QVBoxLayout *calibrationSamplesLayout = new QVBoxLayout(calibrationSamplesWidget); calibrationSamplesWidget->setLayout(calibrationSamplesLayout); calibrationSamplesLayout->setMargin(0); - calibrationSamplesLayout->setSpacing(0); + calibrationSamplesLayout->setSpacing(globalSpacingSmall); calibrationRawDataPlotWidget = new PlotWidget(); - calibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); + calibrationRawDataPlotWidget->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, 0); - calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); + calibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, calibrationRawDataPlotWidget, scopyBluePen); + PrefixFormatter *calibrationRawDataXFormatter = new PrefixFormatter({{" ", 1E0}}, calibrationRawDataXPlotAxis); + calibrationRawDataXFormatter->setTrimZeroes(true); + calibrationRawDataXPlotAxis->setFormatter(calibrationRawDataXFormatter); calibrationRawDataXPlotAxis->setMin(0); - calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); + calibrationRawDataXPlotAxis->scaleDraw()->setFloatPrecision(0); + + calibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, calibrationRawDataPlotWidget, scopyBluePen); + PrefixFormatter *calibrationRawDataYFormatter = new PrefixFormatter({{" ", 1E0}}, calibrationRawDataYPlotAxis); + calibrationRawDataYFormatter->setTrimZeroes(true); + calibrationRawDataYPlotAxis->setFormatter(calibrationRawDataYFormatter); calibrationRawDataYPlotAxis->setInterval(0, 360); + calibrationRawDataYPlotAxis->setUnitsVisible(true); + calibrationRawDataYPlotAxis->setUnits("°"); calibrationRawDataPlotChannel = - new PlotChannel("Samples", scopyBluePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + new PlotChannel("Angle", channel0Pen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); calibrationSineDataPlotChannel = - new PlotChannel("Sine", sinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + new PlotChannel("Sine", channel1Pen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); calibrationCosineDataPlotChannel = - new PlotChannel("Cosine", cosinePen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); + new PlotChannel("Cosine", channel2Pen, calibrationRawDataXPlotAxis, calibrationRawDataYPlotAxis); calibrationRawDataPlotWidget->addPlotChannel(calibrationRawDataPlotChannel); calibrationRawDataPlotWidget->addPlotChannel(calibrationSineDataPlotChannel); calibrationRawDataPlotWidget->addPlotChannel(calibrationCosineDataPlotChannel); - calibrationSineDataPlotChannel->setEnabled(true); - calibrationCosineDataPlotChannel->setEnabled(true); calibrationRawDataPlotChannel->setEnabled(true); + calibrationSineDataPlotChannel->setEnabled(false); + calibrationCosineDataPlotChannel->setEnabled(false); calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); calibrationRawDataPlotWidget->setShowXAxisLabels(true); @@ -717,22 +769,26 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationRawDataPlotWidget->replot(); QWidget *calibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); - ADMTStyleHelper::UIBackgroundStyle(calibrationDataGraphChannelsWidget); + Style::setStyle(calibrationDataGraphChannelsWidget, style::properties::widget::basicBackground); QHBoxLayout *calibrationDataGraphChannelsLayout = new QHBoxLayout(calibrationDataGraphChannelsWidget); calibrationDataGraphChannelsWidget->setLayout(calibrationDataGraphChannelsLayout); - calibrationDataGraphChannelsLayout->setContentsMargins(20, 13, 20, 5); - calibrationDataGraphChannelsLayout->setSpacing(20); - - MenuControlButton *toggleAngleButton = - createChannelToggleWidget("Angle", scopyBlueColor, calibrationDataGraphChannelsWidget); - MenuControlButton *toggleSineButton = - createChannelToggleWidget("Sine", sineColor, calibrationDataGraphChannelsWidget); - MenuControlButton *toggleCosineButton = - createChannelToggleWidget("Cosine", cosineColor, calibrationDataGraphChannelsWidget); - - calibrationDataGraphChannelsLayout->addWidget(toggleAngleButton); - calibrationDataGraphChannelsLayout->addWidget(toggleSineButton); - calibrationDataGraphChannelsLayout->addWidget(toggleCosineButton); + calibrationDataGraphChannelsLayout->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, + globalSpacingSmall); + calibrationDataGraphChannelsLayout->setSpacing(globalSpacingMedium); + + QCheckBox *toggleAngleCheckBox = new QCheckBox("Angle", calibrationDataGraphChannelsWidget); + Style::setStyle(toggleAngleCheckBox, style::properties::admt::coloredCheckBox, "ch0"); + toggleAngleCheckBox->setChecked(true); + QCheckBox *toggleSineCheckBox = new QCheckBox("Sine", calibrationDataGraphChannelsWidget); + Style::setStyle(toggleSineCheckBox, style::properties::admt::coloredCheckBox, "ch1"); + toggleSineCheckBox->setChecked(false); + QCheckBox *toggleCosineCheckBox = new QCheckBox("Cosine", calibrationDataGraphChannelsWidget); + Style::setStyle(toggleCosineCheckBox, style::properties::admt::coloredCheckBox, "ch2"); + toggleCosineCheckBox->setChecked(false); + + calibrationDataGraphChannelsLayout->addWidget(toggleAngleCheckBox); + calibrationDataGraphChannelsLayout->addWidget(toggleSineCheckBox); + calibrationDataGraphChannelsLayout->addWidget(toggleCosineCheckBox); calibrationDataGraphChannelsLayout->addStretch(); calibrationSamplesLayout->addWidget(calibrationRawDataPlotWidget); @@ -745,32 +801,44 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() QVBoxLayout *postCalibrationSamplesLayout = new QVBoxLayout(postCalibrationSamplesWidget); postCalibrationSamplesWidget->setLayout(postCalibrationSamplesLayout); postCalibrationSamplesLayout->setMargin(0); - postCalibrationSamplesLayout->setSpacing(0); + postCalibrationSamplesLayout->setSpacing(globalSpacingSmall); postCalibrationRawDataPlotWidget = new PlotWidget(); - postCalibrationRawDataPlotWidget->setContentsMargins(10, 10, 10, 6); - - postCalibrationRawDataXPlotAxis = new PlotAxis(QwtAxis::XBottom, postCalibrationRawDataPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); + postCalibrationRawDataPlotWidget->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, + 0); + + postCalibrationRawDataXPlotAxis = + new PlotAxis(QwtAxis::XBottom, postCalibrationRawDataPlotWidget, scopyBluePen); + PrefixFormatter *postCalibrationRawDataXFormatter = + new PrefixFormatter({{" ", 1E0}}, postCalibrationRawDataXPlotAxis); + postCalibrationRawDataXFormatter->setTrimZeroes(true); + postCalibrationRawDataXPlotAxis->setFormatter(postCalibrationRawDataXFormatter); postCalibrationRawDataXPlotAxis->setMin(0); - postCalibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, postCalibrationRawDataPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); + postCalibrationRawDataXPlotAxis->scaleDraw()->setFloatPrecision(0); + + postCalibrationRawDataYPlotAxis = new PlotAxis(QwtAxis::YLeft, postCalibrationRawDataPlotWidget, scopyBluePen); + PrefixFormatter *postCalibrationRawDataYFormatter = + new PrefixFormatter({{" ", 1E0}}, postCalibrationRawDataYPlotAxis); + postCalibrationRawDataYFormatter->setTrimZeroes(true); + postCalibrationRawDataYPlotAxis->setFormatter(postCalibrationRawDataYFormatter); postCalibrationRawDataYPlotAxis->setInterval(0, 360); + postCalibrationRawDataYPlotAxis->setUnitsVisible(true); + postCalibrationRawDataYPlotAxis->setUnits("°"); - postCalibrationRawDataPlotChannel = new PlotChannel("Samples", scopyBluePen, postCalibrationRawDataXPlotAxis, - postCalibrationRawDataYPlotAxis); + postCalibrationRawDataPlotChannel = + new PlotChannel("Angle", channel0Pen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); postCalibrationSineDataPlotChannel = - new PlotChannel("Sine", sinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); - postCalibrationCosineDataPlotChannel = - new PlotChannel("Cosine", cosinePen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); + new PlotChannel("Sine", channel1Pen, postCalibrationRawDataXPlotAxis, postCalibrationRawDataYPlotAxis); + postCalibrationCosineDataPlotChannel = new PlotChannel("Cosine", channel2Pen, postCalibrationRawDataXPlotAxis, + postCalibrationRawDataYPlotAxis); postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationRawDataPlotChannel); postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationSineDataPlotChannel); postCalibrationRawDataPlotWidget->addPlotChannel(postCalibrationCosineDataPlotChannel); - postCalibrationSineDataPlotChannel->setEnabled(true); - postCalibrationCosineDataPlotChannel->setEnabled(true); postCalibrationRawDataPlotChannel->setEnabled(true); + postCalibrationSineDataPlotChannel->setEnabled(false); + postCalibrationCosineDataPlotChannel->setEnabled(false); postCalibrationRawDataPlotWidget->selectChannel(postCalibrationRawDataPlotChannel); postCalibrationRawDataPlotWidget->setShowXAxisLabels(true); @@ -779,20 +847,26 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() postCalibrationRawDataPlotWidget->replot(); QWidget *postCalibrationDataGraphChannelsWidget = new QWidget(calibrationDataGraphTabWidget); + Style::setStyle(postCalibrationDataGraphChannelsWidget, style::properties::widget::basicBackground); QHBoxLayout *postCalibrationDataGraphChannelsLayout = new QHBoxLayout(postCalibrationDataGraphChannelsWidget); - ADMTStyleHelper::GraphChannelStyle(postCalibrationDataGraphChannelsWidget, - postCalibrationDataGraphChannelsLayout); - - MenuControlButton *togglePostAngleButton = - createChannelToggleWidget("Angle", scopyBlueColor, postCalibrationDataGraphChannelsWidget); - MenuControlButton *togglePostSineButton = - createChannelToggleWidget("Sine", sineColor, postCalibrationDataGraphChannelsWidget); - MenuControlButton *togglePostCosineButton = - createChannelToggleWidget("Cosine", cosineColor, postCalibrationDataGraphChannelsWidget); - - postCalibrationDataGraphChannelsLayout->addWidget(togglePostAngleButton); - postCalibrationDataGraphChannelsLayout->addWidget(togglePostSineButton); - postCalibrationDataGraphChannelsLayout->addWidget(togglePostCosineButton); + postCalibrationDataGraphChannelsWidget->setLayout(postCalibrationDataGraphChannelsLayout); + postCalibrationDataGraphChannelsLayout->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, + globalSpacingSmall); + postCalibrationDataGraphChannelsLayout->setSpacing(globalSpacingMedium); + + QCheckBox *togglePostAngleCheckBox = new QCheckBox("Angle", postCalibrationDataGraphChannelsWidget); + Style::setStyle(togglePostAngleCheckBox, style::properties::admt::coloredCheckBox, "ch0"); + togglePostAngleCheckBox->setChecked(true); + QCheckBox *togglePostSineCheckBox = new QCheckBox("Sine", postCalibrationDataGraphChannelsWidget); + Style::setStyle(togglePostSineCheckBox, style::properties::admt::coloredCheckBox, "ch1"); + togglePostSineCheckBox->setChecked(false); + QCheckBox *togglePostCosineCheckBox = new QCheckBox("Cosine", postCalibrationDataGraphChannelsWidget); + Style::setStyle(togglePostCosineCheckBox, style::properties::admt::coloredCheckBox, "ch2"); + togglePostCosineCheckBox->setChecked(false); + + postCalibrationDataGraphChannelsLayout->addWidget(togglePostAngleCheckBox); + postCalibrationDataGraphChannelsLayout->addWidget(togglePostSineCheckBox); + postCalibrationDataGraphChannelsLayout->addWidget(togglePostCosineCheckBox); postCalibrationDataGraphChannelsLayout->addStretch(); postCalibrationSamplesLayout->addWidget(postCalibrationRawDataPlotWidget); @@ -804,16 +878,13 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() MenuSectionWidget *resultDataSectionWidget = new MenuSectionWidget(calibrationDataGraphWidget); Style::setStyle(resultDataSectionWidget, style::properties::widget::basicComponent); - resultDataTabWidget = new QTabWidget(resultDataSectionWidget); + resultDataTabWidget = new QTabWidget(calibrationDataGraphWidget); resultDataTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 160px; }"); - resultDataSectionWidget->contentLayout()->setSpacing(8); + resultDataSectionWidget->contentLayout()->setContentsMargins(globalSpacingSmall, 1, globalSpacingSmall, + globalSpacingSmall); + resultDataSectionWidget->contentLayout()->setSpacing(0); resultDataSectionWidget->contentLayout()->addWidget(resultDataTabWidget); - QColor magnitudeColor = Style::getColor(json::global::ch0); - QColor phaseColor = Style::getColor(json::global::ch1); - QPen magnitudePen = QPen(magnitudeColor); - QPen phasePen = QPen(phaseColor); - #pragma region Angle Error Widget QWidget *angleErrorWidget = new QWidget(); Style::setStyle(angleErrorWidget, style::properties::widget::basicBackground); @@ -823,15 +894,24 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() angleErrorLayout->setSpacing(0); angleErrorPlotWidget = new PlotWidget(); - angleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); - angleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, angleErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); + angleErrorPlotWidget->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, 0); + + angleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, angleErrorPlotWidget, scopyBluePen); + PrefixFormatter *angleErrorXFormatter = new PrefixFormatter({{" ", 1E0}}, angleErrorXPlotAxis); + angleErrorXFormatter->setTrimZeroes(true); + angleErrorXPlotAxis->setFormatter(angleErrorXFormatter); angleErrorXPlotAxis->setMin(0); - angleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, angleErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - angleErrorYPlotAxis->setInterval(-4, 4); + angleErrorXPlotAxis->scaleDraw()->setFloatPrecision(0); - angleErrorPlotChannel = new PlotChannel("Angle Error", scopyBluePen, angleErrorXPlotAxis, angleErrorYPlotAxis); + angleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, angleErrorPlotWidget, scopyBluePen); + PrefixFormatter *angleErrorYFormatter = new PrefixFormatter({{" ", 1E0}}, angleErrorYPlotAxis); + angleErrorYFormatter->setTrimZeroes(true); + angleErrorYPlotAxis->setFormatter(angleErrorYFormatter); + angleErrorYPlotAxis->setInterval(defaultAngleErrorGraphMin, defaultAngleErrorGraphMax); + angleErrorYPlotAxis->setUnitsVisible(true); + angleErrorYPlotAxis->setUnits("°"); + + angleErrorPlotChannel = new PlotChannel("Angle Error", channel0Pen, angleErrorXPlotAxis, angleErrorYPlotAxis); angleErrorPlotWidget->addPlotChannel(angleErrorPlotChannel); angleErrorPlotChannel->setEnabled(true); @@ -853,47 +933,76 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() FFTAngleErrorLayout->setMargin(0); FFTAngleErrorLayout->setSpacing(0); - FFTAngleErrorPlotWidget = new PlotWidget(); - FFTAngleErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + QLabel *FFTAngleErrorMagnitudeLabel = new QLabel("Magnitude", FFTAngleErrorWidget); + FFTAngleErrorMagnitudeLabel->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, 0); - FFTAngleErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTAngleErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTAngleErrorXPlotAxis->setMin(0); - FFTAngleErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTAngleErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTAngleErrorYPlotAxis->setInterval(-4, 4); + FFTAngleErrorMagnitudePlotWidget = new PlotWidget(); + FFTAngleErrorMagnitudePlotWidget->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, 0); - FFTAngleErrorMagnitudeChannel = new PlotChannel("FFT Angle Error Magnitude", magnitudePen, - FFTAngleErrorXPlotAxis, FFTAngleErrorYPlotAxis); - FFTAngleErrorPhaseChannel = - new PlotChannel("FFT Angle Error Phase", phasePen, FFTAngleErrorXPlotAxis, FFTAngleErrorYPlotAxis); - FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorMagnitudeChannel); - FFTAngleErrorPlotWidget->addPlotChannel(FFTAngleErrorPhaseChannel); + FFTAngleErrorMagnitudeXPlotAxis = + new PlotAxis(QwtAxis::XBottom, FFTAngleErrorMagnitudePlotWidget, scopyBluePen); + PrefixFormatter *FFTAngleErrorXFormatter = new PrefixFormatter({{" ", 1E0}}, FFTAngleErrorMagnitudeXPlotAxis); + FFTAngleErrorXFormatter->setTrimZeroes(true); + FFTAngleErrorMagnitudeXPlotAxis->setFormatter(FFTAngleErrorXFormatter); + FFTAngleErrorMagnitudeXPlotAxis->setMin(0); + FFTAngleErrorMagnitudeXPlotAxis->scaleDraw()->setFloatPrecision(0); + + FFTAngleErrorMagnitudeYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTAngleErrorMagnitudePlotWidget, scopyBluePen); + PrefixFormatter *FFTAngleErrorYFormatter = new PrefixFormatter({{" ", 1E0}}, FFTAngleErrorMagnitudeYPlotAxis); + FFTAngleErrorYFormatter->setTrimZeroes(true); + FFTAngleErrorMagnitudeYPlotAxis->setFormatter(FFTAngleErrorYFormatter); + FFTAngleErrorMagnitudeYPlotAxis->setInterval(defaultMagnitudeGraphMin, defaultMagnitudeGraphMax); + + FFTAngleErrorMagnitudeChannel = + new PlotChannel("FFT Angle Error Magnitude", channel0Pen, FFTAngleErrorMagnitudeXPlotAxis, + FFTAngleErrorMagnitudeYPlotAxis); + + FFTAngleErrorMagnitudePlotWidget->addPlotChannel(FFTAngleErrorMagnitudeChannel); - FFTAngleErrorPhaseChannel->setEnabled(true); FFTAngleErrorMagnitudeChannel->setEnabled(true); - FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); + FFTAngleErrorMagnitudePlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); + + FFTAngleErrorMagnitudePlotWidget->setShowXAxisLabels(true); + FFTAngleErrorMagnitudePlotWidget->setShowYAxisLabels(true); + FFTAngleErrorMagnitudePlotWidget->showAxisLabels(); + FFTAngleErrorMagnitudePlotWidget->replot(); - FFTAngleErrorPlotWidget->setShowXAxisLabels(true); - FFTAngleErrorPlotWidget->setShowYAxisLabels(true); - FFTAngleErrorPlotWidget->showAxisLabels(); - FFTAngleErrorPlotWidget->replot(); + QLabel *FFTAngleErrorPhaseLabel = new QLabel("Phase", FFTAngleErrorWidget); + FFTAngleErrorPhaseLabel->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, 0); - QWidget *FFTAngleErrorChannelsWidget = new QWidget(); - QHBoxLayout *FFTAngleErrorChannelsLayout = new QHBoxLayout(FFTAngleErrorChannelsWidget); - ADMTStyleHelper::GraphChannelStyle(FFTAngleErrorChannelsWidget, FFTAngleErrorChannelsLayout); + FFTAngleErrorPhasePlotWidget = new PlotWidget(); + FFTAngleErrorPhasePlotWidget->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, 0); - MenuControlButton *toggleFFTAngleErrorMagnitudeButton = - createChannelToggleWidget("Magnitude", magnitudeColor, FFTAngleErrorChannelsWidget); - MenuControlButton *toggleFFTAngleErrorPhaseButton = - createChannelToggleWidget("Phase", phaseColor, FFTAngleErrorChannelsWidget); + FFTAngleErrorPhaseXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTAngleErrorPhasePlotWidget, scopyBluePen); + PrefixFormatter *FFTAngleErrorPhaseXFormatter = new PrefixFormatter({{" ", 1E0}}, FFTAngleErrorPhaseXPlotAxis); + FFTAngleErrorPhaseXFormatter->setTrimZeroes(true); + FFTAngleErrorPhaseXPlotAxis->setFormatter(FFTAngleErrorPhaseXFormatter); + FFTAngleErrorPhaseXPlotAxis->setMin(0); + FFTAngleErrorPhaseXPlotAxis->scaleDraw()->setFloatPrecision(0); - FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorMagnitudeButton); - FFTAngleErrorChannelsLayout->addWidget(toggleFFTAngleErrorPhaseButton); - FFTAngleErrorChannelsLayout->addStretch(); + FFTAngleErrorPhaseYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTAngleErrorPhasePlotWidget, scopyBluePen); + PrefixFormatter *FFTAngleErrorPhaseYFormatter = new PrefixFormatter({{" ", 1E0}}, FFTAngleErrorPhaseYPlotAxis); + FFTAngleErrorPhaseYFormatter->setTrimZeroes(true); + FFTAngleErrorPhaseYPlotAxis->setFormatter(FFTAngleErrorPhaseYFormatter); + FFTAngleErrorPhaseYPlotAxis->setInterval(defaultPhaseGraphMin, defaultPhaseGraphMax); - FFTAngleErrorLayout->addWidget(FFTAngleErrorPlotWidget); - FFTAngleErrorLayout->addWidget(FFTAngleErrorChannelsWidget); + FFTAngleErrorPhaseChannel = new PlotChannel("FFT Angle Error Phase", channel1Pen, FFTAngleErrorPhaseXPlotAxis, + FFTAngleErrorPhaseYPlotAxis); + + FFTAngleErrorPhasePlotWidget->addPlotChannel(FFTAngleErrorPhaseChannel); + + FFTAngleErrorPhaseChannel->setEnabled(true); + FFTAngleErrorPhasePlotWidget->selectChannel(FFTAngleErrorPhaseChannel); + + FFTAngleErrorPhasePlotWidget->setShowXAxisLabels(true); + FFTAngleErrorPhasePlotWidget->setShowYAxisLabels(true); + FFTAngleErrorPhasePlotWidget->showAxisLabels(); + FFTAngleErrorPhasePlotWidget->replot(); + + FFTAngleErrorLayout->addWidget(FFTAngleErrorMagnitudeLabel); + FFTAngleErrorLayout->addWidget(FFTAngleErrorMagnitudePlotWidget); + FFTAngleErrorLayout->addWidget(FFTAngleErrorPhaseLabel); + FFTAngleErrorLayout->addWidget(FFTAngleErrorPhasePlotWidget); #pragma endregion #pragma region Corrected Error Widget @@ -905,17 +1014,25 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() correctedErrorLayout->setSpacing(0); correctedErrorPlotWidget = new PlotWidget(); - correctedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + correctedErrorPlotWidget->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, 0); - correctedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, correctedErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); + correctedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, correctedErrorPlotWidget, scopyBluePen); + PrefixFormatter *correctedErrorXFormatter = new PrefixFormatter({{" ", 1E0}}, correctedErrorXPlotAxis); + correctedErrorXFormatter->setTrimZeroes(true); + correctedErrorXPlotAxis->setFormatter(correctedErrorXFormatter); correctedErrorXPlotAxis->setMin(0); - correctedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, correctedErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - correctedErrorYPlotAxis->setInterval(-4, 4); + correctedErrorXPlotAxis->scaleDraw()->setFloatPrecision(0); + + correctedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, correctedErrorPlotWidget, scopyBluePen); + PrefixFormatter *correctedErrorYFormatter = new PrefixFormatter({{" ", 1E0}}, correctedErrorYPlotAxis); + correctedErrorYFormatter->setTrimZeroes(true); + correctedErrorYPlotAxis->setFormatter(correctedErrorYFormatter); + correctedErrorYPlotAxis->setInterval(defaultAngleErrorGraphMin, defaultAngleErrorGraphMax); + correctedErrorYPlotAxis->setUnitsVisible(true); + correctedErrorYPlotAxis->setUnits("°"); correctedErrorPlotChannel = - new PlotChannel("Corrected Error", scopyBluePen, correctedErrorXPlotAxis, correctedErrorYPlotAxis); + new PlotChannel("Corrected Error", channel0Pen, correctedErrorXPlotAxis, correctedErrorYPlotAxis); correctedErrorPlotWidget->addPlotChannel(correctedErrorPlotChannel); correctedErrorPlotChannel->setEnabled(true); @@ -937,47 +1054,83 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() FFTCorrectedErrorLayout->setMargin(0); FFTCorrectedErrorLayout->setSpacing(0); - FFTCorrectedErrorPlotWidget = new PlotWidget(); - FFTCorrectedErrorPlotWidget->setContentsMargins(10, 10, 10, 6); + QLabel *FFTCorrectedErrorMagnitudeLabel = new QLabel("Magnitude", FFTCorrectedErrorWidget); + FFTCorrectedErrorMagnitudeLabel->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, + 0); - FFTCorrectedErrorXPlotAxis = new PlotAxis(QwtAxis::XBottom, FFTCorrectedErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTCorrectedErrorXPlotAxis->setMin(0); - FFTCorrectedErrorYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTCorrectedErrorPlotWidget, - QPen(Style::getColor(json::theme::interactive_primary_idle))); - FFTCorrectedErrorYPlotAxis->setInterval(-4, 4); + FFTCorrectedErrorMagnitudePlotWidget = new PlotWidget(); + FFTCorrectedErrorMagnitudePlotWidget->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, 0); - FFTCorrectedErrorMagnitudeChannel = new PlotChannel("FFT Corrected Error Magnitude", magnitudePen, - FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); - FFTCorrectedErrorPhaseChannel = new PlotChannel("FFT Corrected Error Phase", phasePen, - FFTCorrectedErrorXPlotAxis, FFTCorrectedErrorYPlotAxis); - FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorMagnitudeChannel); - FFTCorrectedErrorPlotWidget->addPlotChannel(FFTCorrectedErrorPhaseChannel); + FFTCorrectedErrorMagnitudeXPlotAxis = + new PlotAxis(QwtAxis::XBottom, FFTCorrectedErrorMagnitudePlotWidget, scopyBluePen); + PrefixFormatter *FFTCorrectedErrorXFormatter = + new PrefixFormatter({{" ", 1E0}}, FFTCorrectedErrorMagnitudeXPlotAxis); + FFTCorrectedErrorXFormatter->setTrimZeroes(true); + FFTCorrectedErrorMagnitudeXPlotAxis->setFormatter(FFTCorrectedErrorXFormatter); + FFTCorrectedErrorMagnitudeXPlotAxis->setMin(0); + FFTCorrectedErrorMagnitudeXPlotAxis->scaleDraw()->setFloatPrecision(0); - FFTCorrectedErrorPhaseChannel->setEnabled(true); - FFTCorrectedErrorMagnitudeChannel->setEnabled(true); - FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); + FFTCorrectedErrorMagnitudeYPlotAxis = + new PlotAxis(QwtAxis::YLeft, FFTCorrectedErrorMagnitudePlotWidget, scopyBluePen); + PrefixFormatter *FFTCorrectedErrorYFormatter = + new PrefixFormatter({{" ", 1E0}}, FFTCorrectedErrorMagnitudeYPlotAxis); + FFTCorrectedErrorYFormatter->setTrimZeroes(true); + FFTCorrectedErrorMagnitudeYPlotAxis->setFormatter(FFTCorrectedErrorYFormatter); + FFTCorrectedErrorMagnitudeYPlotAxis->setInterval(0, 1.2); - FFTCorrectedErrorPlotWidget->setShowXAxisLabels(true); - FFTCorrectedErrorPlotWidget->setShowYAxisLabels(true); - FFTCorrectedErrorPlotWidget->showAxisLabels(); - FFTCorrectedErrorPlotWidget->replot(); + FFTCorrectedErrorMagnitudeChannel = + new PlotChannel("FFT Corrected Error Magnitude", channel0Pen, FFTCorrectedErrorMagnitudeXPlotAxis, + FFTCorrectedErrorMagnitudeYPlotAxis); - QWidget *FFTCorrectedErrorChannelsWidget = new QWidget(); - QHBoxLayout *FFTCorrectedErrorChannelsLayout = new QHBoxLayout(FFTCorrectedErrorChannelsWidget); - ADMTStyleHelper::GraphChannelStyle(FFTCorrectedErrorChannelsWidget, FFTCorrectedErrorChannelsLayout); + FFTCorrectedErrorMagnitudePlotWidget->addPlotChannel(FFTCorrectedErrorMagnitudeChannel); - MenuControlButton *toggleFFTCorrectedErrorMagnitudeButton = - createChannelToggleWidget("Magnitude", magnitudeColor, FFTCorrectedErrorChannelsWidget); - MenuControlButton *toggleFFTCorrectedErrorPhaseButton = - createChannelToggleWidget("Phase", phaseColor, FFTCorrectedErrorChannelsWidget); + FFTCorrectedErrorMagnitudeChannel->setEnabled(true); + FFTCorrectedErrorMagnitudePlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); + + FFTCorrectedErrorMagnitudePlotWidget->setShowXAxisLabels(true); + FFTCorrectedErrorMagnitudePlotWidget->setShowYAxisLabels(true); + FFTCorrectedErrorMagnitudePlotWidget->showAxisLabels(); + FFTCorrectedErrorMagnitudePlotWidget->replot(); + + QLabel *FFTCorrectedErrorPhaseLabel = new QLabel("Phase", FFTCorrectedErrorWidget); + FFTCorrectedErrorPhaseLabel->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, 0); + + FFTCorrectedErrorPhasePlotWidget = new PlotWidget(); + FFTCorrectedErrorPhasePlotWidget->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, 0); + + FFTCorrectedErrorPhaseXPlotAxis = + new PlotAxis(QwtAxis::XBottom, FFTCorrectedErrorPhasePlotWidget, scopyBluePen); + PrefixFormatter *FFTCorrectedErrorPhaseXFormatter = + new PrefixFormatter({{" ", 1E0}}, FFTCorrectedErrorPhaseXPlotAxis); + FFTCorrectedErrorPhaseXFormatter->setTrimZeroes(true); + FFTCorrectedErrorPhaseXPlotAxis->setFormatter(FFTCorrectedErrorPhaseXFormatter); + FFTCorrectedErrorPhaseXPlotAxis->setMin(0); + FFTCorrectedErrorPhaseXPlotAxis->scaleDraw()->setFloatPrecision(0); + + FFTCorrectedErrorPhaseYPlotAxis = new PlotAxis(QwtAxis::YLeft, FFTCorrectedErrorPhasePlotWidget, scopyBluePen); + PrefixFormatter *FFTCorrectedErrorPhaseYFormatter = + new PrefixFormatter({{" ", 1E0}}, FFTCorrectedErrorPhaseYPlotAxis); + FFTCorrectedErrorPhaseYFormatter->setTrimZeroes(true); + FFTCorrectedErrorPhaseYPlotAxis->setFormatter(FFTCorrectedErrorPhaseYFormatter); + FFTCorrectedErrorPhaseYPlotAxis->setInterval(-4, 4); + + FFTCorrectedErrorPhaseChannel = + new PlotChannel("FFT Corrected Error Phase", channel1Pen, FFTCorrectedErrorPhaseXPlotAxis, + FFTCorrectedErrorPhaseYPlotAxis); + FFTCorrectedErrorPhasePlotWidget->addPlotChannel(FFTCorrectedErrorPhaseChannel); + + FFTCorrectedErrorPhaseChannel->setEnabled(true); + FFTCorrectedErrorPhasePlotWidget->selectChannel(FFTCorrectedErrorPhaseChannel); - FFTCorrectedErrorChannelsLayout->addWidget(toggleFFTCorrectedErrorMagnitudeButton); - FFTCorrectedErrorChannelsLayout->addWidget(toggleFFTCorrectedErrorPhaseButton); - FFTCorrectedErrorChannelsLayout->addStretch(); + FFTCorrectedErrorPhasePlotWidget->setShowXAxisLabels(true); + FFTCorrectedErrorPhasePlotWidget->setShowYAxisLabels(true); + FFTCorrectedErrorPhasePlotWidget->showAxisLabels(); + FFTCorrectedErrorPhasePlotWidget->replot(); - FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorPlotWidget); - FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorChannelsWidget); + FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorMagnitudeLabel); + FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorMagnitudePlotWidget); + FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorPhaseLabel); + FFTCorrectedErrorLayout->addWidget(FFTCorrectedErrorPhasePlotWidget); #pragma endregion resultDataTabWidget->addTab(angleErrorWidget, "Angle Error"); @@ -985,12 +1138,8 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() resultDataTabWidget->addTab(correctedErrorWidget, "Corrected Error"); resultDataTabWidget->addTab(FFTCorrectedErrorWidget, "FFT Corrected Error"); - calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget, 0, 0); - calibrationDataGraphLayout->addWidget(resultDataSectionWidget, 1, 0); - - calibrationDataGraphLayout->setColumnStretch(0, 1); - calibrationDataGraphLayout->setRowStretch(0, 1); - calibrationDataGraphLayout->setRowStretch(1, 1); + calibrationDataGraphLayout->addWidget(calibrationDataGraphSectionWidget, 0, 0, 3, 0); + calibrationDataGraphLayout->addWidget(resultDataSectionWidget, 3, 0, 5, 0); #pragma endregion #pragma region Calibration Settings Widget @@ -998,31 +1147,30 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() QVBoxLayout *calibrationSettingsGroupLayout = new QVBoxLayout(calibrationSettingsGroupWidget); calibrationSettingsGroupWidget->setLayout(calibrationSettingsGroupLayout); calibrationSettingsGroupLayout->setMargin(0); - calibrationSettingsGroupLayout->setSpacing(8); + calibrationSettingsGroupLayout->setSpacing(globalSpacingSmall); #pragma region Device Status Widget MenuSectionWidget *calibrationDeviceStatusWidget = new MenuSectionWidget(calibrationSettingsGroupWidget); Style::setStyle(calibrationDeviceStatusWidget, style::properties::widget::basicComponent); - calibrationDeviceStatusWidget->contentLayout()->setSpacing(8); MenuCollapseSection *calibrationDeviceStatusSection = new MenuCollapseSection( "Device Status", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationSettingsGroupWidget); - calibrationDeviceStatusSection->contentLayout()->setSpacing(8); + calibrationDeviceStatusSection->contentLayout()->setSpacing(globalSpacingSmall); calibrationDeviceStatusWidget->contentLayout()->addWidget(calibrationDeviceStatusSection); calibrationFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", "status", false, calibrationDeviceStatusSection); calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationFaultRegisterLEDWidget); - if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 - { - QCheckBox *calibrationSPICRCLEDWidget = - createStatusLEDWidget("SPI CRC", "status", false, calibrationDeviceStatusSection); - QCheckBox *calibrationSPIFlagLEDWidget = - createStatusLEDWidget("SPI Flag", "status", false, calibrationDeviceStatusSection); - calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPICRCLEDWidget); - calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPIFlagLEDWidget); - } + // if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 + // { + // QCheckBox *calibrationSPICRCLEDWidget = + // createStatusLEDWidget("SPI CRC", "status", false, calibrationDeviceStatusSection); + // QCheckBox *calibrationSPIFlagLEDWidget = + // createStatusLEDWidget("SPI Flag", "status", false, calibrationDeviceStatusSection); + // calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPICRCLEDWidget); + // calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPIFlagLEDWidget); + // } #pragma endregion #pragma region Acquire Calibration Samples Button @@ -1085,7 +1233,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() QVBoxLayout *calibrationSettingsLayout = new QVBoxLayout(calibrationSettingsWidget); calibrationSettingsScrollArea->setWidgetResizable(true); calibrationSettingsScrollArea->setWidget(calibrationSettingsWidget); - calibrationSettingsWidget->setFixedWidth(260); + calibrationSettingsWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); calibrationSettingsWidget->setLayout(calibrationSettingsLayout); calibrationSettingsGroupLayout->addWidget(calibrationDeviceStatusWidget); @@ -1348,46 +1496,30 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() connect(extractDataButton, &QPushButton::clicked, this, &HarmonicCalibration::extractCalibrationData); connect(importSamplesButton, &QPushButton::clicked, this, &HarmonicCalibration::importCalibrationData); connect(clearCalibrateDataButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAllCalibrationState); - connect(toggleAngleButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + connect(toggleAngleCheckBox, &QCheckBox::toggled, this, [this](bool b) { calibrationRawDataPlotWidget->selectChannel(calibrationRawDataPlotChannel); calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); }); - connect(toggleSineButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + connect(toggleSineCheckBox, &QCheckBox::toggled, this, [this](bool b) { calibrationRawDataPlotWidget->selectChannel(calibrationSineDataPlotChannel); calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); }); - connect(toggleCosineButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + connect(toggleCosineCheckBox, &QCheckBox::toggled, this, [this](bool b) { calibrationRawDataPlotWidget->selectChannel(calibrationCosineDataPlotChannel); calibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); }); - connect(togglePostAngleButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + connect(togglePostAngleCheckBox, &QCheckBox::toggled, this, [this](bool b) { postCalibrationRawDataPlotWidget->selectChannel(postCalibrationRawDataPlotChannel); postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); }); - connect(togglePostSineButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + connect(togglePostSineCheckBox, &QCheckBox::toggled, this, [this](bool b) { postCalibrationRawDataPlotWidget->selectChannel(postCalibrationSineDataPlotChannel); postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); }); - connect(togglePostCosineButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { + connect(togglePostCosineCheckBox, &QCheckBox::toggled, this, [this](bool b) { postCalibrationRawDataPlotWidget->selectChannel(postCalibrationCosineDataPlotChannel); postCalibrationRawDataPlotWidget->selectedChannel()->setEnabled(b); }); - connect(toggleFFTAngleErrorMagnitudeButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { - FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorMagnitudeChannel); - FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleFFTAngleErrorPhaseButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { - FFTAngleErrorPlotWidget->selectChannel(FFTAngleErrorPhaseChannel); - FFTAngleErrorPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleFFTCorrectedErrorMagnitudeButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { - FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorMagnitudeChannel); - FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); - }); - connect(toggleFFTCorrectedErrorPhaseButton->checkBox(), &QCheckBox::toggled, this, [this](bool b) { - FFTCorrectedErrorPlotWidget->selectChannel(FFTCorrectedErrorPhaseChannel); - FFTCorrectedErrorPlotWidget->selectedChannel()->setEnabled(b); - }); connect(calibrationDisplayFormatSwitch, &CustomSwitch::toggled, this, [this](bool b) { isAngleDisplayFormat = b; displayCalculatedCoeff(); @@ -2348,7 +2480,7 @@ bool HarmonicCalibration::changeCNVPage(uint32_t page) void HarmonicCalibration::initializeMotor() { - motor_rpm = 60; + motor_rpm = default_motor_rpm; rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(motor_rpm)); writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); @@ -2628,8 +2760,6 @@ void HarmonicCalibration::getAcquisitionSamples(int sampleRate) acquisitionAngleList.clear(); if(acquisitionDataMap.at(ABSANGLE) == false && acquisitionABSAngleList.size() > 0) acquisitionABSAngleList.clear(); - if(acquisitionDataMap.at(TURNCOUNT) == false && acquisitionTurnCountList.size() > 0) - acquisitionTurnCountList.clear(); if(acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) acquisitionTmp0List.clear(); if(acquisitionDataMap.at(SINE) == false && acquisitionSineList.size() > 0) @@ -2638,62 +2768,97 @@ void HarmonicCalibration::getAcquisitionSamples(int sampleRate) acquisitionCosineList.clear(); if(acquisitionDataMap.at(RADIUS) == false && acquisitionRadiusList.size() > 0) acquisitionRadiusList.clear(); + if(acquisitionDataMap.at(ANGLESEC) == false && acquisitionAngleSecList.size() > 0) + acquisitionAngleSecList.clear(); + if(acquisitionDataMap.at(SECANGLI) == false && acquisitionSecAnglIList.size() > 0) + acquisitionSecAnglIList.clear(); + if(acquisitionDataMap.at(SECANGLQ) == false && acquisitionSecAnglQList.size() > 0) + acquisitionSecAnglQList.clear(); + if(acquisitionDataMap.at(TMP1) == false && acquisitionTmp1List.size() > 0) + acquisitionTmp1List.clear(); if(acquisitionDataMap.at(ANGLE)) prependAcquisitionData(angle, acquisitionAngleList); if(acquisitionDataMap.at(ABSANGLE)) prependAcquisitionData(rotation, acquisitionABSAngleList); - if(acquisitionDataMap.at(TURNCOUNT)) - prependAcquisitionData(count, acquisitionTurnCountList); if(acquisitionDataMap.at(TMP0)) prependAcquisitionData(temp, acquisitionTmp0List); if(acquisitionDataMap.at(SINE)) - prependAcquisitionData(getAcquisitionParameterValue(SINE), acquisitionSineList); + prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::SINE), + acquisitionSineList); if(acquisitionDataMap.at(COSINE)) - prependAcquisitionData(getAcquisitionParameterValue(COSINE), acquisitionCosineList); + prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::COSINE), + acquisitionCosineList); if(acquisitionDataMap.at(RADIUS)) - prependAcquisitionData(getAcquisitionParameterValue(RADIUS), acquisitionRadiusList); + prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::RADIUS), + acquisitionRadiusList); + if(acquisitionDataMap.at(ANGLESEC)) + prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::ANGLESEC), + acquisitionAngleSecList); + if(acquisitionDataMap.at(SECANGLI)) + prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLI), + acquisitionSecAnglIList); + if(acquisitionDataMap.at(SECANGLQ)) + prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLQ), + acquisitionSecAnglQList); + if(acquisitionDataMap.at(TMP1)) + prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::TMP1), + acquisitionTmp1List); QThread::msleep(sampleRate); } } -double HarmonicCalibration::getAcquisitionParameterValue(const AcquisitionDataKey &key) +double HarmonicCalibration::getSensorDataAcquisitionValue(const ADMTController::SensorRegister &key) { uint32_t *readValue = new uint32_t; + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(key), readValue) == -1) + return qQNaN(); + switch(key) { - case SINE: { - if(m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(ADMTController::SensorRegister::SINE), readValue) == -1) - return qQNaN(); + case ADMTController::SensorRegister::SINE: { map sineRegisterMap = m_admtController->getSineRegisterBitMapping(static_cast(*readValue)); return sineRegisterMap.at("SINE"); break; } - case COSINE: { - if(m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(ADMTController::SensorRegister::COSINE), - readValue) == -1) - return qQNaN(); + case ADMTController::SensorRegister::COSINE: { map cosineRegisterMap = m_admtController->getCosineRegisterBitMapping(static_cast(*readValue)); return cosineRegisterMap.at("COSINE"); break; } - case RADIUS: { - if(m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(ADMTController::SensorRegister::RADIUS), - readValue) == -1) - return qQNaN(); + case ADMTController::SensorRegister::RADIUS: { map radiusRegisterMap = m_admtController->getRadiusRegisterBitMapping(static_cast(*readValue)); return radiusRegisterMap.at("RADIUS"); break; } + case ADMTController::SensorRegister::ANGLESEC: { + map angleSecRegisterMap = + m_admtController->getAngleSecRegisterBitMapping(static_cast(*readValue)); + return angleSecRegisterMap.at("ANGLESEC"); + break; + } + case ADMTController::SensorRegister::SECANGLI: { + map secAnglIRegisterMap = + m_admtController->getSecAnglIRegisterBitMapping(static_cast(*readValue)); + return secAnglIRegisterMap.at("SECANGLI"); + break; + } + case ADMTController::SensorRegister::SECANGLQ: { + map secAnglQRegisterMap = + m_admtController->getSecAnglQRegisterBitMapping(static_cast(*readValue)); + return secAnglQRegisterMap.at("SECANGLQ"); + break; + } + case ADMTController::SensorRegister::TMP1: { + map tmp1RegisterMap = + m_admtController->getTmp1RegisterBitMapping(static_cast(*readValue), is5V); + return tmp1RegisterMap.at("TMP1"); + break; + } default: return qQNaN(); break; @@ -2734,8 +2899,6 @@ void HarmonicCalibration::acquisitionPlotTask(int sampleRate) plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel); if(acquisitionDataMap.at(ABSANGLE)) plotAcquisition(acquisitionABSAngleList, acquisitionABSAnglePlotChannel); - if(acquisitionDataMap.at(TURNCOUNT)) - plotAcquisition(acquisitionTurnCountList, acquisitionTurnCountPlotChannel); if(acquisitionDataMap.at(TMP0)) plotAcquisition(acquisitionTmp0List, acquisitionTmp0PlotChannel); if(acquisitionDataMap.at(SINE)) @@ -2744,6 +2907,14 @@ void HarmonicCalibration::acquisitionPlotTask(int sampleRate) plotAcquisition(acquisitionCosineList, acquisitionCosinePlotChannel); if(acquisitionDataMap.at(RADIUS)) plotAcquisition(acquisitionRadiusList, acquisitionRadiusPlotChannel); + if(acquisitionDataMap.at(ANGLESEC)) + plotAcquisition(acquisitionAngleSecList, acquisitionAngleSecPlotChannel); + if(acquisitionDataMap.at(SECANGLI)) + plotAcquisition(acquisitionSecAnglIList, acquisitionSecAnglIPlotChannel); + if(acquisitionDataMap.at(SECANGLQ)) + plotAcquisition(acquisitionSecAnglQList, acquisitionSecAnglQPlotChannel); + if(acquisitionDataMap.at(TMP1)) + plotAcquisition(acquisitionTmp1List, acquisitionTmp1PlotChannel); acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); acquisitionGraphPlotWidget->replot(); @@ -2804,10 +2975,62 @@ void HarmonicCalibration::updateSequenceWidget() eighthHarmonicMenuCombo->combo()->findData(GENERALRegisterMap.at("8th Harmonic"))); } +void HarmonicCalibration::updateCapturedDataCheckBoxes() +{ + acquisitionGraphChannelGridLayout->removeWidget(angleCheckBox); + acquisitionGraphChannelGridLayout->removeWidget(sineCheckBox); + acquisitionGraphChannelGridLayout->removeWidget(cosineCheckBox); + acquisitionGraphChannelGridLayout->removeWidget(radiusCheckBox); + acquisitionGraphChannelGridLayout->removeWidget(absAngleCheckBox); + acquisitionGraphChannelGridLayout->removeWidget(temp0CheckBox); + acquisitionGraphChannelGridLayout->removeWidget(angleSecCheckBox); + acquisitionGraphChannelGridLayout->removeWidget(secAnglQCheckBox); + acquisitionGraphChannelGridLayout->removeWidget(secAnglICheckBox); + acquisitionGraphChannelGridLayout->removeWidget(temp1CheckBox); + + if(GENERALRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 + { + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); + angleSecCheckBox->setChecked(false); + secAnglICheckBox->setChecked(false); + secAnglQCheckBox->setChecked(false); + temp1CheckBox->setChecked(false); + angleSecCheckBox->hide(); + secAnglICheckBox->hide(); + secAnglQCheckBox->hide(); + temp1CheckBox->hide(); + } else if(GENERALRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 + { + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(angleSecCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(secAnglQCheckBox, 0, 4); + acquisitionGraphChannelGridLayout->addWidget(secAnglICheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 1, 1); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 2); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 3); + acquisitionGraphChannelGridLayout->addWidget(temp1CheckBox, 1, 4); + angleSecCheckBox->show(); + secAnglICheckBox->show(); + secAnglQCheckBox->show(); + temp1CheckBox->show(); + } + + acquisitionGraphChannelGridLayout->update(); + acquisitionGraphChannelWidget->update(); +} + void HarmonicCalibration::applySequenceAndUpdate() { applySequence(); updateSequenceWidget(); + updateCapturedDataCheckBoxes(); } void HarmonicCalibration::updateGeneralSettingEnabled(bool value) @@ -2816,8 +3039,7 @@ void HarmonicCalibration::updateGeneralSettingEnabled(bool value) displayLengthLineEdit->setEnabled(value); } -void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, - AcquisitionDataKey key) +void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, SensorDataKey key) { connect(widget, &QCheckBox::stateChanged, [this, channel, key](int state) { if(state == Qt::Checked) { @@ -3189,7 +3411,7 @@ void HarmonicCalibration::startOneShotCalibration() clearCalibrationSamples(); clearPostCalibrationSamples(); clearAngleErrorGraphs(); - clearCorrectedAngleErrorGraphs(); + clearFFTAngleErrorGraphs(); } else if(resetToZero) { clearPostCalibrationSamples(); } @@ -3266,7 +3488,7 @@ void HarmonicCalibration::resetAllCalibrationState() calibrationDataGraphTabWidget->setCurrentIndex(0); clearAngleErrorGraphs(); - clearCorrectedAngleErrorGraphs(); + clearFFTAngleErrorGraphs(); resultDataTabWidget->setCurrentIndex(0); toggleCalibrationButtonState(0); @@ -3310,23 +3532,51 @@ void HarmonicCalibration::populateAngleErrorGraphs() angleErrorPlotChannel->curve()->setSamples(angleError); auto angleErrorMinMax = minmax_element(angleError.begin(), angleError.end()); - angleErrorYPlotAxis->setInterval(*angleErrorMinMax.first, *angleErrorMinMax.second); - angleErrorXPlotAxis->setInterval(0, angleError.size()); + if(currentAngleErrorGraphMin > *angleErrorMinMax.first) { + currentAngleErrorGraphMin = *angleErrorMinMax.first; + angleErrorYPlotAxis->setMin(currentAngleErrorGraphMin); + correctedErrorYPlotAxis->setMin(currentAngleErrorGraphMin); + } + if(currentAngleErrorGraphMax < *angleErrorMinMax.second) { + currentAngleErrorGraphMax = *angleErrorMinMax.second; + angleErrorYPlotAxis->setMax(currentAngleErrorGraphMax); + correctedErrorYPlotAxis->setMax(currentAngleErrorGraphMax); + } + angleErrorXPlotAxis->setMax(angleError.size()); angleErrorPlotWidget->replot(); + correctedErrorPlotWidget->replot(); - FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); FFTAngleErrorMagnitudeChannel->curve()->setSamples(FFTAngleErrorMagnitude); auto angleErrorMagnitudeMinMax = minmax_element(FFTAngleErrorMagnitude.begin(), FFTAngleErrorMagnitude.end()); + if(currentMagnitudeGraphMin > *angleErrorMagnitudeMinMax.first) { + currentMagnitudeGraphMin = *angleErrorMagnitudeMinMax.first; + FFTAngleErrorMagnitudeYPlotAxis->setMin(currentMagnitudeGraphMin); + FFTCorrectedErrorMagnitudeYPlotAxis->setMin(currentMagnitudeGraphMin); + } + if(currentMagnitudeGraphMax < *angleErrorMagnitudeMinMax.second) { + currentMagnitudeGraphMax = *angleErrorMagnitudeMinMax.second; + FFTAngleErrorMagnitudeYPlotAxis->setMax(currentMagnitudeGraphMax); + FFTCorrectedErrorMagnitudeYPlotAxis->setMax(currentMagnitudeGraphMax); + } + FFTAngleErrorMagnitudeXPlotAxis->setMax(FFTAngleErrorMagnitude.size()); + FFTAngleErrorMagnitudePlotWidget->replot(); + FFTCorrectedErrorMagnitudePlotWidget->replot(); + + FFTAngleErrorPhaseChannel->curve()->setSamples(FFTAngleErrorPhase); auto angleErrorPhaseMinMax = minmax_element(FFTAngleErrorPhase.begin(), FFTAngleErrorPhase.end()); - double FFTAngleErrorPlotMin = *angleErrorMagnitudeMinMax.first < *angleErrorPhaseMinMax.first - ? *angleErrorMagnitudeMinMax.first - : *angleErrorPhaseMinMax.first; - double FFTAngleErrorPlotMax = *angleErrorMagnitudeMinMax.second > *angleErrorPhaseMinMax.second - ? *angleErrorMagnitudeMinMax.second - : *angleErrorPhaseMinMax.second; - FFTAngleErrorYPlotAxis->setInterval(FFTAngleErrorPlotMin, FFTAngleErrorPlotMax); - FFTAngleErrorXPlotAxis->setInterval(0, FFTAngleErrorMagnitude.size()); - FFTAngleErrorPlotWidget->replot(); + if(currentPhaseGraphMin > *angleErrorPhaseMinMax.first) { + currentPhaseGraphMin = *angleErrorPhaseMinMax.first; + FFTAngleErrorPhaseYPlotAxis->setMin(currentPhaseGraphMin); + FFTCorrectedErrorPhaseYPlotAxis->setMin(currentPhaseGraphMin); + } + if(currentPhaseGraphMax < *angleErrorPhaseMinMax.second) { + currentPhaseGraphMax = *angleErrorPhaseMinMax.second; + FFTAngleErrorPhaseYPlotAxis->setMax(currentPhaseGraphMax); + FFTCorrectedErrorPhaseYPlotAxis->setMax(currentPhaseGraphMax); + } + FFTAngleErrorPhaseXPlotAxis->setInterval(0, FFTAngleErrorPhase.size()); + FFTAngleErrorPhasePlotWidget->replot(); + FFTCorrectedErrorPhasePlotWidget->replot(); resultDataTabWidget->setCurrentIndex(0); // Set tab to Angle Error } @@ -3342,27 +3592,53 @@ void HarmonicCalibration::populateCorrectedAngleErrorGraphs() correctedErrorPlotChannel->curve()->setSamples(correctedError); auto correctedErrorMagnitudeMinMax = minmax_element(correctedError.begin(), correctedError.end()); - correctedErrorYPlotAxis->setInterval(*correctedErrorMagnitudeMinMax.first, - *correctedErrorMagnitudeMinMax.second); + if(currentAngleErrorGraphMin > *correctedErrorMagnitudeMinMax.first) { + currentAngleErrorGraphMin = *correctedErrorMagnitudeMinMax.first; + angleErrorYPlotAxis->setMin(currentAngleErrorGraphMin); + correctedErrorYPlotAxis->setMin(currentAngleErrorGraphMin); + } + if(currentAngleErrorGraphMax < *correctedErrorMagnitudeMinMax.second) { + currentAngleErrorGraphMax = *correctedErrorMagnitudeMinMax.second; + angleErrorYPlotAxis->setMax(currentAngleErrorGraphMax); + correctedErrorYPlotAxis->setMax(currentAngleErrorGraphMax); + } correctedErrorXPlotAxis->setMax(correctedError.size()); + angleErrorPlotWidget->replot(); correctedErrorPlotWidget->replot(); - FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); FFTCorrectedErrorMagnitudeChannel->curve()->setSamples(FFTCorrectedErrorMagnitude); auto FFTCorrectedErrorMagnitudeMinMax = minmax_element(FFTCorrectedErrorMagnitude.begin(), FFTCorrectedErrorMagnitude.end()); + if(currentMagnitudeGraphMin > *FFTCorrectedErrorMagnitudeMinMax.first) { + currentMagnitudeGraphMin = *FFTCorrectedErrorMagnitudeMinMax.first; + FFTAngleErrorMagnitudeYPlotAxis->setMin(currentMagnitudeGraphMin); + FFTCorrectedErrorMagnitudeYPlotAxis->setMin(currentMagnitudeGraphMin); + } + if(currentMagnitudeGraphMax < *FFTCorrectedErrorMagnitudeMinMax.second) { + currentMagnitudeGraphMax = *FFTCorrectedErrorMagnitudeMinMax.second; + FFTAngleErrorMagnitudeYPlotAxis->setMax(currentMagnitudeGraphMax); + FFTCorrectedErrorMagnitudeYPlotAxis->setMax(currentMagnitudeGraphMax); + } + FFTCorrectedErrorMagnitudeXPlotAxis->setMax(FFTCorrectedErrorMagnitude.size()); + FFTAngleErrorMagnitudePlotWidget->replot(); + FFTCorrectedErrorMagnitudePlotWidget->replot(); + + FFTCorrectedErrorPhaseChannel->curve()->setSamples(FFTCorrectedErrorPhase); auto FFTCorrectedErrorPhaseMinMax = minmax_element(FFTCorrectedErrorPhase.begin(), FFTCorrectedErrorPhase.end()); - double FFTCorrectedErrorPlotMin = *FFTCorrectedErrorMagnitudeMinMax.first < *FFTCorrectedErrorPhaseMinMax.first - ? *FFTCorrectedErrorMagnitudeMinMax.first - : *FFTCorrectedErrorPhaseMinMax.first; - double FFTCorrectedErrorPlotMax = - *FFTCorrectedErrorMagnitudeMinMax.second > *FFTCorrectedErrorPhaseMinMax.second - ? *FFTCorrectedErrorMagnitudeMinMax.second - : *FFTCorrectedErrorPhaseMinMax.second; - FFTCorrectedErrorYPlotAxis->setInterval(FFTCorrectedErrorPlotMin, FFTCorrectedErrorPlotMax); - FFTCorrectedErrorXPlotAxis->setMax(FFTCorrectedErrorMagnitude.size()); - FFTCorrectedErrorPlotWidget->replot(); + if(currentPhaseGraphMin > *FFTCorrectedErrorPhaseMinMax.first) { + currentPhaseGraphMin = *FFTCorrectedErrorPhaseMinMax.first; + FFTAngleErrorPhaseYPlotAxis->setMin(currentPhaseGraphMin); + FFTCorrectedErrorPhaseYPlotAxis->setMin(currentPhaseGraphMin); + } + if(currentPhaseGraphMax < *FFTCorrectedErrorPhaseMinMax.second) { + currentPhaseGraphMax = *FFTCorrectedErrorPhaseMinMax.second; + FFTAngleErrorPhaseYPlotAxis->setMax(currentPhaseGraphMax); + FFTCorrectedErrorPhaseYPlotAxis->setMax(currentPhaseGraphMax); + } + FFTCorrectedErrorPhaseXPlotAxis->setMax(FFTCorrectedErrorPhase.size()); + FFTAngleErrorPhasePlotWidget->replot(); + FFTCorrectedErrorPhasePlotWidget->replot(); resultDataTabWidget->setCurrentIndex(2); // Set tab to Angle Error } @@ -3806,20 +4082,35 @@ void HarmonicCalibration::clearPostCalibrationSamples() void HarmonicCalibration::clearAngleErrorGraphs() { + currentAngleErrorGraphMin = defaultAngleErrorGraphMin; + currentAngleErrorGraphMax = defaultAngleErrorGraphMax; + angleErrorYPlotAxis->setInterval(currentAngleErrorGraphMin, currentAngleErrorGraphMax); angleErrorPlotChannel->curve()->setData(nullptr); angleErrorPlotWidget->replot(); - FFTAngleErrorMagnitudeChannel->curve()->setData(nullptr); - FFTAngleErrorPhaseChannel->curve()->setData(nullptr); - FFTAngleErrorPlotWidget->replot(); + correctedErrorYPlotAxis->setInterval(currentAngleErrorGraphMin, currentAngleErrorGraphMax); + correctedErrorPlotChannel->curve()->setData(nullptr); + correctedErrorPlotWidget->replot(); } -void HarmonicCalibration::clearCorrectedAngleErrorGraphs() +void HarmonicCalibration::clearFFTAngleErrorGraphs() { - correctedErrorPlotChannel->curve()->setData(nullptr); - correctedErrorPlotWidget->replot(); + currentMagnitudeGraphMin = defaultMagnitudeGraphMin; + currentMagnitudeGraphMax = defaultMagnitudeGraphMax; + FFTAngleErrorMagnitudeYPlotAxis->setInterval(currentMagnitudeGraphMin, currentMagnitudeGraphMax); + FFTAngleErrorMagnitudeChannel->curve()->setData(nullptr); + FFTAngleErrorMagnitudePlotWidget->replot(); + FFTCorrectedErrorMagnitudeYPlotAxis->setInterval(currentMagnitudeGraphMin, currentMagnitudeGraphMax); FFTCorrectedErrorMagnitudeChannel->curve()->setData(nullptr); + FFTCorrectedErrorMagnitudePlotWidget->replot(); + + currentPhaseGraphMin = defaultPhaseGraphMin; + currentPhaseGraphMax = defaultPhaseGraphMax; + FFTAngleErrorPhaseYPlotAxis->setInterval(currentPhaseGraphMin, currentPhaseGraphMax); + FFTAngleErrorPhaseChannel->curve()->setData(nullptr); + FFTAngleErrorPhasePlotWidget->replot(); + FFTCorrectedErrorPhaseYPlotAxis->setInterval(currentPhaseGraphMin, currentPhaseGraphMax); FFTCorrectedErrorPhaseChannel->curve()->setData(nullptr); - FFTCorrectedErrorPlotWidget->replot(); + FFTCorrectedErrorPhasePlotWidget->replot(); } #pragma endregion @@ -3981,15 +4272,12 @@ void HarmonicCalibration::getDIGIOENRegister() if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), digioRegisterAddress, digioRegValue) != -1) { - uint16_t *digioRegValue16 = new uint16_t; - *digioRegValue16 = static_cast(*digioRegValue); + quint16 digioRegValue16 = static_cast(*digioRegValue); Q_EMIT DIGIORegisterChanged(digioRegValue16); Q_EMIT commandLogWriteSignal("DIGIOEN: 0b" + - QString::number(*digioRegValue, 2).rightJustified(16, '0')); - - delete digioRegValue16; + QString::number(digioRegValue16, 2).rightJustified(16, '0')); } else { Q_EMIT commandLogWriteSignal("Failed to read DIGIOEN Register"); } @@ -3998,9 +4286,9 @@ void HarmonicCalibration::getDIGIOENRegister() delete digioRegValue; } -void HarmonicCalibration::updateDIGIOUI(uint16_t *registerValue) +void HarmonicCalibration::updateDIGIOUI(quint16 registerValue) { - DIGIOENRegisterMap = m_admtController->getDIGIOENRegisterBitMapping(*registerValue); + DIGIOENRegisterMap = m_admtController->getDIGIOENRegisterBitMapping(registerValue); updateDIGIOMonitorUI(); updateDIGIOControlUI(); } @@ -4105,16 +4393,13 @@ void HarmonicCalibration::getDIAG2Register() if(m_admtController->readDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag2RegisterAddress, mtDiag2RegValue) != -1) { - uint16_t *mtDiag2RegValue16 = new uint16_t; - *mtDiag2RegValue16 = static_cast(*mtDiag2RegValue); + quint16 mtDiag2RegValue16 = static_cast(*mtDiag2RegValue); Q_EMIT DIAG2RegisterChanged(mtDiag2RegValue16); Q_EMIT commandLogWriteSignal( "DIAG2: 0b" + - QString::number(*mtDiag2RegValue, 2).rightJustified(16, '0')); - - delete mtDiag2RegValue16; + QString::number(mtDiag2RegValue16, 2).rightJustified(16, '0')); } else { Q_EMIT commandLogWriteSignal("Failed to read MT Diagnostic 2 Register"); } @@ -4132,9 +4417,9 @@ void HarmonicCalibration::getDIAG2Register() delete mtDiag2RegValue, cnvPageRegValue; } -void HarmonicCalibration::updateMTDiagnosticsUI(uint16_t *registerValue) +void HarmonicCalibration::updateMTDiagnosticsUI(quint16 registerValue) { - DIAG2RegisterMap = m_admtController->getDiag2RegisterBitMapping(*registerValue); + DIAG2RegisterMap = m_admtController->getDiag2RegisterBitMapping(registerValue); map regmap = DIAG2RegisterMap; afeDiag0 = regmap.at("AFE Diagnostic 0 (-57%)"); @@ -4160,15 +4445,14 @@ void HarmonicCalibration::getDIAG1Register() if(m_admtController->readDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), mtDiag1RegisterAddress, mtDiag1RegValue) != -1) { - uint16_t *mtDiag1RegValue16 = new uint16_t; - *mtDiag1RegValue16 = static_cast(*mtDiag1RegValue); + quint16 mtDiag1RegValue16 = static_cast(*mtDiag1RegValue); Q_EMIT DIAG1RegisterChanged(mtDiag1RegValue16); Q_EMIT commandLogWriteSignal( "DIAG1: 0b" + - QString::number(*mtDiag1RegValue16, 2).rightJustified(16, '0')); + QString::number(mtDiag1RegValue16, 2).rightJustified(16, '0')); - delete mtDiag1RegValue16; + // delete mtDiag1RegValue16; } else { Q_EMIT commandLogWriteSignal("Failed to read MT Diagnostic 1 Register"); } @@ -4186,10 +4470,10 @@ void HarmonicCalibration::getDIAG1Register() delete mtDiag1RegValue, cnvPageRegValue; } -void HarmonicCalibration::updateMTDiagnosticRegisterUI(uint16_t *registerValue) +void HarmonicCalibration::updateMTDiagnosticRegisterUI(quint16 registerValue) { - DIAG1RegisterMap = m_admtController->getDiag1RegisterBitMapping_Register(*registerValue); - DIAG1AFERegisterMap = m_admtController->getDiag1RegisterBitMapping_Afe(*registerValue, is5V); + DIAG1RegisterMap = m_admtController->getDiag1RegisterBitMapping_Register(registerValue); + DIAG1AFERegisterMap = m_admtController->getDiag1RegisterBitMapping_Afe(registerValue, is5V); map regmap = DIAG1RegisterMap; map afeRegmap = DIAG1AFERegisterMap; @@ -4215,14 +4499,11 @@ void HarmonicCalibration::getFAULTRegister() if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), faultRegisterAddress, faultRegValue) != -1) { - uint16_t *faultRegValue16 = new uint16_t; - *faultRegValue16 = static_cast(*faultRegValue); + quint16 faultRegValue16 = static_cast(*faultRegValue); Q_EMIT FaultRegisterChanged(faultRegValue16); - Q_EMIT commandLogWriteSignal("FAULT: 0b" + QString::number(*faultRegValue, 2).rightJustified(16, '0')); - - delete faultRegValue16; + Q_EMIT commandLogWriteSignal("FAULT: 0b" + QString::number(faultRegValue16, 2).rightJustified(16, '0')); } else { Q_EMIT commandLogWriteSignal("Failed to read FAULT Register"); } @@ -4230,9 +4511,9 @@ void HarmonicCalibration::getFAULTRegister() delete faultRegValue; } -void HarmonicCalibration::updateFaultRegisterUI(uint16_t *faultRegValue) +void HarmonicCalibration::updateFaultRegisterUI(quint16 faultRegValue) { - FAULTRegisterMap = m_admtController->getFaultRegisterBitMapping(*faultRegValue); + FAULTRegisterMap = m_admtController->getFaultRegisterBitMapping(faultRegValue); map regmap = FAULTRegisterMap; VDDUnderVoltageStatusLED->setChecked(regmap.at("VDD Under Voltage")); @@ -4521,21 +4802,6 @@ QCheckBox *HarmonicCalibration::createStatusLEDWidget(const QString &text, QVari checkBox->setEnabled(false); return checkBox; } - -MenuControlButton *HarmonicCalibration::createChannelToggleWidget(const QString title, QColor color, QWidget *parent) -{ - MenuControlButton *menuControlButton = new MenuControlButton(parent); - menuControlButton->setName(title); - menuControlButton->setCheckBoxStyle(MenuControlButton::CheckboxStyle::CS_CIRCLE); - menuControlButton->setOpenMenuChecksThis(true); - menuControlButton->setDoubleClickToOpenMenu(true); - menuControlButton->setColor(color); - menuControlButton->button()->setVisible(false); - menuControlButton->setCheckable(false); - menuControlButton->checkBox()->setChecked(true); - menuControlButton->layout()->setMargin(0); - return menuControlButton; -} #pragma endregion #pragma region Connect Methods diff --git a/plugins/admt/style/qss/properties/admt/coloredCheckBox.qss b/plugins/admt/style/qss/properties/admt/coloredCheckBox.qss new file mode 100644 index 0000000000..fac9efba6e --- /dev/null +++ b/plugins/admt/style/qss/properties/admt/coloredCheckBox.qss @@ -0,0 +1,31 @@ +QCheckBox::indicator[&&property&&="ch0"]::checked { + background-color: &ch0&; +} + +QCheckBox::indicator[&&property&&="ch1"]::checked { + background-color: &ch1&; +} + +QCheckBox::indicator[&&property&&="ch2"]::checked { + background-color: &ch2&; +} + +QCheckBox::indicator[&&property&&="ch3"]::checked { + background-color: &ch3&; +} + +QCheckBox::indicator[&&property&&="ch4"]::checked { + background-color: &ch4&; +} + +QCheckBox::indicator[&&property&&="ch5"]::checked { + background-color: &ch5&; +} + +QCheckBox::indicator[&&property&&="ch6"]::checked { + background-color: &ch6&; +} + +QCheckBox::indicator[&&property&&="ch7"]::checked { + background-color: &ch7&; +} \ No newline at end of file From 84a1e98db9e3b50c632d215dd2801a776749ff74 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 10 Mar 2025 07:27:21 +0800 Subject: [PATCH 093/112] admt: Include XML IIO Emulator for ADMT4000 Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/xmls/admt4000.xml | 116 +++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 plugins/admt/xmls/admt4000.xml diff --git a/plugins/admt/xmls/admt4000.xml b/plugins/admt/xmls/admt4000.xml new file mode 100644 index 0000000000..96c29eda3b --- /dev/null +++ b/plugins/admt/xmls/admt4000.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 86effff7a616c5ff07089c5fd2c2c9605e926070 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 12 Mar 2025 10:01:33 +0800 Subject: [PATCH 094/112] admt: Migrated styles - Removed ADMTStyleHelper and dependencies - Removed unused horizontal spinbox - Updated labels to subtle style - Set fixed size for custom switch Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtstylehelper.h | 81 ---- .../admt/include/admt/harmoniccalibration.h | 6 +- .../include/admt/widgets/horizontalspinbox.h | 63 --- plugins/admt/src/admtstylehelper.cpp | 365 ------------------ plugins/admt/src/harmoniccalibration.cpp | 197 +++++++--- .../admt/src/widgets/horizontalspinbox.cpp | 215 ----------- .../qss/properties/admt/coeffRowContainer.qss | 21 + .../admt/style/qss/properties/admt/tabBar.qss | 4 + 8 files changed, 161 insertions(+), 791 deletions(-) delete mode 100644 plugins/admt/include/admt/admtstylehelper.h delete mode 100644 plugins/admt/include/admt/widgets/horizontalspinbox.h delete mode 100644 plugins/admt/src/admtstylehelper.cpp delete mode 100644 plugins/admt/src/widgets/horizontalspinbox.cpp create mode 100644 plugins/admt/style/qss/properties/admt/coeffRowContainer.qss diff --git a/plugins/admt/include/admt/admtstylehelper.h b/plugins/admt/include/admt/admtstylehelper.h deleted file mode 100644 index 77cdeab639..0000000000 --- a/plugins/admt/include/admt/admtstylehelper.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2025 Analog Devices Inc. - * - * This file is part of Scopy - * (see https://www.github.com/analogdevicesinc/scopy). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef ADMTSTYLEHELPER_H -#define ADMTSTYLEHELPER_H - -#include "scopy-admt_export.h" -#include "style.h" -#include "stylehelper.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace scopy { -namespace admt { -class SCOPY_ADMT_EXPORT ADMTStyleHelper : public QObject -{ - Q_OBJECT -protected: - ADMTStyleHelper(QObject *parent = nullptr); - ~ADMTStyleHelper(); - -public: - // singleton - ADMTStyleHelper(ADMTStyleHelper &other) = delete; - void operator=(const ADMTStyleHelper &) = delete; - static ADMTStyleHelper *GetInstance(); - -public: - static void initColorMap(); - static QString getColor(QString id); - static void TopContainerButtonStyle(QPushButton *btn, QString objectName = ""); - static void PlotWidgetStyle(PlotWidget *widget, QString objectName = ""); - static void ComboBoxStyle(QComboBox *widget, QString objectName = ""); - static void LineEditStyle(QLineEdit *widget, QString objectName = ""); - static void ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName = ""); - static void StartButtonStyle(QPushButton *btn, QString objectName = ""); - static void TextStyle(QWidget *widget, const char *styleHelperColor = json::global::white, bool isBold = false, - QString objectName = ""); // void TextStyle(QWidget *widget, const - // QString& styleHelperColor, bool isBold - // = false, QString objectName = ""); - static void MenuSmallLabel(QLabel *label, QString objectName = ""); - static void LineStyle(QFrame *line, QString objectName = ""); - static void UIBackgroundStyle(QWidget *widget, QString objectName = ""); - static void GraphChannelStyle(QWidget *widget, QLayout *layout, QString objectName = ""); - static void CalculatedCoeffWidgetRowStyle(QWidget *widget, QHBoxLayout *layout, QLabel *hLabel, - QLabel *hMagLabel, QLabel *hPhaseLabel, QString objectName = ""); - -private: - QMap colorMap; - static ADMTStyleHelper *pinstance_; -}; -} // namespace admt -} // namespace scopy - -#endif // ADMTSTYLEHELPER_H \ No newline at end of file diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 6a5859b472..41369a52d9 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -73,7 +73,6 @@ #include #include #include -#include #include enum SensorDataKey @@ -216,9 +215,6 @@ public Q_SLOTS: *postCalibrationCosineDataPlotChannel, *FFTCorrectedErrorMagnitudeChannel, *FFTCorrectedErrorPhaseChannel; - HorizontalSpinBox *motorMaxVelocitySpinBox, *motorAccelTimeSpinBox, *motorMaxDisplacementSpinBox, - *motorTargetPositionSpinBox; - CustomSwitch *acquisitionMotorDirectionSwitch, *calibrationMotorDirectionSwitch, *calibrationDisplayFormatSwitch, *DIGIO0ENToggleSwitch, *DIGIO0FNCToggleSwitch, *DIGIO1ENToggleSwitch, *DIGIO1FNCToggleSwitch, *DIGIO2ENToggleSwitch, *DIGIO2FNCToggleSwitch, *DIGIO3ENToggleSwitch, @@ -383,6 +379,8 @@ public Q_SLOTS: void changeCustomSwitchLabel(CustomSwitch *customSwitch, QString onLabel, QString offLabel); QCheckBox *createStatusLEDWidget(const QString &text, QVariant variant = true, bool checked = false, QWidget *parent = nullptr); + void configureCoeffRow(QWidget *container, QHBoxLayout *layout, QLabel *hLabel, QLabel *hMagLabel, + QLabel *hPhaseLabel); #pragma endregion #pragma region Connect Methods diff --git a/plugins/admt/include/admt/widgets/horizontalspinbox.h b/plugins/admt/include/admt/widgets/horizontalspinbox.h deleted file mode 100644 index c97f30cf73..0000000000 --- a/plugins/admt/include/admt/widgets/horizontalspinbox.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2025 Analog Devices Inc. - * - * This file is part of Scopy - * (see https://www.github.com/analogdevicesinc/scopy). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef HORIZONTALSPINBOX_H -#define HORIZONTALSPINBOX_H - -#include "../scopy-admt_export.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace scopy::admt { -class SCOPY_ADMT_EXPORT HorizontalSpinBox : public QWidget -{ - Q_OBJECT -public: - HorizontalSpinBox(QString header = "", double initialValue = 0.0, QString unit = "", QWidget *parent = nullptr); - QLineEdit *lineEdit(); - void setEnabled(double value); -public Q_SLOTS: - void setValue(double); -protected Q_SLOTS: - void onMinusButtonPressed(); - void onPlusButtonPressed(); - void onLineEditTextEdited(); - -private: - double m_value = 0; - QString m_unit = ""; - QLineEdit *m_lineEdit; - QPushButton *m_minusButton, *m_plusButton; - QLabel *m_unitLabel; - void applyLineEditStyle(QLineEdit *widget); - void applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius = 0, int topRightBorderRadius = 0, - int bottomLeftBorderRadius = 0, int bottomRightBorderRadius = 0); - void applyUnitLabelStyle(QLabel *widget, bool isEnabled = true); -}; -} // namespace scopy::admt - -#endif // HORIZONTALSPINBOX_H \ No newline at end of file diff --git a/plugins/admt/src/admtstylehelper.cpp b/plugins/admt/src/admtstylehelper.cpp deleted file mode 100644 index bffddafc19..0000000000 --- a/plugins/admt/src/admtstylehelper.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (c) 2025 Analog Devices Inc. - * - * This file is part of Scopy - * (see https://www.github.com/analogdevicesinc/scopy). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "admtstylehelper.h" -#include "stylehelper.h" -#include - -using namespace scopy::admt; - -ADMTStyleHelper *ADMTStyleHelper::pinstance_{nullptr}; - -ADMTStyleHelper::ADMTStyleHelper(QObject *parent) {} - -ADMTStyleHelper *ADMTStyleHelper::GetInstance() -{ - if(pinstance_ == nullptr) { - pinstance_ = new ADMTStyleHelper(QApplication::instance()); // singleton has the app as parent - } - return pinstance_; -} - -ADMTStyleHelper::~ADMTStyleHelper() {} - -void ADMTStyleHelper::initColorMap() -{ - auto sh = ADMTStyleHelper::GetInstance(); - sh->colorMap.insert("CH0", "#FF7200"); - sh->colorMap.insert("CH1", "#9013FE"); - sh->colorMap.insert("CH2", "#27B34F"); - sh->colorMap.insert("CH3", "#F8E71C"); - sh->colorMap.insert("CH4", "#4A64FF"); - sh->colorMap.insert("CH5", "#02BCD4"); - sh->colorMap.insert("CH6", "#F44336"); - sh->colorMap.insert("CH7", "#F5A623"); - sh->colorMap.insert("CH8", "#1981AE"); - sh->colorMap.insert("CH9", "#6FCEA6"); - sh->colorMap.insert("CH10", "#F7A1DA"); - sh->colorMap.insert("CH11", "#E3F5FC"); -} - -QString ADMTStyleHelper::getColor(QString id) -{ - auto sh = ADMTStyleHelper::GetInstance(); - return sh->colorMap[id]; -} - -void ADMTStyleHelper::TopContainerButtonStyle(QPushButton *btn, QString objectName) -{ - if(!objectName.isEmpty()) - btn->setObjectName(objectName); - QString style = QString(R"css( - QPushButton { - width: 88px; - height: 48px; - border-radius: 2px; - padding-left: 20px; - padding-right: 20px; - color: white; - font-weight: 700; - font-size: 14px; - background-color: &&ScopyBlue&&; - } - - QPushButton:disabled { - background-color:#727273; /* design token - uiElement*/ - } - - QPushButton:checked { - background-color:#272730; /* design token - scopy blue*/ - } - QPushButton:pressed { - background-color:#272730; - } - })css"); - style.replace("&&ScopyBlue&&", Style::getAttribute(json::theme::interactive_primary_idle)); - btn->setStyleSheet(style); -} - -void ADMTStyleHelper::PlotWidgetStyle(PlotWidget *widget, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - widget->setContentsMargins(10, 10, 10, 6); - widget->plot()->canvas()->setStyleSheet("background-color: black;"); -} - -void ADMTStyleHelper::ComboBoxStyle(QComboBox *widget, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - QString style = QString(R"css( - QWidget { - } - QComboBox { - text-align: right; - color: &&colorname&&; - border-radius: 4px; - height: 30px; - border-bottom: 0px solid none; - padding-left: 12px; - padding-right: 12px; - font-weight: normal; - font-size: 16px; - background-color: black; - } - QComboBox:disabled, QLineEdit:disabled { - background-color: #18181d; - color: #9c4600; - } - QComboBox QAbstractItemView { - border: none; - color: transparent; - outline: none; - background-color: black; - border-bottom: 0px solid transparent; - border-top: 0px solid transparent; - } - QComboBox QAbstractItemView::item { - text-align: right; - } - QComboBox::item:selected { - font-weight: bold; - font-size: 18px; - background-color: transparent; - } - QComboBox::drop-down { - border-image: none; - border: 0px; - width: 16px; - height: 16px; - margin-right: 12px; - } - QComboBox::down-arrow { - image: url(:/admt/chevron-down-s.svg); - } - QComboBox::indicator { - background-color: transparent; - selection-background-color: transparent; - color: transparent; - selection-color: transparent; - } - )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); -} - -void ADMTStyleHelper::LineEditStyle(QLineEdit *widget, QString objectName) -{ - QString style = QString(R"css( - QLineEdit { - font-family: Open Sans; - font-size: 16px; - font-weight: normal; - text-align: right; - color: &&colorname&&; - - background-color: black; - border-radius: 4px; - border: none; - } - - QLineEdit:disabled { - background-color: #18181d; - color: #9c4600; - } - )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setContentsMargins(0, 0, 0, 0); - widget->setTextMargins(12, 4, 12, 4); - widget->setAlignment(Qt::AlignRight); -} - -void ADMTStyleHelper::ColoredSquareCheckbox(QCheckBox *chk, QColor color, QString objectName) -{ - if(!objectName.isEmpty()) - chk->setObjectName(objectName); - QString style = QString(R"css( - QCheckBox { - width:16px; - height:16px; - background-color: rgba(128,128,128,0); - color: rgba(255, 255, 255, 153); - } - QCheckBox::indicator { - width: 12px; - height: 12px; - border: 2px solid #FFFFFF; - border-radius: 4px; - } - QCheckBox::indicator:unchecked { background-color: &&UIElementBackground&&; } - QCheckBox::indicator:checked { background-color: &&colorname&&; } - )css"); - style.replace("&&colorname&&", color.name()); - style.replace("&&UIElementBackground&&", Style::getAttribute(json::theme::background_primary)); - chk->setStyleSheet(style); -} - -void ADMTStyleHelper::StartButtonStyle(QPushButton *btn, QString objectName) -{ - if(!objectName.isEmpty()) - btn->setObjectName(objectName); - QString style = QString(R"css( - QPushButton { - border-radius: 2px; - padding-left: 20px; - padding-right: 20px; - color: white; - font-weight: 700; - font-size: 14px; - } - - QPushButton:!checked { - background-color: #27b34f; - } - - QPushButton:checked { - background-color: #F45000; - } - - QPushButton:disabled { - background-color: grey; - })css"); - btn->setCheckable(true); - btn->setChecked(false); - btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - btn->setFixedHeight(36); - btn->setStyleSheet(style); - QIcon playIcon; - playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/play.svg", "white", 1), QIcon::Normal, QIcon::Off); - playIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/scopy-default/icons/play_stop.svg", "white", 1), - QIcon::Normal, QIcon::On); - btn->setIcon(playIcon); - btn->setIconSize(QSize(64, 64)); -} - -void ADMTStyleHelper::TextStyle(QWidget *widget, const char *styleHelperColor, bool isBold, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - QString existingStyle = widget->styleSheet(); - QString style = QString(R"css( - font-size: 16px; - font-weight: &&fontweight&&; - text-align: right; - color: &&colorname&&; - )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(styleHelperColor)); - QString fontWeight = QString("normal"); - if(isBold) { - fontWeight = QString("bold"); - } - style = style.replace(QString("&&fontweight&&"), fontWeight); - widget->setStyleSheet(existingStyle + style); -} - -void ADMTStyleHelper::MenuSmallLabel(QLabel *label, QString objectName) -{ - if(!objectName.isEmpty()) - label->setObjectName(objectName); - label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - - QString style = QString(R"css( - QLabel { - color: white; - background-color: rgba(255,255,255,0); - font-weight: 500; - font-family: Open Sans; - font-size: 12px; - font-style: normal; - } - QLabel:disabled { - color: grey; - } - )css"); - label->setStyleSheet(style); -} - -void ADMTStyleHelper::LineStyle(QFrame *line, QString objectName) -{ - if(!objectName.isEmpty()) - line->setObjectName(objectName); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Plain); - line->setFixedHeight(1); - QString lineStyle = QString(R"css( - QFrame { - border: 1px solid #808085; - } - )css"); - line->setStyleSheet(lineStyle); -} - -void ADMTStyleHelper::UIBackgroundStyle(QWidget *widget, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - QString style = QString(R"css( - background-color: &&colorname&&; - )css"); - style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::background_primary)); - widget->setStyleSheet(style); -} - -void ADMTStyleHelper::GraphChannelStyle(QWidget *widget, QLayout *layout, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - widget->setLayout(layout); - ADMTStyleHelper::UIBackgroundStyle(widget); - layout->setContentsMargins(20, 13, 20, 5); - layout->setSpacing(20); -} - -void ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(QWidget *widget, QHBoxLayout *layout, QLabel *hLabel, - QLabel *hMagLabel, QLabel *hPhaseLabel, QString objectName) -{ - if(!objectName.isEmpty()) - widget->setObjectName(objectName); - - widget->setLayout(layout); - QString style = QString(R"css( - background-color: &&colorname&&; - border-radius: 4px; - )css"); - style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::background_subtle)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - layout->setContentsMargins(12, 4, 12, 4); - - ADMTStyleHelper::TextStyle(hLabel, json::global::white, true); - ADMTStyleHelper::TextStyle(hMagLabel, json::global::ch0); - ADMTStyleHelper::TextStyle(hPhaseLabel, json::global::ch1); - - hLabel->setFixedWidth(24); - hMagLabel->setContentsMargins(0, 0, 32, 0); - hPhaseLabel->setFixedWidth(72); - - layout->addWidget(hLabel); - layout->addWidget(hMagLabel, 0, Qt::AlignRight); - layout->addWidget(hPhaseLabel); -} - -#include "moc_admtstylehelper.cpp" \ No newline at end of file diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index e42bb1b61c..2b2ca1efcb 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -24,9 +24,7 @@ #include "style.h" #include "style_properties.h" -#include #include -#include using namespace scopy; using namespace scopy::admt; @@ -149,7 +147,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool , isDebug(isDebug) , m_admtController(m_admtController) { - ADMTStyleHelper::GetInstance()->initColorMap(); readDeviceProperties(); initializeADMT(); initializeMotor(); @@ -323,6 +320,7 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() motorRPMLayout->setMargin(0); motorRPMLayout->setSpacing(0); QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); + Style::setStyle(motorRPMLabel, style::properties::label::subtle); acquisitionMotorRPMLineEdit = new QLineEdit(QString::number(motor_rpm), motorRPMWidget); connectLineEditToRPM(acquisitionMotorRPMLineEdit, motor_rpm); motorRPMLayout->addWidget(motorRPMLabel); @@ -334,6 +332,7 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() currentPositionLayout->setMargin(0); currentPositionLayout->setSpacing(0); QLabel *currentPositionLabel = new QLabel("Current Position", currentPositionWidget); + Style::setStyle(currentPositionLabel, style::properties::label::subtle); acquisitionMotorCurrentPositionLineEdit = new QLineEdit("--.--", currentPositionWidget); acquisitionMotorCurrentPositionLineEdit->setReadOnly(true); connectLineEditToDouble(acquisitionMotorCurrentPositionLineEdit, current_pos); @@ -346,6 +345,7 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() targetPositionLayout->setMargin(0); targetPositionLayout->setSpacing(0); QLabel *targetPositionLabel = new QLabel("Target Position", targetPositionWidget); + Style::setStyle(targetPositionLabel, style::properties::label::subtle); motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), targetPositionWidget); connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, ADMTController::MotorAttribute::TARGET_POS); @@ -358,6 +358,7 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() motorDirectionLayout->setMargin(0); motorDirectionLayout->setSpacing(0); QLabel *motorDirectionLabel = new QLabel("Rotation Direction", motorDirectionWidget); + Style::setStyle(motorDirectionLabel, style::properties::label::subtle); acquisitionMotorDirectionSwitch = new CustomSwitch("CW", "CCW", motorControlSectionWidget); acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); connect(acquisitionMotorDirectionSwitch, &CustomSwitch::toggled, this, @@ -569,8 +570,8 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() graphUpdateIntervalWidget->setLayout(graphUpdateIntervalLayout); graphUpdateIntervalLayout->setMargin(0); graphUpdateIntervalLayout->setSpacing(0); - QLabel *graphUpdateIntervalLabel = new QLabel(graphUpdateIntervalWidget); - graphUpdateIntervalLabel->setText("Graph Update Interval (ms)"); + QLabel *graphUpdateIntervalLabel = new QLabel("Graph Update Interval (ms)", graphUpdateIntervalWidget); + Style::setStyle(graphUpdateIntervalLabel, style::properties::label::subtle); graphUpdateIntervalLineEdit = new QLineEdit(graphUpdateIntervalWidget); graphUpdateIntervalLineEdit->setText(QString::number(acquisitionGraphSampleRate)); connectLineEditToNumber(graphUpdateIntervalLineEdit, acquisitionGraphSampleRate, 1, 5000); @@ -584,6 +585,7 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() displayLengthLayout->setMargin(0); displayLengthLayout->setSpacing(0); QLabel *displayLengthLabel = new QLabel("Display Length", displayLengthWidget); + Style::setStyle(displayLengthLabel, style::properties::label::subtle); displayLengthLineEdit = new QLineEdit(displayLengthWidget); displayLengthLineEdit->setText(QString::number(acquisitionDisplayLength)); connectLineEditToNumber(displayLengthLineEdit, acquisitionDisplayLength, 1, 2048); @@ -718,8 +720,8 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() Style::setStyle(calibrationDataGraphSectionWidget, style::properties::widget::basicComponent); calibrationDataGraphTabWidget = new QTabWidget(calibrationDataGraphSectionWidget); calibrationDataGraphTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 176px; }"); - calibrationDataGraphSectionWidget->contentLayout()->setContentsMargins(globalSpacingSmall, 1, - globalSpacingSmall, globalSpacingSmall); + Style::setStyle(calibrationDataGraphTabWidget->tabBar(), style::properties::admt::tabBar, "rounded", true); + calibrationDataGraphSectionWidget->contentLayout()->setMargin(1); calibrationDataGraphSectionWidget->contentLayout()->addWidget(calibrationDataGraphTabWidget); #pragma region Calibration Samples @@ -772,7 +774,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() Style::setStyle(calibrationDataGraphChannelsWidget, style::properties::widget::basicBackground); QHBoxLayout *calibrationDataGraphChannelsLayout = new QHBoxLayout(calibrationDataGraphChannelsWidget); calibrationDataGraphChannelsWidget->setLayout(calibrationDataGraphChannelsLayout); - calibrationDataGraphChannelsLayout->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, + calibrationDataGraphChannelsLayout->setContentsMargins(globalSpacingMedium, 0, globalSpacingMedium, globalSpacingSmall); calibrationDataGraphChannelsLayout->setSpacing(globalSpacingMedium); @@ -850,7 +852,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() Style::setStyle(postCalibrationDataGraphChannelsWidget, style::properties::widget::basicBackground); QHBoxLayout *postCalibrationDataGraphChannelsLayout = new QHBoxLayout(postCalibrationDataGraphChannelsWidget); postCalibrationDataGraphChannelsWidget->setLayout(postCalibrationDataGraphChannelsLayout); - postCalibrationDataGraphChannelsLayout->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, + postCalibrationDataGraphChannelsLayout->setContentsMargins(globalSpacingMedium, 0, globalSpacingMedium, globalSpacingSmall); postCalibrationDataGraphChannelsLayout->setSpacing(globalSpacingMedium); @@ -880,8 +882,8 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() Style::setStyle(resultDataSectionWidget, style::properties::widget::basicComponent); resultDataTabWidget = new QTabWidget(calibrationDataGraphWidget); resultDataTabWidget->tabBar()->setStyleSheet("QTabBar::tab { width: 160px; }"); - resultDataSectionWidget->contentLayout()->setContentsMargins(globalSpacingSmall, 1, globalSpacingSmall, - globalSpacingSmall); + Style::setStyle(resultDataTabWidget->tabBar(), style::properties::admt::tabBar, "rounded", true); + resultDataSectionWidget->contentLayout()->setContentsMargins(1, 1, 1, globalSpacingSmall); resultDataSectionWidget->contentLayout()->setSpacing(0); resultDataSectionWidget->contentLayout()->addWidget(resultDataTabWidget); @@ -934,7 +936,9 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() FFTAngleErrorLayout->setSpacing(0); QLabel *FFTAngleErrorMagnitudeLabel = new QLabel("Magnitude", FFTAngleErrorWidget); - FFTAngleErrorMagnitudeLabel->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, 0); + Style::setStyle(FFTAngleErrorMagnitudeLabel, style::properties::label::menuSmall); + FFTAngleErrorMagnitudeLabel->setContentsMargins(globalSpacingMedium, globalSpacingSmall, globalSpacingSmall, + globalSpacingSmall); FFTAngleErrorMagnitudePlotWidget = new PlotWidget(); FFTAngleErrorMagnitudePlotWidget->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, 0); @@ -968,7 +972,9 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() FFTAngleErrorMagnitudePlotWidget->replot(); QLabel *FFTAngleErrorPhaseLabel = new QLabel("Phase", FFTAngleErrorWidget); - FFTAngleErrorPhaseLabel->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, 0); + Style::setStyle(FFTAngleErrorPhaseLabel, style::properties::label::menuSmall); + FFTAngleErrorPhaseLabel->setContentsMargins(globalSpacingMedium, globalSpacingSmall, globalSpacingSmall, + globalSpacingSmall); FFTAngleErrorPhasePlotWidget = new PlotWidget(); FFTAngleErrorPhasePlotWidget->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, 0); @@ -1055,8 +1061,9 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() FFTCorrectedErrorLayout->setSpacing(0); QLabel *FFTCorrectedErrorMagnitudeLabel = new QLabel("Magnitude", FFTCorrectedErrorWidget); - FFTCorrectedErrorMagnitudeLabel->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, - 0); + Style::setStyle(FFTCorrectedErrorMagnitudeLabel, style::properties::label::menuSmall); + FFTCorrectedErrorMagnitudeLabel->setContentsMargins(globalSpacingMedium, globalSpacingSmall, globalSpacingSmall, + globalSpacingSmall); FFTCorrectedErrorMagnitudePlotWidget = new PlotWidget(); FFTCorrectedErrorMagnitudePlotWidget->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, 0); @@ -1093,7 +1100,9 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() FFTCorrectedErrorMagnitudePlotWidget->replot(); QLabel *FFTCorrectedErrorPhaseLabel = new QLabel("Phase", FFTCorrectedErrorWidget); - FFTCorrectedErrorPhaseLabel->setContentsMargins(globalSpacingSmall, globalSpacingSmall, globalSpacingSmall, 0); + Style::setStyle(FFTCorrectedErrorPhaseLabel, style::properties::label::menuSmall); + FFTCorrectedErrorPhaseLabel->setContentsMargins(globalSpacingMedium, globalSpacingSmall, globalSpacingSmall, + globalSpacingSmall); FFTCorrectedErrorPhasePlotWidget = new PlotWidget(); FFTCorrectedErrorPhasePlotWidget->setContentsMargins(globalSpacingSmall, 0, globalSpacingSmall, 0); @@ -1245,21 +1254,12 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() #pragma region Calibration Coefficient Section Widget MenuSectionWidget *calibrationCoeffSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); Style::setStyle(calibrationCoeffSectionWidget, style::properties::widget::basicComponent); - QLabel *calibrationDisplayFormatLabel = new QLabel(calibrationCoeffSectionWidget); - calibrationDisplayFormatLabel->setText("Display Format"); - Style::setStyle(calibrationDisplayFormatLabel, style::properties::label::menuMedium); - QLabel *calibrationCalculatedCoeffLabel = new QLabel(calibrationCoeffSectionWidget); - calibrationCalculatedCoeffLabel->setText("Calculated Coefficients"); - Style::setStyle(calibrationCalculatedCoeffLabel, style::properties::label::menuMedium); - calibrationDisplayFormatSwitch = new CustomSwitch(); - calibrationDisplayFormatSwitch->setOffText("Hex"); - calibrationDisplayFormatSwitch->setOnText("Angle"); - calibrationDisplayFormatSwitch->setProperty("bigBtn", true); + QLabel *calibrationCalculatedCoeffLabel = new QLabel("Calculated Coefficients", calibrationCoeffSectionWidget); + Style::setStyle(calibrationCalculatedCoeffLabel, style::properties::label::menuMedium); QWidget *calibrationCalculatedCoeffWidget = new QWidget(calibrationCoeffSectionWidget); QGridLayout *calibrationCalculatedCoeffLayout = new QGridLayout(calibrationCalculatedCoeffWidget); - calibrationCalculatedCoeffWidget->setLayout(calibrationCalculatedCoeffLayout); calibrationCalculatedCoeffLayout->setMargin(0); calibrationCalculatedCoeffLayout->setVerticalSpacing(4); @@ -1270,43 +1270,59 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() QLabel *calibrationH1Label = new QLabel("H1", calibrationCalculatedCoeffWidget); calibrationH1MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); calibrationH1PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h1RowContainer, h1RowLayout, calibrationH1Label, - calibrationH1MagLabel, calibrationH1PhaseLabel); + configureCoeffRow(h1RowContainer, h1RowLayout, calibrationH1Label, calibrationH1MagLabel, + calibrationH1PhaseLabel); QWidget *h2RowContainer = new QWidget(calibrationCalculatedCoeffWidget); QHBoxLayout *h2RowLayout = new QHBoxLayout(h2RowContainer); QLabel *calibrationH2Label = new QLabel("H2", calibrationCalculatedCoeffWidget); calibrationH2MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); calibrationH2PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h2RowContainer, h2RowLayout, calibrationH2Label, - calibrationH2MagLabel, calibrationH2PhaseLabel); + configureCoeffRow(h2RowContainer, h2RowLayout, calibrationH2Label, calibrationH2MagLabel, + calibrationH2PhaseLabel); QWidget *h3RowContainer = new QWidget(calibrationCalculatedCoeffWidget); QHBoxLayout *h3RowLayout = new QHBoxLayout(h3RowContainer); QLabel *calibrationH3Label = new QLabel("H3", calibrationCalculatedCoeffWidget); calibrationH3MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); calibrationH3PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h3RowContainer, h3RowLayout, calibrationH3Label, - calibrationH3MagLabel, calibrationH3PhaseLabel); + configureCoeffRow(h3RowContainer, h3RowLayout, calibrationH3Label, calibrationH3MagLabel, + calibrationH3PhaseLabel); QWidget *h8RowContainer = new QWidget(calibrationCalculatedCoeffWidget); QHBoxLayout *h8RowLayout = new QHBoxLayout(h8RowContainer); QLabel *calibrationH8Label = new QLabel("H8", calibrationCalculatedCoeffWidget); calibrationH8MagLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); calibrationH8PhaseLabel = new QLabel("0x----", calibrationCalculatedCoeffWidget); - ADMTStyleHelper::CalculatedCoeffWidgetRowStyle(h8RowContainer, h8RowLayout, calibrationH8Label, - calibrationH8MagLabel, calibrationH8PhaseLabel); + configureCoeffRow(h8RowContainer, h8RowLayout, calibrationH8Label, calibrationH8MagLabel, + calibrationH8PhaseLabel); calibrationCalculatedCoeffLayout->addWidget(h1RowContainer, 0, 0); calibrationCalculatedCoeffLayout->addWidget(h2RowContainer, 1, 0); calibrationCalculatedCoeffLayout->addWidget(h3RowContainer, 2, 0); calibrationCalculatedCoeffLayout->addWidget(h8RowContainer, 3, 0); - calibrationCoeffSectionWidget->contentLayout()->setSpacing(8); - calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatLabel); - calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatSwitch); + QWidget *calibrationDisplayFormatWidget = new QWidget(calibrationCoeffSectionWidget); + QVBoxLayout *calibrationDisplayFormatLayout = new QVBoxLayout(calibrationDisplayFormatWidget); + calibrationDisplayFormatWidget->setLayout(calibrationDisplayFormatLayout); + calibrationDisplayFormatLayout->setMargin(0); + calibrationDisplayFormatLayout->setSpacing(0); + + QLabel *calibrationDisplayFormatLabel = new QLabel("Display Format", calibrationDisplayFormatWidget); + Style::setStyle(calibrationDisplayFormatLabel, style::properties::label::subtle); + + calibrationDisplayFormatSwitch = new CustomSwitch(); + calibrationDisplayFormatSwitch->setOffText("Hex"); + calibrationDisplayFormatSwitch->setOnText("Angle"); + calibrationDisplayFormatSwitch->setProperty("bigBtn", true); + + calibrationDisplayFormatLayout->addWidget(calibrationDisplayFormatLabel); + calibrationDisplayFormatLayout->addWidget(calibrationDisplayFormatSwitch); + + calibrationCoeffSectionWidget->contentLayout()->setSpacing(globalSpacingSmall); calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffLabel); calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationCalculatedCoeffWidget); + calibrationCoeffSectionWidget->contentLayout()->addWidget(calibrationDisplayFormatWidget); #pragma endregion #pragma region Calibration Dataset Configuration @@ -1332,6 +1348,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationCycleCountLayout->setMargin(0); calibrationCycleCountLayout->setSpacing(0); QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", calibrationCycleCountWidget); + Style::setStyle(calibrationCycleCountLabel, style::properties::label::subtle); QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(calibrationCycleCountWidget); calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 1000); @@ -1344,6 +1361,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationSamplesPerCycleLayout->setMargin(0); calibrationSamplesPerCycleLayout->setSpacing(0); QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", calibrationSamplesPerCycleWidget); + Style::setStyle(calibrationSamplesPerCycleLabel, style::properties::label::subtle); QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationSamplesPerCycleWidget); calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, 1, 5000); @@ -1391,6 +1409,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() motorRPMLayout->setMargin(0); motorRPMLayout->setSpacing(0); QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); + Style::setStyle(motorRPMLabel, style::properties::label::subtle); calibrationMotorRPMLineEdit = new QLineEdit(QString::number(motor_rpm), motorRPMWidget); connectLineEditToRPM(calibrationMotorRPMLineEdit, motor_rpm); motorRPMLayout->addWidget(motorRPMLabel); @@ -1402,6 +1421,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() currentPositionLayout->setMargin(0); currentPositionLayout->setSpacing(0); QLabel *currentPositionLabel = new QLabel("Current Position", currentPositionWidget); + Style::setStyle(currentPositionLabel, style::properties::label::subtle); calibrationMotorCurrentPositionLineEdit = new QLineEdit("--.--", currentPositionWidget); calibrationMotorCurrentPositionLineEdit->setReadOnly(true); connectLineEditToDouble(calibrationMotorCurrentPositionLineEdit, current_pos); @@ -1414,6 +1434,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() targetPositionLayout->setMargin(0); targetPositionLayout->setSpacing(0); QLabel *targetPositionLabel = new QLabel("Target Position", targetPositionWidget); + Style::setStyle(targetPositionLabel, style::properties::label::subtle); motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), targetPositionWidget); connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, ADMTController::MotorAttribute::TARGET_POS); @@ -1426,6 +1447,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() motorDirectionLayout->setMargin(0); motorDirectionLayout->setSpacing(0); QLabel *motorDirectionLabel = new QLabel("Rotation Direction", motorDirectionWidget); + Style::setStyle(motorDirectionLabel, style::properties::label::subtle); calibrationMotorDirectionSwitch = new CustomSwitch("CW", "CCW", motorControlSectionWidget); calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); connect(calibrationMotorDirectionSwitch, &CustomSwitch::toggled, this, @@ -1548,11 +1570,11 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() toggleTabSwitching(true); toggleCalibrationControls(true); - QString log = "Calibration Stream Timing: \n"; - for(auto &value : m_admtController->streamBufferedIntervals) { - log += QString::number(value) + "\n"; - } - Q_EMIT calibrationLogWriteSignal(log); + // QString log = "Calibration Stream Timing: \n"; + // for(auto &value : m_admtController->streamBufferedIntervals) { + // log += QString::number(value) + "\n"; + // } + // Q_EMIT calibrationLogWriteSignal(log); if(isPostCalibration) { graphPostDataList = m_admtController->streamBufferedValues; @@ -2043,50 +2065,62 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO0ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Output", "Input"); + DIGIO0ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO0EN", value); }); DIGIO0FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO0FNCToggleSwitch, "GPIO0", "BUSY"); + DIGIO0FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO0FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("BUSY", value); }); DIGIO1ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO1ENToggleSwitch, "Output", "Input"); + DIGIO1ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO1ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO1EN", value); }); DIGIO1FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO1FNCToggleSwitch, "GPIO1", "CNV"); + DIGIO1FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO1FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("CNV", value); }); DIGIO2ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO2ENToggleSwitch, "Output", "Input"); + DIGIO2ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO2ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO2EN", value); }); DIGIO2FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO2FNCToggleSwitch, "GPIO2", "SENT"); + DIGIO2FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO2FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("SENT", value); }); DIGIO3ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO3ENToggleSwitch, "Output", "Input"); + DIGIO3ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO3ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO3EN", value); }); DIGIO3FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO3FNCToggleSwitch, "GPIO3", "ACALC"); + DIGIO3FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO3FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("ACALC", value); }); DIGIO4ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO4ENToggleSwitch, "Output", "Input"); + DIGIO4ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO4ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO4EN", value); }); DIGIO4FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO4FNCToggleSwitch, "GPIO4", "FAULT"); + DIGIO4FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO4FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("FAULT", value); }); DIGIO5ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO5ENToggleSwitch, "Output", "Input"); + DIGIO5ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO5ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO5EN", value); }); DIGIO5FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO5FNCToggleSwitch, "GPIO5", "BOOT"); + DIGIO5FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); connect(DIGIO5FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("BOOTLOAD", value); }); @@ -2186,31 +2220,50 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() "MT Diagnostics", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, MTDiagnosticsSectionWidget); MTDiagnosticsSectionWidget->contentLayout()->addWidget(MTDiagnosticsCollapseSection); - MTDiagnosticsCollapseSection->contentLayout()->setSpacing(8); - - QLabel *AFEDIAG0Label = new QLabel("AFEDIAG0 (%)"); - Style::setStyle(AFEDIAG0Label, style::properties::label::menuSmall); - QLabel *AFEDIAG1Label = new QLabel("AFEDIAG1 (%)"); - Style::setStyle(AFEDIAG1Label, style::properties::label::menuSmall); - QLabel *AFEDIAG2Label = new QLabel("AFEDIAG2 (V)"); - Style::setStyle(AFEDIAG2Label, style::properties::label::menuSmall); - - AFEDIAG0LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); - AFEDIAG1LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); - AFEDIAG2LineEdit = new QLineEdit(MTDiagnosticsSectionWidget); + MTDiagnosticsCollapseSection->contentLayout()->setSpacing(globalSpacingSmall); + + QWidget *AFEDIAG0Widget = new QWidget(MTDiagnosticsSectionWidget); + QVBoxLayout *AFEDIAG0Layout = new QVBoxLayout(AFEDIAG0Widget); + AFEDIAG0Widget->setLayout(AFEDIAG0Layout); + AFEDIAG0Layout->setMargin(0); + AFEDIAG0Layout->setSpacing(0); + QLabel *AFEDIAG0Label = new QLabel("AFEDIAG0 (%)", AFEDIAG0Widget); + Style::setStyle(AFEDIAG0Label, style::properties::label::subtle); + AFEDIAG0LineEdit = new QLineEdit(AFEDIAG0Widget); AFEDIAG0LineEdit->setReadOnly(true); - AFEDIAG1LineEdit->setReadOnly(true); - AFEDIAG2LineEdit->setReadOnly(true); connectLineEditToNumber(AFEDIAG0LineEdit, afeDiag0, "V"); + AFEDIAG0Layout->addWidget(AFEDIAG0Label); + AFEDIAG0Layout->addWidget(AFEDIAG0LineEdit); + + QWidget *AFEDIAG1Widget = new QWidget(MTDiagnosticsSectionWidget); + QVBoxLayout *AFEDIAG1Layout = new QVBoxLayout(AFEDIAG1Widget); + AFEDIAG1Widget->setLayout(AFEDIAG1Layout); + AFEDIAG1Layout->setMargin(0); + AFEDIAG1Layout->setSpacing(0); + QLabel *AFEDIAG1Label = new QLabel("AFEDIAG1 (%)", AFEDIAG1Widget); + Style::setStyle(AFEDIAG1Label, style::properties::label::subtle); + AFEDIAG1LineEdit = new QLineEdit(AFEDIAG1Widget); + AFEDIAG1LineEdit->setReadOnly(true); connectLineEditToNumber(AFEDIAG1LineEdit, afeDiag1, "V"); + AFEDIAG1Layout->addWidget(AFEDIAG1Label); + AFEDIAG1Layout->addWidget(AFEDIAG1LineEdit); + + QWidget *AFEDIAG2Widget = new QWidget(MTDiagnosticsSectionWidget); + QVBoxLayout *AFEDIAG2Layout = new QVBoxLayout(AFEDIAG2Widget); + AFEDIAG2Widget->setLayout(AFEDIAG2Layout); + AFEDIAG2Layout->setMargin(0); + AFEDIAG2Layout->setSpacing(0); + QLabel *AFEDIAG2Label = new QLabel("AFEDIAG2 (V)", AFEDIAG2Widget); + Style::setStyle(AFEDIAG2Label, style::properties::label::subtle); + AFEDIAG2LineEdit = new QLineEdit(AFEDIAG2Widget); + AFEDIAG2LineEdit->setReadOnly(true); connectLineEditToNumber(AFEDIAG2LineEdit, afeDiag2, "V"); + AFEDIAG2Layout->addWidget(AFEDIAG2Label); + AFEDIAG2Layout->addWidget(AFEDIAG2LineEdit); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0Label); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0LineEdit); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1Label); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1LineEdit); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2Label); - MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2LineEdit); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG0Widget); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG1Widget); + MTDiagnosticsCollapseSection->contentLayout()->addWidget(AFEDIAG2Widget); MTDiagnosticsLayout->addWidget(MTDiagnosticsSectionWidget); MTDiagnosticsLayout->addWidget(MTDIAG1SectionWidget); @@ -4802,6 +4855,24 @@ QCheckBox *HarmonicCalibration::createStatusLEDWidget(const QString &text, QVari checkBox->setEnabled(false); return checkBox; } + +void HarmonicCalibration::configureCoeffRow(QWidget *container, QHBoxLayout *layout, QLabel *hLabel, QLabel *hMagLabel, + QLabel *hPhaseLabel) +{ + container->setLayout(layout); + container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + layout->setContentsMargins(12, 4, 12, 4); + hLabel->setProperty("hLabel", true); + hMagLabel->setProperty("hMagLabel", true); + hPhaseLabel->setProperty("hPhaseLabel", true); + hLabel->setFixedWidth(24); + hMagLabel->setContentsMargins(0, 0, 32, 0); + hPhaseLabel->setFixedWidth(72); + layout->addWidget(hLabel); + layout->addWidget(hMagLabel, 0, Qt::AlignRight); + layout->addWidget(hPhaseLabel); + Style::setStyle(container, style::properties::admt::coeffRowContainer, true, true); +} #pragma endregion #pragma region Connect Methods diff --git a/plugins/admt/src/widgets/horizontalspinbox.cpp b/plugins/admt/src/widgets/horizontalspinbox.cpp deleted file mode 100644 index 4ed9421251..0000000000 --- a/plugins/admt/src/widgets/horizontalspinbox.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2025 Analog Devices Inc. - * - * This file is part of Scopy - * (see https://www.github.com/analogdevicesinc/scopy). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "widgets/horizontalspinbox.h" -#include -#include - -using namespace scopy::admt; - -HorizontalSpinBox::HorizontalSpinBox(QString header, double initialValue, QString unit, QWidget *parent) - : QWidget(parent) - , m_value(initialValue) - , m_unit(unit) -{ - QVBoxLayout *container = new QVBoxLayout(this); - setLayout(container); - container->setMargin(0); - container->setSpacing(4); - - if(header != "") { - QLabel *headerLabel = new QLabel(header, this); - Style::setStyle(headerLabel, style::properties::label::menuSmall); - container->addWidget(headerLabel); - } - - QWidget *controlWidget = new QWidget(this); - QHBoxLayout *controlLayout = new QHBoxLayout(controlWidget); - controlWidget->setLayout(controlLayout); - controlLayout->setMargin(0); - controlLayout->setSpacing(2); - - m_lineEdit = new QLineEdit(controlWidget); - QDoubleValidator *validator = new QDoubleValidator(this); - validator->setNotation(QDoubleValidator::StandardNotation); - m_lineEdit->setValidator(validator); - applyLineEditStyle(m_lineEdit); - - if(QString::compare(m_unit, "") != 0) { - QWidget *lineEditContainer = new QWidget(controlWidget); - QHBoxLayout *lineEditLayout = new QHBoxLayout(lineEditContainer); - lineEditContainer->setLayout(lineEditLayout); - lineEditLayout->setMargin(0); - lineEditLayout->setSpacing(0); - - m_unitLabel = new QLabel(m_unit, controlWidget); - applyUnitLabelStyle(m_unitLabel); - - m_lineEdit->setTextMargins(12, 4, 0, 4); - - lineEditLayout->addWidget(m_lineEdit); - lineEditLayout->addWidget(m_unitLabel); - controlLayout->addWidget(lineEditContainer); - } else { - controlLayout->addWidget(m_lineEdit); - } - - m_minusButton = new QPushButton(controlWidget); - m_minusButton->setIcon(QIcon(":/admt/minus.svg")); - applyPushButtonStyle(m_minusButton); - - m_plusButton = new QPushButton(controlWidget); - m_plusButton->setIcon(QIcon(":/admt/plus.svg")); - applyPushButtonStyle(m_plusButton, 0, 4, 0, 4); - - controlLayout->addWidget(m_minusButton); - controlLayout->addWidget(m_plusButton); - - container->addWidget(controlWidget); - - setValue(m_value); - connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(onLineEditTextEdited())); - connect(m_minusButton, SIGNAL(clicked()), SLOT(onMinusButtonPressed())); - connect(m_plusButton, SIGNAL(clicked()), SLOT(onPlusButtonPressed())); -} - -void HorizontalSpinBox::onMinusButtonPressed() -{ - m_value--; - setValue(m_value); - Q_EMIT m_lineEdit->editingFinished(); -} - -void HorizontalSpinBox::onPlusButtonPressed() -{ - m_value++; - setValue(m_value); - Q_EMIT m_lineEdit->editingFinished(); -} - -void HorizontalSpinBox::onLineEditTextEdited() -{ - QLineEdit *lineEdit = static_cast(QObject::sender()); - bool ok; - double value = lineEdit->text().toDouble(&ok); - if(ok) { - m_value = value; - } - setValue(m_value); -} - -void HorizontalSpinBox::setValue(double value) { m_lineEdit->setText(QString::number(value)); } - -void HorizontalSpinBox::setEnabled(double value) -{ - m_lineEdit->setEnabled(value); - m_minusButton->setEnabled(value); - m_plusButton->setEnabled(value); - if(QString::compare(m_unit, "") != 0) { - applyUnitLabelStyle(m_unitLabel, value); - } -} - -void HorizontalSpinBox::applyLineEditStyle(QLineEdit *widget) -{ - QString style = QString(R"css( - QLineEdit { - font-family: Open Sans; - font-size: 16px; - font-weight: normal; - text-align: right; - color: &&colorname&&; - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - - background-color: black; - border: none; - qproperty-frame: false; - } - - QLineEdit:disabled { - background-color: #18181d; - color: #9c4600; - } - )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setAlignment(Qt::AlignRight); - widget->setContentsMargins(0, 0, 0, 0); - widget->setTextMargins(6, 4, 6, 4); -} - -void HorizontalSpinBox::applyPushButtonStyle(QPushButton *widget, int topLeftBorderRadius, int topRightBorderRadius, - int bottomLeftBorderRadius, int bottomRightBorderRadius) -{ - QString style = QString(R"css( - QPushButton{ - background-color: black; - font-family: Open Sans; - font-size: 32px; - font-weight: bold; - text-align: center center; - color: &&colorname&&; - border-top-left-radius: &&topLeftBorderRadius&&px; - border-top-right-radius: &&topRightBorderRadius&&px; - border-bottom-left-radius: &&bottomLeftBorderRadius&&px; - border-bottom-right-radius: &&bottomRightBorderRadius&&px; - } - QPushButton:disabled{ - background-color: #18181d; - color: #2d3d9c; - } - )css"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::theme::interactive_primary_idle)); - style = style.replace(QString("&&topLeftBorderRadius&&"), QString::number(topLeftBorderRadius)); - style = style.replace(QString("&&topRightBorderRadius&&"), QString::number(topRightBorderRadius)); - style = style.replace(QString("&&bottomLeftBorderRadius&&"), QString::number(bottomLeftBorderRadius)); - style = style.replace(QString("&&bottomRightBorderRadius&&"), QString::number(bottomRightBorderRadius)); - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setFixedWidth(38); -} - -void HorizontalSpinBox::applyUnitLabelStyle(QLabel *widget, bool isEnabled) -{ - QString style = QString(R"css( - background-color: &&backgroundcolor&&; - font-family: Open Sans; - font-size: 16px; - text-align: right; - color: &&colorname&&; - border: none; - )css"); - if(isEnabled) { - style = style.replace(QString("&&backgroundcolor&&"), "black"); - style = style.replace(QString("&&colorname&&"), Style::getAttribute(json::global::ch0)); - } else { - style = style.replace(QString("&&backgroundcolor&&"), "#18181d"); - style = style.replace(QString("&&colorname&&"), "#9c4600"); - } - widget->setStyleSheet(style); - widget->setFixedHeight(30); - widget->setAlignment(Qt::AlignRight); - widget->setContentsMargins(0, 4, 12, 4); -} - -QLineEdit *HorizontalSpinBox::lineEdit() { return m_lineEdit; } diff --git a/plugins/admt/style/qss/properties/admt/coeffRowContainer.qss b/plugins/admt/style/qss/properties/admt/coeffRowContainer.qss new file mode 100644 index 0000000000..95b22b7a83 --- /dev/null +++ b/plugins/admt/style/qss/properties/admt/coeffRowContainer.qss @@ -0,0 +1,21 @@ +QWidget[&&property&&=true] { + background: &background_subtle&; + height: 30px; + border-radius: &radius_1&; +} + +QWidget[&&property&&=true] > QLabel { + font-size: &font_size_2&; +} + +QWidget[&&property&&=true] > QLabel[hLabel=true] { + font-weight: 600; +} + +QWidget[&&property&&=true] > QLabel[hMagLabel=true] { + color: &ch0&; +} + +QWidget[&&property&&=true] > QLabel[hPhaseLabel=true] { + color: &ch1&; +} diff --git a/plugins/admt/style/qss/properties/admt/tabBar.qss b/plugins/admt/style/qss/properties/admt/tabBar.qss index 5baf558861..c2d41c8d9a 100644 --- a/plugins/admt/style/qss/properties/admt/tabBar.qss +++ b/plugins/admt/style/qss/properties/admt/tabBar.qss @@ -3,6 +3,10 @@ QTabBar[&&property&&=true] { font-weight: 600; } +QTabBar[&&property&&="rounded"] { + border-radius: &radius_1&; +} + QTabBar[&&property&&=true]::tab { height: 48px; background-color: transparent; From 3148c4e33a7b5c13319c9892132f17be3b845354 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 12 Mar 2025 18:51:21 +0800 Subject: [PATCH 095/112] admt: Added slot and signal for acquisition tab data - Removed graph update interval - Optimized GUI updates using slots and signals - Removed threaded UI update for acquisition tab Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 30 +- plugins/admt/src/harmoniccalibration.cpp | 287 +++++++++--------- 2 files changed, 151 insertions(+), 166 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 41369a52d9..3af446fa88 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -75,7 +75,7 @@ #include #include -enum SensorDataKey +enum SensorData { ABSANGLE, ANGLE, @@ -109,6 +109,8 @@ public Q_SLOTS: void stop(); void start(); void restart(); + void updateAcquisitionData(QMap sensorDataMap); + void updateAcquisitionGraph(); void calibrationLogWrite(QString message = ""); void commandLogWrite(QString message = ""); void updateFaultStatus(bool value); @@ -119,6 +121,8 @@ public Q_SLOTS: void updateMTDiagnosticsUI(quint16 registerValue); Q_SIGNALS: void runningChanged(bool); + void acquisitionDataChanged(QMap sensorDataMap); + void acquisitionGraphChanged(); void canCalibrateChanged(bool); void updateUtilityUI(); void calibrationLogWriteSignal(QString message); @@ -149,12 +153,11 @@ public Q_SLOTS: QButtonGroup *rightMenuButtonGroup; QLineEdit *acquisitionMotorRPMLineEdit, *calibrationMotorRPMLineEdit, *motorTargetPositionLineEdit, - *graphUpdateIntervalLineEdit, *displayLengthLineEdit, *dataGraphSamplesLineEdit, - *tempGraphSamplesLineEdit, *acquisitionMotorCurrentPositionLineEdit, *calibrationH1MagLineEdit, - *calibrationH2MagLineEdit, *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, - *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, *calibrationH3PhaseLineEdit, - *calibrationH8PhaseLineEdit, *calibrationMotorCurrentPositionLineEdit, *AFEDIAG0LineEdit, - *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; + *displayLengthLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, + *acquisitionMotorCurrentPositionLineEdit, *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, + *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, *calibrationH1PhaseLineEdit, + *calibrationH2PhaseLineEdit, *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit, + *calibrationMotorCurrentPositionLineEdit, *AFEDIAG0LineEdit, *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; QLabel *rawAngleValueLabel, *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, *motorAmaxValueLabel, *motorRotateVmaxValueLabel, *motorDmaxValueLabel, *motorDisableValueLabel, @@ -265,22 +268,19 @@ public Q_SLOTS: void updateLineEditValues(); void startAcquisition(); void stopAcquisition(); + void restartAcquisition(); void updateAcquisitionMotorRPM(); void updateAcquisitionMotorRotationDirection(); - void getAcquisitionSamples(int sampleRate); + void getAcquisitionSamples(QMap dataMap); double getSensorDataAcquisitionValue(const ADMTController::SensorRegister &key); - void plotAcquisition(QVector &list, PlotChannel *channel); - void prependAcquisitionData(const double &data, QVector &list); + void plotAcquisition(QVector list, PlotChannel *channel); + void appendAcquisitionData(const double &data, QVector &list); void resetAcquisitionYAxisScale(); - void acquisitionPlotTask(int sampleRate); - void acquisitionUITask(int sampleRate); - void startAcquisitionUITask(); - void stopAcquisitionUITask(); void updateSequenceWidget(); void updateCapturedDataCheckBoxes(); void applySequenceAndUpdate(); void updateGeneralSettingEnabled(bool value); - void connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, SensorDataKey key); + void connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, SensorData key); void GMRReset(); #pragma endregion diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 2b2ca1efcb..d6ba0d8d83 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -29,9 +29,6 @@ using namespace scopy; using namespace scopy::admt; -static int acquisitionUITimerRate = 500; // In ms -static int acquisitionSampleRate = 20; -static int acquisitionGraphSampleRate = 100; static int motorWaitVelocityReachedSampleRate = 50; static int calibrationUITimerRate = 500; @@ -136,7 +133,7 @@ static double defaultPhaseGraphMax = 4; static double currentPhaseGraphMin = defaultPhaseGraphMin; static double currentPhaseGraphMax = defaultPhaseGraphMax; -static map acquisitionDataMap = { +static QMap acquisitionDataMap = { {ABSANGLE, false}, {ANGLE, false}, {ANGLESEC, false}, {SINE, false}, {COSINE, false}, {SECANGLI, false}, {SECANGLQ, false}, {RADIUS, false}, {DIAG1, false}, {DIAG2, false}, {TMP0, false}, {TMP1, false}, {CNVCNT, false}, @@ -187,22 +184,24 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 0) // Acquisition Tab { - startAcquisitionUITask(); + isAcquisitionTab = true; readSequence(); updateSequenceWidget(); updateAcquisitionMotorRPM(); updateAcquisitionMotorRotationDirection(); } else { - stopAcquisitionUITask(); + isAcquisitionTab = false; stop(); } if(index == 1) // Calibration Tab { + isCalibrationTab = true; startCalibrationUITask(); updateCalibrationMotorRPM(); updateCalibrationMotorRotationDirection(); } else { + isCalibrationTab = false; stopCalibrationUITask(); } @@ -223,9 +222,12 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool } }); + qRegisterMetaType>("QMap"); + connect(this, &HarmonicCalibration::acquisitionDataChanged, this, &HarmonicCalibration::updateAcquisitionData); + connect(this, &HarmonicCalibration::acquisitionGraphChanged, this, + &HarmonicCalibration::updateAcquisitionGraph); connect(this, &HarmonicCalibration::updateFaultStatusSignal, this, &HarmonicCalibration::updateFaultStatus); connect(this, &HarmonicCalibration::motorPositionChanged, this, &HarmonicCalibration::updateMotorPosition); - connect(this, &HarmonicCalibration::calibrationLogWriteSignal, this, &HarmonicCalibration::calibrationLogWrite); connect(this, &HarmonicCalibration::commandLogWriteSignal, this, &HarmonicCalibration::commandLogWrite); connect(this, &HarmonicCalibration::DIGIORegisterChanged, this, &HarmonicCalibration::updateDIGIOUI); @@ -234,7 +236,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool &HarmonicCalibration::updateMTDiagnosticRegisterUI); connect(this, &HarmonicCalibration::DIAG2RegisterChanged, this, &HarmonicCalibration::updateMTDiagnosticsUI); - startAcquisitionUITask(); + isAcquisitionTab = true; startDeviceStatusMonitor(); startCurrentMotorPositionMonitor(); } @@ -560,24 +562,9 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() MenuCollapseSection *generalSection = new MenuCollapseSection("Data Acquisition", MenuCollapseSection::MHCW_NONE, MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, generalWidget); - generalSection->header()->toggle(); generalSection->contentLayout()->setSpacing(globalSpacingSmall); generalWidget->contentLayout()->addWidget(generalSection); - // Graph Update Interval - QWidget *graphUpdateIntervalWidget = new QWidget(generalSection); - QVBoxLayout *graphUpdateIntervalLayout = new QVBoxLayout(graphUpdateIntervalWidget); - graphUpdateIntervalWidget->setLayout(graphUpdateIntervalLayout); - graphUpdateIntervalLayout->setMargin(0); - graphUpdateIntervalLayout->setSpacing(0); - QLabel *graphUpdateIntervalLabel = new QLabel("Graph Update Interval (ms)", graphUpdateIntervalWidget); - Style::setStyle(graphUpdateIntervalLabel, style::properties::label::subtle); - graphUpdateIntervalLineEdit = new QLineEdit(graphUpdateIntervalWidget); - graphUpdateIntervalLineEdit->setText(QString::number(acquisitionGraphSampleRate)); - connectLineEditToNumber(graphUpdateIntervalLineEdit, acquisitionGraphSampleRate, 1, 5000); - graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLabel); - graphUpdateIntervalLayout->addWidget(graphUpdateIntervalLineEdit); - // Data Sample Size QWidget *displayLengthWidget = new QWidget(generalSection); QVBoxLayout *displayLengthLayout = new QVBoxLayout(displayLengthWidget); @@ -596,7 +583,6 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() StyleHelper::BasicButton(resetYAxisButton); connect(resetYAxisButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAcquisitionYAxisScale); - generalSection->contentLayout()->addWidget(graphUpdateIntervalWidget); generalSection->contentLayout()->addWidget(displayLengthWidget); generalSection->contentLayout()->addWidget(resetYAxisButton); @@ -2609,7 +2595,6 @@ void HarmonicCalibration::requestDisconnect() { stopAcquisition(); - stopAcquisitionUITask(); stopCalibrationUITask(); stopUtilityTask(); @@ -2754,17 +2739,63 @@ void HarmonicCalibration::updateLineEditValues() } } +void HarmonicCalibration::updateAcquisitionData(QMap sensorDataMap) +{ + if(isStartAcquisition) + updateLineEditValues(); + + if(acquisitionDataMap.value(ANGLE) && sensorDataMap.keys().contains(ANGLE)) + appendAcquisitionData(sensorDataMap.value(ANGLE), acquisitionAngleList); + else + acquisitionAngleList.clear(); + if(acquisitionDataMap.value(ABSANGLE) && sensorDataMap.keys().contains(ABSANGLE)) + appendAcquisitionData(sensorDataMap.value(ABSANGLE), acquisitionABSAngleList); + else + acquisitionABSAngleList.clear(); + if(acquisitionDataMap.value(TMP0) && sensorDataMap.keys().contains(TMP0)) + appendAcquisitionData(sensorDataMap.value(TMP0), acquisitionTmp0List); + else + acquisitionTmp0List.clear(); + if(acquisitionDataMap.value(SINE) && sensorDataMap.keys().contains(SINE)) + appendAcquisitionData(sensorDataMap.value(SINE), acquisitionSineList); + else + acquisitionSineList.clear(); + if(acquisitionDataMap.value(COSINE) && sensorDataMap.keys().contains(COSINE)) + appendAcquisitionData(sensorDataMap.value(COSINE), acquisitionCosineList); + else + acquisitionCosineList.clear(); + if(acquisitionDataMap.value(RADIUS) && sensorDataMap.keys().contains(RADIUS)) + appendAcquisitionData(sensorDataMap.value(RADIUS), acquisitionRadiusList); + else + acquisitionRadiusList.clear(); + if(acquisitionDataMap.value(ANGLESEC) && sensorDataMap.keys().contains(ANGLESEC)) + appendAcquisitionData(sensorDataMap.value(ANGLESEC), acquisitionAngleSecList); + else + acquisitionAngleSecList.clear(); + if(acquisitionDataMap.value(SECANGLI) && sensorDataMap.keys().contains(SECANGLI)) + appendAcquisitionData(sensorDataMap.value(SECANGLI), acquisitionSecAnglIList); + else + acquisitionSecAnglIList.clear(); + if(acquisitionDataMap.value(SECANGLQ) && sensorDataMap.keys().contains(SECANGLQ)) + appendAcquisitionData(sensorDataMap.value(SECANGLQ), acquisitionSecAnglQList); + else + acquisitionSecAnglQList.clear(); + if(acquisitionDataMap.value(TMP1) && sensorDataMap.keys().contains(TMP1)) + appendAcquisitionData(sensorDataMap.value(TMP1), acquisitionTmp1List); + else + acquisitionTmp1List.clear(); + + Q_EMIT acquisitionGraphChanged(); +} + void HarmonicCalibration::startAcquisition() { isStartAcquisition = true; acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); m_acquisitionDataThread = - QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples, acquisitionSampleRate); + QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples, acquisitionDataMap); m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); - m_acquisitionGraphThread = - QtConcurrent::run(this, &HarmonicCalibration::acquisitionPlotTask, acquisitionGraphSampleRate); - m_acquisitionGraphWatcher.setFuture(m_acquisitionGraphThread); } void HarmonicCalibration::stopAcquisition() @@ -2778,8 +2809,14 @@ void HarmonicCalibration::stopAcquisition() m_acquisitionGraphThread.cancel(); m_acquisitionGraphWatcher.waitForFinished(); } +} - stopCurrentMotorPositionMonitor(); +void HarmonicCalibration::restartAcquisition() +{ + if(m_acquisitionDataThread.isRunning()) { + stopAcquisition(); + startAcquisition(); + } } void HarmonicCalibration::updateFaultStatus(bool status) @@ -2802,63 +2839,42 @@ void HarmonicCalibration::updateAcquisitionMotorRotationDirection() acquisitionMotorDirectionSwitch->setChecked(isMotorRotationClockwise); } -void HarmonicCalibration::getAcquisitionSamples(int sampleRate) +void HarmonicCalibration::getAcquisitionSamples(QMap dataMap) { while(isStartAcquisition) { - if(!updateChannelValues()) { - break; + if(updateChannelValues()) { + QMap sensorDataMap; + + if(dataMap.value(ANGLE)) + sensorDataMap[ANGLE] = angle; + if(dataMap.value(ABSANGLE)) + sensorDataMap[ABSANGLE] = rotation; + if(dataMap.value(TMP0)) + sensorDataMap[TMP0] = temp; + if(dataMap.value(SINE)) + sensorDataMap[SINE] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::SINE); + if(dataMap.value(COSINE)) + sensorDataMap[COSINE] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::COSINE); + if(dataMap.value(RADIUS)) + sensorDataMap[RADIUS] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::RADIUS); + if(dataMap.value(ANGLESEC)) + sensorDataMap[ANGLESEC] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::ANGLESEC); + if(dataMap.value(SECANGLI)) + sensorDataMap[SECANGLI] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLI); + if(dataMap.value(SECANGLQ)) + sensorDataMap[SECANGLQ] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLQ); + if(dataMap.value(TMP1)) + sensorDataMap[TMP1] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::TMP1); + + Q_EMIT acquisitionDataChanged(sensorDataMap); } - - if(acquisitionDataMap.at(ANGLE) == false && acquisitionAngleList.size() > 0) - acquisitionAngleList.clear(); - if(acquisitionDataMap.at(ABSANGLE) == false && acquisitionABSAngleList.size() > 0) - acquisitionABSAngleList.clear(); - if(acquisitionDataMap.at(TMP0) == false && acquisitionTmp0List.size() > 0) - acquisitionTmp0List.clear(); - if(acquisitionDataMap.at(SINE) == false && acquisitionSineList.size() > 0) - acquisitionSineList.clear(); - if(acquisitionDataMap.at(COSINE) == false && acquisitionCosineList.size() > 0) - acquisitionCosineList.clear(); - if(acquisitionDataMap.at(RADIUS) == false && acquisitionRadiusList.size() > 0) - acquisitionRadiusList.clear(); - if(acquisitionDataMap.at(ANGLESEC) == false && acquisitionAngleSecList.size() > 0) - acquisitionAngleSecList.clear(); - if(acquisitionDataMap.at(SECANGLI) == false && acquisitionSecAnglIList.size() > 0) - acquisitionSecAnglIList.clear(); - if(acquisitionDataMap.at(SECANGLQ) == false && acquisitionSecAnglQList.size() > 0) - acquisitionSecAnglQList.clear(); - if(acquisitionDataMap.at(TMP1) == false && acquisitionTmp1List.size() > 0) - acquisitionTmp1List.clear(); - - if(acquisitionDataMap.at(ANGLE)) - prependAcquisitionData(angle, acquisitionAngleList); - if(acquisitionDataMap.at(ABSANGLE)) - prependAcquisitionData(rotation, acquisitionABSAngleList); - if(acquisitionDataMap.at(TMP0)) - prependAcquisitionData(temp, acquisitionTmp0List); - if(acquisitionDataMap.at(SINE)) - prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::SINE), - acquisitionSineList); - if(acquisitionDataMap.at(COSINE)) - prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::COSINE), - acquisitionCosineList); - if(acquisitionDataMap.at(RADIUS)) - prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::RADIUS), - acquisitionRadiusList); - if(acquisitionDataMap.at(ANGLESEC)) - prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::ANGLESEC), - acquisitionAngleSecList); - if(acquisitionDataMap.at(SECANGLI)) - prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLI), - acquisitionSecAnglIList); - if(acquisitionDataMap.at(SECANGLQ)) - prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLQ), - acquisitionSecAnglQList); - if(acquisitionDataMap.at(TMP1)) - prependAcquisitionData(getSensorDataAcquisitionValue(ADMTController::SensorRegister::TMP1), - acquisitionTmp1List); - - QThread::msleep(sampleRate); } } @@ -2918,9 +2934,10 @@ double HarmonicCalibration::getSensorDataAcquisitionValue(const ADMTController:: } } -void HarmonicCalibration::plotAcquisition(QVector &list, PlotChannel *channel) +void HarmonicCalibration::plotAcquisition(QVector list, PlotChannel *channel) { - channel->curve()->setSamples(list); + QVector reverseList(list.rbegin(), list.rend()); + channel->curve()->setSamples(reverseList); auto result = minmax_element(list.begin(), list.end()); if(*result.first < acquisitionGraphYMin) acquisitionGraphYMin = *result.first; @@ -2928,10 +2945,13 @@ void HarmonicCalibration::plotAcquisition(QVector &list, PlotChannel *ch acquisitionGraphYMax = *result.second; } -void HarmonicCalibration::prependAcquisitionData(const double &data, QVector &list) +void HarmonicCalibration::appendAcquisitionData(const double &data, QVector &list) { - list.prepend(data); + if(data == qQNaN()) + return; + list.append(data); if(list.size() >= acquisitionDisplayLength) { + list.removeFirst(); list.resize(acquisitionDisplayLength); list.squeeze(); } @@ -2945,64 +2965,31 @@ void HarmonicCalibration::resetAcquisitionYAxisScale() acquisitionGraphPlotWidget->replot(); } -void HarmonicCalibration::acquisitionPlotTask(int sampleRate) -{ - while(isStartAcquisition) { - if(acquisitionDataMap.at(ANGLE)) - plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel); - if(acquisitionDataMap.at(ABSANGLE)) - plotAcquisition(acquisitionABSAngleList, acquisitionABSAnglePlotChannel); - if(acquisitionDataMap.at(TMP0)) - plotAcquisition(acquisitionTmp0List, acquisitionTmp0PlotChannel); - if(acquisitionDataMap.at(SINE)) - plotAcquisition(acquisitionSineList, acquisitionSinePlotChannel); - if(acquisitionDataMap.at(COSINE)) - plotAcquisition(acquisitionCosineList, acquisitionCosinePlotChannel); - if(acquisitionDataMap.at(RADIUS)) - plotAcquisition(acquisitionRadiusList, acquisitionRadiusPlotChannel); - if(acquisitionDataMap.at(ANGLESEC)) - plotAcquisition(acquisitionAngleSecList, acquisitionAngleSecPlotChannel); - if(acquisitionDataMap.at(SECANGLI)) - plotAcquisition(acquisitionSecAnglIList, acquisitionSecAnglIPlotChannel); - if(acquisitionDataMap.at(SECANGLQ)) - plotAcquisition(acquisitionSecAnglQList, acquisitionSecAnglQPlotChannel); - if(acquisitionDataMap.at(TMP1)) - plotAcquisition(acquisitionTmp1List, acquisitionTmp1PlotChannel); - - acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); - acquisitionGraphPlotWidget->replot(); +void HarmonicCalibration::updateAcquisitionGraph() +{ + if(acquisitionDataMap.value(ANGLE)) + plotAcquisition(acquisitionAngleList, acquisitionAnglePlotChannel); + if(acquisitionDataMap.value(ABSANGLE)) + plotAcquisition(acquisitionABSAngleList, acquisitionABSAnglePlotChannel); + if(acquisitionDataMap.value(TMP0)) + plotAcquisition(acquisitionTmp0List, acquisitionTmp0PlotChannel); + if(acquisitionDataMap.value(SINE)) + plotAcquisition(acquisitionSineList, acquisitionSinePlotChannel); + if(acquisitionDataMap.value(COSINE)) + plotAcquisition(acquisitionCosineList, acquisitionCosinePlotChannel); + if(acquisitionDataMap.value(RADIUS)) + plotAcquisition(acquisitionRadiusList, acquisitionRadiusPlotChannel); + if(acquisitionDataMap.value(ANGLESEC)) + plotAcquisition(acquisitionAngleSecList, acquisitionAngleSecPlotChannel); + if(acquisitionDataMap.value(SECANGLI)) + plotAcquisition(acquisitionSecAnglIList, acquisitionSecAnglIPlotChannel); + if(acquisitionDataMap.value(SECANGLQ)) + plotAcquisition(acquisitionSecAnglQList, acquisitionSecAnglQPlotChannel); + if(acquisitionDataMap.value(TMP1)) + plotAcquisition(acquisitionTmp1List, acquisitionTmp1PlotChannel); - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::acquisitionUITask(int sampleRate) -{ - while(isAcquisitionTab) { - if(isStartAcquisition) - updateLineEditValues(); - - QThread::msleep(sampleRate); - } -} - -void HarmonicCalibration::startAcquisitionUITask() -{ - if(!m_acquisitionUIThread.isRunning()) { - isAcquisitionTab = true; - m_acquisitionUIThread = - QtConcurrent::run(this, &HarmonicCalibration::acquisitionUITask, acquisitionUITimerRate); - m_acquisitionUIWatcher.setFuture(m_acquisitionUIThread); - } -} - -void HarmonicCalibration::stopAcquisitionUITask() -{ - isAcquisitionTab = false; - if(m_acquisitionUIThread.isRunning()) { - m_acquisitionUIThread.cancel(); - m_acquisitionUIWatcher.waitForFinished(); - } + acquisitionYPlotAxis->setInterval(acquisitionGraphYMin, acquisitionGraphYMax); + acquisitionGraphPlotWidget->replot(); } void HarmonicCalibration::updateSequenceWidget() @@ -3086,13 +3073,9 @@ void HarmonicCalibration::applySequenceAndUpdate() updateCapturedDataCheckBoxes(); } -void HarmonicCalibration::updateGeneralSettingEnabled(bool value) -{ - graphUpdateIntervalLineEdit->setEnabled(value); - displayLengthLineEdit->setEnabled(value); -} +void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { displayLengthLineEdit->setEnabled(value); } -void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, SensorDataKey key) +void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, SensorData key) { connect(widget, &QCheckBox::stateChanged, [this, channel, key](int state) { if(state == Qt::Checked) { @@ -3102,6 +3085,8 @@ void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox *widget, P channel->setEnabled(false); acquisitionDataMap[key] = false; } + + restartAcquisition(); }); } From 166848d199cb89c746c04d8671a1d5124b649a7a Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 13 Mar 2025 08:46:17 +0800 Subject: [PATCH 096/112] admt: Moved XML emulator file Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/{xmls => res/emu_xml}/admt4000.xml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename plugins/admt/{xmls => res/emu_xml}/admt4000.xml (100%) diff --git a/plugins/admt/xmls/admt4000.xml b/plugins/admt/res/emu_xml/admt4000.xml similarity index 100% rename from plugins/admt/xmls/admt4000.xml rename to plugins/admt/res/emu_xml/admt4000.xml From 97b10271a6bd009a64fcf90b976b1a0883b2dd89 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 13 Mar 2025 10:53:40 +0800 Subject: [PATCH 097/112] admt: Added slot and signal for calibration UI updates - Code cleanup Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 3 - .../admt/include/admt/harmoniccalibration.h | 3 +- plugins/admt/src/admtcontroller.cpp | 10 --- plugins/admt/src/harmoniccalibration.cpp | 85 +++++-------------- 4 files changed, 25 insertions(+), 76 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 797be6ee59..af86151b8a 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -61,7 +61,6 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject double streamedValue = 0.0; QVector streamBufferedValues; - QVector streamBufferedIntervals; QElapsedTimer elapsedStreamTimer; @@ -264,11 +263,9 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject public Q_SLOTS: void handleStreamData(double value); void handleStreamBufferedData(const QVector &value); - void handleStreamBufferedDataInterval(const QVector &value); Q_SIGNALS: void streamData(double value); void streamBufferedData(const QVector &value); - void streamBufferedDataInterval(const QVector &value); private: iio_context *m_iioCtx; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 3af446fa88..e5974e3874 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -111,6 +111,7 @@ public Q_SLOTS: void restart(); void updateAcquisitionData(QMap sensorDataMap); void updateAcquisitionGraph(); + void updateCalibrationGraph(); void calibrationLogWrite(QString message = ""); void commandLogWrite(QString message = ""); void updateFaultStatus(bool value); @@ -123,6 +124,7 @@ public Q_SLOTS: void runningChanged(bool); void acquisitionDataChanged(QMap sensorDataMap); void acquisitionGraphChanged(); + void calibrationGraphChanged(); void canCalibrateChanged(bool); void updateUtilityUI(); void calibrationLogWriteSignal(QString message); @@ -303,7 +305,6 @@ public Q_SLOTS: int calculateContinuousCalibrationSampleRate(double motorRPS, int samplesPerCycle); void configureConversionType(int mode); void configureCalibrationSequenceSettings(); - void getStreamedCalibrationSamples(int microSampleRate); void startOneShotCalibration(); void postCalibrateData(); void resetAllCalibrationState(); diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index dd8a50f955..bfe95082c7 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -51,8 +51,6 @@ ADMTController::ADMTController(QString uri, QObject *parent) { connect(this, &ADMTController::streamData, this, &ADMTController::handleStreamData); connect(this, &ADMTController::streamBufferedData, this, &ADMTController::handleStreamBufferedData); - connect(this, &ADMTController::streamBufferedDataInterval, this, - &ADMTController::handleStreamBufferedDataInterval); } ADMTController::~ADMTController() {} @@ -1749,7 +1747,6 @@ void ADMTController::handleStreamData(double value) { streamedValue = value; } void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) { - streamBufferedIntervals.clear(); QVector bufferedValues; vector rawBufferedValues; sampleCount = 0; @@ -1825,7 +1822,6 @@ void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) while(elapsedNanoseconds < targetSampleRate) { elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); } - streamBufferedIntervals.append(elapsedNanoseconds); } iio_buffer_destroy(buffer); @@ -1835,7 +1831,6 @@ void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) } Q_EMIT streamBufferedData(bufferedValues); - Q_EMIT streamBufferedDataInterval(streamBufferedIntervals); } void ADMTController::handleStreamBufferedData(const QVector &value) { streamBufferedValues = value; } @@ -1846,9 +1841,4 @@ bool ADMTController::checkVelocityReachedFlag(uint16_t registerValue) // set while VACTUAL and VMAX match. return ((registerValue >> 8) & 0x01) ? true : false; } - -void ADMTController::handleStreamBufferedDataInterval(const QVector &value) -{ - streamBufferedIntervals = value; -} #include "moc_admtcontroller.cpp" diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index d6ba0d8d83..8095a37684 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -29,17 +29,18 @@ using namespace scopy; using namespace scopy::admt; +// In milliseconds static int motorWaitVelocityReachedSampleRate = 50; - static int calibrationUITimerRate = 500; static int utilityUITimerRate = 1000; - -static int continuousCalibrationSampleRate = 10000000; // In nanoseconds static int deviceStatusMonitorRate = 500; static int motorPositionMonitorRate = 500; +static int readMotorDebounce = 50; -static int bufferSize = 1; +// In nanoseconds +static int continuousCalibrationSampleRate = 10000000; +static int bufferSize = 1; static int cycleCount = 11; static int samplesPerCycle = 256; static int totalSamplesCount = cycleCount * samplesPerCycle; @@ -60,7 +61,7 @@ static double motorAccelTime = 1; // In seconds static double motorFullStepPerRevolution = 360 / motorFullStepAngle; static double motorMicrostepPerRevolution = motorFullStepPerRevolution * microStepResolution; -static double motorTimeUnit = static_cast(1 << 24) / motorfCLK; // t = 2^24/16Mhz +static double motorTimeUnit = static_cast(1 << 24) / motorfCLK; // t = 2^24/motorfCLK static int acquisitionDisplayLength = 200; static QVector acquisitionAngleList, acquisitionABSAngleList, acquisitionTmp0List, acquisitionTmp1List, @@ -112,7 +113,6 @@ static bool isMotorVelocityCheck = false; static bool isMotorVelocityReached = false; static bool isResetMotorToZero = false; -static int readMotorDebounce = 50; // In ms static int calibrationMode = 0; static int globalSpacingSmall = Style::getDimension(json::global::unit_0_5); @@ -226,6 +226,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connect(this, &HarmonicCalibration::acquisitionDataChanged, this, &HarmonicCalibration::updateAcquisitionData); connect(this, &HarmonicCalibration::acquisitionGraphChanged, this, &HarmonicCalibration::updateAcquisitionGraph); + connect(this, &HarmonicCalibration::calibrationGraphChanged, this, + &HarmonicCalibration::updateCalibrationGraph); connect(this, &HarmonicCalibration::updateFaultStatusSignal, this, &HarmonicCalibration::updateFaultStatus); connect(this, &HarmonicCalibration::motorPositionChanged, this, &HarmonicCalibration::updateMotorPosition); connect(this, &HarmonicCalibration::calibrationLogWriteSignal, this, &HarmonicCalibration::calibrationLogWrite); @@ -646,16 +648,6 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() acquisitionFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", "status", false, acquisitionDeviceStatusSection); acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionFaultRegisterLEDWidget); - - // if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 - // { - // QCheckBox *acquisitionSPICRCLEDWidget = - // createStatusLEDWidget("SPI CRC", "status", false, acquisitionDeviceStatusSection); - // QCheckBox *acquisitionSPIFlagLEDWidget = - // createStatusLEDWidget("SPI Flag", "status", false, acquisitionDeviceStatusSection); - // acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPICRCLEDWidget); - // acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionSPIFlagLEDWidget); - // } #pragma endregion generalSettingLayout->setSpacing(globalSpacingSmall); @@ -1156,16 +1148,6 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationFaultRegisterLEDWidget = createStatusLEDWidget("Fault Register", "status", false, calibrationDeviceStatusSection); calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationFaultRegisterLEDWidget); - - // if(deviceType == "Automotive" && GENERALRegisterMap.at("Sequence Type") == 1) // Automotive & Sequence Mode 2 - // { - // QCheckBox *calibrationSPICRCLEDWidget = - // createStatusLEDWidget("SPI CRC", "status", false, calibrationDeviceStatusSection); - // QCheckBox *calibrationSPIFlagLEDWidget = - // createStatusLEDWidget("SPI Flag", "status", false, calibrationDeviceStatusSection); - // calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPICRCLEDWidget); - // calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationSPIFlagLEDWidget); - // } #pragma endregion #pragma region Acquire Calibration Samples Button @@ -1215,8 +1197,6 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() clearCalibrateDataButton = new QPushButton("Reset Calibration", calibrationSettingsGroupWidget); StyleHelper::BasicButton(clearCalibrateDataButton); QIcon resetIcon; - // resetIcon.addPixmap(Util::ChangeSVGColor(":/gui/icons/refresh.svg", - // "white", 1), QIcon::Normal, QIcon::Off); resetIcon.addPixmap(Style::getPixmap(":/gui/icons/refresh.svg", Style::getColor(json::theme::content_inverse)), QIcon::Normal, QIcon::Off); clearCalibrateDataButton->setIcon(resetIcon); @@ -1481,7 +1461,6 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); calibrationSettingsLayout->addWidget(motorControlSectionWidget); calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); - // calibrationSettingsLayout->addWidget(motorConfigurationSectionWidget); calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); calibrationSettingsLayout->addWidget(logsSectionWidget); calibrationSettingsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); @@ -1556,12 +1535,6 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() toggleTabSwitching(true); toggleCalibrationControls(true); - // QString log = "Calibration Stream Timing: \n"; - // for(auto &value : m_admtController->streamBufferedIntervals) { - // log += QString::number(value) + "\n"; - // } - // Q_EMIT calibrationLogWriteSignal(log); - if(isPostCalibration) { graphPostDataList = m_admtController->streamBufferedValues; postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); @@ -2598,6 +2571,7 @@ void HarmonicCalibration::requestDisconnect() stopCalibrationUITask(); stopUtilityTask(); + stopResetMotorToZero(); stopCalibrationStreamThread(); stopDeviceStatusMonitor(); @@ -3181,18 +3155,23 @@ void HarmonicCalibration::stopCalibrationUITask() } } +void HarmonicCalibration::updateCalibrationGraph() +{ + if(isStartMotor) { + if(isPostCalibration) { + postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); + postCalibrationRawDataPlotWidget->replot(); + } else { + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotWidget->replot(); + } + } +} + void HarmonicCalibration::calibrationUITask(int sampleRate) { while(isCalibrationTab) { - if(isStartMotor) { - if(isPostCalibration) { - postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); - postCalibrationRawDataPlotWidget->replot(); - } else { - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotWidget->replot(); - } - } + Q_EMIT calibrationGraphChanged(); QThread::msleep(sampleRate); } @@ -3429,20 +3408,6 @@ void HarmonicCalibration::configureCalibrationSequenceSettings() writeSequence(GENERALRegisterMap); } -void HarmonicCalibration::getStreamedCalibrationSamples(int microSampleRate) -{ - int currentSamplesCount = graphDataList.size(); - moveMotorContinuous(); - while(isStartMotor && currentSamplesCount < totalSamplesCount) { - graphDataList.append(m_admtController->streamedValue); - // graphPostDataList.append(m_admtController->streamedValue); - currentSamplesCount = graphDataList.size(); - // currentSamplesCount = graphDataPostList.size(); - - QThread::usleep(microSampleRate); - } -} - void HarmonicCalibration::startOneShotCalibration() { if(resetToZero && !isPostCalibration) { @@ -4085,10 +4050,6 @@ void HarmonicCalibration::canCalibrate(bool value) { calibrateDataButton->setEna void HarmonicCalibration::toggleCalibrationControls(bool value) { - // motorMaxVelocitySpinBox->setEnabled(value); - // motorAccelTimeSpinBox->setEnabled(value); - // motorMaxDisplacementSpinBox->setEnabled(value); - // m_calibrationMotorRampModeMenuCombo->setEnabled(value); motorTargetPositionLineEdit->setEnabled(value); calibrationModeMenuCombo->setEnabled(value); } From ad213e6cd2aecc27d3ad26c7fadac62b71b5a44a Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 13 Mar 2025 13:13:54 +0800 Subject: [PATCH 098/112] admt: Handled validations for register maps for emulator Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/harmoniccalibration.cpp | 149 ++++++++++++++++------- 1 file changed, 104 insertions(+), 45 deletions(-) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 8095a37684..a1348c4580 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -208,9 +208,11 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 2) // Utility Tab { readSequence(); - toggleFaultRegisterMode(GENERALRegisterMap.at("Sequence Type")); - toggleMTDiagnostics(GENERALRegisterMap.at("Sequence Type")); - toggleUtilityTask(true); + if(GENERALRegisterMap.contains("Sequence Type")) { + toggleFaultRegisterMode(GENERALRegisterMap.at("Sequence Type")); + toggleMTDiagnostics(GENERALRegisterMap.at("Sequence Type")); + toggleUtilityTask(true); + } } else { toggleUtilityTask(false); } @@ -218,7 +220,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 3) // Registers Tab { readSequence(); - toggleRegisters(GENERALRegisterMap.at("Sequence Type")); + if(GENERALRegisterMap.contains("Sequence Type")) { + toggleRegisters(GENERALRegisterMap.at("Sequence Type")); + } } }); @@ -518,27 +522,45 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() Style::setStyle(temp1CheckBox, style::properties::admt::coloredCheckBox, "ch1"); connectCheckBoxToAcquisitionGraph(temp1CheckBox, acquisitionTmp1PlotChannel, TMP1); - if(GENERALRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 - { + if(!GENERALRegisterMap.contains("Sequence Type")) { acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); - } else if(GENERALRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 - { - acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); - acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); - acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); - acquisitionGraphChannelGridLayout->addWidget(angleSecCheckBox, 0, 3); - acquisitionGraphChannelGridLayout->addWidget(secAnglQCheckBox, 0, 4); - acquisitionGraphChannelGridLayout->addWidget(secAnglICheckBox, 1, 0); - acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 1, 1); - acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 2); - acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 3); - acquisitionGraphChannelGridLayout->addWidget(temp1CheckBox, 1, 4); + angleSecCheckBox->hide(); + secAnglICheckBox->hide(); + secAnglQCheckBox->hide(); + temp1CheckBox->hide(); + } else { + if(GENERALRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 + { + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); + angleSecCheckBox->hide(); + secAnglICheckBox->hide(); + secAnglQCheckBox->hide(); + temp1CheckBox->hide(); + } else if(GENERALRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 + { + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(angleSecCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(secAnglQCheckBox, 0, 4); + acquisitionGraphChannelGridLayout->addWidget(secAnglICheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 1, 1); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 2); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 3); + acquisitionGraphChannelGridLayout->addWidget(temp1CheckBox, 1, 4); + } } + #pragma endregion acquisitionGraphSectionWidget->contentLayout()->addWidget(acquisitionGraphLabel); @@ -646,7 +668,7 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() acquisitionDeviceStatusWidget->contentLayout()->addWidget(acquisitionDeviceStatusSection); acquisitionFaultRegisterLEDWidget = - createStatusLEDWidget("Fault Register", "status", false, acquisitionDeviceStatusSection); + createStatusLEDWidget("Fault Register", "status", deviceStatusFault, acquisitionDeviceStatusSection); acquisitionDeviceStatusSection->contentLayout()->addWidget(acquisitionFaultRegisterLEDWidget); #pragma endregion @@ -1146,7 +1168,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationDeviceStatusWidget->contentLayout()->addWidget(calibrationDeviceStatusSection); calibrationFaultRegisterLEDWidget = - createStatusLEDWidget("Fault Register", "status", false, calibrationDeviceStatusSection); + createStatusLEDWidget("Fault Register", "status", deviceStatusFault, calibrationDeviceStatusSection); calibrationDeviceStatusSection->contentLayout()->addWidget(calibrationFaultRegisterLEDWidget); #pragma endregion @@ -2124,7 +2146,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOControlGridWidget); DIGIOControlCollapseSection->contentLayout()->addWidget(DIGIOResetButton); - if(GENERALRegisterMap.at("Sequence Type") == 0) { + if(deviceType == "Industrial") { DIGIO2FNCToggleSwitch->setVisible(false); DIGIO4FNCToggleSwitch->setVisible(false); } @@ -2366,15 +2388,19 @@ void HarmonicCalibration::readDeviceProperties() if(!success) { StatusBarManager::pushMessage("Failed to read device properties"); + + // If read device property fails, assumes running emulator + deviceName = "ADMT4000"; + deviceType = "Emulator"; } } void HarmonicCalibration::initializeADMT() { - bool success = resetDIGIO(); - success = resetGENERAL(); + bool resetDIGIOSuccess = resetDIGIO(); + bool resetGENERALSuccess = resetGENERAL(); - if(!success) { + if(!resetDIGIOSuccess || !resetGENERALSuccess) { StatusBarManager::pushMessage("Failed initialize ADMT"); } } @@ -2549,16 +2575,19 @@ void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) m_admtController->getConfigurationRegister( ADMTController::ConfigurationRegister::FAULT), readValue) == 0) { - registerFault = m_admtController->checkRegisterFault( - static_cast(*readValue), - GENERALRegisterMap.at("Sequence Type") == 0 ? true : false); - Q_EMIT updateFaultStatusSignal(registerFault); - } else { + if(GENERALRegisterMap.contains("Sequence Type")) { + registerFault = m_admtController->checkRegisterFault( + static_cast(*readValue), + GENERALRegisterMap.at("Sequence Type") == 0 ? true : false); + + Q_EMIT updateFaultStatusSignal(registerFault); + } else + Q_EMIT updateFaultStatusSignal(true); + } else Q_EMIT updateFaultStatusSignal(true); - } - } else { + + } else Q_EMIT updateFaultStatusSignal(true); - } QThread::msleep(sampleRate); } @@ -2622,20 +2651,23 @@ bool HarmonicCalibration::resetGENERAL() { bool success = false; - uint32_t resetValue = 0x0000; - if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { - resetValue = 0x1231; - } // Industrial or ASIL QM - else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { - resetValue = 0x1200; - } // Automotive or ASIL B + if(deviceRegisterMap.contains("ASIL ID")) { + uint32_t resetValue = 0x0000; + if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { + resetValue = 0x1231; + } // Industrial or ASIL QM + else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { + resetValue = 0x1200; + } // Automotive or ASIL B - if(resetValue != 0x0000) { - if(m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL), - resetValue) == 0) { - success = true; + if(resetValue != 0x0000) { + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister( + ADMTController::ConfigurationRegister::GENERAL), + resetValue) == 0) { + success = true; + } } } @@ -2968,6 +3000,12 @@ void HarmonicCalibration::updateAcquisitionGraph() void HarmonicCalibration::updateSequenceWidget() { + if(!GENERALRegisterMap.contains("Sequence Type") || !GENERALRegisterMap.contains("Conversion Type") || + !GENERALRegisterMap.contains("Convert Synchronization") || !GENERALRegisterMap.contains("Angle Filter") || + !GENERALRegisterMap.contains("8th Harmonic")) { + return; + } + if(GENERALRegisterMap.at("Sequence Type") == -1) { sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); } else { @@ -2991,6 +3029,11 @@ void HarmonicCalibration::updateSequenceWidget() void HarmonicCalibration::updateCapturedDataCheckBoxes() { + if(!GENERALRegisterMap.contains("Sequence Type")) { + StatusBarManager::pushMessage("Failed to read sequence settings"); + return; + } + acquisitionGraphChannelGridLayout->removeWidget(angleCheckBox); acquisitionGraphChannelGridLayout->removeWidget(sineCheckBox); acquisitionGraphChannelGridLayout->removeWidget(cosineCheckBox); @@ -3397,6 +3440,11 @@ int HarmonicCalibration::calculateContinuousCalibrationSampleRate(double motorRP void HarmonicCalibration::configureConversionType(int mode) { readSequence(); + if(!GENERALRegisterMap.contains("Conversion Type")) { + StatusBarManager::pushMessage("Failed to configure calibration conversion type"); + return; + } + GENERALRegisterMap.at("Conversion Type") = mode; writeSequence(GENERALRegisterMap); } @@ -3404,6 +3452,11 @@ void HarmonicCalibration::configureConversionType(int mode) void HarmonicCalibration::configureCalibrationSequenceSettings() { readSequence(); + if(!GENERALRegisterMap.contains("8th Harmonic")) { + StatusBarManager::pushMessage("Failed to configure calibration sequence settings"); + return; + } + GENERALRegisterMap.at("8th Harmonic") = 1; // User-supplied 8th Harmonic writeSequence(GENERALRegisterMap); } @@ -4621,6 +4674,11 @@ void HarmonicCalibration::clearCommandLog() { commandLogPlainTextEdit->clear(); #pragma region Register Methods void HarmonicCalibration::readAllRegisters() { + if(!GENERALRegisterMap.contains("Sequence Type")) { + StatusBarManager::pushMessage("Failed to read all registers"); + return; + } + readAllRegistersButton->setEnabled(false); readAllRegistersButton->setText(QString("Reading Registers...")); QTimer::singleShot(1000, this, [this]() { @@ -4628,6 +4686,7 @@ void HarmonicCalibration::readAllRegisters() readAllRegistersButton->setText(QString("Read All Registers")); }); + // TODO: Change to a more efficient way to read all registers cnvPageRegisterBlock->readButton()->click(); digIORegisterBlock->readButton()->click(); faultRegisterBlock->readButton()->click(); From 6272a42e39a56fbdd1e20c9b8074bab869327673 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 13 Mar 2025 16:32:26 +0800 Subject: [PATCH 099/112] resources: Added ADMT4000 emulator device Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- resources/scopy_emu_options_config.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/resources/scopy_emu_options_config.json b/resources/scopy_emu_options_config.json index 718a967d94..f8a09afd9d 100644 --- a/resources/scopy_emu_options_config.json +++ b/resources/scopy_emu_options_config.json @@ -26,6 +26,11 @@ "xml_path": "swiot_runtime1.xml", "uri": "ip:127.0.0.1" }, + { + "device": "admt4000", + "xml_path": "admt4000.xml", + "uri": "ip:127.0.0.1" + }, { "device": "generic", "uri": "ip:127.0.0.1" From e805fa82b67a069ccdf24be4f1e56ae7eda6fd1c Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 14 Mar 2025 16:47:41 +0800 Subject: [PATCH 100/112] admt: Disable ECC when configuring DIGIOEN, GENERAL, and Harmonic registers Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 2 +- .../admt/include/admt/harmoniccalibration.h | 9 +- plugins/admt/src/harmoniccalibration.cpp | 446 +++++++++++------- 3 files changed, 292 insertions(+), 165 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index af86151b8a..a148592f5a 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -138,7 +138,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject GENERAL, DIGIOEN, ANGLECK, - ECCDCDE, + ECCCDE, ECCDIS, CONFIGURATION_REGISTER_COUNT }; diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index e5974e3874..5efb01bdf4 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -227,7 +227,7 @@ public Q_SLOTS: *DIGIO5FNCToggleSwitch, *DIGIOALLToggleSwitch; RegisterBlockWidget *cnvPageRegisterBlock, *digIORegisterBlock, *faultRegisterBlock, *generalRegisterBlock, - *digIOEnRegisterBlock, *angleCkRegisterBlock, *eccDcdeRegisterBlock, *eccDisRegisterBlock, + *digIOEnRegisterBlock, *angleCkRegisterBlock, *eccCdeRegisterBlock, *eccDisRegisterBlock, *absAngleRegisterBlock, *angleRegisterBlock, *angleSecRegisterBlock, *sineRegisterBlock, *cosineRegisterBlock, *secAnglIRegisterBlock, *secAnglQRegisterBlock, *radiusRegisterBlock, *diag1RegisterBlock, *diag2RegisterBlock, *tmp0RegisterBlock, *tmp1RegisterBlock, *cnvCntRegisterBlock, @@ -311,8 +311,8 @@ public Q_SLOTS: void computeSineCosineOfAngles(QVector graphDataList); void populateAngleErrorGraphs(); void populateCorrectedAngleErrorGraphs(); - void clearHarmonicRegisters(); - void flashHarmonicValues(); + bool clearHarmonicRegisters(); + bool flashHarmonicValues(); void calculateHarmonicValues(); void updateCalculatedCoeffAngle(); void updateCalculatedCoeffHex(); @@ -359,10 +359,11 @@ public Q_SLOTS: void getDIAG2Register(); void getDIAG1Register(); void getFAULTRegister(); - void toggleDIGIOEN(string DIGIOENName, bool value); + bool toggleDIGIOEN(string DIGIOENName, bool value); void toggleMTDiagnostics(int mode); void toggleFaultRegisterMode(int mode); bool resetDIGIO(); + bool disableECC(bool disable); void clearCommandLog(); #pragma endregion diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index a1348c4580..e61f9bcff1 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -1681,10 +1681,10 @@ ToolTemplate *HarmonicCalibration::createRegistersWidget() m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ANGLECK), m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ANGLECK), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); - eccDcdeRegisterBlock = new RegisterBlockWidget( - "ECCDCDE", "Error Correction Codes", - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ECCDCDE), - m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCDCDE), + eccCdeRegisterBlock = new RegisterBlockWidget( + "ECCCDE", "Error Correction Codes", + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ECCCDE), + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCCDE), RegisterBlockWidget::ACCESS_PERMISSION::READWRITE, registerWidget); eccDisRegisterBlock = new RegisterBlockWidget( "ECCDIS", "Error Correction Code disable", @@ -1824,7 +1824,7 @@ ToolTemplate *HarmonicCalibration::createRegistersWidget() registerConfigurationGridLayout->addWidget(faultRegisterBlock, 0, 2); registerConfigurationGridLayout->addWidget(generalRegisterBlock, 0, 3); registerConfigurationGridLayout->addWidget(digIOEnRegisterBlock, 0, 4); - registerConfigurationGridLayout->addWidget(eccDcdeRegisterBlock, 1, 0); + registerConfigurationGridLayout->addWidget(eccCdeRegisterBlock, 1, 0); registerConfigurationGridLayout->addWidget(eccDisRegisterBlock, 1, 1); registerConfigurationGridLayout->addWidget(angleCkRegisterBlock, 1, 2); @@ -1906,7 +1906,7 @@ ToolTemplate *HarmonicCalibration::createRegistersWidget() connectRegisterBlockToRegistry(generalRegisterBlock); connectRegisterBlockToRegistry(digIOEnRegisterBlock); connectRegisterBlockToRegistry(angleCkRegisterBlock); - connectRegisterBlockToRegistry(eccDcdeRegisterBlock); + connectRegisterBlockToRegistry(eccCdeRegisterBlock); connectRegisterBlockToRegistry(eccDisRegisterBlock); connectRegisterBlockToRegistry(absAngleRegisterBlock); @@ -2047,70 +2047,109 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO0ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Output", "Input"); DIGIO0ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO0EN", value); }); + connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("DIGIO0EN", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); + }); DIGIO0FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO0FNCToggleSwitch, "GPIO0", "BUSY"); DIGIO0FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO0FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("BUSY", value); }); + connect(DIGIO0FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("BUSY", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO0" : "BUSY")); + }); DIGIO1ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO1ENToggleSwitch, "Output", "Input"); DIGIO1ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO1ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO1EN", value); }); + connect(DIGIO1ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("DIGIO1EN", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); + }); DIGIO1FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO1FNCToggleSwitch, "GPIO1", "CNV"); DIGIO1FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO1FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("CNV", value); }); + connect(DIGIO1FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("CNV", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO1" : "CNV")); + }); DIGIO2ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO2ENToggleSwitch, "Output", "Input"); DIGIO2ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO2ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO2EN", value); }); + connect(DIGIO2ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("DIGIO2EN", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); + }); DIGIO2FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO2FNCToggleSwitch, "GPIO2", "SENT"); DIGIO2FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO2FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("SENT", value); }); + connect(DIGIO2FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("SENT", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO2" : "SENT")); + }); DIGIO3ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO3ENToggleSwitch, "Output", "Input"); DIGIO3ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO3ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO3EN", value); }); + connect(DIGIO3ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("DIGIO3EN", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); + }); DIGIO3FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO3FNCToggleSwitch, "GPIO3", "ACALC"); DIGIO3FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO3FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("ACALC", value); }); + connect(DIGIO3FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("ACALC", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO3" : "ACALC")); + }); DIGIO4ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO4ENToggleSwitch, "Output", "Input"); DIGIO4ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO4ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO4EN", value); }); + connect(DIGIO4ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("DIGIO4EN", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); + }); DIGIO4FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO4FNCToggleSwitch, "GPIO4", "FAULT"); DIGIO4FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO4FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("FAULT", value); }); + connect(DIGIO4FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("FAULT", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO4" : "FAULT")); + }); DIGIO5ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO5ENToggleSwitch, "Output", "Input"); DIGIO5ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO5ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { toggleDIGIOEN("DIGIO5EN", value); }); + connect(DIGIO5ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("DIGIO5EN", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); + }); DIGIO5FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO5FNCToggleSwitch, "GPIO5", "BOOT"); DIGIO5FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO5FNCToggleSwitch, &CustomSwitch::clicked, - [this](bool value) { toggleDIGIOEN("BOOTLOAD", value); }); + connect(DIGIO5FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + if(!toggleDIGIOEN("BOOTLOAD", value)) + StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO5" : "BOOT")); + }); QPushButton *DIGIOResetButton = new QPushButton("Reset DIGIO", DIGIOControlGridWidget); DIGIOResetButton->setFixedWidth(100); StyleHelper::BasicButton(DIGIOResetButton); connect(DIGIOResetButton, &QPushButton::clicked, [this] { toggleUtilityTask(false); - resetDIGIO(); + bool success = resetDIGIO(); + if(success) + StatusBarManager::pushMessage("Successfully reset DIGIO"); + else + StatusBarManager::pushMessage("Failed to reset DIGIO"); toggleUtilityTask(true); }); @@ -2437,29 +2476,39 @@ bool HarmonicCalibration::writeSequence(const map &settings) bool success = false; + if(!disableECC(true)) { + return false; + } + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - generalRegisterAddress, generalRegValue) != -1) { + generalRegisterAddress, generalRegValue) != 0) { + return false; + } - uint32_t newGeneralRegValue = - m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings); - uint32_t generalRegisterPage = - m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); + uint32_t newGeneralRegValue = m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings); + uint32_t generalRegisterPage = + m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); - if(changeCNVPage(generalRegisterPage)) { - if(m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - generalRegisterAddress, newGeneralRegValue) != -1) { - if(readSequence()) { - if(settings.at("Convert Synchronization") == - GENERALRegisterMap.at("Convert Synchronization") && - settings.at("Angle Filter") == GENERALRegisterMap.at("Angle Filter") && - settings.at("8th Harmonic") == GENERALRegisterMap.at("8th Harmonic") && - settings.at("Sequence Type") == GENERALRegisterMap.at("Sequence Type") && - settings.at("Conversion Type") == GENERALRegisterMap.at("Conversion Type")) { - success = true; - } - } - } + if(!changeCNVPage(generalRegisterPage)) { + return false; + } + + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + generalRegisterAddress, newGeneralRegValue) != 0) { + return false; + } + + if(!disableECC(false)) { + return false; + } + + if(readSequence()) { + if(settings.at("Convert Synchronization") == GENERALRegisterMap.at("Convert Synchronization") && + settings.at("Angle Filter") == GENERALRegisterMap.at("Angle Filter") && + settings.at("8th Harmonic") == GENERALRegisterMap.at("8th Harmonic") && + settings.at("Sequence Type") == GENERALRegisterMap.at("Sequence Type") && + settings.at("Conversion Type") == GENERALRegisterMap.at("Conversion Type")) { + success = true; } } @@ -2651,14 +2700,17 @@ bool HarmonicCalibration::resetGENERAL() { bool success = false; + if(!disableECC(true)) { + return false; + } + if(deviceRegisterMap.contains("ASIL ID")) { uint32_t resetValue = 0x0000; - if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { - resetValue = 0x1231; - } // Industrial or ASIL QM - else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { - resetValue = 0x1200; - } // Automotive or ASIL B + + if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") + resetValue = 0x1230; // Industrial or ASIL QM + else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") + resetValue = 0x1200; // Automotive or ASIL B if(resetValue != 0x0000) { if(m_admtController->writeDeviceRegistry( @@ -2671,6 +2723,10 @@ bool HarmonicCalibration::resetGENERAL() } } + if(!disableECC(false)) { + return false; + } + return success; } @@ -3699,103 +3755,126 @@ void HarmonicCalibration::populateCorrectedAngleErrorGraphs() resultDataTabWidget->setCurrentIndex(2); // Set tab to Angle Error } -void HarmonicCalibration::clearHarmonicRegisters() +bool HarmonicCalibration::clearHarmonicRegisters() { bool success = false; + uint32_t value = 0x0; uint32_t harmonicCNVPage = m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1MAG); - if(changeCNVPage(harmonicCNVPage)) { - success = m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), - value) == 0 - ? true - : false; - success = m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), - value) == 0 - ? true - : false; - success = m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), - value) == 0 - ? true - : false; - success = m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), - value) == 0 - ? true - : false; - success = m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), - value) == 0 - ? true - : false; - success = m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), - value) == 0 - ? true - : false; - success = m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), - value) == 0 - ? true - : false; - success = m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), - value) == 0 - ? true - : false; - } + + if(!disableECC(true)) + return false; + + if(!changeCNVPage(harmonicCNVPage)) + return false; + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), value) != 0) + return false; + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), value) != 0) + return false; + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), value) != 0) + return false; + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), value) != 0) + return false; + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), value) != 0) + return false; + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), value) != 0) + return false; + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), value) != 0) + return false; + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), value) != 0) + return false; + + if(disableECC(false)) { + success = true; + } else + return false; if(!success) { - calibrationLogWrite("Unable to clear Harmonic Registers!"); + StatusBarManager::pushMessage("Unable to clear Harmonic Registers!"); } + + return success; } -void HarmonicCalibration::flashHarmonicValues() +bool HarmonicCalibration::flashHarmonicValues() { - if(changeCNVPage(0x02)) { - m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - 0x01, 0x02); + bool success = false; - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), H1_MAG_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), H1_PHASE_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), H2_MAG_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), H2_PHASE_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), H3_MAG_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), H3_PHASE_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), H8_MAG_HEX); - m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), H8_PHASE_HEX); + if(!disableECC(true)) + return false; - isCalculatedCoeff = true; - displayCalculatedCoeff(); - } else { - calibrationLogWrite("Unabled to flash Harmonic Registers!"); - } + if(!changeCNVPage(0x02)) + return false; + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), H1_MAG_HEX) != 0) + return false; + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1PH), H1_PHASE_HEX) != 0) + return false; + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2MAG), H2_MAG_HEX) != 0) + return false; + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H2PH), H2_PHASE_HEX) != 0) + return false; + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3MAG), H3_MAG_HEX) != 0) + return false; + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H3PH), H3_PHASE_HEX) != 0) + return false; + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8MAG), H8_MAG_HEX) != 0) + return false; + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), H8_PHASE_HEX) != 0) + return false; + + isCalculatedCoeff = true; + displayCalculatedCoeff(); + + if(disableECC(true)) + success = true; + else + return false; + + if(!success) + StatusBarManager::pushMessage("Unable to flash Harmonic Registers!"); + + return success; } void HarmonicCalibration::calculateHarmonicValues() @@ -4585,39 +4664,51 @@ void HarmonicCalibration::updateFaultRegisterUI(quint16 faultRegValue) SequencerWatchdogStatusLED->setChecked(regmap.at("Sequencer Watchdog")); } -void HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) +bool HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) { toggleUtilityTask(false); + bool success = false; + + if(!disableECC(true)) + return false; + uint32_t *DIGIOENRegisterValue = new uint32_t; uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - if(changeCNVPage(DIGIOENPage)) { - if(m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != -1) { - map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping( - static_cast(*DIGIOENRegisterValue)); + if(!changeCNVPage(DIGIOENPage)) + return false; - DIGIOSettings.at(DIGIOENName) = value; + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + DIGIOENRegisterValue) != 0) + return false; - uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping( - static_cast(*DIGIOENRegisterValue), DIGIOSettings); + map DIGIOSettings = + m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); - if(changeCNVPage(DIGIOENPage)) { - if(m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister( - ADMTController::ConfigurationRegister::DIGIOEN), - static_cast(newRegisterValue)) != -1) { - updateDIGIOControlUI(); - } - } - } - } + DIGIOSettings.at(DIGIOENName) = value; + + uint16_t newRegisterValue = m_admtController->setDIGIOENRegisterBitMapping( + static_cast(*DIGIOENRegisterValue), DIGIOSettings); + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + static_cast(newRegisterValue)) == 0) { + success = true; + } else + return false; + + updateDIGIOControlUI(); + + if(!disableECC(false)) + return false; toggleUtilityTask(true); + + return success; } void HarmonicCalibration::toggleMTDiagnostics(int mode) @@ -4658,12 +4749,47 @@ void HarmonicCalibration::toggleFaultRegisterMode(int mode) bool HarmonicCalibration::resetDIGIO() { - return (m_admtController->writeDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - 0x241b) == 0 - ? true - : false); + bool success = false; + + uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + + if(!disableECC(true)) { + return false; + } + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), + 0x241b) == 0) { + success = true; + } + + if(!disableECC(false)) { + return false; + } + + return success; +} + +bool HarmonicCalibration::disableECC(bool disable) +{ + bool success = false; + + uint32_t ECCDISRegValue = disable ? 0x4D54 : 0x0000; + uint32_t ECCDISCNVPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCDIS); + + if(!changeCNVPage(ECCDISCNVPage)) { + return success; + } + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::ECCDIS), + ECCDISRegValue) == 0) { + success = true; + } + + return success; } void HarmonicCalibration::commandLogWrite(QString message) { commandLogPlainTextEdit->appendPlainText(message); } @@ -4692,7 +4818,7 @@ void HarmonicCalibration::readAllRegisters() faultRegisterBlock->readButton()->click(); generalRegisterBlock->readButton()->click(); digIOEnRegisterBlock->readButton()->click(); - eccDcdeRegisterBlock->readButton()->click(); + eccCdeRegisterBlock->readButton()->click(); eccDisRegisterBlock->readButton()->click(); absAngleRegisterBlock->readButton()->click(); angleRegisterBlock->readButton()->click(); From b915d471c85f0f5e27b4cdb7c2dc84e029f54be0 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 18 Mar 2025 07:50:21 +0800 Subject: [PATCH 101/112] admt: Use general_use_native_dialogs preference Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/harmoniccalibration.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index e61f9bcff1..32db837b78 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -23,6 +23,7 @@ #include "qtconcurrentrun.h" #include "style.h" #include "style_properties.h" +#include "pluginbase/preferences.h" #include @@ -4055,10 +4056,12 @@ void HarmonicCalibration::calibrationLogWrite(QString message) { logsPlainTextEd void HarmonicCalibration::importCalibrationData() { - QString fileName = QFileDialog::getOpenFileName(this, tr("Import"), "", - tr("Comma-separated values files (*.csv);;" - "Tab-delimited values files (*.txt)"), - nullptr, QFileDialog::Options()); + bool useNativeDialogs = Preferences::get("general_use_native_dialogs").toBool(); + QString fileName = QFileDialog::getOpenFileName( + this, tr("Import"), "", + tr("Comma-separated values files (*.csv);;" + "Tab-delimited values files (*.txt)"), + nullptr, (useNativeDialogs ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog)); FileManager fm("HarmonicCalibration"); @@ -4092,8 +4095,10 @@ void HarmonicCalibration::extractCalibrationData() QString selectedFilter = filter[0]; - QString fileName = QFileDialog::getSaveFileName(this, tr("Export"), "", filter.join(";;"), &selectedFilter, - QFileDialog::Options()); + bool useNativeDialogs = Preferences::get("general_use_native_dialogs").toBool(); + QString fileName = QFileDialog::getSaveFileName( + this, tr("Export"), "", filter.join(";;"), &selectedFilter, + (useNativeDialogs ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog)); if(fileName.split(".").size() <= 1) { QString ext = selectedFilter.split(".")[1].split(")")[0]; From c464b915d9d7fdc9f77198839296d705771ac636 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 18 Mar 2025 07:54:08 +0800 Subject: [PATCH 102/112] admt: Resolve tests Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 1 + plugins/admt/include/admt/admtplugin.h | 1 + plugins/admt/src/admtplugin.cpp | 34 ++++------------------ plugins/admt/test/tst_pluginloader.cpp | 4 ++- 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index a148592f5a..f7fe2fe7bb 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -268,6 +268,7 @@ public Q_SLOTS: void streamBufferedData(const QVector &value); private: + QWidget *m_page; iio_context *m_iioCtx; iio_buffer *m_iioBuffer; Connection *m_conn; diff --git a/plugins/admt/include/admt/admtplugin.h b/plugins/admt/include/admt/admtplugin.h index 23f91c8579..35d3d830c9 100644 --- a/plugins/admt/include/admt/admtplugin.h +++ b/plugins/admt/include/admt/admtplugin.h @@ -52,6 +52,7 @@ class SCOPY_ADMT_EXPORT ADMTPlugin : public QObject, public PluginBase void unload() override; void initMetadata() override; QString description() override; + QString version() override; public Q_SLOTS: bool onConnect() override; diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index 2105dc985b..6c0b724527 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -58,33 +58,7 @@ bool ADMTPlugin::compatible(QString m_param, QString category) bool ADMTPlugin::loadPage() { - // Here you must write the code for the plugin info page - // Below is an example for an iio device - /*m_page = new QWidget(); - m_page->setLayout(new QVBoxLayout(m_page)); - m_page->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_infoPage = new InfoPage(m_page); - m_infoPage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - m_page->layout()->addWidget(m_infoPage); - m_page->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Preferred, - QSizePolicy::Expanding)); - - auto cp = ContextProvider::GetInstance(); - struct iio_context *context = cp->open(m_param); - ssize_t attributeCount = iio_context_get_attrs_count(context); - for(int i = 0; i < attributeCount; ++i) { - const char *name; - const char *value; - int ret = iio_context_get_attr(context, i, &name, &value); - if(ret < 0) { - qWarning(CAT_ADMTPLUGIN) << "Could not read attribute with - index:" << i; continue; - } - - m_infoPage->update(name, value); - } - cp->close(m_param); - m_page->ensurePolished();*/ + m_page = new QWidget(); return true; } @@ -101,7 +75,9 @@ void ADMTPlugin::loadToolList() } void ADMTPlugin::unload() -{ /*delete m_infoPage;*/ +{ + delete m_page; + delete m_admtController; } QString ADMTPlugin::description() { return "Plugin for ADMT Harmonic Calibration"; } @@ -163,4 +139,6 @@ void ADMTPlugin::initMetadata() )plugin"); } +QString ADMTPlugin::version() { return "0.1"; } + #include "moc_admtplugin.cpp" diff --git a/plugins/admt/test/tst_pluginloader.cpp b/plugins/admt/test/tst_pluginloader.cpp index ee227af7db..1cd1ae2025 100644 --- a/plugins/admt/test/tst_pluginloader.cpp +++ b/plugins/admt/test/tst_pluginloader.cpp @@ -44,7 +44,7 @@ private Q_SLOTS: }; #define PLUGIN_LOCATION "../../plugins" -#define FILENAME PLUGIN_LOCATION "/libscopy-admtplugin.so" +#define FILENAME PLUGIN_LOCATION "/libscopy-admt.so" void TST_ADMTPlugin::fileExists() { @@ -67,7 +67,9 @@ void TST_ADMTPlugin::className() void TST_ADMTPlugin::loaded() { QPluginLoader qp(FILENAME, this); + qDebug() << qp.errorString(); qp.load(); + QVERIFY(qp.isLoaded()); } From 2028da1e6967f52e65ca9645e91e7aac7ff37f69 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 28 Mar 2025 13:07:04 +0800 Subject: [PATCH 103/112] admt: Fix displayed turn count - Code cleanup potential memory leaks - Disabled ECC on startup - Adusted layout for calibration tab - Replaced maps with QMap Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 8 +- .../admt/include/admt/harmoniccalibration.h | 31 +- plugins/admt/src/admtcontroller.cpp | 50 +- plugins/admt/src/admtplugin.cpp | 3 + plugins/admt/src/harmoniccalibration.cpp | 731 ++++++++---------- 5 files changed, 390 insertions(+), 433 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index f7fe2fe7bb..0607401656 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -24,7 +24,6 @@ #include "scopy-admt_export.h" -#include #include #include @@ -34,14 +33,10 @@ #include #include -#include #include -#include #include #include -#include #include -#include #include using namespace std; @@ -266,6 +261,7 @@ public Q_SLOTS: Q_SIGNALS: void streamData(double value); void streamBufferedData(const QVector &value); + void requestDisconnect(); private: QWidget *m_page; @@ -288,4 +284,4 @@ public Q_SLOTS: }; } // namespace scopy::admt -#endif // ADMTCONTROLLER_H \ No newline at end of file +#endif // ADMTCONTROLLER_H diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 5efb01bdf4..fc2245c66c 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -104,6 +104,7 @@ class SCOPY_ADMT_EXPORT HarmonicCalibration : public QWidget bool running() const; void setRunning(bool newRunning); void requestDisconnect(); + public Q_SLOTS: void run(bool); void stop(); @@ -150,16 +151,28 @@ public Q_SLOTS: double rotation, angle, count, temp = 0.0, motor_rpm, amax, rotate_vmax, dmax, disable, target_pos, current_pos, ramp_mode, afeDiag0, afeDiag1, afeDiag2; + QPen channel0Pen, channel1Pen, channel2Pen, channel3Pen, channel4Pen, channel5Pen, channel6Pen, channel7Pen; + + QMap deviceRegisterMap; + QMap GENERALRegisterMap; + QMap DIGIOENRegisterMap, FAULTRegisterMap, DIAG1RegisterMap; + QMap DIAG2RegisterMap, DIAG1AFERegisterMap; + + QVector acquisitionAngleList, acquisitionABSAngleList, acquisitionTmp0List, acquisitionTmp1List, + acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, acquisitionAngleSecList, + acquisitionSecAnglIList, acquisitionSecAnglQList, graphDataList, graphPostDataList; + QPushButton *openLastMenuButton, *calibrationStartMotorButton, *calibrateDataButton, *extractDataButton, *clearCalibrateDataButton, *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; QButtonGroup *rightMenuButtonGroup; - QLineEdit *acquisitionMotorRPMLineEdit, *calibrationMotorRPMLineEdit, *motorTargetPositionLineEdit, - *displayLengthLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, - *acquisitionMotorCurrentPositionLineEdit, *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, - *calibrationH3MagLineEdit, *calibrationH8MagLineEdit, *calibrationH1PhaseLineEdit, - *calibrationH2PhaseLineEdit, *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit, - *calibrationMotorCurrentPositionLineEdit, *AFEDIAG0LineEdit, *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; + QLineEdit *acquisitionMotorRPMLineEdit, *calibrationCycleCountLineEdit, *calibrationSamplesPerCycleLineEdit, + *calibrationMotorRPMLineEdit, *motorTargetPositionLineEdit, *displayLengthLineEdit, + *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, *acquisitionMotorCurrentPositionLineEdit, + *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, *calibrationH3MagLineEdit, + *calibrationH8MagLineEdit, *calibrationH1PhaseLineEdit, *calibrationH2PhaseLineEdit, + *calibrationH3PhaseLineEdit, *calibrationH8PhaseLineEdit, *calibrationMotorCurrentPositionLineEdit, + *AFEDIAG0LineEdit, *AFEDIAG1LineEdit, *AFEDIAG2LineEdit; QLabel *rawAngleValueLabel, *rotationValueLabel, *angleValueLabel, *countValueLabel, *tempValueLabel, *motorAmaxValueLabel, *motorRotateVmaxValueLabel, *motorDmaxValueLabel, *motorDisableValueLabel, @@ -249,10 +262,10 @@ public Q_SLOTS: ToolTemplate *createRegistersWidget(); ToolTemplate *createUtilityWidget(); - void readDeviceProperties(); + bool readDeviceProperties(); void initializeADMT(); bool readSequence(); - bool writeSequence(const map &settings); + bool writeSequence(QMap settings); void applySequence(); bool changeCNVPage(uint32_t page); void initializeMotor(); @@ -263,6 +276,7 @@ public Q_SLOTS: void stopCurrentMotorPositionMonitor(); void currentMotorPositionTask(int sampleRate); bool resetGENERAL(); + void stopTasks(); #pragma region Acquisition Methods bool updateChannelValues(); @@ -383,6 +397,7 @@ public Q_SLOTS: QWidget *parent = nullptr); void configureCoeffRow(QWidget *container, QHBoxLayout *layout, QLabel *hLabel, QLabel *hMagLabel, QLabel *hPhaseLabel); + void initializeChannelColors(); #pragma endregion #pragma region Connect Methods diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index bfe95082c7..6cef9ef845 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -28,14 +28,11 @@ #include #include #include -#include -#include #include #include #include #include #include -#include #include static const size_t maxAttrSize = 512; @@ -252,13 +249,17 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann double *scaleVal = new double(1); int scaleRet = iio_channel_attr_read_double(channel, scaleAttr, scaleVal); - if(scaleRet != 0) + if(scaleRet != 0) { + delete scaleVal; return static_cast(UINT64_MAX); // return QString("Cannot read scale attribute"); + } scale = *scaleVal; + delete scaleVal; char *offsetDst = new char[maxAttrSize]; iio_channel_attr_read(channel, offsetAttr, offsetDst, maxAttrSize); offsetAttrVal = std::atoi(offsetDst); + delete[] offsetDst; iio_buffer *iioBuffer = iio_device_create_buffer(admtDevice, bufferSize, false); if(iioBuffer == NULL) @@ -273,14 +274,9 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann if(numBytesRead < 0) return static_cast(UINT64_MAX); // return QString("Cannot refill buffer."); - pointerIncrement = reinterpret_cast(iio_buffer_step(iioBuffer)); - pointerEnd = static_cast(iio_buffer_end(iioBuffer)); - const struct iio_data_format *format = iio_channel_get_data_format(channel); const struct iio_data_format channelFormat = *format; unsigned int repeat = channelFormat.repeat; - uint8_t bitLength = static_cast(channelFormat.bits); - size_t offset = static_cast(channelFormat.shift); QString result; std::list rawSamples; @@ -726,7 +722,6 @@ void ADMTController::getPreCalibrationFFT(const vector &PANG, vector PANG, int cycleCount, int samplesPerCycle, bool CCW) { int circshiftData = 0; - QString result = ""; /* Check CCW flag to know if array is to be reversed */ if(CCW) @@ -1220,12 +1215,12 @@ int ADMTController::getAbsAngleTurnCount(uint16_t registerValue) // Bits 15:8: Turn count in quarter turns uint8_t turnCount = (registerValue & 0xFF00) >> 8; - if(turnCount <= 0xD5) { + if(turnCount <= 0xD7) { // Straight binary turn count return turnCount / 4; // Convert from quarter turns to whole turns - } else if(turnCount == 0xD6) { + } else if(turnCount >= 0xD8 && turnCount <= 0xDB) { // Invalid turn count - return -1; + return -10; } else { // 2's complement turn count int8_t signedTurnCount = static_cast(turnCount); // Handle as signed value @@ -1688,9 +1683,7 @@ int ADMTController::streamIO() iio_library_get_version(&major, &minor, git_tag); bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; - double *scaleAttrValue = new double(1); int offsetAttrValue = 0; - char *offsetDst = new char[maxAttrSize]; if(!m_iioCtx) return result; // Check if the context is valid @@ -1703,13 +1696,19 @@ int ADMTController::streamIO() iio_device_find_channel(admtDevice, channelName, isOutput); // Find the rotation channel if(channel == NULL) return result; - iio_channel_enable(channel); // Enable the channel + iio_channel_enable(channel); + double *scaleAttrValue = new double(1); int scaleRet = iio_channel_attr_read_double(channel, scaleAttrName, scaleAttrValue); // Read the scale attribute - if(scaleRet != 0) + if(scaleRet != 0) { + delete scaleAttrValue; return scaleRet; + } + + char *offsetDst = new char[maxAttrSize]; iio_channel_attr_read(channel, offsetAttrName, offsetDst, maxAttrSize); // Read the offset attribute offsetAttrValue = atoi(offsetDst); + delete[] offsetDst; struct iio_buffer *buffer = iio_device_create_buffer(admtDevice, samples, isCyclic); // Create a buffer while(!stopStream) { @@ -1739,6 +1738,7 @@ int ADMTController::streamIO() } } + delete scaleAttrValue; iio_buffer_destroy(buffer); return 0; } @@ -1765,9 +1765,7 @@ void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) iio_library_get_version(&major, &minor, git_tag); bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; - double *scaleAttrValue = new double(1); int offsetAttrValue = 0; - char *offsetDst = new char[maxAttrSize]; if(!m_iioCtx) return; // result; // Check if the context is valid @@ -1779,11 +1777,16 @@ void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) struct iio_channel *channel = iio_device_find_channel(admtDevice, channelName, isOutput); // Find the rotation channel if(channel == NULL) - return; // result; - iio_channel_enable(channel); // Enable the channel + return; + iio_channel_enable(channel); + double *scaleAttrValue = new double(1); int scaleRet = iio_channel_attr_read_double(channel, scaleAttrName, scaleAttrValue); // Read the scale attribute - if(scaleRet != 0) + if(scaleRet != 0) { + delete scaleAttrValue; return; // scaleRet; + } + + char *offsetDst = new char[maxAttrSize]; iio_channel_attr_read(channel, offsetAttrName, offsetDst, maxAttrSize); // Read the offset attribute offsetAttrValue = atoi(offsetDst); @@ -1831,6 +1834,9 @@ void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) } Q_EMIT streamBufferedData(bufferedValues); + + delete scaleAttrValue; + delete[] offsetDst; } void ADMTController::handleStreamBufferedData(const QVector &value) { streamBufferedValues = value; } diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index 6c0b724527..ef0eadbcb2 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -100,6 +100,9 @@ bool ADMTPlugin::onConnect() harmonicCalibration = new HarmonicCalibration(m_admtController, isDebug); m_toolList[0]->setTool(harmonicCalibration); + connect(m_admtController, &ADMTController::requestDisconnect, this, &ADMTPlugin::disconnectDevice, + Qt::QueuedConnection); + return true; } diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 32db837b78..204acfaf14 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -65,32 +65,12 @@ static double motorMicrostepPerRevolution = motorFullStepPerRevolution * microSt static double motorTimeUnit = static_cast(1 << 24) / motorfCLK; // t = 2^24/motorfCLK static int acquisitionDisplayLength = 200; -static QVector acquisitionAngleList, acquisitionABSAngleList, acquisitionTmp0List, acquisitionTmp1List, - acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, acquisitionAngleSecList, - acquisitionSecAnglIList, acquisitionSecAnglQList, graphDataList, graphPostDataList; static const QColor scopyBlueColor = Style::getColor(json::theme::interactive_primary_idle); -static const QPen scopyBluePen(scopyBlueColor); -static const QPen channel0Pen(StyleHelper::getChannelColor(0)); -static const QPen channel1Pen(StyleHelper::getChannelColor(1)); -static const QPen channel2Pen(StyleHelper::getChannelColor(2)); -static const QPen channel3Pen(StyleHelper::getChannelColor(3)); -static const QPen channel4Pen(StyleHelper::getChannelColor(4)); -static const QPen channel5Pen(StyleHelper::getChannelColor(5)); -static const QPen channel6Pen(StyleHelper::getChannelColor(6)); -static const QPen channel7Pen(StyleHelper::getChannelColor(7)); - -static map deviceRegisterMap; -static map GENERALRegisterMap; -static map DIGIOENRegisterMap; -static map FAULTRegisterMap; -static map DIAG1RegisterMap; -static map DIAG2RegisterMap; -static map DIAG1AFERegisterMap; - -static QString deviceName = ""; -static QString deviceType = ""; +QPen scopyBluePen(scopyBlueColor); + +QString deviceName = "", deviceType = ""; static bool is5V = false; static double H1_MAG_ANGLE, H2_MAG_ANGLE, H3_MAG_ANGLE, H8_MAG_ANGLE, H1_PHASE_ANGLE, H2_PHASE_ANGLE, H3_PHASE_ANGLE, @@ -134,7 +114,7 @@ static double defaultPhaseGraphMax = 4; static double currentPhaseGraphMin = defaultPhaseGraphMin; static double currentPhaseGraphMax = defaultPhaseGraphMax; -static QMap acquisitionDataMap = { +QMap acquisitionDataMap = { {ABSANGLE, false}, {ANGLE, false}, {ANGLESEC, false}, {SINE, false}, {COSINE, false}, {SECANGLI, false}, {SECANGLQ, false}, {RADIUS, false}, {DIAG1, false}, {DIAG2, false}, {TMP0, false}, {TMP1, false}, {CNVCNT, false}, @@ -155,6 +135,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool countChannelName = m_admtController->getChannelId(ADMTController::Channel::COUNT); temperatureChannelName = m_admtController->getChannelId(ADMTController::Channel::TEMPERATURE); + initializeChannelColors(); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QHBoxLayout *lay = new QHBoxLayout(this); tabWidget = new QTabWidget(this); @@ -172,16 +154,13 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool tabWidget->addTab(createUtilityWidget(), "Utility"); tabWidget->addTab(createRegistersWidget(), "Registers"); - connect(tabWidget, &QTabWidget::currentChanged, [this](int index) { + connect(tabWidget, &QTabWidget::currentChanged, this, [this](int index) { tabWidget->setCurrentIndex(index); - if(index == 0 || index == 1) { + if(index == 0 || index == 1) startDeviceStatusMonitor(); - startCurrentMotorPositionMonitor(); - } else { + else stopDeviceStatusMonitor(); - stopCurrentMotorPositionMonitor(); - } if(index == 0) // Acquisition Tab { @@ -190,9 +169,11 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool updateSequenceWidget(); updateAcquisitionMotorRPM(); updateAcquisitionMotorRotationDirection(); + startCurrentMotorPositionMonitor(); } else { isAcquisitionTab = false; stop(); + stopCurrentMotorPositionMonitor(); } if(index == 1) // Calibration Tab @@ -210,8 +191,8 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool { readSequence(); if(GENERALRegisterMap.contains("Sequence Type")) { - toggleFaultRegisterMode(GENERALRegisterMap.at("Sequence Type")); - toggleMTDiagnostics(GENERALRegisterMap.at("Sequence Type")); + toggleFaultRegisterMode(GENERALRegisterMap.value("Sequence Type")); + toggleMTDiagnostics(GENERALRegisterMap.value("Sequence Type")); toggleUtilityTask(true); } } else { @@ -222,7 +203,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool { readSequence(); if(GENERALRegisterMap.contains("Sequence Type")) { - toggleRegisters(GENERALRegisterMap.at("Sequence Type")); + toggleRegisters(GENERALRegisterMap.value("Sequence Type")); } } }); @@ -248,7 +229,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool startCurrentMotorPositionMonitor(); } -HarmonicCalibration::~HarmonicCalibration() { requestDisconnect(); } +HarmonicCalibration::~HarmonicCalibration() { stopTasks(); } ToolTemplate *HarmonicCalibration::createAcquisitionWidget() { @@ -535,7 +516,7 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() secAnglQCheckBox->hide(); temp1CheckBox->hide(); } else { - if(GENERALRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 + if(GENERALRegisterMap.value("Sequence Type") == 0) // Sequence Mode 1 { acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); @@ -547,7 +528,7 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() secAnglICheckBox->hide(); secAnglQCheckBox->hide(); temp1CheckBox->hide(); - } else if(GENERALRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 + } else if(GENERALRegisterMap.value("Sequence Type") == 1) // Sequence Mode 2 { acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); @@ -1338,9 +1319,9 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationCycleCountLayout->setSpacing(0); QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", calibrationCycleCountWidget); Style::setStyle(calibrationCycleCountLabel, style::properties::label::subtle); - QLineEdit *calibrationCycleCountLineEdit = new QLineEdit(calibrationCycleCountWidget); + calibrationCycleCountLineEdit = new QLineEdit(calibrationCycleCountWidget); calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); - connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 1000); + connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 100); calibrationCycleCountLayout->addWidget(calibrationCycleCountLabel); calibrationCycleCountLayout->addWidget(calibrationCycleCountLineEdit); @@ -1351,48 +1332,13 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationSamplesPerCycleLayout->setSpacing(0); QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", calibrationSamplesPerCycleWidget); Style::setStyle(calibrationSamplesPerCycleLabel, style::properties::label::subtle); - QLineEdit *calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationSamplesPerCycleWidget); + calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationSamplesPerCycleWidget); calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); - connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, 1, 5000); + connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, 1, 256); calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLabel); calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLineEdit); - calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(8); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationModeMenuCombo); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountWidget); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleWidget); - -#pragma endregion - -#pragma region Calibration Data Section Widget - MenuSectionWidget *calibrationDataSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(calibrationDataSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection( - "Calibration Data", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationDataSectionWidget); - calibrationDataSectionWidget->contentLayout()->setSpacing(8); - calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); - - QPushButton *importSamplesButton = new QPushButton("Import Samples", calibrationDataCollapseSection); - QPushButton *extractDataButton = new QPushButton("Save to CSV", calibrationDataCollapseSection); - StyleHelper::BasicButton(importSamplesButton); - StyleHelper::BasicButton(extractDataButton); - - calibrationDataCollapseSection->contentLayout()->setSpacing(8); - calibrationDataCollapseSection->contentLayout()->addWidget(importSamplesButton); - calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); -#pragma endregion - -#pragma region Motor Control Section Widget - MenuSectionWidget *motorControlSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); - Style::setStyle(motorControlSectionWidget, style::properties::widget::basicComponent); - MenuCollapseSection *motorControlCollapseSection = new MenuCollapseSection( - "Motor Control", MenuCollapseSection::MHCW_NONE, - MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, motorControlSectionWidget); - motorControlSectionWidget->contentLayout()->setSpacing(8); - motorControlSectionWidget->contentLayout()->addWidget(motorControlCollapseSection); - - QWidget *motorRPMWidget = new QWidget(motorControlSectionWidget); + QWidget *motorRPMWidget = new QWidget(calibrationDatasetConfigCollapseSection); QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); motorRPMWidget->setLayout(motorRPMLayout); motorRPMLayout->setMargin(0); @@ -1404,61 +1350,46 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() motorRPMLayout->addWidget(motorRPMLabel); motorRPMLayout->addWidget(calibrationMotorRPMLineEdit); - QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); - currentPositionWidget->setLayout(currentPositionLayout); - currentPositionLayout->setMargin(0); - currentPositionLayout->setSpacing(0); - QLabel *currentPositionLabel = new QLabel("Current Position", currentPositionWidget); - Style::setStyle(currentPositionLabel, style::properties::label::subtle); - calibrationMotorCurrentPositionLineEdit = new QLineEdit("--.--", currentPositionWidget); - calibrationMotorCurrentPositionLineEdit->setReadOnly(true); - connectLineEditToDouble(calibrationMotorCurrentPositionLineEdit, current_pos); - currentPositionLayout->addWidget(currentPositionLabel); - currentPositionLayout->addWidget(calibrationMotorCurrentPositionLineEdit); - - QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); - targetPositionWidget->setLayout(targetPositionLayout); - targetPositionLayout->setMargin(0); - targetPositionLayout->setSpacing(0); - QLabel *targetPositionLabel = new QLabel("Target Position", targetPositionWidget); - Style::setStyle(targetPositionLabel, style::properties::label::subtle); - motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), targetPositionWidget); - connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, - ADMTController::MotorAttribute::TARGET_POS); - targetPositionLayout->addWidget(targetPositionLabel); - targetPositionLayout->addWidget(motorTargetPositionLineEdit); - - QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); + QWidget *motorDirectionWidget = new QWidget(calibrationDatasetConfigCollapseSection); QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); motorDirectionWidget->setLayout(motorDirectionLayout); motorDirectionLayout->setMargin(0); motorDirectionLayout->setSpacing(0); QLabel *motorDirectionLabel = new QLabel("Rotation Direction", motorDirectionWidget); Style::setStyle(motorDirectionLabel, style::properties::label::subtle); - calibrationMotorDirectionSwitch = new CustomSwitch("CW", "CCW", motorControlSectionWidget); + calibrationMotorDirectionSwitch = new CustomSwitch("CW", "CCW", motorDirectionWidget); calibrationMotorDirectionSwitch->setChecked(isMotorRotationClockwise); connect(calibrationMotorDirectionSwitch, &CustomSwitch::toggled, this, [this](bool b) { isMotorRotationClockwise = b; }); motorDirectionLayout->addWidget(motorDirectionLabel); motorDirectionLayout->addWidget(calibrationMotorDirectionSwitch); - QPushButton *continuousRotationButton = new QPushButton("Continuous Rotation", motorControlSectionWidget); - StyleHelper::BasicButton(continuousRotationButton); - connect(continuousRotationButton, &QPushButton::clicked, this, &HarmonicCalibration::moveMotorContinuous); + calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(8); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationModeMenuCombo); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountWidget); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleWidget); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(motorRPMWidget); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(motorDirectionWidget); - QPushButton *stopMotorButton = new QPushButton("Stop Motor", motorControlSectionWidget); - StyleHelper::BasicButton(stopMotorButton); - connect(stopMotorButton, &QPushButton::clicked, this, &HarmonicCalibration::stopMotor); +#pragma endregion - motorControlCollapseSection->contentLayout()->setSpacing(8); - motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); - motorControlCollapseSection->contentLayout()->addWidget(currentPositionWidget); - motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); - motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); - motorControlCollapseSection->contentLayout()->addWidget(continuousRotationButton); - motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); +#pragma region Calibration Data Section Widget + MenuSectionWidget *calibrationDataSectionWidget = new MenuSectionWidget(calibrationSettingsWidget); + Style::setStyle(calibrationDataSectionWidget, style::properties::widget::basicComponent); + MenuCollapseSection *calibrationDataCollapseSection = new MenuCollapseSection( + "Calibration Data", MenuCollapseSection::MenuHeaderCollapseStyle::MHCW_NONE, + MenuCollapseSection::MenuHeaderWidgetType::MHW_BASEWIDGET, calibrationDataSectionWidget); + calibrationDataSectionWidget->contentLayout()->setSpacing(8); + calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); + + QPushButton *importSamplesButton = new QPushButton("Import Samples", calibrationDataCollapseSection); + QPushButton *extractDataButton = new QPushButton("Save to CSV", calibrationDataCollapseSection); + StyleHelper::BasicButton(importSamplesButton); + StyleHelper::BasicButton(extractDataButton); + + calibrationDataCollapseSection->contentLayout()->setSpacing(8); + calibrationDataCollapseSection->contentLayout()->addWidget(importSamplesButton); + calibrationDataCollapseSection->contentLayout()->addWidget(extractDataButton); #pragma endregion #pragma region Logs Section Widget @@ -1482,7 +1413,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationSettingsLayout->setMargin(0); calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); - calibrationSettingsLayout->addWidget(motorControlSectionWidget); + // calibrationSettingsLayout->addWidget(motorControlSectionWidget); calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); calibrationSettingsLayout->addWidget(logsSectionWidget); @@ -1547,7 +1478,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() connect(&m_resetMotorToZeroWatcher, &QFutureWatcher::finished, this, [this]() { startWaitForVelocityReachedThread(1); }); - connect(&m_calibrationStreamWatcher, &QFutureWatcher::started, [this]() { + connect(&m_calibrationStreamWatcher, &QFutureWatcher::started, this, [this]() { QThread *thread = QThread::currentThread(); thread->setPriority(QThread::TimeCriticalPriority); }); @@ -2048,7 +1979,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO0ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO0ENToggleSwitch, "Output", "Input"); DIGIO0ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO0ENToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("DIGIO0EN", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); }); @@ -2056,7 +1987,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO0FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO0FNCToggleSwitch, "GPIO0", "BUSY"); DIGIO0FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO0FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO0FNCToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("BUSY", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO0" : "BUSY")); }); @@ -2064,7 +1995,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO1ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO1ENToggleSwitch, "Output", "Input"); DIGIO1ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO1ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO1ENToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("DIGIO1EN", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); }); @@ -2072,7 +2003,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO1FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO1FNCToggleSwitch, "GPIO1", "CNV"); DIGIO1FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO1FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO1FNCToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("CNV", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO1" : "CNV")); }); @@ -2080,7 +2011,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO2ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO2ENToggleSwitch, "Output", "Input"); DIGIO2ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO2ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO2ENToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("DIGIO2EN", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); }); @@ -2088,7 +2019,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO2FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO2FNCToggleSwitch, "GPIO2", "SENT"); DIGIO2FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO2FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO2FNCToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("SENT", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO2" : "SENT")); }); @@ -2096,7 +2027,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO3ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO3ENToggleSwitch, "Output", "Input"); DIGIO3ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO3ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO3ENToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("DIGIO3EN", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); }); @@ -2104,7 +2035,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO3FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO3FNCToggleSwitch, "GPIO3", "ACALC"); DIGIO3FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO3FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO3FNCToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("ACALC", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO3" : "ACALC")); }); @@ -2112,7 +2043,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO4ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO4ENToggleSwitch, "Output", "Input"); DIGIO4ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO4ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO4ENToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("DIGIO4EN", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); }); @@ -2120,7 +2051,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO4FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO4FNCToggleSwitch, "GPIO4", "FAULT"); DIGIO4FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO4FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO4FNCToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("FAULT", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO4" : "FAULT")); }); @@ -2128,7 +2059,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO5ENToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO5ENToggleSwitch, "Output", "Input"); DIGIO5ENToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO5ENToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO5ENToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("DIGIO5EN", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "Output" : "Input")); }); @@ -2136,7 +2067,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() DIGIO5FNCToggleSwitch = new CustomSwitch(); changeCustomSwitchLabel(DIGIO5FNCToggleSwitch, "GPIO5", "BOOT"); DIGIO5FNCToggleSwitch->setFixedWidth(Style::getDimension(json::global::unit_6)); - connect(DIGIO5FNCToggleSwitch, &CustomSwitch::clicked, [this](bool value) { + connect(DIGIO5FNCToggleSwitch, &CustomSwitch::clicked, this, [this](bool value) { if(!toggleDIGIOEN("BOOTLOAD", value)) StatusBarManager::pushMessage("Failed to toggle " + QString(value ? "GPIO5" : "BOOT")); }); @@ -2144,7 +2075,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() QPushButton *DIGIOResetButton = new QPushButton("Reset DIGIO", DIGIOControlGridWidget); DIGIOResetButton->setFixedWidth(100); StyleHelper::BasicButton(DIGIOResetButton); - connect(DIGIOResetButton, &QPushButton::clicked, [this] { + connect(DIGIOResetButton, &QPushButton::clicked, this, [this] { toggleUtilityTask(false); bool success = resetDIGIO(); if(success) @@ -2379,52 +2310,44 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() return tool; } -void HarmonicCalibration::readDeviceProperties() +bool HarmonicCalibration::readDeviceProperties() { - uint32_t *uniqId3RegisterValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; - uint32_t page = m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3); - uint32_t cnvPageAddress = - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + uint32_t UNIQID3Page = m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3); bool success = false; - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, page) != -1) { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, cnvPageRegValue) != -1) { - if(*cnvPageRegValue == page) { - if(m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getUniqueIdRegister( - ADMTController::UniqueIDRegister::UNIQID3), - uniqId3RegisterValue) != -1) { - deviceRegisterMap = m_admtController->getUNIQID3RegisterMapping( - static_cast(*uniqId3RegisterValue)); - - if(deviceRegisterMap.at("Supply ID") == "5V") { - is5V = true; - } else if(deviceRegisterMap.at("Supply ID") == "3.3V") { - is5V = false; - } else { - is5V = false; - } + if(!changeCNVPage(UNIQID3Page)) + return false; - deviceName = QString::fromStdString(deviceRegisterMap.at("Product ID")); + uint32_t *uniqId3RegisterValue = new uint32_t; + if(m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getUniqueIdRegister(ADMTController::UniqueIDRegister::UNIQID3), + uniqId3RegisterValue) != -1) { + deviceRegisterMap = + QMap(m_admtController->getUNIQID3RegisterMapping(static_cast(*uniqId3RegisterValue))); + + if(deviceRegisterMap.value("Supply ID") == "5V") { + is5V = true; + } else if(deviceRegisterMap.value("Supply ID") == "3.3V") { + is5V = false; + } else { + is5V = false; + } - if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") { - deviceType = QString::fromStdString("Industrial"); - } else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") { - deviceType = QString::fromStdString("Automotive"); - } else { - deviceType = QString::fromStdString(deviceRegisterMap.at("ASIL ID")); - } + deviceName = QString::fromStdString(deviceRegisterMap.value("Product ID")); - success = true; - } - } + if(deviceRegisterMap.value("ASIL ID") == "ASIL QM") { + deviceType = QString::fromStdString("Industrial"); + } else if(deviceRegisterMap.value("ASIL ID") == "ASIL B") { + deviceType = QString::fromStdString("Automotive"); + } else { + deviceType = QString::fromStdString(deviceRegisterMap.value("ASIL ID")); } + + success = true; } + delete uniqId3RegisterValue; if(!success) { StatusBarManager::pushMessage("Failed to read device properties"); @@ -2433,21 +2356,23 @@ void HarmonicCalibration::readDeviceProperties() deviceName = "ADMT4000"; deviceType = "Emulator"; } + + return success; } void HarmonicCalibration::initializeADMT() { + bool disabledECC = disableECC(true); bool resetDIGIOSuccess = resetDIGIO(); bool resetGENERALSuccess = resetGENERAL(); - if(!resetDIGIOSuccess || !resetGENERALSuccess) { + if(!disabledECC || !resetDIGIOSuccess || !resetGENERALSuccess) { StatusBarManager::pushMessage("Failed initialize ADMT"); } } bool HarmonicCalibration::readSequence() { - uint32_t *generalRegValue = new uint32_t; uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); uint32_t generalRegisterPage = @@ -2455,63 +2380,57 @@ bool HarmonicCalibration::readSequence() bool success = false; - if(changeCNVPage(generalRegisterPage)) { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - generalRegisterAddress, generalRegValue) != -1) { - if(*generalRegValue != UINT32_MAX) { - GENERALRegisterMap = m_admtController->getGeneralRegisterBitMapping( - static_cast(*generalRegValue)); - success = true; - } + if(!changeCNVPage(generalRegisterPage)) + return false; + + uint32_t *generalRegValue = new uint32_t; + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + generalRegisterAddress, generalRegValue) != -1) { + if(*generalRegValue != UINT32_MAX) { + GENERALRegisterMap = QMap(m_admtController->getGeneralRegisterBitMapping( + static_cast(*generalRegValue))); + success = true; } } + delete generalRegValue; return success; } -bool HarmonicCalibration::writeSequence(const map &settings) +bool HarmonicCalibration::writeSequence(QMap settings) { - uint32_t *generalRegValue = new uint32_t; - uint32_t generalRegisterAddress = - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); - bool success = false; - if(!disableECC(true)) { + if(!disableECC(true)) return false; - } + uint32_t generalRegisterAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); + uint32_t *generalRegValue = new uint32_t; if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - generalRegisterAddress, generalRegValue) != 0) { + generalRegisterAddress, generalRegValue) != 0) return false; - } - uint32_t newGeneralRegValue = m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings); + uint32_t newGeneralRegValue = + m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings.toStdMap()); uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); - if(!changeCNVPage(generalRegisterPage)) { + if(!changeCNVPage(generalRegisterPage)) return false; - } if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - generalRegisterAddress, newGeneralRegValue) != 0) { + generalRegisterAddress, newGeneralRegValue) != 0) return false; - } - if(!disableECC(false)) { - return false; - } - - if(readSequence()) { - if(settings.at("Convert Synchronization") == GENERALRegisterMap.at("Convert Synchronization") && - settings.at("Angle Filter") == GENERALRegisterMap.at("Angle Filter") && - settings.at("8th Harmonic") == GENERALRegisterMap.at("8th Harmonic") && - settings.at("Sequence Type") == GENERALRegisterMap.at("Sequence Type") && - settings.at("Conversion Type") == GENERALRegisterMap.at("Conversion Type")) { + if(readSequence()) + if(settings.value("Convert Synchronization") == + GENERALRegisterMap.value("Convert Synchronizvalueion") && + settings.value("Angle Filter") == GENERALRegisterMap.value("Angle Filter") && + settings.value("8th Harmonic") == GENERALRegisterMap.value("8th Harmonic") && + settings.value("Sequence Type") == GENERALRegisterMap.value("Sequence Type") && + settings.value("Conversion Type") == GENERALRegisterMap.value("Conversion Type")) success = true; - } - } return success; } @@ -2524,10 +2443,8 @@ void HarmonicCalibration::applySequence() this->toggleWidget(applySequenceButton, true); applySequenceButton->setText("Apply"); }); - uint32_t *generalRegValue = new uint32_t; - uint32_t generalRegisterAddress = - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); - map settings; + + QMap settings; bool success = false; @@ -2542,9 +2459,9 @@ void HarmonicCalibration::applySequence() success = writeSequence(settings); if(!success) - StatusBarManager::pushMessage("Failed to apply sequence settings"); + StatusBarManager::pushUrgentMessage("Failed to apply sequence settings"); else - StatusBarManager::pushMessage("Sequence settings applied successfully"); + StatusBarManager::pushUrgentMessage("Sequence settings applied successfully"); } bool HarmonicCalibration::changeCNVPage(uint32_t page) @@ -2563,6 +2480,8 @@ bool HarmonicCalibration::changeCNVPage(uint32_t page) } } + delete cnvPageRegValue; + return false; } @@ -2613,13 +2532,14 @@ void HarmonicCalibration::stopDeviceStatusMonitor() void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) { - uint32_t *readValue = new uint32_t; bool registerFault = false; + bool success = true; while(isDeviceStatusMonitor) { if(m_admtController->writeDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::FAULT), 0) == 0) { + uint32_t *readValue = new uint32_t; if(m_admtController->readDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister( @@ -2628,22 +2548,31 @@ void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) if(GENERALRegisterMap.contains("Sequence Type")) { registerFault = m_admtController->checkRegisterFault( static_cast(*readValue), - GENERALRegisterMap.at("Sequence Type") == 0 ? true : false); + GENERALRegisterMap.value("Sequence Type") == 0 ? true : false); Q_EMIT updateFaultStatusSignal(registerFault); } else - Q_EMIT updateFaultStatusSignal(true); - } else - Q_EMIT updateFaultStatusSignal(true); - + success = false; + } else { + success = false; + delete readValue; + } } else - Q_EMIT updateFaultStatusSignal(true); + success = false; + + if(!success) { + StatusBarManager::pushUrgentMessage("Could not read device, disconnecting device"); + Q_EMIT m_admtController->requestDisconnect(); + break; + } QThread::msleep(sampleRate); } } -void HarmonicCalibration::requestDisconnect() +void HarmonicCalibration::requestDisconnect() { Q_EMIT m_admtController->requestDisconnect(); } + +void HarmonicCalibration::stopTasks() { stopAcquisition(); @@ -2693,24 +2622,26 @@ void HarmonicCalibration::updateMotorPosition(double position) current_pos = position; if(isAcquisitionTab) updateLineEditValue(acquisitionMotorCurrentPositionLineEdit, current_pos); - else if(isCalibrationTab) - updateLineEditValue(calibrationMotorCurrentPositionLineEdit, current_pos); } bool HarmonicCalibration::resetGENERAL() { bool success = false; - if(!disableECC(true)) { + uint32_t GENERALPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); + + if(!disableECC(true)) + return false; + + if(!changeCNVPage(GENERALPage)) return false; - } if(deviceRegisterMap.contains("ASIL ID")) { uint32_t resetValue = 0x0000; - if(deviceRegisterMap.at("ASIL ID") == "ASIL QM") + if(deviceRegisterMap.value("ASIL ID") == "ASIL QM") resetValue = 0x1230; // Industrial or ASIL QM - else if(deviceRegisterMap.at("ASIL ID") == "ASIL B") + else if(deviceRegisterMap.value("ASIL ID") == "ASIL B") resetValue = 0x1200; // Automotive or ASIL B if(resetValue != 0x0000) { @@ -2724,10 +2655,6 @@ bool HarmonicCalibration::resetGENERAL() } } - if(!disableECC(false)) { - return false; - } - return success; } @@ -2746,6 +2673,8 @@ bool HarmonicCalibration::updateChannelValues() return false; } updateCountValue(); + // count = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + // countChannelName, bufferSize); if(count == static_cast(UINT64_MAX)) { return false; } @@ -2754,28 +2683,29 @@ bool HarmonicCalibration::updateChannelValues() if(temp == static_cast(UINT64_MAX)) { return false; } - return success = true; + + success = true; + + return success; } void HarmonicCalibration::updateCountValue() { uint32_t *absAngleRegValue = new uint32_t; bool success = false; - if(m_admtController->writeDeviceRegistry( + + if(m_admtController->readDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE), - 0x0000) == 0) { - if(m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), - absAngleRegValue) == 0) { - count = m_admtController->getAbsAngleTurnCount(static_cast(*absAngleRegValue)); - success = true; - } + m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), + absAngleRegValue) == 0) { + count = m_admtController->getAbsAngleTurnCount(static_cast(*absAngleRegValue)); + success = true; } - if(!success) { + + delete absAngleRegValue; + + if(!success) count = static_cast(UINT64_MAX); - } } void HarmonicCalibration::updateLineEditValues() @@ -2793,12 +2723,15 @@ void HarmonicCalibration::updateLineEditValues() if(count == static_cast(UINT64_MAX)) { countValueLabel->setText("N/A"); } else { - countValueLabel->setText(QString::number(count)); + if(count == -10) + countValueLabel->setText("Invalid turn count"); + else + countValueLabel->setText(QString::number(count)); } if(temp == static_cast(UINT64_MAX)) { tempValueLabel->setText("N/A"); } else { - tempValueLabel->setText(QString::number(temp) + " °C"); + tempValueLabel->setText(QString::number(temp, 10, 2) + " °C"); } } @@ -2807,43 +2740,43 @@ void HarmonicCalibration::updateAcquisitionData(QMap sensorD if(isStartAcquisition) updateLineEditValues(); - if(acquisitionDataMap.value(ANGLE) && sensorDataMap.keys().contains(ANGLE)) + if(acquisitionDataMap.value(ANGLE) && sensorDataMap.contains(ANGLE)) appendAcquisitionData(sensorDataMap.value(ANGLE), acquisitionAngleList); else acquisitionAngleList.clear(); - if(acquisitionDataMap.value(ABSANGLE) && sensorDataMap.keys().contains(ABSANGLE)) + if(acquisitionDataMap.value(ABSANGLE) && sensorDataMap.contains(ABSANGLE)) appendAcquisitionData(sensorDataMap.value(ABSANGLE), acquisitionABSAngleList); else acquisitionABSAngleList.clear(); - if(acquisitionDataMap.value(TMP0) && sensorDataMap.keys().contains(TMP0)) + if(acquisitionDataMap.value(TMP0) && sensorDataMap.contains(TMP0)) appendAcquisitionData(sensorDataMap.value(TMP0), acquisitionTmp0List); else acquisitionTmp0List.clear(); - if(acquisitionDataMap.value(SINE) && sensorDataMap.keys().contains(SINE)) + if(acquisitionDataMap.value(SINE) && sensorDataMap.contains(SINE)) appendAcquisitionData(sensorDataMap.value(SINE), acquisitionSineList); else acquisitionSineList.clear(); - if(acquisitionDataMap.value(COSINE) && sensorDataMap.keys().contains(COSINE)) + if(acquisitionDataMap.value(COSINE) && sensorDataMap.contains(COSINE)) appendAcquisitionData(sensorDataMap.value(COSINE), acquisitionCosineList); else acquisitionCosineList.clear(); - if(acquisitionDataMap.value(RADIUS) && sensorDataMap.keys().contains(RADIUS)) + if(acquisitionDataMap.value(RADIUS) && sensorDataMap.contains(RADIUS)) appendAcquisitionData(sensorDataMap.value(RADIUS), acquisitionRadiusList); else acquisitionRadiusList.clear(); - if(acquisitionDataMap.value(ANGLESEC) && sensorDataMap.keys().contains(ANGLESEC)) + if(acquisitionDataMap.value(ANGLESEC) && sensorDataMap.contains(ANGLESEC)) appendAcquisitionData(sensorDataMap.value(ANGLESEC), acquisitionAngleSecList); else acquisitionAngleSecList.clear(); - if(acquisitionDataMap.value(SECANGLI) && sensorDataMap.keys().contains(SECANGLI)) + if(acquisitionDataMap.value(SECANGLI) && sensorDataMap.contains(SECANGLI)) appendAcquisitionData(sensorDataMap.value(SECANGLI), acquisitionSecAnglIList); else acquisitionSecAnglIList.clear(); - if(acquisitionDataMap.value(SECANGLQ) && sensorDataMap.keys().contains(SECANGLQ)) + if(acquisitionDataMap.value(SECANGLQ) && sensorDataMap.contains(SECANGLQ)) appendAcquisitionData(sensorDataMap.value(SECANGLQ), acquisitionSecAnglQList); else acquisitionSecAnglQList.clear(); - if(acquisitionDataMap.value(TMP1) && sensorDataMap.keys().contains(TMP1)) + if(acquisitionDataMap.value(TMP1) && sensorDataMap.contains(TMP1)) appendAcquisitionData(sensorDataMap.value(TMP1), acquisitionTmp1List); else acquisitionTmp1List.clear(); @@ -3063,25 +2996,25 @@ void HarmonicCalibration::updateSequenceWidget() return; } - if(GENERALRegisterMap.at("Sequence Type") == -1) { + if(GENERALRegisterMap.value("Sequence Type") == -1) { sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); } else { sequenceTypeMenuCombo->combo()->setCurrentIndex( - sequenceTypeMenuCombo->combo()->findData(GENERALRegisterMap.at("Sequence Type"))); + sequenceTypeMenuCombo->combo()->findData(GENERALRegisterMap.value("Sequence Type"))); } conversionTypeMenuCombo->combo()->setCurrentIndex( - conversionTypeMenuCombo->combo()->findData(GENERALRegisterMap.at("Conversion Type"))); - if(GENERALRegisterMap.at("Convert Synchronization") == -1) { + conversionTypeMenuCombo->combo()->findData(GENERALRegisterMap.value("Conversion Type"))); + if(GENERALRegisterMap.value("Convert Synchronization") == -1) { convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); } else { convertSynchronizationMenuCombo->combo()->setCurrentIndex( convertSynchronizationMenuCombo->combo()->findData( - GENERALRegisterMap.at("Convert Synchronization"))); + GENERALRegisterMap.value("Convert Synchronization"))); } angleFilterMenuCombo->combo()->setCurrentIndex( - angleFilterMenuCombo->combo()->findData(GENERALRegisterMap.at("Angle Filter"))); + angleFilterMenuCombo->combo()->findData(GENERALRegisterMap.value("Angle Filter"))); eighthHarmonicMenuCombo->combo()->setCurrentIndex( - eighthHarmonicMenuCombo->combo()->findData(GENERALRegisterMap.at("8th Harmonic"))); + eighthHarmonicMenuCombo->combo()->findData(GENERALRegisterMap.value("8th Harmonic"))); } void HarmonicCalibration::updateCapturedDataCheckBoxes() @@ -3102,7 +3035,7 @@ void HarmonicCalibration::updateCapturedDataCheckBoxes() acquisitionGraphChannelGridLayout->removeWidget(secAnglICheckBox); acquisitionGraphChannelGridLayout->removeWidget(temp1CheckBox); - if(GENERALRegisterMap.at("Sequence Type") == 0) // Sequence Mode 1 + if(GENERALRegisterMap.value("Sequence Type") == 0) // Sequence Mode 1 { acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); @@ -3118,7 +3051,7 @@ void HarmonicCalibration::updateCapturedDataCheckBoxes() secAnglICheckBox->hide(); secAnglQCheckBox->hide(); temp1CheckBox->hide(); - } else if(GENERALRegisterMap.at("Sequence Type") == 1) // Sequence Mode 2 + } else if(GENERALRegisterMap.value("Sequence Type") == 1) // Sequence Mode 2 { acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); @@ -3142,6 +3075,7 @@ void HarmonicCalibration::updateCapturedDataCheckBoxes() void HarmonicCalibration::applySequenceAndUpdate() { + disableECC(true); applySequence(); updateSequenceWidget(); updateCapturedDataCheckBoxes(); @@ -3151,7 +3085,7 @@ void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { displayLengt void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, SensorData key) { - connect(widget, &QCheckBox::stateChanged, [this, channel, key](int state) { + connect(widget, &QCheckBox::stateChanged, this, [this, channel, key](int state) { if(state == Qt::Checked) { channel->setEnabled(true); acquisitionDataMap[key] = true; @@ -3290,11 +3224,9 @@ void HarmonicCalibration::updateCalibrationMotorRotationDirection() void HarmonicCalibration::getCalibrationSamples() { if(resetCurrentPositionToZero()) { - double step = 0; - if(isMotorRotationClockwise) - step = motorFullStepPerRevolution; - else - step = -motorFullStepPerRevolution; + int step = floor(motorMicrostepPerRevolution / samplesPerCycle); + if(!isMotorRotationClockwise) + step = -step; if(isPostCalibration) { int currentSamplesCount = graphPostDataList.size(); while(isStartMotor && currentSamplesCount < totalSamplesCount) { @@ -3331,8 +3263,8 @@ void HarmonicCalibration::startCalibration() graphDataList.reserve(totalSamplesCount); graphDataList.squeeze(); - // configureConversionType(calibrationMode); // TODO uncomment when conversion - // type is okay + configureConversionType(calibrationMode); + configureCalibrationSequenceSettings(); clearHarmonicRegisters(); @@ -3502,7 +3434,7 @@ void HarmonicCalibration::configureConversionType(int mode) return; } - GENERALRegisterMap.at("Conversion Type") = mode; + GENERALRegisterMap["Conversion Type"] = mode; writeSequence(GENERALRegisterMap); } @@ -3514,7 +3446,7 @@ void HarmonicCalibration::configureCalibrationSequenceSettings() return; } - GENERALRegisterMap.at("8th Harmonic") = 1; // User-supplied 8th Harmonic + GENERALRegisterMap["8th Harmonic"] = 1; // User-supplied 8th Harmonic writeSequence(GENERALRegisterMap); } @@ -3763,10 +3695,10 @@ bool HarmonicCalibration::clearHarmonicRegisters() uint32_t value = 0x0; uint32_t harmonicCNVPage = m_admtController->getHarmonicPage(ADMTController::HarmonicRegister::H1MAG); - if(!disableECC(true)) + if(!changeCNVPage(harmonicCNVPage)) return false; - if(!changeCNVPage(harmonicCNVPage)) + if(!disableECC(true)) return false; if(m_admtController->writeDeviceRegistry( @@ -3809,14 +3741,7 @@ bool HarmonicCalibration::clearHarmonicRegisters() m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H8PH), value) != 0) return false; - if(disableECC(false)) { - success = true; - } else - return false; - - if(!success) { - StatusBarManager::pushMessage("Unable to clear Harmonic Registers!"); - } + success = true; return success; } @@ -3825,10 +3750,10 @@ bool HarmonicCalibration::flashHarmonicValues() { bool success = false; - if(!disableECC(true)) + if(!changeCNVPage(0x02)) return false; - if(!changeCNVPage(0x02)) + if(!disableECC(true)) return false; if(m_admtController->writeDeviceRegistry( @@ -3867,24 +3792,18 @@ bool HarmonicCalibration::flashHarmonicValues() isCalculatedCoeff = true; displayCalculatedCoeff(); - if(disableECC(true)) - success = true; - else - return false; - - if(!success) - StatusBarManager::pushMessage("Unable to flash Harmonic Registers!"); + success = true; return success; } void HarmonicCalibration::calculateHarmonicValues() { - uint32_t *h1MagCurrent = new uint32_t, *h1PhaseCurrent = new uint32_t, *h2MagCurrent = new uint32_t, - *h2PhaseCurrent = new uint32_t, *h3MagCurrent = new uint32_t, *h3PhaseCurrent = new uint32_t, - *h8MagCurrent = new uint32_t, *h8PhaseCurrent = new uint32_t; - if(changeCNVPage(0x02)) { + uint32_t *h1MagCurrent = new uint32_t, *h1PhaseCurrent = new uint32_t, *h2MagCurrent = new uint32_t, + *h2PhaseCurrent = new uint32_t, *h3MagCurrent = new uint32_t, *h3PhaseCurrent = new uint32_t, + *h8MagCurrent = new uint32_t, *h8PhaseCurrent = new uint32_t; + // Read and store current harmonic values m_admtController->readDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), @@ -4187,8 +4106,11 @@ void HarmonicCalibration::canCalibrate(bool value) { calibrateDataButton->setEna void HarmonicCalibration::toggleCalibrationControls(bool value) { - motorTargetPositionLineEdit->setEnabled(value); calibrationModeMenuCombo->setEnabled(value); + calibrationCycleCountLineEdit->setEnabled(value); + calibrationSamplesPerCycleLineEdit->setEnabled(value); + calibrationMotorRPMLineEdit->setEnabled(value); + calibrationMotorDirectionSwitch->setEnabled(value); } void HarmonicCalibration::clearCalibrationSamples() @@ -4424,70 +4346,70 @@ void HarmonicCalibration::getDIGIOENRegister() void HarmonicCalibration::updateDIGIOUI(quint16 registerValue) { - DIGIOENRegisterMap = m_admtController->getDIGIOENRegisterBitMapping(registerValue); + DIGIOENRegisterMap = QMap(m_admtController->getDIGIOENRegisterBitMapping(registerValue)); updateDIGIOMonitorUI(); updateDIGIOControlUI(); } void HarmonicCalibration::updateDIGIOMonitorUI() { - map registerMap = DIGIOENRegisterMap; - DIGIOBusyStatusLED->setChecked(registerMap.at("BUSY")); - DIGIOCNVStatusLED->setChecked(registerMap.at("CNV")); - DIGIOSENTStatusLED->setChecked(registerMap.at("SENT")); - DIGIOACALCStatusLED->setChecked(registerMap.at("ACALC")); - DIGIOFaultStatusLED->setChecked(registerMap.at("FAULT")); - DIGIOBootloaderStatusLED->setChecked(registerMap.at("BOOTLOAD")); + QMap registerMap = DIGIOENRegisterMap; + DIGIOBusyStatusLED->setChecked(registerMap.value("BUSY")); + DIGIOCNVStatusLED->setChecked(registerMap.value("CNV")); + DIGIOSENTStatusLED->setChecked(registerMap.value("SENT")); + DIGIOACALCStatusLED->setChecked(registerMap.value("ACALC")); + DIGIOFaultStatusLED->setChecked(registerMap.value("FAULT")); + DIGIOBootloaderStatusLED->setChecked(registerMap.value("BOOTLOAD")); - if(!registerMap.at("BUSY")) + if(!registerMap.value("BUSY")) DIGIOBusyStatusLED->setText("BUSY (Output)"); else { - if(registerMap.at("DIGIO0EN")) + if(registerMap.value("DIGIO0EN")) DIGIOBusyStatusLED->setText("GPIO0 (Output)"); else DIGIOBusyStatusLED->setText("GPIO0 (Input)"); } - if(!registerMap.at("CNV")) + if(!registerMap.value("CNV")) DIGIOCNVStatusLED->setText("CNV (Input)"); else { - if(registerMap.at("DIGIO1EN")) + if(registerMap.value("DIGIO1EN")) DIGIOCNVStatusLED->setText("GPIO1 (Output)"); else DIGIOCNVStatusLED->setText("GPIO1 (Input)"); } - if(!registerMap.at("SENT")) + if(!registerMap.value("SENT")) DIGIOSENTStatusLED->setText("SENT (Output)"); else { - if(registerMap.at("DIGIO2EN")) + if(registerMap.value("DIGIO2EN")) DIGIOSENTStatusLED->setText("GPIO2 (Output)"); else DIGIOSENTStatusLED->setText("GPIO2 (Input)"); } - if(!registerMap.at("ACALC")) + if(!registerMap.value("ACALC")) DIGIOACALCStatusLED->setText("ACALC (Output)"); else { - if(registerMap.at("DIGIO3EN")) + if(registerMap.value("DIGIO3EN")) DIGIOACALCStatusLED->setText("GPIO3 (Output)"); else DIGIOACALCStatusLED->setText("GPIO3 (Input)"); } - if(!registerMap.at("FAULT")) + if(!registerMap.value("FAULT")) DIGIOFaultStatusLED->setText("FAULT (Output)"); else { - if(registerMap.at("DIGIO4EN")) + if(registerMap.value("DIGIO4EN")) DIGIOFaultStatusLED->setText("GPIO4 (Output)"); else DIGIOFaultStatusLED->setText("GPIO4 (Input)"); } - if(!registerMap.at("BOOTLOAD")) + if(!registerMap.value("BOOTLOAD")) DIGIOBootloaderStatusLED->setText("BOOTLOAD (Output)"); else { - if(registerMap.at("DIGIO5EN")) + if(registerMap.value("DIGIO5EN")) DIGIOBootloaderStatusLED->setText("GPIO5 (Output)"); else DIGIOBootloaderStatusLED->setText("GPIO5 (Input)"); @@ -4496,26 +4418,25 @@ void HarmonicCalibration::updateDIGIOMonitorUI() void HarmonicCalibration::updateDIGIOControlUI() { - map registerMap = DIGIOENRegisterMap; + QMap registerMap = DIGIOENRegisterMap; - DIGIO0ENToggleSwitch->setChecked(registerMap.at("DIGIO0EN")); - DIGIO1ENToggleSwitch->setChecked(registerMap.at("DIGIO1EN")); - DIGIO2ENToggleSwitch->setChecked(registerMap.at("DIGIO2EN")); - DIGIO3ENToggleSwitch->setChecked(registerMap.at("DIGIO3EN")); - DIGIO4ENToggleSwitch->setChecked(registerMap.at("DIGIO4EN")); - DIGIO5ENToggleSwitch->setChecked(registerMap.at("DIGIO5EN")); - DIGIO0FNCToggleSwitch->setChecked(registerMap.at("BUSY")); - DIGIO1FNCToggleSwitch->setChecked(registerMap.at("CNV")); - DIGIO2FNCToggleSwitch->setChecked(registerMap.at("SENT")); - DIGIO3FNCToggleSwitch->setChecked(registerMap.at("ACALC")); - DIGIO4FNCToggleSwitch->setChecked(registerMap.at("FAULT")); - DIGIO5FNCToggleSwitch->setChecked(registerMap.at("BOOTLOAD")); + DIGIO0ENToggleSwitch->setChecked(registerMap.value("DIGIO0EN")); + DIGIO1ENToggleSwitch->setChecked(registerMap.value("DIGIO1EN")); + DIGIO2ENToggleSwitch->setChecked(registerMap.value("DIGIO2EN")); + DIGIO3ENToggleSwitch->setChecked(registerMap.value("DIGIO3EN")); + DIGIO4ENToggleSwitch->setChecked(registerMap.value("DIGIO4EN")); + DIGIO5ENToggleSwitch->setChecked(registerMap.value("DIGIO5EN")); + DIGIO0FNCToggleSwitch->setChecked(registerMap.value("BUSY")); + DIGIO1FNCToggleSwitch->setChecked(registerMap.value("CNV")); + DIGIO2FNCToggleSwitch->setChecked(registerMap.value("SENT")); + DIGIO3FNCToggleSwitch->setChecked(registerMap.value("ACALC")); + DIGIO4FNCToggleSwitch->setChecked(registerMap.value("FAULT")); + DIGIO5FNCToggleSwitch->setChecked(registerMap.value("BOOTLOAD")); } void HarmonicCalibration::getDIAG2Register() { uint32_t *mtDiag2RegValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; uint32_t mtDiag2RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG2); uint32_t mtDiag2PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG2); uint32_t cnvPageAddress = @@ -4523,6 +4444,7 @@ void HarmonicCalibration::getDIAG2Register() if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag2PageValue) != -1) { + uint32_t *cnvPageRegValue = new uint32_t; if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1) { if(*cnvPageRegValue == mtDiag2PageValue) { @@ -4546,20 +4468,22 @@ void HarmonicCalibration::getDIAG2Register() } else { Q_EMIT commandLogWriteSignal("Failed to read CNVPAGE for MT Diagnostic 2"); } + + delete cnvPageRegValue; } else { Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 2"); } - delete mtDiag2RegValue, cnvPageRegValue; + delete mtDiag2RegValue; } void HarmonicCalibration::updateMTDiagnosticsUI(quint16 registerValue) { - DIAG2RegisterMap = m_admtController->getDiag2RegisterBitMapping(registerValue); + DIAG2RegisterMap = QMap(m_admtController->getDiag2RegisterBitMapping(registerValue)); - map regmap = DIAG2RegisterMap; - afeDiag0 = regmap.at("AFE Diagnostic 0 (-57%)"); - afeDiag1 = regmap.at("AFE Diagnostic 1 (+57%)"); + QMap regmap = DIAG2RegisterMap; + afeDiag0 = regmap.value("AFE Diagnostic 0 (-57%)"); + afeDiag1 = regmap.value("AFE Diagnostic 1 (+57%)"); AFEDIAG0LineEdit->setText(QString::number(afeDiag0) + " V"); AFEDIAG1LineEdit->setText(QString::number(afeDiag1) + " V"); } @@ -4567,7 +4491,7 @@ void HarmonicCalibration::updateMTDiagnosticsUI(quint16 registerValue) void HarmonicCalibration::getDIAG1Register() { uint32_t *mtDiag1RegValue = new uint32_t; - uint32_t *cnvPageRegValue = new uint32_t; + uint32_t mtDiag1RegisterAddress = m_admtController->getSensorRegister(ADMTController::SensorRegister::DIAG1); uint32_t mtDiag1PageValue = m_admtController->getSensorPage(ADMTController::SensorRegister::DIAG1); uint32_t cnvPageAddress = @@ -4575,6 +4499,7 @@ void HarmonicCalibration::getDIAG1Register() if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, mtDiag1PageValue) != -1) { + uint32_t *cnvPageRegValue = new uint32_t; if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, cnvPageRegValue) != -1) { if(*cnvPageRegValue == mtDiag1PageValue) { @@ -4599,29 +4524,31 @@ void HarmonicCalibration::getDIAG1Register() } else { Q_EMIT commandLogWriteSignal("Failed to read CNVPAGE for MT Diagnostic 1"); } + + delete cnvPageRegValue; } else { Q_EMIT commandLogWriteSignal("Failed to write CNVPAGE for MT Diagnostic 1"); } - delete mtDiag1RegValue, cnvPageRegValue; + delete mtDiag1RegValue; } void HarmonicCalibration::updateMTDiagnosticRegisterUI(quint16 registerValue) { - DIAG1RegisterMap = m_admtController->getDiag1RegisterBitMapping_Register(registerValue); - DIAG1AFERegisterMap = m_admtController->getDiag1RegisterBitMapping_Afe(registerValue, is5V); - - map regmap = DIAG1RegisterMap; - map afeRegmap = DIAG1AFERegisterMap; - R0StatusLED->setChecked(regmap.at("R0")); - R1StatusLED->setChecked(regmap.at("R1")); - R2StatusLED->setChecked(regmap.at("R2")); - R3StatusLED->setChecked(regmap.at("R3")); - R4StatusLED->setChecked(regmap.at("R4")); - R5StatusLED->setChecked(regmap.at("R5")); - R6StatusLED->setChecked(regmap.at("R6")); - R7StatusLED->setChecked(regmap.at("R7")); - afeDiag2 = afeRegmap.at("AFE Diagnostic 2"); + DIAG1RegisterMap = QMap(m_admtController->getDiag1RegisterBitMapping_Register(registerValue)); + DIAG1AFERegisterMap = QMap(m_admtController->getDiag1RegisterBitMapping_Afe(registerValue, is5V)); + + QMap regmap = DIAG1RegisterMap; + QMap afeRegmap = DIAG1AFERegisterMap; + R0StatusLED->setChecked(regmap.value("R0")); + R1StatusLED->setChecked(regmap.value("R1")); + R2StatusLED->setChecked(regmap.value("R2")); + R3StatusLED->setChecked(regmap.value("R3")); + R4StatusLED->setChecked(regmap.value("R4")); + R5StatusLED->setChecked(regmap.value("R5")); + R6StatusLED->setChecked(regmap.value("R6")); + R7StatusLED->setChecked(regmap.value("R7")); + afeDiag2 = afeRegmap.value("AFE Diagnostic 2"); AFEDIAG2LineEdit->setText(QString::number(afeDiag2) + " V"); } @@ -4649,24 +4576,24 @@ void HarmonicCalibration::getFAULTRegister() void HarmonicCalibration::updateFaultRegisterUI(quint16 faultRegValue) { - FAULTRegisterMap = m_admtController->getFaultRegisterBitMapping(faultRegValue); - - map regmap = FAULTRegisterMap; - VDDUnderVoltageStatusLED->setChecked(regmap.at("VDD Under Voltage")); - VDDOverVoltageStatusLED->setChecked(regmap.at("VDD Over Voltage")); - VDRIVEUnderVoltageStatusLED->setChecked(regmap.at("VDRIVE Under Voltage")); - VDRIVEOverVoltageStatusLED->setChecked(regmap.at("VDRIVE Over Voltage")); - AFEDIAGStatusLED->setChecked(regmap.at("AFE Diagnostic")); - NVMCRCFaultStatusLED->setChecked(regmap.at("NVM CRC Fault")); - ECCDoubleBitErrorStatusLED->setChecked(regmap.at("ECC Double Bit Error")); - OscillatorDriftStatusLED->setChecked(regmap.at("Oscillator Drift")); - CountSensorFalseStateStatusLED->setChecked(regmap.at("Count Sensor False State")); - AngleCrossCheckStatusLED->setChecked(regmap.at("Angle Cross Check")); - TurnCountSensorLevelsStatusLED->setChecked(regmap.at("Turn Count Sensor Levels")); - MTDIAGStatusLED->setChecked(regmap.at("MT Diagnostic")); - TurnCounterCrossCheckStatusLED->setChecked(regmap.at("Turn Counter Cross Check")); - RadiusCheckStatusLED->setChecked(regmap.at("AMR Radius Check")); - SequencerWatchdogStatusLED->setChecked(regmap.at("Sequencer Watchdog")); + FAULTRegisterMap = QMap(m_admtController->getFaultRegisterBitMapping(faultRegValue)); + + QMap regmap = FAULTRegisterMap; + VDDUnderVoltageStatusLED->setChecked(regmap.value("VDD Under Voltage")); + VDDOverVoltageStatusLED->setChecked(regmap.value("VDD Over Voltage")); + VDRIVEUnderVoltageStatusLED->setChecked(regmap.value("VDRIVE Under Voltage")); + VDRIVEOverVoltageStatusLED->setChecked(regmap.value("VDRIVE Over Voltage")); + AFEDIAGStatusLED->setChecked(regmap.value("AFE Diagnostic")); + NVMCRCFaultStatusLED->setChecked(regmap.value("NVM CRC Fault")); + ECCDoubleBitErrorStatusLED->setChecked(regmap.value("ECC Double Bit Error")); + OscillatorDriftStatusLED->setChecked(regmap.value("Oscillator Drift")); + CountSensorFalseStateStatusLED->setChecked(regmap.value("Count Sensor False State")); + AngleCrossCheckStatusLED->setChecked(regmap.value("Angle Cross Check")); + TurnCountSensorLevelsStatusLED->setChecked(regmap.value("Turn Count Sensor Levels")); + MTDIAGStatusLED->setChecked(regmap.value("MT Diagnostic")); + TurnCounterCrossCheckStatusLED->setChecked(regmap.value("Turn Counter Cross Check")); + RadiusCheckStatusLED->setChecked(regmap.value("AMR Radius Check")); + SequencerWatchdogStatusLED->setChecked(regmap.value("Sequencer Watchdog")); } bool HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) @@ -4678,17 +4605,20 @@ bool HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) if(!disableECC(true)) return false; - uint32_t *DIGIOENRegisterValue = new uint32_t; uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); if(!changeCNVPage(DIGIOENPage)) return false; + uint32_t *DIGIOENRegisterValue = new uint32_t; + if(m_admtController->readDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - DIGIOENRegisterValue) != 0) + DIGIOENRegisterValue) != 0) { + delete DIGIOENRegisterValue; return false; + } map DIGIOSettings = m_admtController->getDIGIOENRegisterBitMapping(static_cast(*DIGIOENRegisterValue)); @@ -4708,11 +4638,9 @@ bool HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) updateDIGIOControlUI(); - if(!disableECC(false)) - return false; - toggleUtilityTask(true); + delete DIGIOENRegisterValue; return success; } @@ -4758,21 +4686,19 @@ bool HarmonicCalibration::resetDIGIO() uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - if(!disableECC(true)) { + if(!disableECC(true)) + return false; + + if(!changeCNVPage(DIGIOENPage)) return false; - } if(m_admtController->writeDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN), - 0x241b) == 0) { + 0x241b) == 0) { // Reset value is 0x241b success = true; } - if(!disableECC(false)) { - return false; - } - return success; } @@ -4783,9 +4709,8 @@ bool HarmonicCalibration::disableECC(bool disable) uint32_t ECCDISRegValue = disable ? 0x4D54 : 0x0000; uint32_t ECCDISCNVPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCDIS); - if(!changeCNVPage(ECCDISCNVPage)) { - return success; - } + if(!changeCNVPage(ECCDISCNVPage)) + return false; if(m_admtController->writeDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), @@ -4844,7 +4769,7 @@ void HarmonicCalibration::readAllRegisters() h8MagRegisterBlock->readButton()->click(); h8PhRegisterBlock->readButton()->click(); - if(GENERALRegisterMap.at("Sequence Type") == 1) { + if(GENERALRegisterMap.value("Sequence Type") == 1) { angleSecRegisterBlock->readButton()->click(); secAnglIRegisterBlock->readButton()->click(); secAnglQRegisterBlock->readButton()->click(); @@ -4926,6 +4851,8 @@ void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorA case ADMTController::MotorAttribute::RAMP_MODE: label->setText(QString::number(ramp_mode)); break; + default: + break; } } @@ -5009,13 +4936,23 @@ void HarmonicCalibration::configureCoeffRow(QWidget *container, QHBoxLayout *lay layout->addWidget(hPhaseLabel); Style::setStyle(container, style::properties::admt::coeffRowContainer, true, true); } + +void HarmonicCalibration::initializeChannelColors() +{ + channel0Pen = QPen(StyleHelper::getChannelColor(0)); + channel1Pen = QPen(StyleHelper::getChannelColor(1)); + channel2Pen = QPen(StyleHelper::getChannelColor(2)); + channel3Pen = QPen(StyleHelper::getChannelColor(3)); + channel4Pen = QPen(StyleHelper::getChannelColor(4)); + channel5Pen = QPen(StyleHelper::getChannelColor(5)); + channel6Pen = QPen(StyleHelper::getChannelColor(6)); + channel7Pen = QPen(StyleHelper::getChannelColor(7)); +} #pragma endregion #pragma region Connect Methods void HarmonicCalibration::connectLineEditToNumber(QLineEdit *lineEdit, int &variable, int min, int max) { - QIntValidator *validator = new QIntValidator(min, max, this); - lineEdit->setValidator(validator); connect(lineEdit, &QLineEdit::editingFinished, this, [&variable, lineEdit, min, max]() { bool ok; int value = lineEdit->text().toInt(&ok); @@ -5063,7 +5000,7 @@ void HarmonicCalibration::connectLineEditToNumberWrite(QLineEdit *lineEdit, doub QDoubleValidator *validator = new QDoubleValidator(this); validator->setNotation(QDoubleValidator::StandardNotation); lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, attribute, &variable]() { + connect(lineEdit, &QLineEdit::editingFinished, this, [this, lineEdit, attribute, &variable]() { bool ok; double value = lineEdit->text().toDouble(&ok); if(ok) { @@ -5092,7 +5029,7 @@ void HarmonicCalibration::connectMenuComboToNumber(MenuCombo *menuCombo, int &va void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit *lineEdit, double &vmax) { - connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, &vmax]() { + connect(lineEdit, &QLineEdit::editingFinished, this, [this, lineEdit, &vmax]() { bool ok; double rps = lineEdit->text().toDouble(&ok); if(ok) { @@ -5112,7 +5049,7 @@ void HarmonicCalibration::connectLineEditToRPSConversion(QLineEdit *lineEdit, do void HarmonicCalibration::connectLineEditToAMAXConversion(QLineEdit *lineEdit, double &amax) { - connect(lineEdit, &QLineEdit::editingFinished, [this, lineEdit, &amax]() { + connect(lineEdit, &QLineEdit::editingFinished, this, [this, lineEdit, &amax]() { bool ok; double accelTime = lineEdit->text().toDouble(&ok); if(ok) { @@ -5186,7 +5123,7 @@ void HarmonicCalibration::connectLineEditToRPM(QLineEdit *lineEdit, double &vari connect(lineEdit, &QLineEdit::editingFinished, this, [this, lineEdit, &variable]() { bool ok; double value = lineEdit->text().toDouble(&ok); - if(ok) { + if(ok && variable != value) { variable = value; rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(variable)); writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); @@ -5228,11 +5165,11 @@ QString HarmonicCalibration::readRegmapDumpAttributeValue() { QString output = ""; char value[1024]; - int result = -1; - result = m_admtController->getDeviceAttributeValueString( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getDeviceAttribute(ADMTController::DeviceAttribute::REGMAP_DUMP), value, 1024); - output = QString(value); + if(m_admtController->getDeviceAttributeValueString( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getDeviceAttribute(ADMTController::DeviceAttribute::REGMAP_DUMP), value, + 1024) == 0) + output = QString(value); return output; } #pragma endregion From 98ba8c6a7fbf93a34641b1591d4f58db41402e2d Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 31 Mar 2025 12:35:28 +0800 Subject: [PATCH 104/112] admt: Changed samples per cycle to total samples in calibration tab - Revised displayed turn count in acquisition tab Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 4 +- plugins/admt/src/admtcontroller.cpp | 2 +- plugins/admt/src/harmoniccalibration.cpp | 61 ++++++++++--------- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index fc2245c66c..94ade5d676 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -166,7 +166,7 @@ public Q_SLOTS: *clearCalibrateDataButton, *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; QButtonGroup *rightMenuButtonGroup; - QLineEdit *acquisitionMotorRPMLineEdit, *calibrationCycleCountLineEdit, *calibrationSamplesPerCycleLineEdit, + QLineEdit *acquisitionMotorRPMLineEdit, *calibrationCycleCountLineEdit, *calibrationTotalSamplesLineEdit, *calibrationMotorRPMLineEdit, *motorTargetPositionLineEdit, *displayLengthLineEdit, *dataGraphSamplesLineEdit, *tempGraphSamplesLineEdit, *acquisitionMotorCurrentPositionLineEdit, *calibrationH1MagLineEdit, *calibrationH2MagLineEdit, *calibrationH3MagLineEdit, @@ -411,7 +411,7 @@ public Q_SLOTS: void connectLineEditToRPSConversion(QLineEdit *lineEdit, double &vmax); void connectLineEditToAMAXConversion(QLineEdit *lineEdit, double &amax); void connectRegisterBlockToRegistry(RegisterBlockWidget *widget); - void connectLineEditToRPM(QLineEdit *lineEdit, double &variable); + void connectLineEditToRPM(QLineEdit *lineEdit, double &variable, double min, double max); #pragma endregion #pragma region Convert Methods diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 6cef9ef845..5ac421b557 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -1220,7 +1220,7 @@ int ADMTController::getAbsAngleTurnCount(uint16_t registerValue) return turnCount / 4; // Convert from quarter turns to whole turns } else if(turnCount >= 0xD8 && turnCount <= 0xDB) { // Invalid turn count - return -10; + return turnCount / 4; } else { // 2's complement turn count int8_t signedTurnCount = static_cast(turnCount); // Handle as signed value diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 204acfaf14..4b92765b21 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -43,8 +43,8 @@ static int continuousCalibrationSampleRate = 10000000; static int bufferSize = 1; static int cycleCount = 11; -static int samplesPerCycle = 256; -static int totalSamplesCount = cycleCount * samplesPerCycle; +static int samplesPerCycle = 24; +static int totalSamplesCount = 256; static bool isStartMotor = false; static bool isPostCalibration = false; static bool isCalculatedCoeff = false; @@ -312,7 +312,7 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); Style::setStyle(motorRPMLabel, style::properties::label::subtle); acquisitionMotorRPMLineEdit = new QLineEdit(QString::number(motor_rpm), motorRPMWidget); - connectLineEditToRPM(acquisitionMotorRPMLineEdit, motor_rpm); + connectLineEditToRPM(acquisitionMotorRPMLineEdit, motor_rpm, 1, fast_motor_rpm); motorRPMLayout->addWidget(motorRPMLabel); motorRPMLayout->addWidget(acquisitionMotorRPMLineEdit); @@ -1325,18 +1325,18 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationCycleCountLayout->addWidget(calibrationCycleCountLabel); calibrationCycleCountLayout->addWidget(calibrationCycleCountLineEdit); - QWidget *calibrationSamplesPerCycleWidget = new QWidget(calibrationDatasetConfigCollapseSection); - QVBoxLayout *calibrationSamplesPerCycleLayout = new QVBoxLayout(calibrationSamplesPerCycleWidget); - calibrationSamplesPerCycleWidget->setLayout(calibrationSamplesPerCycleLayout); - calibrationSamplesPerCycleLayout->setMargin(0); - calibrationSamplesPerCycleLayout->setSpacing(0); - QLabel *calibrationSamplesPerCycleLabel = new QLabel("Samples Per Cycle", calibrationSamplesPerCycleWidget); - Style::setStyle(calibrationSamplesPerCycleLabel, style::properties::label::subtle); - calibrationSamplesPerCycleLineEdit = new QLineEdit(calibrationSamplesPerCycleWidget); - calibrationSamplesPerCycleLineEdit->setText(QString::number(samplesPerCycle)); - connectLineEditToNumber(calibrationSamplesPerCycleLineEdit, samplesPerCycle, 1, 256); - calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLabel); - calibrationSamplesPerCycleLayout->addWidget(calibrationSamplesPerCycleLineEdit); + QWidget *calibrationTotalSamplesWidget = new QWidget(calibrationDatasetConfigCollapseSection); + QVBoxLayout *calibrationTotalSamplesLayout = new QVBoxLayout(calibrationTotalSamplesWidget); + calibrationTotalSamplesWidget->setLayout(calibrationTotalSamplesLayout); + calibrationTotalSamplesLayout->setMargin(0); + calibrationTotalSamplesLayout->setSpacing(0); + QLabel *calibrationTotalSamplesLabel = new QLabel("Total Samples", calibrationTotalSamplesWidget); + Style::setStyle(calibrationTotalSamplesLabel, style::properties::label::subtle); + calibrationTotalSamplesLineEdit = new QLineEdit(calibrationTotalSamplesWidget); + calibrationTotalSamplesLineEdit->setText(QString::number(totalSamplesCount)); + connectLineEditToNumber(calibrationTotalSamplesLineEdit, totalSamplesCount, 1, 8192); + calibrationTotalSamplesLayout->addWidget(calibrationTotalSamplesLabel); + calibrationTotalSamplesLayout->addWidget(calibrationTotalSamplesLineEdit); QWidget *motorRPMWidget = new QWidget(calibrationDatasetConfigCollapseSection); QVBoxLayout *motorRPMLayout = new QVBoxLayout(motorRPMWidget); @@ -1346,7 +1346,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); Style::setStyle(motorRPMLabel, style::properties::label::subtle); calibrationMotorRPMLineEdit = new QLineEdit(QString::number(motor_rpm), motorRPMWidget); - connectLineEditToRPM(calibrationMotorRPMLineEdit, motor_rpm); + connectLineEditToRPM(calibrationMotorRPMLineEdit, motor_rpm, 1, fast_motor_rpm); motorRPMLayout->addWidget(motorRPMLabel); motorRPMLayout->addWidget(calibrationMotorRPMLineEdit); @@ -1367,7 +1367,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationDatasetConfigCollapseSection->contentLayout()->setSpacing(8); calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationModeMenuCombo); calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationCycleCountWidget); - calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationSamplesPerCycleWidget); + calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(calibrationTotalSamplesWidget); calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(motorRPMWidget); calibrationDatasetConfigCollapseSection->contentLayout()->addWidget(motorDirectionWidget); @@ -1487,7 +1487,6 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() stopMotor(); isStartMotor = false; toggleTabSwitching(true); - toggleCalibrationControls(true); if(isPostCalibration) { graphPostDataList = m_admtController->streamBufferedValues; @@ -2561,7 +2560,7 @@ void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) success = false; if(!success) { - StatusBarManager::pushUrgentMessage("Could not read device, disconnecting device"); + StatusBarManager::pushMessage("Could not read device, disconnecting device"); Q_EMIT m_admtController->requestDisconnect(); break; } @@ -2723,8 +2722,10 @@ void HarmonicCalibration::updateLineEditValues() if(count == static_cast(UINT64_MAX)) { countValueLabel->setText("N/A"); } else { - if(count == -10) - countValueLabel->setText("Invalid turn count"); + if(count == 54) + countValueLabel->setText("Invalid turn count (54)"); + else if(count == -9) + countValueLabel->setText("Invalid turn count (-9)"); else countValueLabel->setText(QString::number(count)); } @@ -3257,7 +3258,8 @@ void HarmonicCalibration::getCalibrationSamples() void HarmonicCalibration::startCalibration() { - totalSamplesCount = cycleCount * samplesPerCycle; + // totalSamplesCount = cycleCount * samplesPerCycle; + samplesPerCycle = ceil(totalSamplesCount / cycleCount); graphPostDataList.reserve(totalSamplesCount); graphPostDataList.squeeze(); graphDataList.reserve(totalSamplesCount); @@ -3542,6 +3544,10 @@ void HarmonicCalibration::resetAllCalibrationState() isCalculatedCoeff = false; resetToZero = true; displayCalculatedCoeff(); + + clearHarmonicRegisters(); + + toggleCalibrationControls(true); } void HarmonicCalibration::computeSineCosineOfAngles(QVector graphDataList) @@ -4108,7 +4114,7 @@ void HarmonicCalibration::toggleCalibrationControls(bool value) { calibrationModeMenuCombo->setEnabled(value); calibrationCycleCountLineEdit->setEnabled(value); - calibrationSamplesPerCycleLineEdit->setEnabled(value); + calibrationTotalSamplesLineEdit->setEnabled(value); calibrationMotorRPMLineEdit->setEnabled(value); calibrationMotorDirectionSwitch->setEnabled(value); } @@ -5115,15 +5121,12 @@ void HarmonicCalibration::connectRegisterBlockToRegistry(RegisterBlockWidget *wi } } -void HarmonicCalibration::connectLineEditToRPM(QLineEdit *lineEdit, double &variable) +void HarmonicCalibration::connectLineEditToRPM(QLineEdit *lineEdit, double &variable, double min, double max) { - QDoubleValidator *validator = new QDoubleValidator(this); - validator->setNotation(QDoubleValidator::StandardNotation); - lineEdit->setValidator(validator); - connect(lineEdit, &QLineEdit::editingFinished, this, [this, lineEdit, &variable]() { + connect(lineEdit, &QLineEdit::editingFinished, this, [this, lineEdit, min, max, &variable]() { bool ok; double value = lineEdit->text().toDouble(&ok); - if(ok && variable != value) { + if(ok && variable != value && value >= min && value <= max) { variable = value; rotate_vmax = convertRPStoVMAX(convertRPMtoRPS(variable)); writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); From bf024c614383fad6572fd270d1fd258713765e6f Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 2 Apr 2025 16:11:40 +0800 Subject: [PATCH 105/112] admt: Added turn count to acquisition tab - Removed raw motor target and current position - Added reset motor position button - Revised ABS angle turn count calculation - Code cleanup Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 4 +- .../admt/include/admt/harmoniccalibration.h | 7 +- plugins/admt/src/admtcontroller.cpp | 6 +- plugins/admt/src/harmoniccalibration.cpp | 174 ++++++------------ 4 files changed, 64 insertions(+), 127 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 0607401656..c1a97768ae 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -191,8 +191,8 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject const uint32_t HarmonicPages[HARMONIC_REGISTER_COUNT] = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}; const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = {0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14}; - const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = {UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; + const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = {0x00, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; const uint32_t RampGeneratorDriverFeatureControlRegisters[RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT] = { diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 94ade5d676..c404f3fc61 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -272,8 +272,6 @@ public Q_SLOTS: void startDeviceStatusMonitor(); void stopDeviceStatusMonitor(); void getDeviceFaultStatus(int sampleRate); - void startCurrentMotorPositionMonitor(); - void stopCurrentMotorPositionMonitor(); void currentMotorPositionTask(int sampleRate); bool resetGENERAL(); void stopTasks(); @@ -357,7 +355,7 @@ public Q_SLOTS: int readMotorRegisterValue(uint32_t address, uint32_t *value); void setRampMode(bool motorRotationClockwise); void getRampMode(); - void startResetMotorToZero(); + void startResetMotorToZero(bool enableWatcher = false); void stopResetMotorToZero(); void resetMotorToZero(); #pragma endregion @@ -387,8 +385,6 @@ public Q_SLOTS: #pragma endregion #pragma region UI Helper Methods - void updateLabelValue(QLabel *label, int channelIndex); - void updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute); bool updateChannelValue(int channelIndex); void updateLineEditValue(QLineEdit *lineEdit, double value); void toggleWidget(QPushButton *widget, bool value); @@ -406,6 +402,7 @@ public Q_SLOTS: void connectLineEditToDouble(QLineEdit *lineEdit, double &variable); void connectLineEditToNumberWrite(QLineEdit *lineEdit, double &variable, ADMTController::MotorAttribute attribute); + void connectLineEditToMotorTurnCount(QLineEdit *lineEdit, int &variable, int min, int max); void connectMenuComboToNumber(MenuCombo *menuCombo, double &variable); void connectMenuComboToNumber(MenuCombo *menuCombo, int &variable); void connectLineEditToRPSConversion(QLineEdit *lineEdit, double &vmax); diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 5ac421b557..502848ea65 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -1213,12 +1213,12 @@ uint16_t ADMTController::setGeneralRegisterBitMapping(uint16_t currentRegisterVa int ADMTController::getAbsAngleTurnCount(uint16_t registerValue) { // Bits 15:8: Turn count in quarter turns - uint8_t turnCount = (registerValue & 0xFF00) >> 8; + uint8_t turnCount = (registerValue >> 8) & 0xFC; - if(turnCount <= 0xD7) { + if(turnCount <= 0xD4) { // Straight binary turn count return turnCount / 4; // Convert from quarter turns to whole turns - } else if(turnCount >= 0xD8 && turnCount <= 0xDB) { + } else if(turnCount == 0xD8) { // Invalid turn count return turnCount / 4; } else { diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 4b92765b21..6be5ea97b1 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -65,6 +65,7 @@ static double motorMicrostepPerRevolution = motorFullStepPerRevolution * microSt static double motorTimeUnit = static_cast(1 << 24) / motorfCLK; // t = 2^24/motorfCLK static int acquisitionDisplayLength = 200; +static int turnCount = 0; static const QColor scopyBlueColor = Style::getColor(json::theme::interactive_primary_idle); @@ -169,11 +170,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool updateSequenceWidget(); updateAcquisitionMotorRPM(); updateAcquisitionMotorRotationDirection(); - startCurrentMotorPositionMonitor(); } else { isAcquisitionTab = false; stop(); - stopCurrentMotorPositionMonitor(); } if(index == 1) // Calibration Tab @@ -215,7 +214,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connect(this, &HarmonicCalibration::calibrationGraphChanged, this, &HarmonicCalibration::updateCalibrationGraph); connect(this, &HarmonicCalibration::updateFaultStatusSignal, this, &HarmonicCalibration::updateFaultStatus); - connect(this, &HarmonicCalibration::motorPositionChanged, this, &HarmonicCalibration::updateMotorPosition); connect(this, &HarmonicCalibration::calibrationLogWriteSignal, this, &HarmonicCalibration::calibrationLogWrite); connect(this, &HarmonicCalibration::commandLogWriteSignal, this, &HarmonicCalibration::commandLogWrite); connect(this, &HarmonicCalibration::DIGIORegisterChanged, this, &HarmonicCalibration::updateDIGIOUI); @@ -226,7 +224,6 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool isAcquisitionTab = true; startDeviceStatusMonitor(); - startCurrentMotorPositionMonitor(); } HarmonicCalibration::~HarmonicCalibration() { stopTasks(); } @@ -316,32 +313,6 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() motorRPMLayout->addWidget(motorRPMLabel); motorRPMLayout->addWidget(acquisitionMotorRPMLineEdit); - QWidget *currentPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *currentPositionLayout = new QVBoxLayout(currentPositionWidget); - currentPositionWidget->setLayout(currentPositionLayout); - currentPositionLayout->setMargin(0); - currentPositionLayout->setSpacing(0); - QLabel *currentPositionLabel = new QLabel("Current Position", currentPositionWidget); - Style::setStyle(currentPositionLabel, style::properties::label::subtle); - acquisitionMotorCurrentPositionLineEdit = new QLineEdit("--.--", currentPositionWidget); - acquisitionMotorCurrentPositionLineEdit->setReadOnly(true); - connectLineEditToDouble(acquisitionMotorCurrentPositionLineEdit, current_pos); - currentPositionLayout->addWidget(currentPositionLabel); - currentPositionLayout->addWidget(acquisitionMotorCurrentPositionLineEdit); - - QWidget *targetPositionWidget = new QWidget(motorControlSectionWidget); - QVBoxLayout *targetPositionLayout = new QVBoxLayout(targetPositionWidget); - targetPositionWidget->setLayout(targetPositionLayout); - targetPositionLayout->setMargin(0); - targetPositionLayout->setSpacing(0); - QLabel *targetPositionLabel = new QLabel("Target Position", targetPositionWidget); - Style::setStyle(targetPositionLabel, style::properties::label::subtle); - motorTargetPositionLineEdit = new QLineEdit(QString::number(target_pos), targetPositionWidget); - connectLineEditToNumberWrite(motorTargetPositionLineEdit, target_pos, - ADMTController::MotorAttribute::TARGET_POS); - targetPositionLayout->addWidget(targetPositionLabel); - targetPositionLayout->addWidget(motorTargetPositionLineEdit); - QWidget *motorDirectionWidget = new QWidget(motorControlSectionWidget); QVBoxLayout *motorDirectionLayout = new QVBoxLayout(motorDirectionWidget); motorDirectionWidget->setLayout(motorDirectionLayout); @@ -356,6 +327,22 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() motorDirectionLayout->addWidget(motorDirectionLabel); motorDirectionLayout->addWidget(acquisitionMotorDirectionSwitch); + QWidget *turnCountWidget = new QWidget(motorControlSectionWidget); + QVBoxLayout *turnCountLayout = new QVBoxLayout(turnCountWidget); + turnCountWidget->setLayout(turnCountLayout); + turnCountLayout->setMargin(0); + turnCountLayout->setSpacing(0); + QLabel *turnCountLabel = new QLabel("Turn Count", turnCountWidget); + Style::setStyle(turnCountLabel, style::properties::label::subtle); + QLineEdit *turnCountLineEdit = new QLineEdit(QString::number(turnCount), turnCountWidget); + connectLineEditToMotorTurnCount(turnCountLineEdit, turnCount, 0, 100); + turnCountLayout->addWidget(turnCountLabel); + turnCountLayout->addWidget(turnCountLineEdit); + + QPushButton *resetMotorPositionButton = new QPushButton("Reset Motor Position", motorControlSectionWidget); + StyleHelper::BasicButton(resetMotorPositionButton); + connect(resetMotorPositionButton, &QPushButton::clicked, this, &HarmonicCalibration::startResetMotorToZero); + QPushButton *continuousRotationButton = new QPushButton("Continuous Rotation", motorControlSectionWidget); StyleHelper::BasicButton(continuousRotationButton); connect(continuousRotationButton, &QPushButton::clicked, this, &HarmonicCalibration::moveMotorContinuous); @@ -366,9 +353,9 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() motorControlCollapseSection->contentLayout()->setSpacing(globalSpacingSmall); motorControlCollapseSection->contentLayout()->addWidget(motorRPMWidget); - motorControlCollapseSection->contentLayout()->addWidget(currentPositionWidget); - motorControlCollapseSection->contentLayout()->addWidget(targetPositionWidget); motorControlCollapseSection->contentLayout()->addWidget(motorDirectionWidget); + motorControlCollapseSection->contentLayout()->addWidget(turnCountWidget); + motorControlCollapseSection->contentLayout()->addWidget(resetMotorPositionButton); motorControlCollapseSection->contentLayout()->addWidget(continuousRotationButton); motorControlCollapseSection->contentLayout()->addWidget(stopMotorButton); #pragma endregion @@ -1413,7 +1400,6 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationSettingsLayout->setMargin(0); calibrationSettingsLayout->addWidget(calibrationDatasetConfigSectionWidget); - // calibrationSettingsLayout->addWidget(motorControlSectionWidget); calibrationSettingsLayout->addWidget(calibrationCoeffSectionWidget); calibrationSettingsLayout->addWidget(calibrationDataSectionWidget); calibrationSettingsLayout->addWidget(logsSectionWidget); @@ -1470,7 +1456,6 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() if(isMotorVelocityReached) { startCalibrationStreamThread(); } else { - startCurrentMotorPositionMonitor(); startDeviceStatusMonitor(); } }); @@ -1521,7 +1506,6 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() } } - startCurrentMotorPositionMonitor(); startDeviceStatusMonitor(); }); @@ -2415,6 +2399,9 @@ bool HarmonicCalibration::writeSequence(QMap settings) uint32_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); + if(settings.value("Sequence Type") != GENERALRegisterMap.value("Sequence Type")) + generalRegisterPage = 0xc002; + if(!changeCNVPage(generalRegisterPage)) return false; @@ -2423,8 +2410,7 @@ bool HarmonicCalibration::writeSequence(QMap settings) return false; if(readSequence()) - if(settings.value("Convert Synchronization") == - GENERALRegisterMap.value("Convert Synchronizvalueion") && + if(settings.value("Convert Synchronization") == GENERALRegisterMap.value("Convert Synchronization") && settings.value("Angle Filter") == GENERALRegisterMap.value("Angle Filter") && settings.value("8th Harmonic") == GENERALRegisterMap.value("8th Harmonic") && settings.value("Sequence Type") == GENERALRegisterMap.value("Sequence Type") && @@ -2582,26 +2568,6 @@ void HarmonicCalibration::stopTasks() stopCalibrationStreamThread(); stopDeviceStatusMonitor(); - stopCurrentMotorPositionMonitor(); -} - -void HarmonicCalibration::startCurrentMotorPositionMonitor() -{ - if(!m_currentMotorPositionThread.isRunning()) { - isMotorPositionMonitor = true; - m_currentMotorPositionThread = QtConcurrent::run(this, &HarmonicCalibration::currentMotorPositionTask, - motorPositionMonitorRate); - m_currentMotorPositionWatcher.setFuture(m_currentMotorPositionThread); - } -} - -void HarmonicCalibration::stopCurrentMotorPositionMonitor() -{ - isMotorPositionMonitor = false; - if(m_currentMotorPositionThread.isRunning()) { - m_currentMotorPositionThread.cancel(); - m_currentMotorPositionWatcher.waitForFinished(); - } } void HarmonicCalibration::currentMotorPositionTask(int sampleRate) @@ -2672,8 +2638,6 @@ bool HarmonicCalibration::updateChannelValues() return false; } updateCountValue(); - // count = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - // countChannelName, bufferSize); if(count == static_cast(UINT64_MAX)) { return false; } @@ -2690,16 +2654,23 @@ bool HarmonicCalibration::updateChannelValues() void HarmonicCalibration::updateCountValue() { + bool success = true; + + uint32_t absAngleRegPage = m_admtController->getSensorPage(ADMTController::SensorRegister::ABSANGLE); + if(!changeCNVPage(absAngleRegPage)) + success = false; + uint32_t *absAngleRegValue = new uint32_t; - bool success = false; - if(m_admtController->readDeviceRegistry( + if(success && + m_admtController->readDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), absAngleRegValue) == 0) { count = m_admtController->getAbsAngleTurnCount(static_cast(*absAngleRegValue)); success = true; - } + } else + success = false; delete absAngleRegValue; @@ -3258,7 +3229,6 @@ void HarmonicCalibration::getCalibrationSamples() void HarmonicCalibration::startCalibration() { - // totalSamplesCount = cycleCount * samplesPerCycle; samplesPerCycle = ceil(totalSamplesCount / cycleCount); graphPostDataList.reserve(totalSamplesCount); graphPostDataList.squeeze(); @@ -3296,14 +3266,13 @@ void HarmonicCalibration::stopCalibration() void HarmonicCalibration::startContinuousCalibration() { - stopCurrentMotorPositionMonitor(); stopDeviceStatusMonitor(); if(isPostCalibration) StatusBarManager::pushMessage("Acquiring Post Calibration Samples, Please Wait..."); else StatusBarManager::pushMessage("Acquiring Calibration Samples, Please Wait..."); - startResetMotorToZero(); + startResetMotorToZero(true); } void HarmonicCalibration::stopContinuousCalibration() @@ -3312,16 +3281,16 @@ void HarmonicCalibration::stopContinuousCalibration() stopWaitForVelocityReachedThread(); stopCalibrationStreamThread(); - startCurrentMotorPositionMonitor(); startDeviceStatusMonitor(); } -void HarmonicCalibration::startResetMotorToZero() +void HarmonicCalibration::startResetMotorToZero(bool enableWatcher) { isResetMotorToZero = true; if(!m_resetMotorToZeroThread.isRunning()) { m_resetMotorToZeroThread = QtConcurrent::run(this, &HarmonicCalibration::resetMotorToZero); - m_resetMotorToZeroWatcher.setFuture(m_resetMotorToZeroThread); + if(enableWatcher) + m_resetMotorToZeroWatcher.setFuture(m_resetMotorToZeroThread); } } @@ -4518,8 +4487,6 @@ void HarmonicCalibration::getDIAG1Register() Q_EMIT commandLogWriteSignal( "DIAG1: 0b" + QString::number(mtDiag1RegValue16, 2).rightJustified(16, '0')); - - // delete mtDiag1RegValue16; } else { Q_EMIT commandLogWriteSignal("Failed to read MT Diagnostic 1 Register"); } @@ -4815,53 +4782,6 @@ void HarmonicCalibration::toggleRegisters(int mode) #pragma endregion #pragma region UI Helper Methods -void HarmonicCalibration::updateLabelValue(QLabel *label, int channelIndex) -{ - switch(channelIndex) { - case ADMTController::Channel::ROTATION: - label->setText(QString("%1").arg(rotation, 0, 'f', 2) + "°"); - break; - case ADMTController::Channel::ANGLE: - label->setText(QString("%1").arg(angle, 0, 'f', 2) + "°"); - break; - case ADMTController::Channel::COUNT: - label->setText(QString::number(count)); - break; - case ADMTController::Channel::TEMPERATURE: - label->setText(QString("%1").arg(temp, 0, 'f', 2) + "°C"); - break; - } -} - -void HarmonicCalibration::updateLabelValue(QLabel *label, ADMTController::MotorAttribute attribute) -{ - switch(attribute) { - case ADMTController::MotorAttribute::AMAX: - label->setText(QString::number(amax)); - break; - case ADMTController::MotorAttribute::ROTATE_VMAX: - label->setText(QString::number(rotate_vmax)); - break; - case ADMTController::MotorAttribute::DMAX: - label->setText(QString::number(dmax)); - break; - case ADMTController::MotorAttribute::DISABLE: - label->setText(QString::number(disable)); - break; - case ADMTController::MotorAttribute::TARGET_POS: - label->setText(QString::number(target_pos)); - break; - case ADMTController::MotorAttribute::CURRENT_POS: - label->setText(QString::number(current_pos)); - break; - case ADMTController::MotorAttribute::RAMP_MODE: - label->setText(QString::number(ramp_mode)); - break; - default: - break; - } -} - bool HarmonicCalibration::updateChannelValue(int channelIndex) { bool success = false; @@ -5019,6 +4939,26 @@ void HarmonicCalibration::connectLineEditToNumberWrite(QLineEdit *lineEdit, doub }); } +void HarmonicCalibration::connectLineEditToMotorTurnCount(QLineEdit *lineEdit, int &variable, int min, int max) +{ + connect(lineEdit, &QLineEdit::editingFinished, this, [this, lineEdit, &variable, min, max]() { + bool ok; + int value = lineEdit->text().toInt(&ok); + if(ok && value >= min && value <= max && value != 0) { + readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); + int target_pos = value * motorMicrostepPerRevolution; + if(!isMotorRotationClockwise) + target_pos *= -1; + + int final_pos = current_pos + target_pos; + writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, final_pos); + variable = 0; + } else + variable = 0; + lineEdit->setText(QString::number(variable)); + }); +} + void HarmonicCalibration::connectMenuComboToNumber(MenuCombo *menuCombo, double &variable) { QComboBox *combo = menuCombo->combo(); From aafd094ad47483cd097737bf241db9ed94db30cb Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 3 Apr 2025 11:57:51 +0800 Subject: [PATCH 106/112] admt: Inverted CW and CCW motor direction - Added call to stop reset to zero - Clear harmonic registers on init Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/harmoniccalibration.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 6be5ea97b1..57efdc295b 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -572,7 +572,7 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() displayLengthLayout->addWidget(displayLengthLabel); displayLengthLayout->addWidget(displayLengthLineEdit); - QPushButton *resetYAxisButton = new QPushButton("Reset Y-Axis Scale", generalSection); + QPushButton *resetYAxisButton = new QPushButton("Reset Graph Scale", generalSection); StyleHelper::BasicButton(resetYAxisButton); connect(resetYAxisButton, &QPushButton::clicked, this, &HarmonicCalibration::resetAcquisitionYAxisScale); @@ -2348,8 +2348,9 @@ void HarmonicCalibration::initializeADMT() bool disabledECC = disableECC(true); bool resetDIGIOSuccess = resetDIGIO(); bool resetGENERALSuccess = resetGENERAL(); + bool resetHarmonicSuccess = clearHarmonicRegisters(); - if(!disabledECC || !resetDIGIOSuccess || !resetGENERALSuccess) { + if(!disabledECC || !resetDIGIOSuccess || !resetGENERALSuccess || resetHarmonicSuccess) { StatusBarManager::pushMessage("Failed initialize ADMT"); } } @@ -3197,7 +3198,7 @@ void HarmonicCalibration::getCalibrationSamples() { if(resetCurrentPositionToZero()) { int step = floor(motorMicrostepPerRevolution / samplesPerCycle); - if(!isMotorRotationClockwise) + if(isMotorRotationClockwise) step = -step; if(isPostCalibration) { int currentSamplesCount = graphPostDataList.size(); @@ -3307,6 +3308,7 @@ void HarmonicCalibration::resetMotorToZero() { if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) { if(current_pos != 0) { + setRampMode(true); // Write to ramp mode in case of motor disable writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, convertRPStoVMAX(convertRPMtoRPS(fast_motor_rpm))); writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); @@ -4172,6 +4174,7 @@ bool HarmonicCalibration::moveMotorToPosition(double &position, bool validate) void HarmonicCalibration::moveMotorContinuous() { + stopResetMotorToZero(); writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, rotate_vmax); setRampMode(isMotorRotationClockwise); } @@ -4200,7 +4203,11 @@ bool HarmonicCalibration::resetCurrentPositionToZero() return success; } -void HarmonicCalibration::stopMotor() { writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); } +void HarmonicCalibration::stopMotor() +{ + stopResetMotorToZero(); + writeMotorAttributeValue(ADMTController::MotorAttribute::DISABLE, 1); +} int HarmonicCalibration::readMotorAttributeValue(ADMTController::MotorAttribute attribute, double &value) { @@ -4234,9 +4241,9 @@ int HarmonicCalibration::readMotorRegisterValue(uint32_t address, uint32_t *valu void HarmonicCalibration::setRampMode(bool motorRotationClockwise) { - // Ramp Mode 1: Clockwise, Ramp Mode 2: Counter-Clockwise + // Ramp Mode 1: Counter-Clockwise, Ramp Mode 2: Clockwise isMotorRotationClockwise = motorRotationClockwise; - int mode = isMotorRotationClockwise ? 1 : 2; + int mode = !isMotorRotationClockwise ? 1 : 2; writeMotorAttributeValue(ADMTController::MotorAttribute::RAMP_MODE, mode); } @@ -4947,7 +4954,7 @@ void HarmonicCalibration::connectLineEditToMotorTurnCount(QLineEdit *lineEdit, i if(ok && value >= min && value <= max && value != 0) { readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos); int target_pos = value * motorMicrostepPerRevolution; - if(!isMotorRotationClockwise) + if(isMotorRotationClockwise) target_pos *= -1; int final_pos = current_pos + target_pos; From 381b8416653d7a9d71aa393ffe1f45bb3052d79d Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 3 Apr 2025 16:20:51 +0800 Subject: [PATCH 107/112] admt: Save calibration coeff. hex code to CSV - Revised CSV saving format - Included post calibration samples, corrected errors, and FFTs Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/harmoniccalibration.cpp | 148 ++++++++++++++++++----- 1 file changed, 121 insertions(+), 27 deletions(-) diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 57efdc295b..826e66ba85 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -4006,33 +4006,127 @@ void HarmonicCalibration::extractCalibrationData() FileManager fm("HarmonicCalibration"); fm.open(fileName, FileManager::EXPORT); - QVector preCalibrationAngleErrorsFFTMagnitude(m_admtController->angle_errors_fft_pre.begin(), - m_admtController->angle_errors_fft_pre.end()); - QVector preCalibrationAngleErrorsFFTPhase(m_admtController->angle_errors_fft_phase_pre.begin(), - m_admtController->angle_errors_fft_phase_pre.end()); - - QVector h1Mag = {H1_MAG_ANGLE}; - QVector h2Mag = {H2_MAG_ANGLE}; - QVector h3Mag = {H3_MAG_ANGLE}; - QVector h8Mag = {H8_MAG_ANGLE}; - QVector h1Phase = {H1_PHASE_ANGLE}; - QVector h2Phase = {H2_PHASE_ANGLE}; - QVector h3Phase = {H3_PHASE_ANGLE}; - QVector h8Phase = {H8_PHASE_ANGLE}; - - fm.save(graphDataList, "Raw Data"); - fm.save(preCalibrationAngleErrorsFFTMagnitude, "Pre-Calibration Angle Errors FFT Magnitude"); - fm.save(preCalibrationAngleErrorsFFTPhase, "Pre-Calibration Angle Errors FFT Phase"); - fm.save(h1Mag, "H1 Mag"); - fm.save(h2Mag, "H2 Mag"); - fm.save(h3Mag, "H3 Mag"); - fm.save(h8Mag, "H8 Mag"); - fm.save(h1Phase, "H1 Phase"); - fm.save(h2Phase, "H2 Phase"); - fm.save(h3Phase, "H3 Phase"); - fm.save(h8Phase, "H8 Phase"); - - fm.performWrite(withScopyHeader); + QVector angleError = + QVector(m_admtController->angleError.begin(), m_admtController->angleError.end()); + QVector FFTAngleErrorMagnitude = + QVector(m_admtController->FFTAngleErrorMagnitude.begin(), + m_admtController->FFTAngleErrorMagnitude.end()); + QVector FFTAngleErrorPhase = QVector(m_admtController->FFTAngleErrorPhase.begin(), + m_admtController->FFTAngleErrorPhase.end()); + + QVector correctedError(m_admtController->correctedError.begin(), + m_admtController->correctedError.end()); + QVector FFTCorrectedErrorMagnitude(m_admtController->FFTCorrectedErrorMagnitude.begin(), + m_admtController->FFTCorrectedErrorMagnitude.end()); + QVector FFTCorrectedErrorPhase(m_admtController->FFTCorrectedErrorPhase.begin(), + m_admtController->FFTCorrectedErrorPhase.end()); + + QVector h1Mag = {QString::number(H1_MAG_ANGLE)}; + QVector h2Mag = {QString::number(H2_MAG_ANGLE)}; + QVector h3Mag = {QString::number(H3_MAG_ANGLE)}; + QVector h8Mag = {QString::number(H8_MAG_ANGLE)}; + QVector h1Phase = {QString::number(H1_PHASE_ANGLE)}; + QVector h2Phase = {QString::number(H2_PHASE_ANGLE)}; + QVector h3Phase = {QString::number(H3_PHASE_ANGLE)}; + QVector h8Phase = {QString::number(H8_PHASE_ANGLE)}; + + QVector h1MagHex = {QString("0x%1").arg(H1_MAG_HEX, 4, 16, QChar('0'))}; + QVector h2MagHex = {QString("0x%1").arg(H2_MAG_HEX, 4, 16, QChar('0'))}; + QVector h3MagHex = {QString("0x%1").arg(H3_MAG_HEX, 4, 16, QChar('0'))}; + QVector h8MagHex = {QString("0x%1").arg(H8_MAG_HEX, 4, 16, QChar('0'))}; + QVector h1PhaseHex = {QString("0x%1").arg(H1_PHASE_HEX, 4, 16, QChar('0'))}; + QVector h2PhaseHex = {QString("0x%1").arg(H2_PHASE_HEX, 4, 16, QChar('0'))}; + QVector h3PhaseHex = {QString("0x%1").arg(H3_PHASE_HEX, 4, 16, QChar('0'))}; + QVector h8PhaseHex = {QString("0x%1").arg(H8_PHASE_HEX, 4, 16, QChar('0'))}; + + QVector stringGraphDataList(graphDataList.size()); + QVector stringGraphPostDataList(graphPostDataList.size()); + + transform(graphDataList.begin(), graphDataList.end(), stringGraphDataList.begin(), + [](double value) { return QString::number(value); }); + transform(graphPostDataList.begin(), graphPostDataList.end(), stringGraphPostDataList.begin(), + [](double value) { return QString::number(value); }); + + QMap> headerData; + + headerData["a"] = {"Calibration Samples"}; + headerData["b"] = {"Angle Error"}; + headerData["c"] = {"FFT Angle Error Magnitude"}; + headerData["d"] = {"FFT Angle Error Phase"}; + headerData["e"] = {"Post Calibration Samples"}; + headerData["f"] = {"Corrected Error"}; + headerData["g"] = {"FFT Corrected Error Magnitude"}; + headerData["h"] = {"FFT Corrected Error Phase"}; + headerData["i"] = {"H1 Mag"}; + headerData["j"] = {"H2 Mag"}; + headerData["k"] = {"H3 Mag"}; + headerData["l"] = {"H8 Mag"}; + headerData["m"] = {"H1 Phase"}; + headerData["n"] = {"H2 Phase"}; + headerData["o"] = {"H3 Phase"}; + headerData["p"] = {"H8 Phase"}; + fm.writeToFile(false, headerData); + + bool addedHarmonicAngleValues = false, addedHarmonicHexValues = false; + for(int i = 0; i < stringGraphDataList.count(); i++) { + QMap> tempData; + tempData["a"] = {stringGraphDataList[i]}; + + if(i < angleError.count()) + tempData["b"] = {QString::number(angleError[i])}; + + if(i < FFTAngleErrorMagnitude.count()) + tempData["c"] = {QString::number(FFTAngleErrorMagnitude[i])}; + + if(i < FFTAngleErrorPhase.count()) + tempData["d"] = {QString::number(FFTAngleErrorPhase[i])}; + + if(stringGraphPostDataList.count() > 0 && i < stringGraphPostDataList.count()) + tempData["e"] = {stringGraphPostDataList[i]}; + else + tempData["e"] = {""}; + + if(correctedError.count() > 0 && i < correctedError.count()) + tempData["f"] = {QString::number(correctedError[i])}; + else + tempData["f"] = {""}; + + if(FFTCorrectedErrorMagnitude.count() > 0 && i < FFTCorrectedErrorMagnitude.count()) + tempData["g"] = {QString::number(FFTCorrectedErrorMagnitude[i])}; + else + tempData["g"] = {""}; + + if(FFTCorrectedErrorPhase.count() > 0 && i < FFTCorrectedErrorPhase.count()) + tempData["h"] = {QString::number(FFTCorrectedErrorPhase[i])}; + else + tempData["h"] = {""}; + + if(!addedHarmonicAngleValues) { + tempData["i"] = h1Mag; + tempData["j"] = h2Mag; + tempData["k"] = h3Mag; + tempData["l"] = h8Mag; + tempData["m"] = h1Phase; + tempData["n"] = h2Phase; + tempData["o"] = h3Phase; + tempData["p"] = h8Phase; + + addedHarmonicAngleValues = true; + } else if(!addedHarmonicHexValues) { + tempData["i"] = h1MagHex; + tempData["j"] = h2MagHex; + tempData["k"] = h3MagHex; + tempData["l"] = h8MagHex; + tempData["m"] = h1PhaseHex; + tempData["n"] = h2PhaseHex; + tempData["o"] = h3PhaseHex; + tempData["p"] = h8PhaseHex; + + addedHarmonicHexValues = true; + } + + fm.writeToFile(false, tempData); + } } } From 0ae5e8045beb0d53e573a2cf4b5839ba4f37b9fa Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 10 Apr 2025 09:35:07 +0800 Subject: [PATCH 108/112] admt: Updated CNV change method - Changed CNV page to uint8_t - Added registry read for rotation, angle, count, temp channels - Added disable state for lineedit - Changed error value for double to UINT32_MAX Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 30 +- .../admt/include/admt/harmoniccalibration.h | 16 +- .../admt/widgets/registerblockwidget.h | 4 +- plugins/admt/src/admtcontroller.cpp | 120 ++++- plugins/admt/src/harmoniccalibration.cpp | 451 ++++++++++-------- .../admt/src/widgets/registerblockwidget.cpp | 2 +- .../style/qss/properties/admt/lineEdit.qss | 12 + 7 files changed, 410 insertions(+), 225 deletions(-) create mode 100644 plugins/admt/style/qss/properties/admt/lineEdit.qss diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index c1a97768ae..d9a164abb6 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -67,7 +67,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject enum Channel { ROTATION, - ANGLE, + ANGL, COUNT, TEMPERATURE, CHANNEL_COUNT @@ -141,7 +141,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject enum SensorRegister { ABSANGLE, - ANGLEREG, + ANGLE, ANGLESEC, SINE, COSINE, @@ -183,16 +183,16 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject "target_pos", "current_pos", "ramp_mode"}; const uint32_t ConfigurationRegisters[CONFIGURATION_REGISTER_COUNT] = {0x01, 0x04, 0x06, 0x10, 0x12, 0x13, 0x1D, 0x23}; - const uint32_t ConfigurationPages[CONFIGURATION_REGISTER_COUNT] = {UINT32_MAX, UINT32_MAX, UINT32_MAX, 0x02, - 0x02, 0x02, 0x02, 0x02}; + const uint8_t ConfigurationPages[CONFIGURATION_REGISTER_COUNT] = {UINT8_MAX, UINT8_MAX, UINT8_MAX, 0x02, + 0x02, 0x02, 0x02, 0x02}; const uint32_t UniqueIdRegisters[UNIQID_REGISTER_COUNT] = {0x1E, 0x1F, 0x20, 0x21}; - const uint32_t UniqueIdPages[UNIQID_REGISTER_COUNT] = {0x02, 0x02, 0x02, 0x02}; + const uint8_t UniqueIdPages[UNIQID_REGISTER_COUNT] = {0x02, 0x02, 0x02, 0x02}; const uint32_t HarmonicRegisters[HARMONIC_REGISTER_COUNT] = {0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C}; - const uint32_t HarmonicPages[HARMONIC_REGISTER_COUNT] = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}; + const uint8_t HarmonicPages[HARMONIC_REGISTER_COUNT] = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}; const uint32_t SensorRegisters[SENSOR_REGISTER_COUNT] = {0x03, 0x05, 0x08, 0x10, 0x11, 0x12, 0x13, 0x18, 0x1D, 0x1E, 0x20, 0x23, 0x14}; - const uint32_t SensorPages[SENSOR_REGISTER_COUNT] = {0x00, UINT32_MAX, UINT32_MAX, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; + const uint8_t SensorPages[SENSOR_REGISTER_COUNT] = {0x00, UINT8_MAX, UINT8_MAX, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; const uint32_t RampGeneratorDriverFeatureControlRegisters[RAMP_GENERATOR_DRIVER_FEATURE_CONTROL_REGISTER_COUNT] = { @@ -203,13 +203,13 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject const char *getDeviceAttribute(DeviceAttribute attribute); const char *getMotorAttribute(MotorAttribute attribute); const uint32_t getConfigurationRegister(ConfigurationRegister registerID); - const uint32_t getConfigurationPage(ConfigurationRegister registerID); + const uint8_t getConfigurationPage(ConfigurationRegister registerID); const uint32_t getUniqueIdRegister(UniqueIDRegister registerID); const uint32_t getHarmonicRegister(HarmonicRegister registerID); - const uint32_t getHarmonicPage(HarmonicRegister registerID); - const uint32_t getUniqueIdPage(UniqueIDRegister registerID); + const uint8_t getHarmonicPage(HarmonicRegister registerID); + const uint8_t getUniqueIdPage(UniqueIDRegister registerID); const uint32_t getSensorRegister(SensorRegister registerID); - const uint32_t getSensorPage(SensorRegister registerID); + const uint8_t getSensorPage(SensorRegister registerID); const uint32_t getRampGeneratorDriverFeatureControlRegister(RampGeneratorDriverFeatureControlRegister registerID); @@ -240,6 +240,9 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject uint16_t setGeneralRegisterBitMapping(uint16_t currentRegisterValue, map settings); void postcalibrate(vector PANG, int cycleCount, int samplesPerCycle, bool CCW); int getAbsAngleTurnCount(uint16_t registerValue); + double getAbsAngle(uint16_t registerValue); + double getAngle(uint16_t registerValue); + double getTemperature(uint16_t registerValue); uint16_t setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings); uint16_t setDIGIORegisterBitMapping(uint16_t currentRegisterValue, map settings); void unwrapAngles(vector &angles_rad); @@ -254,7 +257,10 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject bool checkRegisterFault(uint16_t registerValue, bool isMode1); int streamIO(); void bufferedStreamIO(int totalSamples, int targetSampleRate); + void registryStream(int totalSamples, int targetSampleRate); bool checkVelocityReachedFlag(uint16_t registerValue); + uint16_t changeCNVPage(uint16_t registerValue, uint8_t page); + uint16_t convertStart(bool start, uint16_t registerValue); public Q_SLOTS: void handleStreamData(double value); void handleStreamBufferedData(const QVector &value); diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index c404f3fc61..3d7b05610e 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -162,8 +162,10 @@ public Q_SLOTS: acquisitionSineList, acquisitionCosineList, acquisitionRadiusList, acquisitionAngleSecList, acquisitionSecAnglIList, acquisitionSecAnglQList, graphDataList, graphPostDataList; - QPushButton *openLastMenuButton, *calibrationStartMotorButton, *calibrateDataButton, *extractDataButton, - *clearCalibrateDataButton, *clearCommandLogButton, *applySequenceButton, *readAllRegistersButton; + QPushButton *openLastMenuButton, *calibrationStartMotorButton, *calibrateDataButton, *importSamplesButton, + *extractDataButton, *clearCalibrateDataButton, *clearCommandLogButton, *applySequenceButton, + *readAllRegistersButton; + QButtonGroup *rightMenuButtonGroup; QLineEdit *acquisitionMotorRPMLineEdit, *calibrationCycleCountLineEdit, *calibrationTotalSamplesLineEdit, @@ -185,7 +187,7 @@ public Q_SLOTS: MenuSectionWidget *rightMenuSectionWidget; MenuCollapseSection *rotationCollapse, *angleCollapse, *countCollapse, *tempCollapse; MenuCombo *m_dataGraphChannelMenuCombo, *m_dataGraphDirectionMenuCombo, *m_tempGraphDirectionMenuCombo, - *m_calibrationMotorRampModeMenuCombo, *sequenceTypeMenuCombo, *conversionTypeMenuCombo, + *m_calibrationMotorRampModeMenuCombo, *sequenceModeMenuCombo, *conversionModeMenuCombo, *cnvSourceMenuCombo, *convertSynchronizationMenuCombo, *angleFilterMenuCombo, *eighthHarmonicMenuCombo, *calibrationModeMenuCombo; @@ -267,7 +269,9 @@ public Q_SLOTS: bool readSequence(); bool writeSequence(QMap settings); void applySequence(); - bool changeCNVPage(uint32_t page); + bool changeCNVPage(uint8_t page); + bool convertStart(bool start); + bool convertRestart(); void initializeMotor(); void startDeviceStatusMonitor(); void stopDeviceStatusMonitor(); @@ -278,7 +282,7 @@ public Q_SLOTS: #pragma region Acquisition Methods bool updateChannelValues(); - void updateCountValue(); + bool updateSensorValue(ADMTController::SensorRegister sensor); void updateLineEditValues(); void startAcquisition(); void stopAcquisition(); @@ -293,7 +297,7 @@ public Q_SLOTS: void updateSequenceWidget(); void updateCapturedDataCheckBoxes(); void applySequenceAndUpdate(); - void updateGeneralSettingEnabled(bool value); + void toggleAcquisitionControls(bool value); void connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, SensorData key); void GMRReset(); #pragma endregion diff --git a/plugins/admt/include/admt/widgets/registerblockwidget.h b/plugins/admt/include/admt/widgets/registerblockwidget.h index 27db3aa2b3..039328e73e 100644 --- a/plugins/admt/include/admt/widgets/registerblockwidget.h +++ b/plugins/admt/include/admt/widgets/registerblockwidget.h @@ -47,7 +47,7 @@ class SCOPY_ADMT_EXPORT RegisterBlockWidget : public QWidget QPushButton *m_readButton, *m_writeButton; - RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t cnvPage, + RegisterBlockWidget(QString header, QString description, uint32_t address, uint8_t cnvPage, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent = nullptr); virtual ~RegisterBlockWidget(); QPushButton *readButton(); @@ -82,4 +82,4 @@ class SCOPY_ADMT_EXPORT PaddedSpinBox : public QSpinBox }; } // namespace scopy::admt -#endif // REGISTERBLOCKWIDGET_H \ No newline at end of file +#endif // REGISTERBLOCKWIDGET_H diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 502848ea65..51ab5b70c2 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -109,12 +109,12 @@ const uint32_t ADMTController::getHarmonicRegister(HarmonicRegister registerID) return UINT32_MAX; } -const uint32_t ADMTController::getHarmonicPage(HarmonicRegister registerID) +const uint8_t ADMTController::getHarmonicPage(HarmonicRegister registerID) { if(registerID >= 0 && registerID < HARMONIC_REGISTER_COUNT) { return HarmonicPages[registerID]; } - return UINT32_MAX; + return UINT8_MAX; } const uint32_t ADMTController::getConfigurationRegister(ConfigurationRegister registerID) @@ -125,12 +125,12 @@ const uint32_t ADMTController::getConfigurationRegister(ConfigurationRegister re return UINT32_MAX; } -const uint32_t ADMTController::getConfigurationPage(ConfigurationRegister registerID) +const uint8_t ADMTController::getConfigurationPage(ConfigurationRegister registerID) { if(registerID >= 0 && registerID < CONFIGURATION_REGISTER_COUNT) { return ConfigurationPages[registerID]; } - return UINT32_MAX; + return UINT8_MAX; } const uint32_t ADMTController::getSensorRegister(SensorRegister registerID) @@ -141,12 +141,12 @@ const uint32_t ADMTController::getSensorRegister(SensorRegister registerID) return UINT32_MAX; } -const uint32_t ADMTController::getSensorPage(SensorRegister registerID) +const uint8_t ADMTController::getSensorPage(SensorRegister registerID) { if(registerID >= 0 && registerID < SENSOR_REGISTER_COUNT) { return SensorPages[registerID]; } - return UINT32_MAX; + return UINT8_MAX; } const uint32_t ADMTController::getUniqueIdRegister(UniqueIDRegister registerID) @@ -157,12 +157,12 @@ const uint32_t ADMTController::getUniqueIdRegister(UniqueIDRegister registerID) return UINT32_MAX; } -const uint32_t ADMTController::getUniqueIdPage(UniqueIDRegister registerID) +const uint8_t ADMTController::getUniqueIdPage(UniqueIDRegister registerID) { if(registerID >= 0 && registerID < UNIQID_REGISTER_COUNT) { return UniqueIdPages[registerID]; } - return UINT32_MAX; + return UINT8_MAX; } const uint32_t @@ -203,21 +203,21 @@ int ADMTController::getChannelIndex(const char *deviceName, const char *channelN double ADMTController::getChannelValue(const char *deviceName, const char *channelName, int bufferSize) { if(!m_iioCtx) { - return static_cast(UINT64_MAX); + return UINT32_MAX; } // return QString("No context available."); double value; int deviceCount = iio_context_get_devices_count(m_iioCtx); if(deviceCount < 1) - return static_cast(UINT64_MAX); // return QString("No devices found"); + return UINT32_MAX; // return QString("No devices found"); iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); if(admtDevice == NULL) - return static_cast(UINT64_MAX); // return QString("No ADMT4000 device"); + return UINT32_MAX; // return QString("No ADMT4000 device"); int channelCount = iio_device_get_channels_count(admtDevice); if(channelCount < 1) - return static_cast(UINT64_MAX); // return QString("No channels found."); + return UINT32_MAX; // return QString("No channels found."); iio_channel *channel; std::string message = ""; @@ -233,7 +233,7 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann } } if(channel == NULL) - return static_cast(UINT64_MAX); // return QString("Channel not found."); + return UINT32_MAX; // return QString("Channel not found."); iio_channel_enable(channel); double scale = 1.0; @@ -242,16 +242,16 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann const char *offsetAttrName = "offset"; const char *scaleAttr = iio_channel_find_attr(channel, scaleAttrName); if(scaleAttr == NULL) - return static_cast(UINT64_MAX); // return QString("No scale attribute"); + return UINT32_MAX; // return QString("No scale attribute"); const char *offsetAttr = iio_channel_find_attr(channel, offsetAttrName); if(offsetAttr == NULL) - return static_cast(UINT64_MAX); // return QString("No offset attribute"); + return UINT32_MAX; // return QString("No offset attribute"); double *scaleVal = new double(1); int scaleRet = iio_channel_attr_read_double(channel, scaleAttr, scaleVal); if(scaleRet != 0) { delete scaleVal; - return static_cast(UINT64_MAX); // return QString("Cannot read scale attribute"); + return UINT32_MAX; // return QString("Cannot read scale attribute"); } scale = *scaleVal; delete scaleVal; @@ -263,7 +263,7 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann iio_buffer *iioBuffer = iio_device_create_buffer(admtDevice, bufferSize, false); if(iioBuffer == NULL) - return static_cast(UINT64_MAX); // return QString("Cannot create buffer."); + return UINT32_MAX; // return QString("Cannot create buffer."); ssize_t numBytesRead; int8_t *pointerData, *pointerEnd; @@ -272,7 +272,7 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann numBytesRead = iio_buffer_refill(iioBuffer); if(numBytesRead < 0) - return static_cast(UINT64_MAX); // return QString("Cannot refill buffer."); + return UINT32_MAX; // return QString("Cannot refill buffer."); const struct iio_data_format *format = iio_channel_get_data_format(channel); const struct iio_data_format channelFormat = *format; @@ -1228,6 +1228,40 @@ int ADMTController::getAbsAngleTurnCount(uint16_t registerValue) } } +double ADMTController::getAbsAngle(uint16_t registerValue) +{ + double scale = 0.351562500; + + int turnCount = getAbsAngleTurnCount(registerValue); + + double angle = static_cast(registerValue & 0x03FF) * scale; + double absAngle = angle; + + if(turnCount != 0) + absAngle += (turnCount * 360); + + return absAngle; +} + +double ADMTController::getAngle(uint16_t registerValue) +{ + // Angle resolution: 360 deg / 4096 + double scale = 0.087890625; + + // Bits 15:4: Magnetic Field Angle with 360 deg range. + double angle = static_cast(registerValue >> 4) * scale; + + return angle; +} + +double ADMTController::getTemperature(uint16_t registerValue) +{ + // Bits 15:4: Internal Temperature Sensor. + double temperature = (static_cast((registerValue >> 4)) - 1168) / 15.66; + + return temperature; +} + uint16_t ADMTController::setDIGIOENRegisterBitMapping(uint16_t currentRegisterValue, map settings) { uint16_t registerValue = currentRegisterValue; // Start with the current register value @@ -1839,6 +1873,41 @@ void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) delete[] offsetDst; } +void ADMTController::registryStream(int totalSamples, int targetSampleRate) +{ + QVector values; + sampleCount = 0; + double angle = 0; + bool readSuccess = false; + uint32_t *registerValue = new uint32_t; + + while(!stopStream && sampleCount < totalSamples) { + elapsedStreamTimer.start(); + + qint64 elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); + while(elapsedNanoseconds < targetSampleRate) { + if(readDeviceRegistry(getDeviceId(Device::ADMT4000), getSensorRegister(SensorRegister::ANGLE), + registerValue) == 0) + break; + elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); + } + + angle = getAngle(static_cast(*registerValue)); + + values.append(angle); + sampleCount++; + + elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); + while(elapsedNanoseconds < targetSampleRate) { + elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); + } + } + + delete registerValue; + + Q_EMIT streamBufferedData(values); +} + void ADMTController::handleStreamBufferedData(const QVector &value) { streamBufferedValues = value; } bool ADMTController::checkVelocityReachedFlag(uint16_t registerValue) @@ -1847,4 +1916,19 @@ bool ADMTController::checkVelocityReachedFlag(uint16_t registerValue) // set while VACTUAL and VMAX match. return ((registerValue >> 8) & 0x01) ? true : false; } + +uint16_t ADMTController::changeCNVPage(uint16_t registerValue, uint8_t page) +{ + return (registerValue & ~0x001F) | (page & 0x1F); +} + +uint16_t ADMTController::convertStart(bool start, uint16_t registerValue) +{ + registerValue &= ~(0b11 << 14); + + if(!start) + registerValue |= (0b11 << 14); + + return registerValue; +} #include "moc_admtcontroller.cpp" diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 826e66ba85..806104fe53 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -115,6 +115,10 @@ static double defaultPhaseGraphMax = 4; static double currentPhaseGraphMin = defaultPhaseGraphMin; static double currentPhaseGraphMax = defaultPhaseGraphMax; +static int sequenceMode = 0; // 0: Sequence Mode 1, 1: Sequence Mode 2 +static int conversionMode = 0; // 0: One-shot Conversion, 1: Continuous Conversion +static int readMode = 1; // 0: Channel Read, 1: Register Read + QMap acquisitionDataMap = { {ABSANGLE, false}, {ANGLE, false}, {ANGLESEC, false}, {SINE, false}, {COSINE, false}, {SECANGLI, false}, {SECANGLQ, false}, {RADIUS, false}, {DIAG1, false}, {DIAG2, false}, @@ -132,7 +136,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool readSequence(); rotationChannelName = m_admtController->getChannelId(ADMTController::Channel::ROTATION); - angleChannelName = m_admtController->getChannelId(ADMTController::Channel::ANGLE); + angleChannelName = m_admtController->getChannelId(ADMTController::Channel::ANGL); countChannelName = m_admtController->getChannelId(ADMTController::Channel::COUNT); temperatureChannelName = m_admtController->getChannelId(ADMTController::Channel::TEMPERATURE); @@ -189,11 +193,9 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 2) // Utility Tab { readSequence(); - if(GENERALRegisterMap.contains("Sequence Type")) { - toggleFaultRegisterMode(GENERALRegisterMap.value("Sequence Type")); - toggleMTDiagnostics(GENERALRegisterMap.value("Sequence Type")); - toggleUtilityTask(true); - } + toggleFaultRegisterMode(sequenceMode); + toggleMTDiagnostics(sequenceMode); + toggleUtilityTask(true); } else { toggleUtilityTask(false); } @@ -201,9 +203,7 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool if(index == 3) // Registers Tab { readSequence(); - if(GENERALRegisterMap.contains("Sequence Type")) { - toggleRegisters(GENERALRegisterMap.value("Sequence Type")); - } + toggleRegisters(sequenceMode); } }); @@ -491,7 +491,8 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() Style::setStyle(temp1CheckBox, style::properties::admt::coloredCheckBox, "ch1"); connectCheckBoxToAcquisitionGraph(temp1CheckBox, acquisitionTmp1PlotChannel, TMP1); - if(!GENERALRegisterMap.contains("Sequence Type")) { + if(sequenceMode == 0) // Sequence Mode 1 + { acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); @@ -502,32 +503,18 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() secAnglICheckBox->hide(); secAnglQCheckBox->hide(); temp1CheckBox->hide(); - } else { - if(GENERALRegisterMap.value("Sequence Type") == 0) // Sequence Mode 1 - { - acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); - acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); - acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); - acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 0, 3); - acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 0); - acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 1); - angleSecCheckBox->hide(); - secAnglICheckBox->hide(); - secAnglQCheckBox->hide(); - temp1CheckBox->hide(); - } else if(GENERALRegisterMap.value("Sequence Type") == 1) // Sequence Mode 2 - { - acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); - acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); - acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); - acquisitionGraphChannelGridLayout->addWidget(angleSecCheckBox, 0, 3); - acquisitionGraphChannelGridLayout->addWidget(secAnglQCheckBox, 0, 4); - acquisitionGraphChannelGridLayout->addWidget(secAnglICheckBox, 1, 0); - acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 1, 1); - acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 2); - acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 3); - acquisitionGraphChannelGridLayout->addWidget(temp1CheckBox, 1, 4); - } + } else if(sequenceMode == 1) // Sequence Mode 2 + { + acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); + acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); + acquisitionGraphChannelGridLayout->addWidget(cosineCheckBox, 0, 2); + acquisitionGraphChannelGridLayout->addWidget(angleSecCheckBox, 0, 3); + acquisitionGraphChannelGridLayout->addWidget(secAnglQCheckBox, 0, 4); + acquisitionGraphChannelGridLayout->addWidget(secAnglICheckBox, 1, 0); + acquisitionGraphChannelGridLayout->addWidget(radiusCheckBox, 1, 1); + acquisitionGraphChannelGridLayout->addWidget(absAngleCheckBox, 1, 2); + acquisitionGraphChannelGridLayout->addWidget(temp0CheckBox, 1, 3); + acquisitionGraphChannelGridLayout->addWidget(temp1CheckBox, 1, 4); } #pragma endregion @@ -566,8 +553,8 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() displayLengthLayout->setSpacing(0); QLabel *displayLengthLabel = new QLabel("Display Length", displayLengthWidget); Style::setStyle(displayLengthLabel, style::properties::label::subtle); - displayLengthLineEdit = new QLineEdit(displayLengthWidget); - displayLengthLineEdit->setText(QString::number(acquisitionDisplayLength)); + displayLengthLineEdit = new QLineEdit(QString::number(acquisitionDisplayLength), displayLengthWidget); + Style::setStyle(displayLengthLineEdit, style::properties::admt::lineEdit); connectLineEditToNumber(displayLengthLineEdit, acquisitionDisplayLength, 1, 2048); displayLengthLayout->addWidget(displayLengthLabel); displayLengthLayout->addWidget(displayLengthLineEdit); @@ -587,19 +574,19 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() sequenceWidget->contentLayout()->addWidget(sequenceSection); sequenceSection->contentLayout()->setSpacing(globalSpacingSmall); - sequenceTypeMenuCombo = new MenuCombo("Sequence Type", sequenceSection); - QComboBox *sequenceTypeComboBox = sequenceTypeMenuCombo->combo(); - sequenceTypeComboBox->addItem("Mode 1", QVariant(0)); + sequenceModeMenuCombo = new MenuCombo("Sequence Mode", sequenceSection); + QComboBox *sequenceModeComboBox = sequenceModeMenuCombo->combo(); + sequenceModeComboBox->addItem("Mode 1", QVariant(0)); if(deviceType.toStdString() == "Automotive") { - sequenceTypeComboBox->addItem("Mode 2", QVariant(1)); + sequenceModeComboBox->addItem("Mode 2", QVariant(1)); } - conversionTypeMenuCombo = new MenuCombo("Conversion Type", sequenceSection); - QComboBox *conversionTypeComboBox = conversionTypeMenuCombo->combo(); - conversionTypeComboBox->addItem("Continuous conversions", QVariant(0)); - conversionTypeComboBox->addItem("One-shot conversion", QVariant(1)); + conversionModeMenuCombo = new MenuCombo("Conversion Mode", sequenceSection); + QComboBox *conversionModeComboBox = conversionModeMenuCombo->combo(); + conversionModeComboBox->addItem("Continuous conversions", QVariant(0)); + conversionModeComboBox->addItem("One-shot conversion", QVariant(1)); - convertSynchronizationMenuCombo = new MenuCombo("Convert Synchronization", sequenceSection); + convertSynchronizationMenuCombo = new MenuCombo("Convert Start Synchronization Mode", sequenceSection); QComboBox *convertSynchronizationComboBox = convertSynchronizationMenuCombo->combo(); convertSynchronizationComboBox->addItem("Enabled", QVariant(1)); convertSynchronizationComboBox->addItem("Disabled", QVariant(0)); @@ -620,8 +607,8 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() StyleHelper::BasicButton(applySequenceButton); connect(applySequenceButton, &QPushButton::clicked, this, &HarmonicCalibration::applySequenceAndUpdate); - sequenceSection->contentLayout()->addWidget(sequenceTypeMenuCombo); - sequenceSection->contentLayout()->addWidget(conversionTypeMenuCombo); + sequenceSection->contentLayout()->addWidget(sequenceModeMenuCombo); + sequenceSection->contentLayout()->addWidget(conversionModeMenuCombo); sequenceSection->contentLayout()->addWidget(convertSynchronizationMenuCombo); sequenceSection->contentLayout()->addWidget(angleFilterMenuCombo); sequenceSection->contentLayout()->addWidget(eighthHarmonicMenuCombo); @@ -1306,8 +1293,8 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationCycleCountLayout->setSpacing(0); QLabel *calibrationCycleCountLabel = new QLabel("Cycle Count", calibrationCycleCountWidget); Style::setStyle(calibrationCycleCountLabel, style::properties::label::subtle); - calibrationCycleCountLineEdit = new QLineEdit(calibrationCycleCountWidget); - calibrationCycleCountLineEdit->setText(QString::number(cycleCount)); + calibrationCycleCountLineEdit = new QLineEdit(QString::number(cycleCount), calibrationCycleCountWidget); + Style::setStyle(calibrationCycleCountLineEdit, style::properties::admt::lineEdit); connectLineEditToNumber(calibrationCycleCountLineEdit, cycleCount, 1, 100); calibrationCycleCountLayout->addWidget(calibrationCycleCountLabel); calibrationCycleCountLayout->addWidget(calibrationCycleCountLineEdit); @@ -1319,8 +1306,9 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationTotalSamplesLayout->setSpacing(0); QLabel *calibrationTotalSamplesLabel = new QLabel("Total Samples", calibrationTotalSamplesWidget); Style::setStyle(calibrationTotalSamplesLabel, style::properties::label::subtle); - calibrationTotalSamplesLineEdit = new QLineEdit(calibrationTotalSamplesWidget); - calibrationTotalSamplesLineEdit->setText(QString::number(totalSamplesCount)); + calibrationTotalSamplesLineEdit = + new QLineEdit(QString::number(totalSamplesCount), calibrationTotalSamplesWidget); + Style::setStyle(calibrationTotalSamplesLineEdit, style::properties::admt::lineEdit); connectLineEditToNumber(calibrationTotalSamplesLineEdit, totalSamplesCount, 1, 8192); calibrationTotalSamplesLayout->addWidget(calibrationTotalSamplesLabel); calibrationTotalSamplesLayout->addWidget(calibrationTotalSamplesLineEdit); @@ -1333,6 +1321,7 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() QLabel *motorRPMLabel = new QLabel("Motor RPM", motorRPMWidget); Style::setStyle(motorRPMLabel, style::properties::label::subtle); calibrationMotorRPMLineEdit = new QLineEdit(QString::number(motor_rpm), motorRPMWidget); + Style::setStyle(calibrationMotorRPMLineEdit, style::properties::admt::lineEdit); connectLineEditToRPM(calibrationMotorRPMLineEdit, motor_rpm, 1, fast_motor_rpm); motorRPMLayout->addWidget(motorRPMLabel); motorRPMLayout->addWidget(calibrationMotorRPMLineEdit); @@ -1369,8 +1358,8 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() calibrationDataSectionWidget->contentLayout()->setSpacing(8); calibrationDataSectionWidget->contentLayout()->addWidget(calibrationDataCollapseSection); - QPushButton *importSamplesButton = new QPushButton("Import Samples", calibrationDataCollapseSection); - QPushButton *extractDataButton = new QPushButton("Save to CSV", calibrationDataCollapseSection); + importSamplesButton = new QPushButton("Import Samples", calibrationDataCollapseSection); + extractDataButton = new QPushButton("Save to CSV", calibrationDataCollapseSection); StyleHelper::BasicButton(importSamplesButton); StyleHelper::BasicButton(extractDataButton); @@ -1612,11 +1601,10 @@ ToolTemplate *HarmonicCalibration::createRegistersWidget() m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), m_admtController->getSensorPage(ADMTController::SensorRegister::ABSANGLE), RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); - angleRegisterBlock = - new RegisterBlockWidget("ANGLE", "Angle Register", - m_admtController->getSensorRegister(ADMTController::SensorRegister::ANGLEREG), - m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLEREG), - RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); + angleRegisterBlock = new RegisterBlockWidget( + "ANGLE", "Angle Register", m_admtController->getSensorRegister(ADMTController::SensorRegister::ANGLE), + m_admtController->getSensorPage(ADMTController::SensorRegister::ANGLE), + RegisterBlockWidget::ACCESS_PERMISSION::READ, registerWidget); angleSecRegisterBlock = new RegisterBlockWidget("ANGLESEC", "Secondary Angle", m_admtController->getSensorRegister(ADMTController::SensorRegister::ANGLESEC), @@ -2295,7 +2283,7 @@ ToolTemplate *HarmonicCalibration::createUtilityWidget() bool HarmonicCalibration::readDeviceProperties() { - uint32_t UNIQID3Page = m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3); + uint8_t UNIQID3Page = m_admtController->getUniqueIdPage(ADMTController::UniqueIDRegister::UNIQID3); bool success = false; @@ -2345,13 +2333,12 @@ bool HarmonicCalibration::readDeviceProperties() void HarmonicCalibration::initializeADMT() { - bool disabledECC = disableECC(true); bool resetDIGIOSuccess = resetDIGIO(); bool resetGENERALSuccess = resetGENERAL(); bool resetHarmonicSuccess = clearHarmonicRegisters(); - if(!disabledECC || !resetDIGIOSuccess || !resetGENERALSuccess || resetHarmonicSuccess) { - StatusBarManager::pushMessage("Failed initialize ADMT"); + if(!resetDIGIOSuccess || !resetGENERALSuccess || !resetHarmonicSuccess) { + StatusBarManager::pushMessage("Failed to initialize ADMT"); } } @@ -2359,7 +2346,7 @@ bool HarmonicCalibration::readSequence() { uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); - uint32_t generalRegisterPage = + uint8_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); bool success = false; @@ -2373,6 +2360,8 @@ bool HarmonicCalibration::readSequence() if(*generalRegValue != UINT32_MAX) { GENERALRegisterMap = QMap(m_admtController->getGeneralRegisterBitMapping( static_cast(*generalRegValue))); + sequenceMode = GENERALRegisterMap.value("Sequence Type"); + conversionMode = GENERALRegisterMap.value("Conversion Type"); success = true; } } @@ -2385,9 +2374,6 @@ bool HarmonicCalibration::writeSequence(QMap settings) { bool success = false; - if(!disableECC(true)) - return false; - uint32_t generalRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); uint32_t *generalRegValue = new uint32_t; @@ -2397,15 +2383,14 @@ bool HarmonicCalibration::writeSequence(QMap settings) uint32_t newGeneralRegValue = m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings.toStdMap()); - uint32_t generalRegisterPage = + uint8_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); - if(settings.value("Sequence Type") != GENERALRegisterMap.value("Sequence Type")) - generalRegisterPage = 0xc002; - if(!changeCNVPage(generalRegisterPage)) return false; + convertStart(false); + if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, newGeneralRegValue) != 0) return false; @@ -2418,6 +2403,8 @@ bool HarmonicCalibration::writeSequence(QMap settings) settings.value("Conversion Type") == GENERALRegisterMap.value("Conversion Type")) success = true; + convertStart(true); + return success; } @@ -2434,9 +2421,9 @@ void HarmonicCalibration::applySequence() bool success = false; - settings["Sequence Type"] = qvariant_cast(sequenceTypeMenuCombo->combo()->currentData()); // sequenceType; + settings["Sequence Type"] = qvariant_cast(sequenceModeMenuCombo->combo()->currentData()); // sequenceType; settings["Conversion Type"] = - qvariant_cast(conversionTypeMenuCombo->combo()->currentData()); // conversionType; + qvariant_cast(conversionModeMenuCombo->combo()->currentData()); // conversionType; settings["Convert Synchronization"] = qvariant_cast(convertSynchronizationMenuCombo->combo()->currentData()); // convertSync; settings["Angle Filter"] = qvariant_cast(angleFilterMenuCombo->combo()->currentData()); // angleFilter; @@ -2450,25 +2437,98 @@ void HarmonicCalibration::applySequence() StatusBarManager::pushUrgentMessage("Sequence settings applied successfully"); } -bool HarmonicCalibration::changeCNVPage(uint32_t page) +bool HarmonicCalibration::changeCNVPage(uint8_t page) { + if(page == UINT8_MAX) + return true; + + bool success = false; uint32_t *cnvPageRegValue = new uint32_t; uint32_t cnvPageAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, page) != -1) { - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - cnvPageAddress, cnvPageRegValue) != -1) { - if(*cnvPageRegValue == page) { - return true; - } - } + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) == 0) { + uint32_t newCNVPageRegValue = + m_admtController->changeCNVPage(static_cast(*cnvPageRegValue), page); + + if(newCNVPageRegValue != *cnvPageRegValue) { + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, + newCNVPageRegValue) == 0 && + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, + cnvPageRegValue) == 0) + if(newCNVPageRegValue == *cnvPageRegValue) + success = true; + } else + success = true; + } + + delete cnvPageRegValue; + + return success; +} + +bool HarmonicCalibration::convertStart(bool start) +{ + bool success = false; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t cnvPageAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) == 0) { + uint32_t newCNVPageRegValue = + m_admtController->convertStart(start, static_cast(*cnvPageRegValue)); + + if(newCNVPageRegValue != *cnvPageRegValue) { + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, + newCNVPageRegValue) == 0 && + m_admtController->readDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, + cnvPageRegValue) == 0) + if(newCNVPageRegValue == *cnvPageRegValue) + success = true; + } else + success = true; } delete cnvPageRegValue; - return false; + return success; +} + +bool HarmonicCalibration::convertRestart() +{ + bool success = false; + uint32_t *cnvPageRegValue = new uint32_t; + uint32_t cnvPageAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::CNVPAGE); + + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) == 0) { + uint32_t stopConvertCNVPageRegValue = + m_admtController->convertStart(false, static_cast(*cnvPageRegValue)); + uint32_t startConvertCNVPageRegValue = + m_admtController->convertStart(true, static_cast(*cnvPageRegValue)); + + if(m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, + stopConvertCNVPageRegValue) == 0 && + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), cnvPageAddress, + startConvertCNVPageRegValue) && + m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + cnvPageAddress, cnvPageRegValue) == 0) + if(startConvertCNVPageRegValue == *cnvPageRegValue) + success = true; + } + + delete cnvPageRegValue; + + return success; } void HarmonicCalibration::initializeMotor() @@ -2531,14 +2591,10 @@ void HarmonicCalibration::getDeviceFaultStatus(int sampleRate) m_admtController->getConfigurationRegister( ADMTController::ConfigurationRegister::FAULT), readValue) == 0) { - if(GENERALRegisterMap.contains("Sequence Type")) { - registerFault = m_admtController->checkRegisterFault( - static_cast(*readValue), - GENERALRegisterMap.value("Sequence Type") == 0 ? true : false); - - Q_EMIT updateFaultStatusSignal(registerFault); - } else - success = false; + registerFault = m_admtController->checkRegisterFault(static_cast(*readValue), + sequenceMode == 0 ? true : false); + + Q_EMIT updateFaultStatusSignal(registerFault); } else { success = false; delete readValue; @@ -2594,10 +2650,7 @@ bool HarmonicCalibration::resetGENERAL() { bool success = false; - uint32_t GENERALPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); - - if(!disableECC(true)) - return false; + uint8_t GENERALPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); if(!changeCNVPage(GENERALPage)) return false; @@ -2628,70 +2681,100 @@ bool HarmonicCalibration::resetGENERAL() bool HarmonicCalibration::updateChannelValues() { bool success = false; - rotation = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - rotationChannelName, bufferSize); - if(rotation == static_cast(UINT64_MAX)) { - return false; + + if(readMode == 0) { + updateChannelValue(0); + updateChannelValue(1); + updateChannelValue(2); + updateChannelValue(3); + } else if(readMode == 1) { + if(conversionMode == 1) + convertStart(true); + updateSensorValue(ADMTController::SensorRegister::ANGLE); + updateSensorValue(ADMTController::SensorRegister::ABSANGLE); + updateSensorValue(ADMTController::SensorRegister::TMP0); + if(conversionMode == 1) + convertStart(false); } - angle = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - angleChannelName, bufferSize); - if(angle == static_cast(UINT64_MAX)) { + + if(rotation == UINT32_MAX) return false; - } - updateCountValue(); - if(count == static_cast(UINT64_MAX)) { + if(angle == UINT32_MAX) return false; - } - temp = m_admtController->getChannelValue(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - temperatureChannelName, bufferSize); - if(temp == static_cast(UINT64_MAX)) { + if(count == UINT32_MAX) + return false; + if(temp == UINT32_MAX) return false; - } success = true; return success; } -void HarmonicCalibration::updateCountValue() +bool HarmonicCalibration::updateSensorValue(ADMTController::SensorRegister sensor) { - bool success = true; + bool success = false; - uint32_t absAngleRegPage = m_admtController->getSensorPage(ADMTController::SensorRegister::ABSANGLE); - if(!changeCNVPage(absAngleRegPage)) - success = false; + uint32_t sensorPage = m_admtController->getSensorPage(sensor); + if(!changeCNVPage(sensorPage)) + return false; - uint32_t *absAngleRegValue = new uint32_t; + uint32_t *registerValue = new uint32_t; - if(success && - m_admtController->readDeviceRegistry( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(ADMTController::SensorRegister::ABSANGLE), - absAngleRegValue) == 0) { - count = m_admtController->getAbsAngleTurnCount(static_cast(*absAngleRegValue)); + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + m_admtController->getSensorRegister(sensor), registerValue) == 0) { + switch(sensor) { + case ADMTController::SensorRegister::ABSANGLE: + rotation = m_admtController->getAbsAngle(static_cast(*registerValue)); + count = m_admtController->getAbsAngleTurnCount(static_cast(*registerValue)); + break; + case ADMTController::SensorRegister::ANGLE: + angle = m_admtController->getAngle(static_cast(*registerValue)); + if(angle < 5) { + qInfo() << angle; + qInfo() << *registerValue; + } + break; + case ADMTController::SensorRegister::TMP0: + temp = m_admtController->getTemperature(static_cast(*registerValue)); + default: + break; + } success = true; - } else - success = false; + } else { + switch(sensor) { + case ADMTController::SensorRegister::ABSANGLE: + rotation = UINT32_MAX; + count = UINT32_MAX; + break; + case ADMTController::SensorRegister::ANGLE: + angle = UINT32_MAX; + break; + case ADMTController::SensorRegister::TMP0: + temp = UINT32_MAX; + default: + break; + } + } - delete absAngleRegValue; + delete registerValue; - if(!success) - count = static_cast(UINT64_MAX); + return success; } void HarmonicCalibration::updateLineEditValues() { - if(rotation == static_cast(UINT64_MAX)) { + if(rotation == UINT32_MAX) { rotationValueLabel->setText("N/A"); } else { rotationValueLabel->setText(QString::number(rotation) + "°"); } - if(angle == static_cast(UINT64_MAX)) { + if(angle == UINT32_MAX) { angleValueLabel->setText("N/A"); } else { angleValueLabel->setText(QString::number(angle) + "°"); } - if(count == static_cast(UINT64_MAX)) { + if(count == UINT32_MAX) { countValueLabel->setText("N/A"); } else { if(count == 54) @@ -2701,7 +2784,7 @@ void HarmonicCalibration::updateLineEditValues() else countValueLabel->setText(QString::number(count)); } - if(temp == static_cast(UINT64_MAX)) { + if(temp == UINT32_MAX) { tempValueLabel->setText("N/A"); } else { tempValueLabel->setText(QString::number(temp, 10, 2) + " °C"); @@ -2762,6 +2845,8 @@ void HarmonicCalibration::startAcquisition() isStartAcquisition = true; acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); + convertRestart(); + m_acquisitionDataThread = QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples, acquisitionDataMap); m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); @@ -2810,10 +2895,9 @@ void HarmonicCalibration::updateAcquisitionMotorRotationDirection() void HarmonicCalibration::getAcquisitionSamples(QMap dataMap) { + QMap sensorDataMap; while(isStartAcquisition) { if(updateChannelValues()) { - QMap sensorDataMap; - if(dataMap.value(ANGLE)) sensorDataMap[ANGLE] = angle; if(dataMap.value(ABSANGLE)) @@ -2970,13 +3054,13 @@ void HarmonicCalibration::updateSequenceWidget() } if(GENERALRegisterMap.value("Sequence Type") == -1) { - sequenceTypeMenuCombo->combo()->setCurrentText("Reserved"); + sequenceModeMenuCombo->combo()->setCurrentText("Reserved"); } else { - sequenceTypeMenuCombo->combo()->setCurrentIndex( - sequenceTypeMenuCombo->combo()->findData(GENERALRegisterMap.value("Sequence Type"))); + sequenceModeMenuCombo->combo()->setCurrentIndex( + sequenceModeMenuCombo->combo()->findData(GENERALRegisterMap.value("Sequence Type"))); } - conversionTypeMenuCombo->combo()->setCurrentIndex( - conversionTypeMenuCombo->combo()->findData(GENERALRegisterMap.value("Conversion Type"))); + conversionModeMenuCombo->combo()->setCurrentIndex( + conversionModeMenuCombo->combo()->findData(GENERALRegisterMap.value("Conversion Type"))); if(GENERALRegisterMap.value("Convert Synchronization") == -1) { convertSynchronizationMenuCombo->combo()->setCurrentText("Reserved"); } else { @@ -2992,11 +3076,6 @@ void HarmonicCalibration::updateSequenceWidget() void HarmonicCalibration::updateCapturedDataCheckBoxes() { - if(!GENERALRegisterMap.contains("Sequence Type")) { - StatusBarManager::pushMessage("Failed to read sequence settings"); - return; - } - acquisitionGraphChannelGridLayout->removeWidget(angleCheckBox); acquisitionGraphChannelGridLayout->removeWidget(sineCheckBox); acquisitionGraphChannelGridLayout->removeWidget(cosineCheckBox); @@ -3008,7 +3087,7 @@ void HarmonicCalibration::updateCapturedDataCheckBoxes() acquisitionGraphChannelGridLayout->removeWidget(secAnglICheckBox); acquisitionGraphChannelGridLayout->removeWidget(temp1CheckBox); - if(GENERALRegisterMap.value("Sequence Type") == 0) // Sequence Mode 1 + if(sequenceMode == 0) // Sequence Mode 1 { acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); @@ -3024,7 +3103,7 @@ void HarmonicCalibration::updateCapturedDataCheckBoxes() secAnglICheckBox->hide(); secAnglQCheckBox->hide(); temp1CheckBox->hide(); - } else if(GENERALRegisterMap.value("Sequence Type") == 1) // Sequence Mode 2 + } else if(sequenceMode == 1) // Sequence Mode 2 { acquisitionGraphChannelGridLayout->addWidget(angleCheckBox, 0, 0); acquisitionGraphChannelGridLayout->addWidget(sineCheckBox, 0, 1); @@ -3048,13 +3127,21 @@ void HarmonicCalibration::updateCapturedDataCheckBoxes() void HarmonicCalibration::applySequenceAndUpdate() { - disableECC(true); applySequence(); updateSequenceWidget(); updateCapturedDataCheckBoxes(); } -void HarmonicCalibration::updateGeneralSettingEnabled(bool value) { displayLengthLineEdit->setEnabled(value); } +void HarmonicCalibration::toggleAcquisitionControls(bool value) +{ + sequenceModeMenuCombo->setEnabled(value); + conversionModeMenuCombo->setEnabled(value); + convertSynchronizationMenuCombo->setEnabled(value); + angleFilterMenuCombo->setEnabled(value); + eighthHarmonicMenuCombo->setEnabled(value); + applySequenceButton->setEnabled(value); + displayLengthLineEdit->setEnabled(value); +} void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, SensorData key) { @@ -3138,7 +3225,7 @@ void HarmonicCalibration::run(bool b) startAcquisition(); } - updateGeneralSettingEnabled(!b); + toggleAcquisitionControls(!b); } #pragma endregion @@ -3204,8 +3291,12 @@ void HarmonicCalibration::getCalibrationSamples() int currentSamplesCount = graphPostDataList.size(); while(isStartMotor && currentSamplesCount < totalSamplesCount) { target_pos = current_pos + step; - moveMotorToPosition(target_pos, true); - updateChannelValue(ADMTController::Channel::ANGLE); + if(moveMotorToPosition(target_pos, true) == false) + m_admtController->disconnectADMT(); + convertStart(true); + if(!updateSensorValue(ADMTController::SensorRegister::ANGLE)) + break; + convertStart(false); graphPostDataList.append(angle); currentSamplesCount++; } @@ -3213,12 +3304,12 @@ void HarmonicCalibration::getCalibrationSamples() int currentSamplesCount = graphDataList.size(); while(isStartMotor && currentSamplesCount < totalSamplesCount) { target_pos = current_pos + step; - if(moveMotorToPosition(target_pos, true) == false) { + if(moveMotorToPosition(target_pos, true) == false) m_admtController->disconnectADMT(); - } - if(updateChannelValue(ADMTController::Channel::ANGLE)) { + convertStart(true); + if(!updateSensorValue(ADMTController::SensorRegister::ANGLE)) break; - } + convertStart(false); graphDataList.append(angle); currentSamplesCount++; } @@ -3335,7 +3426,7 @@ void HarmonicCalibration::startCalibrationStreamThread() continuousCalibrationSampleRate = calculateContinuousCalibrationSampleRate(convertVMAXtoRPS(rotate_vmax), samplesPerCycle); m_calibrationStreamThread = QtConcurrent::run([this]() { - m_admtController->bufferedStreamIO(totalSamplesCount, continuousCalibrationSampleRate); + m_admtController->registryStream(totalSamplesCount, continuousCalibrationSampleRate); }); m_calibrationStreamWatcher.setFuture(m_calibrationStreamThread); } @@ -3675,9 +3766,6 @@ bool HarmonicCalibration::clearHarmonicRegisters() if(!changeCNVPage(harmonicCNVPage)) return false; - if(!disableECC(true)) - return false; - if(m_admtController->writeDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), value) != 0) @@ -3730,9 +3818,6 @@ bool HarmonicCalibration::flashHarmonicValues() if(!changeCNVPage(0x02)) return false; - if(!disableECC(true)) - return false; - if(m_admtController->writeDeviceRegistry( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), m_admtController->getHarmonicRegister(ADMTController::HarmonicRegister::H1MAG), H1_MAG_HEX) != 0) @@ -4157,16 +4242,19 @@ void HarmonicCalibration::toggleCalibrationButtonState(int state) calibrateDataButton->setEnabled(true); calibrateDataButton->setChecked(false); clearCalibrateDataButton->setEnabled(true); + extractDataButton->setEnabled(true); break; case 3: // Post-Calibration calibrationStartMotorButton->setEnabled(false); calibrateDataButton->setEnabled(true); clearCalibrateDataButton->setEnabled(false); + extractDataButton->setEnabled(false); break; case 4: // After Post-Calibration calibrationStartMotorButton->setEnabled(false); calibrateDataButton->setEnabled(false); clearCalibrateDataButton->setEnabled(true); + extractDataButton->setEnabled(true); break; } } @@ -4182,6 +4270,8 @@ void HarmonicCalibration::toggleCalibrationControls(bool value) calibrationTotalSamplesLineEdit->setEnabled(value); calibrationMotorRPMLineEdit->setEnabled(value); calibrationMotorDirectionSwitch->setEnabled(value); + importSamplesButton->setEnabled(value); + extractDataButton->setEnabled(value); } void HarmonicCalibration::clearCalibrationSamples() @@ -4399,7 +4489,7 @@ void HarmonicCalibration::toggleUtilityTask(bool run) void HarmonicCalibration::getDIGIOENRegister() { uint32_t *digioRegValue = new uint32_t; - uint32_t digioEnPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + uint8_t digioEnPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); if(changeCNVPage(digioEnPage)) { uint32_t digioRegisterAddress = m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::DIGIOEN); @@ -4676,10 +4766,7 @@ bool HarmonicCalibration::toggleDIGIOEN(string DIGIOENName, bool value) bool success = false; - if(!disableECC(true)) - return false; - - uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); + uint8_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); if(!changeCNVPage(DIGIOENPage)) return false; @@ -4758,10 +4845,7 @@ bool HarmonicCalibration::resetDIGIO() { bool success = false; - uint32_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); - - if(!disableECC(true)) - return false; + uint8_t DIGIOENPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::DIGIOEN); if(!changeCNVPage(DIGIOENPage)) return false; @@ -4781,7 +4865,7 @@ bool HarmonicCalibration::disableECC(bool disable) bool success = false; uint32_t ECCDISRegValue = disable ? 0x4D54 : 0x0000; - uint32_t ECCDISCNVPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCDIS); + uint8_t ECCDISCNVPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::ECCDIS); if(!changeCNVPage(ECCDISCNVPage)) return false; @@ -4804,11 +4888,6 @@ void HarmonicCalibration::clearCommandLog() { commandLogPlainTextEdit->clear(); #pragma region Register Methods void HarmonicCalibration::readAllRegisters() { - if(!GENERALRegisterMap.contains("Sequence Type")) { - StatusBarManager::pushMessage("Failed to read all registers"); - return; - } - readAllRegistersButton->setEnabled(false); readAllRegistersButton->setText(QString("Reading Registers...")); QTimer::singleShot(1000, this, [this]() { @@ -4843,7 +4922,7 @@ void HarmonicCalibration::readAllRegisters() h8MagRegisterBlock->readButton()->click(); h8PhRegisterBlock->readButton()->click(); - if(GENERALRegisterMap.value("Sequence Type") == 1) { + if(sequenceMode == 1) { angleSecRegisterBlock->readButton()->click(); secAnglIRegisterBlock->readButton()->click(); secAnglQRegisterBlock->readButton()->click(); @@ -4890,28 +4969,28 @@ bool HarmonicCalibration::updateChannelValue(int channelIndex) case ADMTController::Channel::ROTATION: rotation = m_admtController->getChannelValue( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, 1); - if(rotation == static_cast(UINT64_MAX)) { + if(rotation == UINT32_MAX) { success = false; } break; - case ADMTController::Channel::ANGLE: + case ADMTController::Channel::ANGL: angle = m_admtController->getChannelValue( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, 1); - if(angle == static_cast(UINT64_MAX)) { + if(angle == UINT32_MAX) { success = false; } break; case ADMTController::Channel::COUNT: count = m_admtController->getChannelValue( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, 1); - if(count == static_cast(UINT64_MAX)) { + if(count == UINT32_MAX) { success = false; } break; case ADMTController::Channel::TEMPERATURE: temp = m_admtController->getChannelValue( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, 1); - if(temp == static_cast(UINT64_MAX)) { + if(temp == UINT32_MAX) { success = false; } break; @@ -4921,7 +5000,7 @@ bool HarmonicCalibration::updateChannelValue(int channelIndex) void HarmonicCalibration::updateLineEditValue(QLineEdit *lineEdit, double value) { - if(value == static_cast(UINT64_MAX)) { + if(value == UINT32_MAX) { lineEdit->setText("N/A"); } else { lineEdit->setText(QString::number(value)); @@ -5115,7 +5194,7 @@ void HarmonicCalibration::connectRegisterBlockToRegistry(RegisterBlockWidget *wi connect(widget->readButton(), &QPushButton::clicked, this, [this, widget, readValue] { bool ok = false, success = false; - if(widget->getCnvPage() != UINT32_MAX) { + if(widget->getCnvPage() != UINT8_MAX) { ok = this->changeCNVPage(widget->getCnvPage()); } else { ok = true; @@ -5136,7 +5215,7 @@ void HarmonicCalibration::connectRegisterBlockToRegistry(RegisterBlockWidget *wi connect(widget->writeButton(), &QPushButton::clicked, this, [this, widget, readValue] { bool ok = false, success = false; - if(widget->getCnvPage() != UINT32_MAX) { + if(widget->getCnvPage() != UINT8_MAX) { ok = this->changeCNVPage(widget->getCnvPage()); } else { ok = true; diff --git a/plugins/admt/src/widgets/registerblockwidget.cpp b/plugins/admt/src/widgets/registerblockwidget.cpp index 35377a073b..c09b8b20e7 100644 --- a/plugins/admt/src/widgets/registerblockwidget.cpp +++ b/plugins/admt/src/widgets/registerblockwidget.cpp @@ -27,7 +27,7 @@ using namespace scopy; using namespace scopy::admt; -RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, uint32_t address, uint32_t cnvPage, +RegisterBlockWidget::RegisterBlockWidget(QString header, QString description, uint32_t address, uint8_t cnvPage, RegisterBlockWidget::ACCESS_PERMISSION accessPermission, QWidget *parent) : QWidget(parent) , m_address(address) diff --git a/plugins/admt/style/qss/properties/admt/lineEdit.qss b/plugins/admt/style/qss/properties/admt/lineEdit.qss new file mode 100644 index 0000000000..b21a4f6bcf --- /dev/null +++ b/plugins/admt/style/qss/properties/admt/lineEdit.qss @@ -0,0 +1,12 @@ +QLineEdit[&&property&&=true] { + height: &unit_2&; + border: &border_width& solid &interactive_subtle_idle&; + border-bottom: &border_width_interactive& solid &interactive_subtle_idle&; + border-radius: &radius_interactive&; + padding: 0 &padding_interactive& 0 &padding_interactive&; + selection-background-color: &interactive_subtle_pressed&; +} + +QLineEdit[&&property&&=true]:disabled { + color: &interactive_subtle_idle&; +} \ No newline at end of file From b968ad92985fc51b4322c845cd0cdb94744a956a Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 10 Apr 2025 17:14:48 +0800 Subject: [PATCH 109/112] admt: Fixed sequence configuration - Added conversion restart on calibration - Fixed bug when deselect all graph channel in acquisition - Changed ramp mode variable for reset motor to zero - Remove unused methods Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- .../admt/include/admt/harmoniccalibration.h | 3 +- plugins/admt/src/harmoniccalibration.cpp | 127 +++++++++--------- 2 files changed, 68 insertions(+), 62 deletions(-) diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index 3d7b05610e..e3c2e28bc5 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -319,8 +319,7 @@ public Q_SLOTS: void stopWaitForVelocityReachedThread(); void waitForVelocityReached(int mode, int sampleRate); int calculateContinuousCalibrationSampleRate(double motorRPS, int samplesPerCycle); - void configureConversionType(int mode); - void configureCalibrationSequenceSettings(); + void configureCalibrationSequenceSettings(int conversionMode); void startOneShotCalibration(); void postCalibrateData(); void resetAllCalibrationState(); diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 806104fe53..fd30087f7a 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -2372,38 +2372,41 @@ bool HarmonicCalibration::readSequence() bool HarmonicCalibration::writeSequence(QMap settings) { - bool success = false; - - uint32_t generalRegisterAddress = - m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); - uint32_t *generalRegValue = new uint32_t; - if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - generalRegisterAddress, generalRegValue) != 0) + if(!disableECC(true)) return false; - uint32_t newGeneralRegValue = - m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings.toStdMap()); uint8_t generalRegisterPage = m_admtController->getConfigurationPage(ADMTController::ConfigurationRegister::GENERAL); if(!changeCNVPage(generalRegisterPage)) return false; - convertStart(false); + bool success = false; - if(m_admtController->writeDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - generalRegisterAddress, newGeneralRegValue) != 0) - return false; + uint32_t generalRegisterAddress = + m_admtController->getConfigurationRegister(ADMTController::ConfigurationRegister::GENERAL); + uint32_t *generalRegValue = new uint32_t; + + if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + generalRegisterAddress, generalRegValue) == 0) { + uint32_t newGeneralRegValue = + m_admtController->setGeneralRegisterBitMapping(*generalRegValue, settings.toStdMap()); - if(readSequence()) - if(settings.value("Convert Synchronization") == GENERALRegisterMap.value("Convert Synchronization") && + if(convertStart(false) && changeCNVPage(generalRegisterPage) && + m_admtController->writeDeviceRegistry( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), generalRegisterAddress, + newGeneralRegValue) == 0 && + readSequence() && + settings.value("Convert Synchronization") == GENERALRegisterMap.value("Convert Synchronization") && settings.value("Angle Filter") == GENERALRegisterMap.value("Angle Filter") && settings.value("8th Harmonic") == GENERALRegisterMap.value("8th Harmonic") && settings.value("Sequence Type") == GENERALRegisterMap.value("Sequence Type") && - settings.value("Conversion Type") == GENERALRegisterMap.value("Conversion Type")) + settings.value("Conversion Type") == GENERALRegisterMap.value("Conversion Type")) { success = true; + } + } - convertStart(true); + delete generalRegValue; return success; } @@ -2689,12 +2692,10 @@ bool HarmonicCalibration::updateChannelValues() updateChannelValue(3); } else if(readMode == 1) { if(conversionMode == 1) - convertStart(true); + convertRestart(); updateSensorValue(ADMTController::SensorRegister::ANGLE); updateSensorValue(ADMTController::SensorRegister::ABSANGLE); updateSensorValue(ADMTController::SensorRegister::TMP0); - if(conversionMode == 1) - convertStart(false); } if(rotation == UINT32_MAX) @@ -2730,10 +2731,6 @@ bool HarmonicCalibration::updateSensorValue(ADMTController::SensorRegister senso break; case ADMTController::SensorRegister::ANGLE: angle = m_admtController->getAngle(static_cast(*registerValue)); - if(angle < 5) { - qInfo() << angle; - qInfo() << *registerValue; - } break; case ADMTController::SensorRegister::TMP0: temp = m_admtController->getTemperature(static_cast(*registerValue)); @@ -2896,37 +2893,61 @@ void HarmonicCalibration::updateAcquisitionMotorRotationDirection() void HarmonicCalibration::getAcquisitionSamples(QMap dataMap) { QMap sensorDataMap; + bool dataChanged = false; while(isStartAcquisition) { if(updateChannelValues()) { - if(dataMap.value(ANGLE)) + dataChanged = false; + + if(dataMap.value(ANGLE)) { sensorDataMap[ANGLE] = angle; - if(dataMap.value(ABSANGLE)) + dataChanged = true; + } + if(dataMap.value(ABSANGLE)) { sensorDataMap[ABSANGLE] = rotation; - if(dataMap.value(TMP0)) + dataChanged = true; + } + if(dataMap.value(TMP0)) { sensorDataMap[TMP0] = temp; - if(dataMap.value(SINE)) + dataChanged = true; + } + if(dataMap.value(SINE)) { sensorDataMap[SINE] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::SINE); - if(dataMap.value(COSINE)) + dataChanged = true; + } + if(dataMap.value(COSINE)) { sensorDataMap[COSINE] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::COSINE); - if(dataMap.value(RADIUS)) + dataChanged = true; + } + if(dataMap.value(RADIUS)) { sensorDataMap[RADIUS] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::RADIUS); - if(dataMap.value(ANGLESEC)) + dataChanged = true; + } + if(dataMap.value(ANGLESEC)) { sensorDataMap[ANGLESEC] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::ANGLESEC); - if(dataMap.value(SECANGLI)) + dataChanged = true; + } + if(dataMap.value(SECANGLI)) { sensorDataMap[SECANGLI] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLI); - if(dataMap.value(SECANGLQ)) + dataChanged = true; + } + if(dataMap.value(SECANGLQ)) { sensorDataMap[SECANGLQ] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLQ); - if(dataMap.value(TMP1)) + dataChanged = true; + } + if(dataMap.value(TMP1)) { sensorDataMap[TMP1] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::TMP1); + dataChanged = true; + } - Q_EMIT acquisitionDataChanged(sensorDataMap); + if(dataChanged) + Q_EMIT acquisitionDataChanged(sensorDataMap); } } } @@ -3327,18 +3348,16 @@ void HarmonicCalibration::startCalibration() graphDataList.reserve(totalSamplesCount); graphDataList.squeeze(); - configureConversionType(calibrationMode); - - configureCalibrationSequenceSettings(); - clearHarmonicRegisters(); - - toggleTabSwitching(false); - toggleCalibrationControls(false); - calibrationDataGraphTabWidget->setCurrentIndex(0); calibrationRawDataXPlotAxis->setInterval(0, totalSamplesCount); + toggleTabSwitching(false); + toggleCalibrationControls(false); toggleCalibrationButtonState(1); + + configureCalibrationSequenceSettings(calibrationMode); + clearHarmonicRegisters(); + convertRestart(); if(calibrationMode == 0) startContinuousCalibration(); else @@ -3399,7 +3418,7 @@ void HarmonicCalibration::resetMotorToZero() { if(readMotorAttributeValue(ADMTController::MotorAttribute::CURRENT_POS, current_pos) == 0) { if(current_pos != 0) { - setRampMode(true); // Write to ramp mode in case of motor disable + setRampMode(isMotorRotationClockwise); // Write to ramp mode in case of motor disable writeMotorAttributeValue(ADMTController::MotorAttribute::ROTATE_VMAX, convertRPStoVMAX(convertRPMtoRPS(fast_motor_rpm))); writeMotorAttributeValue(ADMTController::MotorAttribute::TARGET_POS, 0); @@ -3490,27 +3509,15 @@ int HarmonicCalibration::calculateContinuousCalibrationSampleRate(double motorRP return static_cast(floor(1 / motorRPS / samplesPerCycle * 1000 * 1000 * 1000)); // In nanoseconds } -void HarmonicCalibration::configureConversionType(int mode) -{ - readSequence(); - if(!GENERALRegisterMap.contains("Conversion Type")) { - StatusBarManager::pushMessage("Failed to configure calibration conversion type"); - return; - } - - GENERALRegisterMap["Conversion Type"] = mode; - writeSequence(GENERALRegisterMap); -} - -void HarmonicCalibration::configureCalibrationSequenceSettings() +void HarmonicCalibration::configureCalibrationSequenceSettings(int conversionMode) { - readSequence(); - if(!GENERALRegisterMap.contains("8th Harmonic")) { + if(!readSequence()) { StatusBarManager::pushMessage("Failed to configure calibration sequence settings"); return; } - GENERALRegisterMap["8th Harmonic"] = 1; // User-supplied 8th Harmonic + GENERALRegisterMap["Conversion Type"] = conversionMode; // 0: One-shot Conversion, 1: Continuous Conversion + GENERALRegisterMap["8th Harmonic"] = 1; // Always use user-supplied 8th Harmonic writeSequence(GENERALRegisterMap); } From 5652da8c201a17a5f258ad6bfd0ce1eee0fe817a Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 14 Apr 2025 08:28:51 +0800 Subject: [PATCH 110/112] admt: Updated channel read value Signed-off-by: John Lloyd Juanillo Signed-off-by: JJuanill --- plugins/admt/src/admtcontroller.cpp | 126 ++++++++++------------------ 1 file changed, 42 insertions(+), 84 deletions(-) diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index 51ab5b70c2..addad3ac4f 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -202,111 +202,69 @@ int ADMTController::getChannelIndex(const char *deviceName, const char *channelN double ADMTController::getChannelValue(const char *deviceName, const char *channelName, int bufferSize) { - if(!m_iioCtx) { - return UINT32_MAX; - } // return QString("No context available."); double value; + const char *scaleAttrName = "scale"; + const char *offsetAttrName = "offset"; + size_t samples = 1; + bool isOutput = false, isCyclic = false; - int deviceCount = iio_context_get_devices_count(m_iioCtx); - if(deviceCount < 1) - return UINT32_MAX; // return QString("No devices found"); - - iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); - if(admtDevice == NULL) - return UINT32_MAX; // return QString("No ADMT4000 device"); - - int channelCount = iio_device_get_channels_count(admtDevice); - if(channelCount < 1) - return UINT32_MAX; // return QString("No channels found."); + unsigned int i, j, major, minor; + char git_tag[8]; + iio_library_get_version(&major, &minor, git_tag); + bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; - iio_channel *channel; - std::string message = ""; - for(int i = 0; i < channelCount; i++) { - channel = iio_device_get_channel(admtDevice, i); - const char *deviceChannel = iio_channel_get_id(channel); + int offsetAttrValue = 0; - if(deviceChannel != nullptr && std::string(deviceChannel) == std::string(channelName)) { - message = message + "[" + std::to_string(i) + "]" + std::string(deviceChannel) + ", "; - break; - } else { - channel = NULL; - } - } + if(!m_iioCtx) + return UINT32_MAX; + if(iio_context_get_devices_count(m_iioCtx) < 1) + return UINT32_MAX; + struct iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); + if(admtDevice == NULL) + return UINT32_MAX; + struct iio_channel *channel = iio_device_find_channel(admtDevice, channelName, isOutput); if(channel == NULL) - return UINT32_MAX; // return QString("Channel not found."); + return UINT32_MAX; iio_channel_enable(channel); - - double scale = 1.0; - int offsetAttrVal = 0; - const char *scaleAttrName = "scale"; - const char *offsetAttrName = "offset"; - const char *scaleAttr = iio_channel_find_attr(channel, scaleAttrName); - if(scaleAttr == NULL) - return UINT32_MAX; // return QString("No scale attribute"); - const char *offsetAttr = iio_channel_find_attr(channel, offsetAttrName); - if(offsetAttr == NULL) - return UINT32_MAX; // return QString("No offset attribute"); - - double *scaleVal = new double(1); - int scaleRet = iio_channel_attr_read_double(channel, scaleAttr, scaleVal); + double *scaleAttrValue = new double(1); + int scaleRet = iio_channel_attr_read_double(channel, scaleAttrName, scaleAttrValue); // Read the scale attribute if(scaleRet != 0) { - delete scaleVal; - return UINT32_MAX; // return QString("Cannot read scale attribute"); + delete scaleAttrValue; + return scaleRet; } - scale = *scaleVal; - delete scaleVal; char *offsetDst = new char[maxAttrSize]; - iio_channel_attr_read(channel, offsetAttr, offsetDst, maxAttrSize); - offsetAttrVal = std::atoi(offsetDst); + iio_channel_attr_read(channel, offsetAttrName, offsetDst, + maxAttrSize); // Read the offset attribute + offsetAttrValue = atoi(offsetDst); delete[] offsetDst; - iio_buffer *iioBuffer = iio_device_create_buffer(admtDevice, bufferSize, false); - if(iioBuffer == NULL) - return UINT32_MAX; // return QString("Cannot create buffer."); - + struct iio_buffer *buffer = iio_device_create_buffer(admtDevice, samples, isCyclic); // Create a buffer ssize_t numBytesRead; - int8_t *pointerData, *pointerEnd; - void *buffer; + char *pointerData, *pointerEnd; ptrdiff_t pointerIncrement; - numBytesRead = iio_buffer_refill(iioBuffer); - if(numBytesRead < 0) - return UINT32_MAX; // return QString("Cannot refill buffer."); + numBytesRead = iio_buffer_refill(buffer); + + pointerIncrement = iio_buffer_step(buffer); + pointerEnd = static_cast(iio_buffer_end(buffer)); const struct iio_data_format *format = iio_channel_get_data_format(channel); - const struct iio_data_format channelFormat = *format; - unsigned int repeat = channelFormat.repeat; - - QString result; - std::list rawSamples; - // std::list unsignedSamples; - std::list castSamples; - - size_t sample, bytes; - - size_t sampleSize = channelFormat.length / 8 * repeat; - // if(sampleSize == 0) return QString("Sample size is zero."); - - buffer = malloc(sampleSize * bufferSize); - // if(!buffer) return QString("Cannot allocate memory for buffer."); - - bytes = iio_channel_read(channel, iioBuffer, buffer, sampleSize * bufferSize); - for(sample = 0; sample < bytes / sampleSize; ++sample) { - for(int j = 0; j < repeat; ++j) { - if(channelFormat.length / 8 == sizeof(int16_t)) { - rawSamples.push_back(*((int8_t *)buffer)); - int16_t rawValue = ((int16_t *)buffer)[sample + j]; - castSamples.push_back(rawValue); - value = (rawValue - static_cast(offsetAttrVal)) * scale; - result = QString::number(value); + unsigned int repeat = has_repeat ? format->repeat : 1; + + for(pointerData = static_cast(iio_buffer_first(buffer, channel)); pointerData < pointerEnd; + pointerData += pointerIncrement) { + for(int j = 0; j < repeat; j++) { + if(format->length / 8 == sizeof(int16_t)) { + int16_t rawValue = (reinterpret_cast(pointerData))[j]; + value = (rawValue - offsetAttrValue) * *scaleAttrValue; } } } - message = message + result.toStdString(); - iio_buffer_destroy(iioBuffer); - return value; // QString::fromStdString(message); + delete scaleAttrValue; + iio_buffer_destroy(buffer); + return value; } /** @brief Get the attribute value of a device From fd704c34a0cc901ec038c8df6b8868372745bd54 Mon Sep 17 00:00:00 2001 From: JJuanill Date: Mon, 28 Apr 2025 12:55:56 +0800 Subject: [PATCH 111/112] admt: Updated channel read - Added disable state for colored checkbox Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 8 +- .../admt/include/admt/harmoniccalibration.h | 9 +- plugins/admt/src/admtcontroller.cpp | 166 +++++++++-- plugins/admt/src/harmoniccalibration.cpp | 282 +++++++++++++----- .../qss/properties/admt/coloredCheckBox.qss | 74 ++++- 5 files changed, 424 insertions(+), 115 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index d9a164abb6..50c346ffbe 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -52,10 +52,11 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject int HAR_MAG_1, HAR_MAG_2, HAR_MAG_3, HAR_MAG_8, HAR_PHASE_1, HAR_PHASE_2, HAR_PHASE_3, HAR_PHASE_8, sampleCount = 0; - bool stopStream = false; + QAtomicInt stopStream = false; double streamedValue = 0.0; QVector streamBufferedValues; + QMap streamedChannelDataMap; QElapsedTimer elapsedStreamTimer; @@ -256,16 +257,19 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject map getTmp1RegisterBitMapping(uint16_t registerValue, bool is5V); bool checkRegisterFault(uint16_t registerValue, bool isMode1); int streamIO(); - void bufferedStreamIO(int totalSamples, int targetSampleRate); + void bufferedStreamIO(int totalSamples, int targetSampleRate, int bufferSize); void registryStream(int totalSamples, int targetSampleRate); bool checkVelocityReachedFlag(uint16_t registerValue); uint16_t changeCNVPage(uint16_t registerValue, uint8_t page); uint16_t convertStart(bool start, uint16_t registerValue); + int streamChannel(const char *deviceName, const QVector channelNames, int bufferSize); public Q_SLOTS: void handleStreamData(double value); + void handleStreamChannelData(QMap dataMap); void handleStreamBufferedData(const QVector &value); Q_SIGNALS: void streamData(double value); + void streamChannelData(QMap dataMap); void streamBufferedData(const QVector &value); void requestDisconnect(); diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index e3c2e28bc5..a6389659af 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -121,6 +121,8 @@ public Q_SLOTS: void updateFaultRegisterUI(quint16 registerValue); void updateMTDiagnosticRegisterUI(quint16 registerValue); void updateMTDiagnosticsUI(quint16 registerValue); + void handleStreamChannelData(QMap dataMap); + void handleStreamCalibrationData(double value); Q_SIGNALS: void runningChanged(bool); void acquisitionDataChanged(QMap sensorDataMap); @@ -148,8 +150,8 @@ public Q_SLOTS: const char *rotationChannelName, *angleChannelName, *countChannelName, *temperatureChannelName; - double rotation, angle, count, temp = 0.0, motor_rpm, amax, rotate_vmax, dmax, disable, target_pos, current_pos, - ramp_mode, afeDiag0, afeDiag1, afeDiag2; + double rotation = 0, angle = 0, count = 0, temp = 0, motor_rpm, amax, rotate_vmax, dmax, disable, target_pos, + current_pos, ramp_mode, afeDiag0, afeDiag1, afeDiag2; QPen channel0Pen, channel1Pen, channel2Pen, channel3Pen, channel4Pen, channel5Pen, channel6Pen, channel7Pen; @@ -290,9 +292,10 @@ public Q_SLOTS: void updateAcquisitionMotorRPM(); void updateAcquisitionMotorRotationDirection(); void getAcquisitionSamples(QMap dataMap); + double calculateABSAngle(double &absAngle, double &turnCount); double getSensorDataAcquisitionValue(const ADMTController::SensorRegister &key); void plotAcquisition(QVector list, PlotChannel *channel); - void appendAcquisitionData(const double &data, QVector &list); + void appendAcquisitionData(double data, QVector &list); void resetAcquisitionYAxisScale(); void updateSequenceWidget(); void updateCapturedDataCheckBoxes(); diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index addad3ac4f..c63e5c5825 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -46,7 +45,6 @@ ADMTController::ADMTController(QString uri, QObject *parent) : QObject(parent) , uri(uri) { - connect(this, &ADMTController::streamData, this, &ADMTController::handleStreamData); connect(this, &ADMTController::streamBufferedData, this, &ADMTController::handleStreamBufferedData); } @@ -205,7 +203,8 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann double value; const char *scaleAttrName = "scale"; const char *offsetAttrName = "offset"; - size_t samples = 1; + size_t samples = bufferSize; + vector values; bool isOutput = false, isCyclic = false; unsigned int i, j, major, minor; @@ -255,15 +254,21 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann for(pointerData = static_cast(iio_buffer_first(buffer, channel)); pointerData < pointerEnd; pointerData += pointerIncrement) { for(int j = 0; j < repeat; j++) { - if(format->length / 8 == sizeof(int16_t)) { + if(format->bits <= 8) { + int8_t rawValue = (reinterpret_cast(pointerData))[j]; + values.push_back((rawValue - offsetAttrValue) * *scaleAttrValue); + } else if(format->length / 8 == sizeof(int16_t)) { int16_t rawValue = (reinterpret_cast(pointerData))[j]; - value = (rawValue - offsetAttrValue) * *scaleAttrValue; + values.push_back((rawValue - offsetAttrValue) * *scaleAttrValue); } } } + value = values[bufferSize - 1]; + delete scaleAttrValue; iio_buffer_destroy(buffer); + iio_channel_disable(channel); return value; } @@ -1703,7 +1708,7 @@ int ADMTController::streamIO() delete[] offsetDst; struct iio_buffer *buffer = iio_device_create_buffer(admtDevice, samples, isCyclic); // Create a buffer - while(!stopStream) { + while(!stopStream.loadAcquire()) { ssize_t numBytesRead; char *pointerData, *pointerEnd; ptrdiff_t pointerIncrement; @@ -1735,20 +1740,131 @@ int ADMTController::streamIO() return 0; } +int ADMTController::streamChannel(const char *deviceName, const QVector channelNames, int bufferSize) +{ + int result = -1; + const char *scaleAttrName = "scale"; + const char *offsetAttrName = "offset"; + size_t samples = bufferSize; + vector values; + bool isOutput = false, isCyclic = true; + + unsigned int i, j, major, minor; + char git_tag[8]; + iio_library_get_version(&major, &minor, git_tag); + bool has_repeat = ((major * 10000) + minor) >= 8 ? true : false; + + if(!m_iioCtx) + return result; // Check if the context is valid + if(iio_context_get_devices_count(m_iioCtx) < 1) + return result; // Check if there are devices in the context + struct iio_device *device = iio_context_find_device(m_iioCtx, deviceName); // Find the ADMT device + + if(device == NULL) + return result; + + QVector channels; + QVector scales; + QVector offsets; + + for(int i = 0; i < channelNames.size(); i++) { + struct iio_channel *channel = + iio_device_find_channel(device, channelNames.at(i).toLocal8Bit().data(), isOutput); + if(channel == NULL) + break; + iio_channel_enable(channel); + channels.append(channel); + } + + if(channels.size() == 0 && channels.size() != channelNames.size()) + return result; + + double *scaleAttrValue = new double(); + for(int i = 0; i < channels.size(); i++) { + int scaleRet = iio_channel_attr_read_double(const_cast(channels[i]), scaleAttrName, + scaleAttrValue); // Read the scale attribute + if(scaleRet != 0) + break; + scales.insert(i, *scaleAttrValue); + } + + delete scaleAttrValue; + + for(int i = 0; i < channels.size(); i++) { + char *offsetDst = new char[maxAttrSize]; + iio_channel_attr_read(const_cast(channels[i]), offsetAttrName, offsetDst, + maxAttrSize); // Read the offset attribute + int offsetAttrValue = atoi(offsetDst); + delete[] offsetDst; + offsets.insert(i, offsetAttrValue); + } + + struct iio_buffer *buffer = iio_device_create_buffer(device, samples, isCyclic); // Create a buffer + + QMap streamDataMap; + while(!stopStream.loadAcquire()) { + for(int i = 0; i < channels.size(); i++) { + values.clear(); + + ssize_t numBytesRead; + char *pointerData, *pointerEnd; + ptrdiff_t pointerIncrement; + + numBytesRead = iio_buffer_refill(buffer); + if(numBytesRead < 0) + break; + + pointerIncrement = iio_buffer_step(buffer); + pointerEnd = static_cast(iio_buffer_end(buffer)); + + const struct iio_data_format *format = + iio_channel_get_data_format(const_cast(channels[i])); + unsigned int repeat = has_repeat ? format->repeat : 1; + + for(pointerData = static_cast( + iio_buffer_first(buffer, const_cast(channels[i]))); + pointerData < pointerEnd; pointerData += pointerIncrement) { + for(int j = 0; j < repeat; j++) { + if(format->bits <= 8) { + int8_t rawValue = (reinterpret_cast(pointerData))[j]; + values.push_back((rawValue - offsets.at(i)) * scales.at(i)); + } else if(format->length / 8 == sizeof(int16_t)) { + int16_t rawValue = (reinterpret_cast(pointerData))[j]; + values.push_back((rawValue - offsets.at(i)) * scales.at(i)); + } + } + } + + streamDataMap[channelNames.at(i)] = values[bufferSize - 1]; + } + + Q_EMIT streamChannelData(streamDataMap); + } + + iio_buffer_destroy(buffer); + + for(int i = 0; i < channels.size(); i++) { + iio_channel_disable(const_cast(channels[i])); + } + + return 0; +} + void ADMTController::handleStreamData(double value) { streamedValue = value; } -void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) +void ADMTController::handleStreamChannelData(QMap dataMap) { streamedChannelDataMap = dataMap; } + +void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate, int bufferSize) { - QVector bufferedValues; - vector rawBufferedValues; + vector values; sampleCount = 0; int result = -1; const char *deviceName = "admt4000"; - const char *channelName = "rot"; + const char *channelName = "angl"; const char *scaleAttrName = "scale"; const char *offsetAttrName = "offset"; - size_t samples = 1; + size_t samples = bufferSize; bool isOutput = false; bool isCyclic = true; @@ -1784,8 +1900,9 @@ void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) offsetAttrValue = atoi(offsetDst); struct iio_buffer *buffer = iio_device_create_buffer(admtDevice, samples, isCyclic); // Create a buffer - while(!stopStream && sampleCount < totalSamples) { + while(!stopStream.loadAcquire() && sampleCount < totalSamples) { elapsedStreamTimer.start(); + values.clear(); ssize_t numBytesRead; char *pointerData, *pointerEnd; @@ -1806,26 +1923,23 @@ void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) pointerData += pointerIncrement) { for(j = 0; j < repeat; j++) { if(format->length / 8 == sizeof(int16_t)) { - rawBufferedValues.push_back((reinterpret_cast(pointerData))[j]); - sampleCount++; - continue; + int16_t rawValue = (reinterpret_cast(pointerData))[j]; + values.push_back((rawValue - offsetAttrValue) * *scaleAttrValue); } } } + double value = values[bufferSize - 1]; + Q_EMIT streamData(value); + sampleCount++; + qint64 elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); while(elapsedNanoseconds < targetSampleRate) { elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); } } iio_buffer_destroy(buffer); - - for(int i = 0; i < rawBufferedValues.size(); i++) { - double scaledValue = (rawBufferedValues[i] - offsetAttrValue) * *scaleAttrValue; - bufferedValues.append(scaledValue); - } - - Q_EMIT streamBufferedData(bufferedValues); + iio_channel_disable(channel); delete scaleAttrValue; delete[] offsetDst; @@ -1833,13 +1947,12 @@ void ADMTController::bufferedStreamIO(int totalSamples, int targetSampleRate) void ADMTController::registryStream(int totalSamples, int targetSampleRate) { - QVector values; sampleCount = 0; double angle = 0; bool readSuccess = false; uint32_t *registerValue = new uint32_t; - while(!stopStream && sampleCount < totalSamples) { + while(!stopStream.loadAcquire() && sampleCount < totalSamples) { elapsedStreamTimer.start(); qint64 elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); @@ -1852,9 +1965,10 @@ void ADMTController::registryStream(int totalSamples, int targetSampleRate) angle = getAngle(static_cast(*registerValue)); - values.append(angle); sampleCount++; + Q_EMIT streamData(angle); + elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); while(elapsedNanoseconds < targetSampleRate) { elapsedNanoseconds = elapsedStreamTimer.nsecsElapsed(); @@ -1862,8 +1976,6 @@ void ADMTController::registryStream(int totalSamples, int targetSampleRate) } delete registerValue; - - Q_EMIT streamBufferedData(values); } void ADMTController::handleStreamBufferedData(const QVector &value) { streamBufferedValues = value; } diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index fd30087f7a..347361a8cf 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -37,14 +37,15 @@ static int utilityUITimerRate = 1000; static int deviceStatusMonitorRate = 500; static int motorPositionMonitorRate = 500; static int readMotorDebounce = 50; +static int readDeviceDebounce = 20; // In nanoseconds static int continuousCalibrationSampleRate = 10000000; -static int bufferSize = 1; +static int bufferSize = 5; static int cycleCount = 11; -static int samplesPerCycle = 24; -static int totalSamplesCount = 256; +static int samplesPerCycle = 47; +static int totalSamplesCount = 512; static bool isStartMotor = false; static bool isPostCalibration = false; static bool isCalculatedCoeff = false; @@ -53,7 +54,7 @@ static bool resetToZero = true; static bool hasMTDiagnostics = false; static bool isMotorRotationClockwise = true; -static double default_motor_rpm = 30; +static double default_motor_rpm = 60; static double fast_motor_rpm = 300; static double motorFullStepAngle = 0.9; // TODO input as configuration static double microStepResolution = 256; // TODO input as configuration @@ -221,6 +222,10 @@ HarmonicCalibration::HarmonicCalibration(ADMTController *m_admtController, bool connect(this, &HarmonicCalibration::DIAG1RegisterChanged, this, &HarmonicCalibration::updateMTDiagnosticRegisterUI); connect(this, &HarmonicCalibration::DIAG2RegisterChanged, this, &HarmonicCalibration::updateMTDiagnosticsUI); + qRegisterMetaType>("QMap"); + connect(m_admtController, &ADMTController::streamChannelData, this, + &HarmonicCalibration::handleStreamChannelData); + connect(m_admtController, &ADMTController::streamData, this, &HarmonicCalibration::handleStreamCalibrationData); isAcquisitionTab = true; startDeviceStatusMonitor(); @@ -1463,9 +1468,6 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() toggleTabSwitching(true); if(isPostCalibration) { - graphPostDataList = m_admtController->streamBufferedValues; - postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); - postCalibrationRawDataPlotWidget->replot(); if(static_cast(graphPostDataList.size()) == totalSamplesCount) { computeSineCosineOfAngles(graphPostDataList); m_admtController->postcalibrate( @@ -1478,9 +1480,6 @@ ToolTemplate *HarmonicCalibration::createCalibrationWidget() toggleCalibrationButtonState(4); } } else { - graphDataList = m_admtController->streamBufferedValues; - calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); - calibrationRawDataPlotWidget->replot(); if(static_cast(graphDataList.size()) >= totalSamplesCount) { computeSineCosineOfAngles(graphDataList); calibrationLogWrite(m_admtController->calibrate( @@ -2688,7 +2687,7 @@ bool HarmonicCalibration::updateChannelValues() if(readMode == 0) { updateChannelValue(0); updateChannelValue(1); - updateChannelValue(2); + // updateChannelValue(2); updateChannelValue(3); } else if(readMode == 1) { if(conversionMode == 1) @@ -2844,6 +2843,10 @@ void HarmonicCalibration::startAcquisition() convertRestart(); + stopDeviceStatusMonitor(); + + m_admtController->stopStream.storeRelease(false); + m_acquisitionDataThread = QtConcurrent::run(this, &HarmonicCalibration::getAcquisitionSamples, acquisitionDataMap); m_acquisitionDataWatcher.setFuture(m_acquisitionDataThread); @@ -2852,6 +2855,7 @@ void HarmonicCalibration::startAcquisition() void HarmonicCalibration::stopAcquisition() { isStartAcquisition = false; + m_admtController->stopStream.storeRelease(true); if(m_acquisitionDataThread.isRunning()) { m_acquisitionDataThread.cancel(); m_acquisitionDataWatcher.waitForFinished(); @@ -2892,66 +2896,121 @@ void HarmonicCalibration::updateAcquisitionMotorRotationDirection() void HarmonicCalibration::getAcquisitionSamples(QMap dataMap) { - QMap sensorDataMap; - bool dataChanged = false; - while(isStartAcquisition) { - if(updateChannelValues()) { - dataChanged = false; - - if(dataMap.value(ANGLE)) { - sensorDataMap[ANGLE] = angle; - dataChanged = true; - } - if(dataMap.value(ABSANGLE)) { - sensorDataMap[ABSANGLE] = rotation; - dataChanged = true; - } - if(dataMap.value(TMP0)) { - sensorDataMap[TMP0] = temp; - dataChanged = true; - } - if(dataMap.value(SINE)) { - sensorDataMap[SINE] = - getSensorDataAcquisitionValue(ADMTController::SensorRegister::SINE); - dataChanged = true; - } - if(dataMap.value(COSINE)) { - sensorDataMap[COSINE] = - getSensorDataAcquisitionValue(ADMTController::SensorRegister::COSINE); - dataChanged = true; - } - if(dataMap.value(RADIUS)) { - sensorDataMap[RADIUS] = - getSensorDataAcquisitionValue(ADMTController::SensorRegister::RADIUS); - dataChanged = true; - } - if(dataMap.value(ANGLESEC)) { - sensorDataMap[ANGLESEC] = - getSensorDataAcquisitionValue(ADMTController::SensorRegister::ANGLESEC); - dataChanged = true; - } - if(dataMap.value(SECANGLI)) { - sensorDataMap[SECANGLI] = - getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLI); - dataChanged = true; - } - if(dataMap.value(SECANGLQ)) { - sensorDataMap[SECANGLQ] = - getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLQ); - dataChanged = true; - } - if(dataMap.value(TMP1)) { - sensorDataMap[TMP1] = - getSensorDataAcquisitionValue(ADMTController::SensorRegister::TMP1); - dataChanged = true; + if(readMode == 0) { + QVector channelNames = {"rot", "angl", "count", "temp"}; + + m_admtController->streamChannel(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), + channelNames, bufferSize); + } else if(readMode == 1) { + QMap sensorDataMap; + while(isStartAcquisition) { + if(updateChannelValues()) { + + if(acquisitionDataMap.value(ANGLE)) { + sensorDataMap[ANGLE] = angle; + } + if(acquisitionDataMap.value(ABSANGLE)) { + sensorDataMap[ABSANGLE] = rotation; + } + if(acquisitionDataMap.value(TMP0)) { + sensorDataMap[TMP0] = temp; + } + if(acquisitionDataMap.value(SINE)) { + sensorDataMap[SINE] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::SINE); + } + if(acquisitionDataMap.value(COSINE)) { + sensorDataMap[COSINE] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::COSINE); + } + if(acquisitionDataMap.value(RADIUS)) { + sensorDataMap[RADIUS] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::RADIUS); + } + if(acquisitionDataMap.value(ANGLESEC)) { + sensorDataMap[ANGLESEC] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::ANGLESEC); + } + if(acquisitionDataMap.value(SECANGLI)) { + sensorDataMap[SECANGLI] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLI); + } + if(acquisitionDataMap.value(SECANGLQ)) { + sensorDataMap[SECANGLQ] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLQ); + } + if(acquisitionDataMap.value(TMP1)) { + sensorDataMap[TMP1] = + getSensorDataAcquisitionValue(ADMTController::SensorRegister::TMP1); + } + + if(sensorDataMap.count() > 0) + Q_EMIT acquisitionDataChanged(sensorDataMap); } - if(dataChanged) - Q_EMIT acquisitionDataChanged(sensorDataMap); + QThread::msleep(readDeviceDebounce); } } } +void HarmonicCalibration::handleStreamChannelData(QMap dataMap) +{ + if(dataMap.contains("angl")) + angle = dataMap.value("angl"); + if(dataMap.contains("rot") && dataMap.contains("count")) { + double tempCount = dataMap.value("count"); + count = tempCount; + double tempRotation = dataMap.value("rot"); + rotation = calculateABSAngle(tempRotation, tempCount); + } + if(dataMap.contains("temp")) + temp = dataMap.value("temp"); + + QMap sensorDataMap; + + if(acquisitionDataMap.value(ANGLE)) { + sensorDataMap[ANGLE] = angle; + } + if(acquisitionDataMap.value(ABSANGLE)) { + sensorDataMap[ABSANGLE] = rotation; + } + if(acquisitionDataMap.value(TMP0)) { + sensorDataMap[TMP0] = temp; + } + if(acquisitionDataMap.value(SINE)) { + sensorDataMap[SINE] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::SINE); + } + if(acquisitionDataMap.value(COSINE)) { + sensorDataMap[COSINE] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::COSINE); + } + if(acquisitionDataMap.value(RADIUS)) { + sensorDataMap[RADIUS] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::RADIUS); + } + if(acquisitionDataMap.value(ANGLESEC)) { + sensorDataMap[ANGLESEC] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::ANGLESEC); + } + if(acquisitionDataMap.value(SECANGLI)) { + sensorDataMap[SECANGLI] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLI); + } + if(acquisitionDataMap.value(SECANGLQ)) { + sensorDataMap[SECANGLQ] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::SECANGLQ); + } + if(acquisitionDataMap.value(TMP1)) { + sensorDataMap[TMP1] = getSensorDataAcquisitionValue(ADMTController::SensorRegister::TMP1); + } + + if(sensorDataMap.count() > 0) + Q_EMIT acquisitionDataChanged(sensorDataMap); +} + +double HarmonicCalibration::calculateABSAngle(double &absAngle, double &turnCount) +{ + if(turnCount != 0) + return absAngle + (turnCount * 360); + else + return absAngle; +} + double HarmonicCalibration::getSensorDataAcquisitionValue(const ADMTController::SensorRegister &key) { uint32_t *readValue = new uint32_t; @@ -3019,7 +3078,7 @@ void HarmonicCalibration::plotAcquisition(QVector list, PlotChannel *cha acquisitionGraphYMax = *result.second; } -void HarmonicCalibration::appendAcquisitionData(const double &data, QVector &list) +void HarmonicCalibration::appendAcquisitionData(double data, QVector &list) { if(data == qQNaN()) return; @@ -3162,20 +3221,43 @@ void HarmonicCalibration::toggleAcquisitionControls(bool value) eighthHarmonicMenuCombo->setEnabled(value); applySequenceButton->setEnabled(value); displayLengthLineEdit->setEnabled(value); + + if(sequenceMode == 0) // Sequence Mode 1 + { + angleCheckBox->setEnabled(value); + sineCheckBox->setEnabled(value); + cosineCheckBox->setEnabled(value); + radiusCheckBox->setEnabled(value); + absAngleCheckBox->setEnabled(value); + temp0CheckBox->setEnabled(value); + } else if(sequenceMode == 1) // Sequence Mode 2 + { + angleCheckBox->setEnabled(value); + sineCheckBox->setEnabled(value); + cosineCheckBox->setEnabled(value); + angleSecCheckBox->setEnabled(value); + secAnglQCheckBox->setEnabled(value); + secAnglICheckBox->setEnabled(value); + radiusCheckBox->setEnabled(value); + absAngleCheckBox->setEnabled(value); + temp0CheckBox->setEnabled(value); + temp1CheckBox->setEnabled(value); + } } void HarmonicCalibration::connectCheckBoxToAcquisitionGraph(QCheckBox *widget, PlotChannel *channel, SensorData key) { connect(widget, &QCheckBox::stateChanged, this, [this, channel, key](int state) { + bool value = true; if(state == Qt::Checked) { - channel->setEnabled(true); - acquisitionDataMap[key] = true; + value = true; } else { - channel->setEnabled(false); - acquisitionDataMap[key] = false; + value = false; } - - restartAcquisition(); + channel->setEnabled(value); + acquisitionDataMap[key] = value; + if(!value) + acquisitionGraphPlotWidget->replot(); }); } @@ -3242,6 +3324,7 @@ void HarmonicCalibration::run(bool b) if(!b) { isStartAcquisition = false; runButton->setChecked(false); + stopAcquisition(); } else { startAcquisition(); } @@ -3437,23 +3520,43 @@ void HarmonicCalibration::resetMotorToZero() } } +void HarmonicCalibration::handleStreamCalibrationData(double value) +{ + if(isPostCalibration) { + graphPostDataList.append(value); + postCalibrationRawDataPlotChannel->curve()->setSamples(graphPostDataList); + postCalibrationRawDataPlotWidget->replot(); + } else { + graphDataList.append(value); + calibrationRawDataPlotChannel->curve()->setSamples(graphDataList); + calibrationRawDataPlotWidget->replot(); + } +} + void HarmonicCalibration::startCalibrationStreamThread() { if(!m_calibrationStreamThread.isRunning()) { - m_admtController->stopStream = false; + m_admtController->stopStream.storeRelease(false); continuousCalibrationSampleRate = calculateContinuousCalibrationSampleRate(convertVMAXtoRPS(rotate_vmax), samplesPerCycle); - m_calibrationStreamThread = QtConcurrent::run([this]() { - m_admtController->registryStream(totalSamplesCount, continuousCalibrationSampleRate); - }); + if(readMode == 0) { + m_calibrationStreamThread = QtConcurrent::run([this]() { + m_admtController->bufferedStreamIO(totalSamplesCount, continuousCalibrationSampleRate, + bufferSize); + }); + } else if(readMode == 1) { + m_calibrationStreamThread = QtConcurrent::run([this]() { + m_admtController->registryStream(totalSamplesCount, continuousCalibrationSampleRate); + }); + } m_calibrationStreamWatcher.setFuture(m_calibrationStreamThread); } } void HarmonicCalibration::stopCalibrationStreamThread() { - m_admtController->stopStream = true; + m_admtController->stopStream.storeRelease(true); if(m_calibrationStreamThread.isRunning()) { m_calibrationStreamThread.cancel(); m_calibrationStreamWatcher.waitForFinished(); @@ -4974,29 +5077,44 @@ bool HarmonicCalibration::updateChannelValue(int channelIndex) bool success = false; switch(channelIndex) { case ADMTController::Channel::ROTATION: - rotation = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, 1); + double tempRotation; + count = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, bufferSize); + if(count == UINT32_MAX) { + success = false; + break; + } + tempRotation = m_admtController->getChannelValue( + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, + bufferSize); if(rotation == UINT32_MAX) { success = false; + break; } + + if(count != 0) + rotation = tempRotation + (count * 360); + else + rotation = tempRotation; break; case ADMTController::Channel::ANGL: angle = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, 1); + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), angleChannelName, bufferSize); if(angle == UINT32_MAX) { success = false; } break; case ADMTController::Channel::COUNT: count = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, 1); + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, bufferSize); if(count == UINT32_MAX) { success = false; } break; case ADMTController::Channel::TEMPERATURE: temp = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, 1); + m_admtController->getDeviceId(ADMTController::Device::ADMT4000), temperatureChannelName, + bufferSize); if(temp == UINT32_MAX) { success = false; } diff --git a/plugins/admt/style/qss/properties/admt/coloredCheckBox.qss b/plugins/admt/style/qss/properties/admt/coloredCheckBox.qss index fac9efba6e..489ed17f3d 100644 --- a/plugins/admt/style/qss/properties/admt/coloredCheckBox.qss +++ b/plugins/admt/style/qss/properties/admt/coloredCheckBox.qss @@ -1,31 +1,103 @@ +QCheckBox[&&property&&="ch0"]::disabled { + color: &interactive_subtle_idle&; +} + +QCheckBox[&&property&&="ch1"]::disabled { + color: &interactive_subtle_idle&; +} + +QCheckBox[&&property&&="ch2"]::disabled { + color: &interactive_subtle_idle&; +} + +QCheckBox[&&property&&="ch3"]::disabled { + color: &interactive_subtle_idle&; +} + +QCheckBox[&&property&&="ch4"]::disabled { + color: &interactive_subtle_idle&; +} + +QCheckBox[&&property&&="ch5"]::disabled { + color: &interactive_subtle_idle&; +} + +QCheckBox[&&property&&="ch6"]::disabled { + color: &interactive_subtle_idle&; +} + +QCheckBox[&&property&&="ch7"]::disabled { + color: &interactive_subtle_idle&; +} + QCheckBox::indicator[&&property&&="ch0"]::checked { background-color: &ch0&; } +QCheckBox::indicator[&&property&&="ch0"]::checked::disabled { + border: &border_width_interactive& solid &interactive_subtle_idle&; + background-color: &ch0&; +} + QCheckBox::indicator[&&property&&="ch1"]::checked { background-color: &ch1&; } +QCheckBox::indicator[&&property&&="ch1"]::checked::disabled { + border: &border_width_interactive& solid &interactive_subtle_idle&; + background-color: &ch1&; +} + QCheckBox::indicator[&&property&&="ch2"]::checked { background-color: &ch2&; } +QCheckBox::indicator[&&property&&="ch2"]::checked::disabled { + border: &border_width_interactive& solid &interactive_subtle_idle&; + background-color: &ch2&; +} + QCheckBox::indicator[&&property&&="ch3"]::checked { background-color: &ch3&; } +QCheckBox::indicator[&&property&&="ch3"]::checked::disabled { + border: &border_width_interactive& solid &interactive_subtle_idle&; + background-color: &ch3&; +} + QCheckBox::indicator[&&property&&="ch4"]::checked { background-color: &ch4&; } +QCheckBox::indicator[&&property&&="ch4"]::checked::disabled { + border: &border_width_interactive& solid &interactive_subtle_idle&; + background-color: &ch4&; +} + QCheckBox::indicator[&&property&&="ch5"]::checked { background-color: &ch5&; } +QCheckBox::indicator[&&property&&="ch5"]::checked::disabled { + border: &border_width_interactive& solid &interactive_subtle_idle&; + background-color: &ch5&; +} + QCheckBox::indicator[&&property&&="ch6"]::checked { background-color: &ch6&; } +QCheckBox::indicator[&&property&&="ch6"]::checked::disabled { + border: &border_width_interactive& solid &interactive_subtle_idle&; + background-color: &ch6&; +} + QCheckBox::indicator[&&property&&="ch7"]::checked { background-color: &ch7&; -} \ No newline at end of file +} + +QCheckBox::indicator[&&property&&="ch7"]::checked::disabled { + border: &border_width_interactive& solid &interactive_subtle_idle&; + background-color: &ch7&; +} From 63eb05a36924c318969ec477c890b9793d3dd1a7 Mon Sep 17 00:00:00 2001 From: JJuanill Date: Tue, 29 Apr 2025 11:57:36 +0800 Subject: [PATCH 112/112] admt: Added mixed read mode - Changed fast motor RPM to 200 Signed-off-by: JJuanill --- plugins/admt/include/admt/admtcontroller.h | 3 +- .../admt/include/admt/harmoniccalibration.h | 2 + plugins/admt/src/admtcontroller.cpp | 114 ++++++++++++----- plugins/admt/src/harmoniccalibration.cpp | 115 ++++++++++-------- 4 files changed, 153 insertions(+), 81 deletions(-) diff --git a/plugins/admt/include/admt/admtcontroller.h b/plugins/admt/include/admt/admtcontroller.h index 50c346ffbe..2c5fe94b0a 100644 --- a/plugins/admt/include/admt/admtcontroller.h +++ b/plugins/admt/include/admt/admtcontroller.h @@ -226,6 +226,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject QString calibrate(vector PANG, int cycles, int samplesPerCycle, bool CCW); int writeDeviceRegistry(const char *deviceName, uint32_t address, uint32_t value); int readDeviceRegistry(const char *deviceName, uint32_t address, uint32_t *returnValue); + int readDeviceRegistry(const char *deviceName, uint32_t address, uint8_t page, uint32_t *returnValue); void computeSineCosineOfAngles(const vector &angles); uint16_t calculateHarmonicCoefficientMagnitude(uint16_t harmonicCoefficient, uint16_t originalValue, const string &key); @@ -262,7 +263,7 @@ class SCOPY_ADMT_EXPORT ADMTController : public QObject bool checkVelocityReachedFlag(uint16_t registerValue); uint16_t changeCNVPage(uint16_t registerValue, uint8_t page); uint16_t convertStart(bool start, uint16_t registerValue); - int streamChannel(const char *deviceName, const QVector channelNames, int bufferSize); + int streamChannel(const char *deviceName, const QVector channelNames, int bufferSize, int sampleRate); public Q_SLOTS: void handleStreamData(double value); void handleStreamChannelData(QMap dataMap); diff --git a/plugins/admt/include/admt/harmoniccalibration.h b/plugins/admt/include/admt/harmoniccalibration.h index a6389659af..1d2f69036e 100644 --- a/plugins/admt/include/admt/harmoniccalibration.h +++ b/plugins/admt/include/admt/harmoniccalibration.h @@ -293,6 +293,8 @@ public Q_SLOTS: void updateAcquisitionMotorRotationDirection(); void getAcquisitionSamples(QMap dataMap); double calculateABSAngle(double &absAngle, double &turnCount); + double getTurnCount(double rawAbsAngleValue); + double getABSAngle(double rawAbsAngleValue); double getSensorDataAcquisitionValue(const ADMTController::SensorRegister &key); void plotAcquisition(QVector list, PlotChannel *channel); void appendAcquisitionData(double data, QVector &list); diff --git a/plugins/admt/src/admtcontroller.cpp b/plugins/admt/src/admtcontroller.cpp index c63e5c5825..b4faf440fa 100644 --- a/plugins/admt/src/admtcontroller.cpp +++ b/plugins/admt/src/admtcontroller.cpp @@ -200,7 +200,7 @@ int ADMTController::getChannelIndex(const char *deviceName, const char *channelN double ADMTController::getChannelValue(const char *deviceName, const char *channelName, int bufferSize) { - double value; + double value = UINT32_MAX; const char *scaleAttrName = "scale"; const char *offsetAttrName = "offset"; size_t samples = bufferSize; @@ -218,10 +218,10 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann return UINT32_MAX; if(iio_context_get_devices_count(m_iioCtx) < 1) return UINT32_MAX; - struct iio_device *admtDevice = iio_context_find_device(m_iioCtx, deviceName); - if(admtDevice == NULL) + struct iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) return UINT32_MAX; - struct iio_channel *channel = iio_device_find_channel(admtDevice, channelName, isOutput); + struct iio_channel *channel = iio_device_find_channel(iioDevice, channelName, isOutput); if(channel == NULL) return UINT32_MAX; iio_channel_enable(channel); @@ -238,33 +238,37 @@ double ADMTController::getChannelValue(const char *deviceName, const char *chann offsetAttrValue = atoi(offsetDst); delete[] offsetDst; - struct iio_buffer *buffer = iio_device_create_buffer(admtDevice, samples, isCyclic); // Create a buffer + struct iio_buffer *buffer = iio_device_create_buffer(iioDevice, samples, isCyclic); // Create a buffer ssize_t numBytesRead; char *pointerData, *pointerEnd; ptrdiff_t pointerIncrement; numBytesRead = iio_buffer_refill(buffer); - pointerIncrement = iio_buffer_step(buffer); - pointerEnd = static_cast(iio_buffer_end(buffer)); - - const struct iio_data_format *format = iio_channel_get_data_format(channel); - unsigned int repeat = has_repeat ? format->repeat : 1; - - for(pointerData = static_cast(iio_buffer_first(buffer, channel)); pointerData < pointerEnd; - pointerData += pointerIncrement) { - for(int j = 0; j < repeat; j++) { - if(format->bits <= 8) { - int8_t rawValue = (reinterpret_cast(pointerData))[j]; - values.push_back((rawValue - offsetAttrValue) * *scaleAttrValue); - } else if(format->length / 8 == sizeof(int16_t)) { - int16_t rawValue = (reinterpret_cast(pointerData))[j]; - values.push_back((rawValue - offsetAttrValue) * *scaleAttrValue); + if(numBytesRead >= 0) { + pointerIncrement = iio_buffer_step(buffer); + pointerEnd = static_cast(iio_buffer_end(buffer)); + + const struct iio_data_format *format = iio_channel_get_data_format(channel); + unsigned int repeat = has_repeat ? format->repeat : 1; + + for(pointerData = static_cast(iio_buffer_first(buffer, channel)); pointerData < pointerEnd; + pointerData += pointerIncrement) { + for(int j = 0; j < repeat; j++) { + if(format->bits <= 8) { + int8_t rawValue = (reinterpret_cast(pointerData))[j]; + values.push_back((rawValue - offsetAttrValue) * *scaleAttrValue); + } else if(format->is_fully_defined) { + values.push_back((reinterpret_cast(pointerData))[j]); + } else if(format->length / 8 == sizeof(int16_t)) { + int16_t rawValue = (reinterpret_cast(pointerData))[j]; + values.push_back((rawValue - offsetAttrValue) * *scaleAttrValue); + } } } - } - value = values[bufferSize - 1]; + value = values[bufferSize - 1]; + } delete scaleAttrValue; iio_buffer_destroy(buffer); @@ -398,6 +402,43 @@ int ADMTController::readDeviceRegistry(const char *deviceName, uint32_t address, return result; } +int ADMTController::readDeviceRegistry(const char *deviceName, uint32_t address, uint8_t page, uint32_t *returnValue) +{ + if(!m_iioCtx) + return -1; + if(address == UINT32_MAX) + return -1; + + int result = -1; + int deviceCount = iio_context_get_devices_count(m_iioCtx); + if(deviceCount == 0) { + return result; + } + iio_device *iioDevice = iio_context_find_device(m_iioCtx, deviceName); + if(iioDevice == NULL) { + return result; + } + + if(page != UINT8_MAX) { + uint32_t *readCNVValue = new uint32_t; + + if(iio_device_reg_read(iioDevice, getConfigurationRegister(ConfigurationRegister::CNVPAGE), + readCNVValue) == 0) { + iio_device_reg_write(iioDevice, getConfigurationRegister(ConfigurationRegister::CNVPAGE), + changeCNVPage(static_cast(*readCNVValue), page)); + } else { + delete readCNVValue; + return -1; + } + + delete readCNVValue; + } + + result = iio_device_reg_read(iioDevice, address, returnValue); + + return result; +} + /* bit reversal from online example */ unsigned int ADMTController::bitReverse(unsigned int x, int log2n) { @@ -1175,19 +1216,21 @@ uint16_t ADMTController::setGeneralRegisterBitMapping(uint16_t currentRegisterVa int ADMTController::getAbsAngleTurnCount(uint16_t registerValue) { - // Bits 15:8: Turn count in quarter turns - uint8_t turnCount = (registerValue >> 8) & 0xFC; + // Bits 15:10: Number of whole turns + int8_t turnCount = registerValue >> 10; - if(turnCount <= 0xD4) { + if(turnCount <= 0x35) { // Straight binary turn count - return turnCount / 4; // Convert from quarter turns to whole turns - } else if(turnCount == 0xD8) { + return turnCount; // Convert from quarter turns to whole turns + } else if(turnCount == 0x36) { // Invalid turn count - return turnCount / 4; + return turnCount; } else { // 2's complement turn count - int8_t signedTurnCount = static_cast(turnCount); // Handle as signed value - return signedTurnCount / 4; // Convert from quarter turns to whole turns + if(turnCount & (1 << 5)) { + turnCount -= 64; + } + return turnCount; } } @@ -1740,14 +1783,15 @@ int ADMTController::streamIO() return 0; } -int ADMTController::streamChannel(const char *deviceName, const QVector channelNames, int bufferSize) +int ADMTController::streamChannel(const char *deviceName, const QVector channelNames, int bufferSize, + int sampleRate) { int result = -1; const char *scaleAttrName = "scale"; const char *offsetAttrName = "offset"; size_t samples = bufferSize; vector values; - bool isOutput = false, isCyclic = true; + bool isOutput = false, isCyclic = false; unsigned int i, j, major, minor; char git_tag[8]; @@ -1803,6 +1847,7 @@ int ADMTController::streamChannel(const char *deviceName, const QVector QMap streamDataMap; while(!stopStream.loadAcquire()) { + elapsedStreamTimer.start(); for(int i = 0; i < channels.size(); i++) { values.clear(); @@ -1839,6 +1884,11 @@ int ADMTController::streamChannel(const char *deviceName, const QVector } Q_EMIT streamChannelData(streamDataMap); + + qint64 elapsed = elapsedStreamTimer.elapsed(); + while(elapsed < sampleRate) { + elapsed = elapsedStreamTimer.elapsed(); + } } iio_buffer_destroy(buffer); diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp index 347361a8cf..1b8e6a075f 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -37,7 +37,7 @@ static int utilityUITimerRate = 1000; static int deviceStatusMonitorRate = 500; static int motorPositionMonitorRate = 500; static int readMotorDebounce = 50; -static int readDeviceDebounce = 20; +static int readDeviceDebounce = 60; // In nanoseconds static int continuousCalibrationSampleRate = 10000000; @@ -55,7 +55,7 @@ static bool hasMTDiagnostics = false; static bool isMotorRotationClockwise = true; static double default_motor_rpm = 60; -static double fast_motor_rpm = 300; +static double fast_motor_rpm = 200; static double motorFullStepAngle = 0.9; // TODO input as configuration static double microStepResolution = 256; // TODO input as configuration static int motorfCLK = 12500000; // 12.5 Mhz, TODO input as configuration @@ -118,7 +118,7 @@ static double currentPhaseGraphMax = defaultPhaseGraphMax; static int sequenceMode = 0; // 0: Sequence Mode 1, 1: Sequence Mode 2 static int conversionMode = 0; // 0: One-shot Conversion, 1: Continuous Conversion -static int readMode = 1; // 0: Channel Read, 1: Register Read +static int readMode = 2; // 0: Channel Read, 1: Register Read, 2: Mixed QMap acquisitionDataMap = { {ABSANGLE, false}, {ANGLE, false}, {ANGLESEC, false}, {SINE, false}, {COSINE, false}, @@ -414,7 +414,7 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() new PlotChannel("SECANGLQ", channel7Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); acquisitionSecAnglIPlotChannel = new PlotChannel("SECANGLI", channel0Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); - acquisitionTmp1PlotChannel = new PlotChannel("TMP 1", channel4Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); + acquisitionTmp1PlotChannel = new PlotChannel("TMP 1", channel1Pen, acquisitionXPlotAxis, acquisitionYPlotAxis); acquisitionGraphPlotWidget->addPlotChannel(acquisitionAnglePlotChannel); acquisitionGraphPlotWidget->addPlotChannel(acquisitionABSAnglePlotChannel); @@ -610,7 +610,15 @@ ToolTemplate *HarmonicCalibration::createAcquisitionWidget() applySequenceButton = new QPushButton("Apply", sequenceSection); StyleHelper::BasicButton(applySequenceButton); - connect(applySequenceButton, &QPushButton::clicked, this, &HarmonicCalibration::applySequenceAndUpdate); + connect(applySequenceButton, &QPushButton::clicked, this, [this]() { + applySequenceAndUpdate(); + toggleWidget(applySequenceButton, false); + applySequenceButton->setText("Writing..."); + QTimer::singleShot(1000, this, [this]() { + this->toggleWidget(applySequenceButton, true); + applySequenceButton->setText("Apply"); + }); + }); sequenceSection->contentLayout()->addWidget(sequenceModeMenuCombo); sequenceSection->contentLayout()->addWidget(conversionModeMenuCombo); @@ -2412,13 +2420,6 @@ bool HarmonicCalibration::writeSequence(QMap settings) void HarmonicCalibration::applySequence() { - toggleWidget(applySequenceButton, false); - applySequenceButton->setText("Writing..."); - QTimer::singleShot(1000, this, [this]() { - this->toggleWidget(applySequenceButton, true); - applySequenceButton->setText("Apply"); - }); - QMap settings; bool success = false; @@ -2684,11 +2685,10 @@ bool HarmonicCalibration::updateChannelValues() { bool success = false; - if(readMode == 0) { - updateChannelValue(0); - updateChannelValue(1); - // updateChannelValue(2); - updateChannelValue(3); + if(readMode == 0 || readMode == 2) { + updateChannelValue(ADMTController::Channel::ROTATION); + updateChannelValue(ADMTController::Channel::ANGL); + updateChannelValue(ADMTController::Channel::TEMPERATURE); } else if(readMode == 1) { if(conversionMode == 1) convertRestart(); @@ -2841,9 +2841,7 @@ void HarmonicCalibration::startAcquisition() isStartAcquisition = true; acquisitionXPlotAxis->setInterval(0, acquisitionDisplayLength); - convertRestart(); - - stopDeviceStatusMonitor(); + applySequenceAndUpdate(); m_admtController->stopStream.storeRelease(false); @@ -2900,8 +2898,8 @@ void HarmonicCalibration::getAcquisitionSamples(QMap dataMap) QVector channelNames = {"rot", "angl", "count", "temp"}; m_admtController->streamChannel(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - channelNames, bufferSize); - } else if(readMode == 1) { + channelNames, bufferSize, readDeviceDebounce); + } else if(readMode == 1 || readMode == 2) { QMap sensorDataMap; while(isStartAcquisition) { if(updateChannelValues()) { @@ -2946,9 +2944,8 @@ void HarmonicCalibration::getAcquisitionSamples(QMap dataMap) if(sensorDataMap.count() > 0) Q_EMIT acquisitionDataChanged(sensorDataMap); - } - - QThread::msleep(readDeviceDebounce); + } else + break; } } } @@ -2958,10 +2955,14 @@ void HarmonicCalibration::handleStreamChannelData(QMap dataMap) if(dataMap.contains("angl")) angle = dataMap.value("angl"); if(dataMap.contains("rot") && dataMap.contains("count")) { - double tempCount = dataMap.value("count"); - count = tempCount; double tempRotation = dataMap.value("rot"); + double tempCount = dataMap.value("count"); rotation = calculateABSAngle(tempRotation, tempCount); + count = tempCount; + } else if(dataMap.contains("rot")) { + count = getTurnCount(dataMap.value("rot")); + double tempRotation = getABSAngle(dataMap.value("rot")); + rotation = calculateABSAngle(tempRotation, count); } if(dataMap.contains("temp")) temp = dataMap.value("temp"); @@ -3011,11 +3012,24 @@ double HarmonicCalibration::calculateABSAngle(double &absAngle, double &turnCoun return absAngle; } +double HarmonicCalibration::getTurnCount(double rawAbsAngleValue) +{ + uint16_t value = static_cast(rawAbsAngleValue); + return m_admtController->getAbsAngleTurnCount(value); +} + +double HarmonicCalibration::getABSAngle(double rawAbsAngleValue) +{ + uint16_t value = static_cast(rawAbsAngleValue); + return m_admtController->getAbsAngle(value); +} + double HarmonicCalibration::getSensorDataAcquisitionValue(const ADMTController::SensorRegister &key) { uint32_t *readValue = new uint32_t; if(m_admtController->readDeviceRegistry(m_admtController->getDeviceId(ADMTController::Device::ADMT4000), - m_admtController->getSensorRegister(key), readValue) == -1) + m_admtController->getSensorRegister(key), + m_admtController->getSensorPage(key), readValue) != 0) return qQNaN(); switch(key) { @@ -3397,10 +3411,16 @@ void HarmonicCalibration::getCalibrationSamples() target_pos = current_pos + step; if(moveMotorToPosition(target_pos, true) == false) m_admtController->disconnectADMT(); - convertStart(true); - if(!updateSensorValue(ADMTController::SensorRegister::ANGLE)) - break; - convertStart(false); + + if(readMode == 0 || readMode == 2) { + if(updateChannelValue(ADMTController::Channel::ANGL)) + break; + } else if(readMode == 1) { + convertStart(true); + if(!updateSensorValue(ADMTController::SensorRegister::ANGLE)) + break; + convertStart(false); + } graphPostDataList.append(angle); currentSamplesCount++; } @@ -3410,10 +3430,16 @@ void HarmonicCalibration::getCalibrationSamples() target_pos = current_pos + step; if(moveMotorToPosition(target_pos, true) == false) m_admtController->disconnectADMT(); - convertStart(true); - if(!updateSensorValue(ADMTController::SensorRegister::ANGLE)) - break; - convertStart(false); + + if(readMode == 0 || readMode == 2) { + if(updateChannelValue(ADMTController::Channel::ANGL)) + break; + } else if(readMode == 1) { + convertStart(true); + if(!updateSensorValue(ADMTController::SensorRegister::ANGLE)) + break; + convertStart(false); + } graphDataList.append(angle); currentSamplesCount++; } @@ -3540,7 +3566,7 @@ void HarmonicCalibration::startCalibrationStreamThread() continuousCalibrationSampleRate = calculateContinuousCalibrationSampleRate(convertVMAXtoRPS(rotate_vmax), samplesPerCycle); - if(readMode == 0) { + if(readMode == 0 || readMode == 2) { m_calibrationStreamThread = QtConcurrent::run([this]() { m_admtController->bufferedStreamIO(totalSamplesCount, continuousCalibrationSampleRate, bufferSize); @@ -5078,24 +5104,17 @@ bool HarmonicCalibration::updateChannelValue(int channelIndex) switch(channelIndex) { case ADMTController::Channel::ROTATION: double tempRotation; - count = m_admtController->getChannelValue( - m_admtController->getDeviceId(ADMTController::Device::ADMT4000), countChannelName, bufferSize); - if(count == UINT32_MAX) { - success = false; - break; - } tempRotation = m_admtController->getChannelValue( m_admtController->getDeviceId(ADMTController::Device::ADMT4000), rotationChannelName, bufferSize); - if(rotation == UINT32_MAX) { + + if(tempRotation == UINT32_MAX) { success = false; break; } - if(count != 0) - rotation = tempRotation + (count * 360); - else - rotation = tempRotation; + rotation = getABSAngle(tempRotation); + count = getTurnCount(tempRotation); break; case ADMTController::Channel::ANGL: angle = m_admtController->getChannelValue(