From 718a4393b33b168a4aa6efb4441ce2c5526ef91e Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 29 May 2024 12:46:27 +0800 Subject: [PATCH 01/93] cmake: added post build to copy .DLLs when debugging or launching scopy Signed-off-by: John Lloyd Juanillo --- CMakeLists.txt | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a743ad4fee..148a8e0af7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,3 +209,33 @@ install(TARGETS ${PROJECT_NAME} BUNDLE DESTINATION .) if(QT_VERSION_MAJOR EQUAL 6) qt_finalize_executable(${PROJECT_NAME}) endif() + +# Helper function to copy DLLs from a given directory +function(copy_dlls_from_dir dir) +file(GLOB DLLS "${dir}/*.dll") +foreach(DLL ${DLLS}) + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${DLL} + $ + ) +endforeach() +endfunction() + +# List of directories containing DLLs +set(DLL_DIRS + "${CMAKE_BINARY_DIR}/common" + "${CMAKE_BINARY_DIR}/core" + "${CMAKE_BINARY_DIR}/gr-util" + "${CMAKE_BINARY_DIR}/gui" + "${CMAKE_BINARY_DIR}/iioutil" + "${CMAKE_BINARY_DIR}/iio-widgets" + "${CMAKE_BINARY_DIR}/pluginbase" + "${CMAKE_BINARY_DIR}/gui/sigrok-gui" + "${CMAKE_BINARY_DIR}/gui/gr-gui" +) + +# Copy DLLs from each directory +foreach(DIR ${DLL_DIRS}) + copy_dlls_from_dir(${DIR}) +endforeach() \ No newline at end of file From a63abe9ffd60a8358f9276a4dbffa3f3fa8a0d7d Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 29 May 2024 14:26:18 +0800 Subject: [PATCH 02/93] tools/plugingenerator: modified CMake list template to output generated library to plugins folder Signed-off-by: John Lloyd Juanillo --- .../plugingenerator/templates/cmakelists_template.mako | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/plugingenerator/templates/cmakelists_template.mako b/tools/plugingenerator/templates/cmakelists_template.mako index b0ab99cbb2..3ae58033cc 100644 --- a/tools/plugingenerator/templates/cmakelists_template.mako +++ b/tools/plugingenerator/templates/cmakelists_template.mako @@ -47,9 +47,13 @@ endif() set(PROJECT_SOURCES ${"${SRC_LIST}"} ${"${HEADER_LIST}"} ${"${UI_LIST}"}) find_package(Qt${"${QT_VERSION_MAJOR}"} COMPONENTS REQUIRED Widgets Core) -if(NOT "${"${SCOPY_PLUGIN_BUILD_PATH}"}" STREQUAL "") - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${"${SCOPY_PLUGIN_BUILD_PATH}"}) -endif() +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}"}) From c6f3b9c78a22de735afb8a377ab987e33b53e926 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 29 May 2024 14:38:40 +0800 Subject: [PATCH 03/93] doc: Included documentation for building Scopy locally on Windows environment Signed-off-by: John Lloyd Juanillo --- .gitignore | 1 + doc/local-windows-build-readme.md | 64 +++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 doc/local-windows-build-readme.md diff --git a/.gitignore b/.gitignore index e0dda138fd..7229d161e2 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ html/ build_arm64-v8a/ doc/* !doc/Doxyfile +!doc/local-windows-build-readme.md .cache/* build/* .vscode/* diff --git a/doc/local-windows-build-readme.md b/doc/local-windows-build-readme.md new file mode 100644 index 0000000000..d8b08378aa --- /dev/null +++ b/doc/local-windows-build-readme.md @@ -0,0 +1,64 @@ +This is a guide for installing the dependencies and setting up the environment for SCOPYv2 development. It is recommended to do these steps on a virtual machine since this has the potential to ruin the configuration of the system. The commands shown in this guide came from the [ci-for-scopy2](https://github.com/analogdevicesinc/scopy-mingw-build-deps/blob/ci-for-scopy2/docker/Dockerfile) dockerfile which can be visited and used as a reference. Most of the content of this guide is tailored fit to be executed using CMD or Windows Command Prompt which explains why there are some commands that are slightly different from the ones in the dockerfile. + +## Build prerequisites +- [Visual Studio Code](https://code.visualstudio.com/download) +- [LibIIO v0.25](https://github.com/analogdevicesinc/libiio/releases/download/v0.25/libiio-0.25.gb6028fd-setup.exe) +- [MSYS2](https://www.msys2.org/) (Use default installation settings. **Do not change the directory locations.** Uncheck Run MSYS2 now after installation.) + +> If running Virtual Machines (e.g. VirtualBox, Hyper-V, VMWare, etc.) Open **Microsoft Store** and search for **OpenCL, OpenGL, and Vulkan Compatibility Pack**. This would install the packages needed in rendering the graphics of the software. Without this, Scopy would just crash. + +## Build instructions +1. Create folder with the following directory *C:\msys64\home\docker* + +2. Make a **backup** of your user PATH variable. + + > To make a backup, open run window using keyboard command **`WIN`**+**`R`** > Type **`SystemPropertiesAdvanced.exe`** and press the **`ENTER`** key > *System Properties* window will appear > Under the *Advanced* tab, click **`Environment Variables...`** > Under *User variables for (your user name)* find and click on *Path* and click **`Edit...`** > Then click **`Edit text...`** > copy and store the variable value in your preferred text editor > Save and close all opened windows. + +3. Execute the following commands using Windows Command prompt *(CMD)* and **not MINGW64**: + + ```sh + cd C:/msys64/home/docker/ + set PATH=%PATH%;C:\msys64\bin;C:\msys64\mingw64\bin;C:\msys64\usr\bin + setx HOME C:\msys64\home\docker + setx CHERE_INVOKING yes + setx MSYSTEM MINGW64 + C:\msys64\usr\bin\bash.exe -lc " " + C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Syyu" + C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Sy msys2-keyring" + C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Su" + C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Syuu" & C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Syuu" & C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Scc " + C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm --needed -Sy git" + C:\msys64\usr\bin\bash.exe -lc "git clone https://github.com/analogdevicesinc/scopy-mingw-build-deps --branch ci-for-scopy2" + ``` +4. Check if **scopy-mingw-build-deps** directory is at *C:\msys64\home\\(your user name)\\*, if it is then move it to *C:\msys64\home\docker\\* + +5. Continue to run commands + ```sh + C:\msys64\usr\bin\bash.exe -lc "cd /home/docker/scopy-mingw-build-deps && ls && echo Building for x86_64 && ./init_staging.sh x86_64 OFF" + C:\msys64\usr\bin\bash.exe -lc "cd /home/docker/scopy-mingw-build-deps && source build.sh && install_tools && install_deps && recurse_submodules" + C:\msys64\home\docker\scopy-mingw-build-deps\is.exe /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART /LOG=C:\msys64\home\docker\iss.log /DIR=C:\innosetup + C:\msys64\usr\bin\bash.exe -lc "cd /home/docker/scopy-mingw-build-deps && source build.sh && build_deps" + ``` + +6. Clone **scopy** using tag **dev** to the directory: *C:\msys64\home\docker* + + ```sh + C:\msys64\usr\bin\bash.exe -lc "git clone https://github.com/analogdevicesinc/scopy/ --branch dev" + ``` + +7. Check if **scopy** directory is at *C:\msys64\home\\(your user name)*, if it is then move it to *C:\msys64\home\docker\\* + +8. Install GDB for build debugging + ```sh + C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -S mingw-w64-x86_64-gdb" + ``` + +9. In VS Code, install [**C/C++ Extension Pack**](vscode:extension/ms-vscode.cpptools-extension-pack) + +10. Open Scopy folder in VS Code + + > When opening Scopy folder for the first time, a popup may appear to ask to trust the authors of the files in this folder. Simply click on **`Yes, I trust the authors`** + +11. In VS Code, go to the toolbar on your left and locate CMake tool. On the **PROJECT OUTLINE** dropdown, click on the icon for *Configure All Projects*. This will instruct CMake to build the scripts necessary in building the source code. + +12. Under the **PROJECT STATUS** dropdown in CMake tool, click on the icon for *Build* to build the project. \ No newline at end of file From 329876096cc60f299b44b9f51b0a5f36a4312f12 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 30 May 2024 10:22:37 +0800 Subject: [PATCH 04/93] admt: Initialized plugin files Signed-off-by: John Lloyd Juanillo --- plugins/CMakeLists.txt | 6 + plugins/admt/.gitignore | 1 + plugins/admt/CMakeLists.txt | 69 +++++++++ plugins/admt/include/admtplugin/admtplugin.h | 31 ++++ .../include/admtplugin/harmoniccalibration.h | 16 +++ plugins/admt/res/resources.qrc | 2 + plugins/admt/src/admtplugin.cpp | 108 ++++++++++++++ plugins/admt/src/harmoniccalibration.cpp | 7 + plugins/admt/test/CMakeLists.txt | 5 + plugins/admt/test/tst_pluginloader.cpp | 132 ++++++++++++++++++ 10 files changed, 377 insertions(+) create mode 100644 plugins/admt/.gitignore create mode 100644 plugins/admt/CMakeLists.txt create mode 100644 plugins/admt/include/admtplugin/admtplugin.h create mode 100644 plugins/admt/include/admtplugin/harmoniccalibration.h create mode 100644 plugins/admt/res/resources.qrc create mode 100644 plugins/admt/src/admtplugin.cpp create mode 100644 plugins/admt/src/harmoniccalibration.cpp create mode 100644 plugins/admt/test/CMakeLists.txt create mode 100644 plugins/admt/test/tst_pluginloader.cpp diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index d3812fdef9..41021ba1f3 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -4,6 +4,7 @@ project(scopy-plugins VERSION 0.1 LANGUAGES CXX) message(STATUS "Plugins folder: " ${SCOPY_PLUGIN_BUILD_PATH}) message(STATUS "Plugins folder after install: " ${SCOPY_PLUGIN_INSTALL_PATH}) +option(ENABLE_PLUGIN_ADMT "Enable ADMT plugin" ON) option(ENABLE_PLUGIN_M2K "Enable m2k plugin" ON) option(ENABLE_PLUGIN_TEST "Enable test plugin" OFF) option(ENABLE_PLUGIN_REGMAP "Enable regmap plugin" ON) @@ -14,6 +15,11 @@ option(ENABLE_PLUGIN_PQM "Enable PQM plugin" ON) option(ENABLE_PLUGIN_DATALOGGER "Enable DATALOGGER plugin" ON) option(ENABLE_PLUGIN_IIODEBUGPLUGIN "Enable IIODEBUGPLUGIN plugin" ON) +if(ENABLE_PLUGIN_ADMT) + add_subdirectory(admt) + list(APPEND PLUGINS ${PLUGIN_NAME}) +endif() + set(PLUGIN_COMPONENTS "") set(PLUGIN_COMPONENTS_FILES "") diff --git a/plugins/admt/.gitignore b/plugins/admt/.gitignore new file mode 100644 index 0000000000..507043e39f --- /dev/null +++ b/plugins/admt/.gitignore @@ -0,0 +1 @@ +include/admtplugin/scopy-admtplugin_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..0fb5ff28e2 --- /dev/null +++ b/plugins/admt/CMakeLists.txt @@ -0,0 +1,69 @@ +cmake_minimum_required(VERSION 3.9) + +set(SCOPY_MODULE admtplugin) + +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) + +install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${SCOPY_PLUGIN_INSTALL_DIR}) \ No newline at end of file diff --git a/plugins/admt/include/admtplugin/admtplugin.h b/plugins/admt/include/admtplugin/admtplugin.h new file mode 100644 index 0000000000..b7694de751 --- /dev/null +++ b/plugins/admt/include/admtplugin/admtplugin.h @@ -0,0 +1,31 @@ +#ifndef ADMTPLUGIN_H +#define ADMTPLUGIN_H + +#define SCOPY_PLUGIN_NAME ADMTPlugin + +#include "scopy-admtplugin_export.h" +#include +#include +#include + +namespace scopy::admt { +class SCOPY_ADMTPLUGIN_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/admtplugin/harmoniccalibration.h new file mode 100644 index 0000000000..7e76b2a9cb --- /dev/null +++ b/plugins/admt/include/admtplugin/harmoniccalibration.h @@ -0,0 +1,16 @@ +#ifndef HARMONICCALIBRATION_H +#define HARMONICCALIBRATION_H + +#include "scopy-admtplugin_export.h" +#include + +namespace scopy::admt { +class SCOPY_ADMTPLUGIN_EXPORT HarmonicCalibration : public QWidget +{ + Q_OBJECT +public: + HarmonicCalibration(QWidget *parent = nullptr); + ~HarmonicCalibration(); +}; +} // namespace scopy::admt +#endif // HARMONICCALIBRATION_H diff --git a/plugins/admt/res/resources.qrc b/plugins/admt/res/resources.qrc new file mode 100644 index 0000000000..deb4ca6b8c --- /dev/null +++ b/plugins/admt/res/resources.qrc @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp new file mode 100644 index 0000000000..42d453c2e5 --- /dev/null +++ b/plugins/admt/src/admtplugin.cpp @@ -0,0 +1,108 @@ +#include "admtplugin.h" + +#include +#include + +#include "harmoniccalibration.h" + +Q_LOGGING_CATEGORY(CAT_ADMTPLUGIN, "ADMTPlugin") +using namespace scopy::admt; + +bool ADMTPlugin::compatible(QString m_param, QString category) +{ + // This function defines the characteristics according to which the + // plugin is compatible with a specific device + bool ret = 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::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/gear_wheel.svg")); +} + +void ADMTPlugin::unload() { /*delete m_infoPage;*/ } + +QString ADMTPlugin::description() { return "Write the plugin description here"; } + +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"); +} diff --git a/plugins/admt/src/harmoniccalibration.cpp b/plugins/admt/src/harmoniccalibration.cpp new file mode 100644 index 0000000000..dddcbaa776 --- /dev/null +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -0,0 +1,7 @@ +#include "harmoniccalibration.h" + +using namespace scopy::admt; + +HarmonicCalibration::HarmonicCalibration(QWidget *parent) {} + +HarmonicCalibration::~HarmonicCalibration() {} diff --git a/plugins/admt/test/CMakeLists.txt b/plugins/admt/test/CMakeLists.txt new file mode 100644 index 0000000000..b26ba3bfe4 --- /dev/null +++ b/plugins/admt/test/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.5) + +include(ScopyTest) + +setup_scopy_tests(pluginloader) \ No newline at end of file diff --git a/plugins/admt/test/tst_pluginloader.cpp b/plugins/admt/test/tst_pluginloader.cpp new file mode 100644 index 0000000000..ee227af7db --- /dev/null +++ b/plugins/admt/test/tst_pluginloader.cpp @@ -0,0 +1,132 @@ +/* + * 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 c420a2c0179cebc2a121f7484d679c583075f956 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 30 May 2024 10:53:56 +0800 Subject: [PATCH 05/93] admt: Configured ADMT plugin - Added logic for compatible - Changed Harmonic Calibration icon - Changed plugin description Signed-off-by: John Lloyd Juanillo --- plugins/admt/src/admtplugin.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/plugins/admt/src/admtplugin.cpp b/plugins/admt/src/admtplugin.cpp index 42d453c2e5..26dc28bc9c 100644 --- a/plugins/admt/src/admtplugin.cpp +++ b/plugins/admt/src/admtplugin.cpp @@ -1,18 +1,32 @@ #include "admtplugin.h" +#include "harmoniccalibration.h" #include #include -#include "harmoniccalibration.h" +#include Q_LOGGING_CATEGORY(CAT_ADMTPLUGIN, "ADMTPlugin") using namespace scopy::admt; bool ADMTPlugin::compatible(QString m_param, QString category) { - // This function defines the characteristics according to which the - // plugin is compatible with a specific device - bool ret = true; + 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; } @@ -56,12 +70,12 @@ bool ADMTPlugin::loadIcon() void ADMTPlugin::loadToolList() { m_toolList.append( - SCOPY_NEW_TOOLMENUENTRY("harmoniccalibration", "Harmonic Calibration", ":/gui/icons/scopy-default/icons/gear_wheel.svg")); + SCOPY_NEW_TOOLMENUENTRY("harmoniccalibration", "Harmonic Calibration", ":/gui/icons/scopy-default/icons/tool_oscilloscope.svg")); } void ADMTPlugin::unload() { /*delete m_infoPage;*/ } -QString ADMTPlugin::description() { return "Write the plugin description here"; } +QString ADMTPlugin::description() { return "Plugin for ADMT Harmonic Calibration"; } bool ADMTPlugin::onConnect() { From 8267a16495b4d87cfefc568d34fd811869ea616e Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 3 Jun 2024 11:39:46 +0800 Subject: [PATCH 06/93] admt: Added test GUI textbox and button for rotation, count, and angle Signed-off-by: John Lloyd Juanillo --- .../include/admtplugin/harmoniccalibration.h | 27 ++++++ plugins/admt/src/harmoniccalibration.cpp | 85 ++++++++++++++++++- 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/plugins/admt/include/admtplugin/harmoniccalibration.h b/plugins/admt/include/admtplugin/harmoniccalibration.h index 7e76b2a9cb..e6a073ca8f 100644 --- a/plugins/admt/include/admtplugin/harmoniccalibration.h +++ b/plugins/admt/include/admtplugin/harmoniccalibration.h @@ -2,7 +2,21 @@ #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 @@ -11,6 +25,19 @@ class SCOPY_ADMTPLUGIN_EXPORT HarmonicCalibration : public QWidget 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 index dddcbaa776..5ad36d2e86 100644 --- a/plugins/admt/src/harmoniccalibration.cpp +++ b/plugins/admt/src/harmoniccalibration.cpp @@ -1,7 +1,90 @@ #include "harmoniccalibration.h" +#include + using namespace scopy::admt; -HarmonicCalibration::HarmonicCalibration(QWidget *parent) {} +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 47bbf6d95cd05ce116a2f65bfb881643f1980298 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 6 Jun 2024 15:01:51 +0800 Subject: [PATCH 07/93] admt: Renamed plugin and include directories Signed-off-by: John Lloyd Juanillo --- plugins/CMakeLists.txt | 11 ++++++----- plugins/admt/.gitignore | 2 +- plugins/admt/CMakeLists.txt | 5 +++-- .../admt/include/{admtplugin => admt}/admtplugin.h | 4 ++-- .../{admtplugin => admt}/harmoniccalibration.h | 4 ++-- 5 files changed, 14 insertions(+), 12 deletions(-) rename plugins/admt/include/{admtplugin => admt}/admtplugin.h (83%) rename plugins/admt/include/{admtplugin => admt}/harmoniccalibration.h (90%) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 2fd0418408..6eb680fa45 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -15,11 +15,6 @@ option(ENABLE_PLUGIN_PQM "Enable PQM plugin" ON) option(ENABLE_PLUGIN_DATALOGGER "Enable DATALOGGER plugin" ON) option(ENABLE_PLUGIN_IIODEBUGPLUGIN "Enable IIODEBUGPLUGIN plugin" ON) -if(ENABLE_PLUGIN_ADMT) - add_subdirectory(admt) - list(APPEND PLUGINS ${PLUGIN_NAME}) -endif() - set(PLUGIN_COMPONENTS "") set(PLUGIN_COMPONENTS_FILES "") @@ -125,6 +120,12 @@ if(ENABLE_PLUGIN_M2K) endif() endif() +if(ENABLE_PLUGIN_ADMT) + add_subdirectory(admt) + list(APPEND PLUGINS ${PLUGIN_NAME}) + configureinstallersettings(${PLUGIN_NAME} ${PLUGIN_DESCRIPTION} "disablenouninstallwarning") +endif() + message(STATUS "Building plugins:" ${PLUGINS}) message("PLUGIN_COMPONENTS" ${PLUGIN_COMPONENTS}) set(PLUGINS ${PLUGINS} PARENT_SCOPE) diff --git a/plugins/admt/.gitignore b/plugins/admt/.gitignore index 507043e39f..cf99da1b8f 100644 --- a/plugins/admt/.gitignore +++ b/plugins/admt/.gitignore @@ -1 +1 @@ -include/admtplugin/scopy-admtplugin_export.h \ No newline at end of file +include/admt/scopy-admt_export.h \ No newline at end of file diff --git a/plugins/admt/CMakeLists.txt b/plugins/admt/CMakeLists.txt index 0fb5ff28e2..18678584b4 100644 --- a/plugins/admt/CMakeLists.txt +++ b/plugins/admt/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.9) -set(SCOPY_MODULE admtplugin) +set(SCOPY_MODULE admt) message(STATUS "building plugin: " ${SCOPY_MODULE}) @@ -64,6 +64,7 @@ target_link_libraries( scopy-iioutil ) -set(PLUGIN_NAME ${PROJECT_NAME} PARENT_SCOPE) +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/admtplugin/admtplugin.h b/plugins/admt/include/admt/admtplugin.h similarity index 83% rename from plugins/admt/include/admtplugin/admtplugin.h rename to plugins/admt/include/admt/admtplugin.h index b7694de751..09f0ce35c1 100644 --- a/plugins/admt/include/admtplugin/admtplugin.h +++ b/plugins/admt/include/admt/admtplugin.h @@ -3,13 +3,13 @@ #define SCOPY_PLUGIN_NAME ADMTPlugin -#include "scopy-admtplugin_export.h" +#include "scopy-admt_export.h" #include #include #include namespace scopy::admt { -class SCOPY_ADMTPLUGIN_EXPORT ADMTPlugin : public QObject, public PluginBase +class SCOPY_ADMT_EXPORT ADMTPlugin : public QObject, public PluginBase { Q_OBJECT SCOPY_PLUGIN; 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 290f4ec0009ce557a2059405282b709d5ca11b1e Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 10 Jun 2024 12:19:39 +0800 Subject: [PATCH 08/93] admt: Connected button to output to text field Signed-off-by: John Lloyd Juanillo --- .../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 6799ce153944cd9c3f351b901d42d98974a151c8 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 13 Jun 2024 07:31:22 +0800 Subject: [PATCH 09/93] admt: Added GRTimePlotAddon Signed-off-by: John Lloyd Juanillo --- 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 69af835d89532885c60f10d7401053d7dd805207 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 14 Jun 2024 16:30:11 +0800 Subject: [PATCH 10/93] admt: Implemented channel control and init methods Signed-off-by: John Lloyd Juanillo --- .../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 6f1d4d8d6f369738a0b2186ef4ff9fcd58cda2ee Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 18 Jun 2024 09:51:15 +0800 Subject: [PATCH 11/93] admt: Update CMakeList - Reverted C++ standard from 20 to 17 Signed-off-by: John Lloyd Juanillo --- 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 eced5a4230e91542c7cceebee532f794499690b4 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 19 Jun 2024 14:03:09 +0800 Subject: [PATCH 12/93] cmake: Added post build to copy library to binary path Signed-off-by: John Lloyd Juanillo --- CMakeLists.txt | 33 ++------------------------------- common/CMakeLists.txt | 6 ++++++ core/CMakeLists.txt | 6 ++++++ gr-util/CMakeLists.txt | 6 ++++++ gui/CMakeLists.txt | 6 ++++++ iio-widgets/CMakeLists.txt | 6 ++++++ iioutil/CMakeLists.txt | 6 ++++++ pluginbase/CMakeLists.txt | 6 ++++++ 8 files changed, 44 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 148a8e0af7..40356cff19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,6 +110,7 @@ set(SCOPY_PLUGIN_BUILD_PATH ${CMAKE_CURRENT_BINARY_DIR}/plugins/plugins) set(SCOPY_PLUGIN_INSTALL_PATH ${CMAKE_INSTALL_FULL_DATADIR}/scopy-plugins) set(SCOPY_TRANSLATION_BUILD_PATH ${CMAKE_CURRENT_BINARY_DIR}/translations) set(SCOPY_TRANSLATION_INSTALL_PATH ${CMAKE_INSTALL_FULL_DATADIR}/translations) +set(SCOPY_CURRENT_BINARY_PATH ${CMAKE_CURRENT_BINARY_DIR}) add_subdirectory(common) add_subdirectory(iioutil) @@ -208,34 +209,4 @@ install(TARGETS ${PROJECT_NAME} BUNDLE DESTINATION .) if(QT_VERSION_MAJOR EQUAL 6) qt_finalize_executable(${PROJECT_NAME}) -endif() - -# Helper function to copy DLLs from a given directory -function(copy_dlls_from_dir dir) -file(GLOB DLLS "${dir}/*.dll") -foreach(DLL ${DLLS}) - add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy - ${DLL} - $ - ) -endforeach() -endfunction() - -# List of directories containing DLLs -set(DLL_DIRS - "${CMAKE_BINARY_DIR}/common" - "${CMAKE_BINARY_DIR}/core" - "${CMAKE_BINARY_DIR}/gr-util" - "${CMAKE_BINARY_DIR}/gui" - "${CMAKE_BINARY_DIR}/iioutil" - "${CMAKE_BINARY_DIR}/iio-widgets" - "${CMAKE_BINARY_DIR}/pluginbase" - "${CMAKE_BINARY_DIR}/gui/sigrok-gui" - "${CMAKE_BINARY_DIR}/gui/gr-gui" -) - -# Copy DLLs from each directory -foreach(DIR ${DLL_DIRS}) - copy_dlls_from_dir(${DIR}) -endforeach() \ No newline at end of file +endif() \ No newline at end of file diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 098359de90..87926ca6d9 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -53,3 +53,9 @@ endforeach() target_link_libraries(${PROJECT_NAME} PUBLIC ${SCOPY_QT_LIBRARIES}) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SCOPY_DLL_PATH} RUNTIME DESTINATION ${SCOPY_DLL_PATH}) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + $ + ${SCOPY_CURRENT_BINARY_PATH} +) \ No newline at end of file diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 0bfc9ea582..86161e6fb9 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -107,3 +107,9 @@ target_link_libraries( ) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SCOPY_DLL_PATH} RUNTIME DESTINATION ${SCOPY_DLL_PATH}) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + $ + ${SCOPY_CURRENT_BINARY_PATH} +) \ No newline at end of file diff --git a/gr-util/CMakeLists.txt b/gr-util/CMakeLists.txt index b0cca35211..edd7ee0745 100644 --- a/gr-util/CMakeLists.txt +++ b/gr-util/CMakeLists.txt @@ -75,3 +75,9 @@ target_link_libraries( ) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SCOPY_DLL_PATH} RUNTIME DESTINATION ${SCOPY_DLL_PATH}) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + $ + ${SCOPY_CURRENT_BINARY_PATH} +) \ No newline at end of file diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 3aa038180a..a180566f4b 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -129,3 +129,9 @@ target_link_libraries( ) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SCOPY_DLL_PATH} RUNTIME DESTINATION ${SCOPY_DLL_PATH}) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + $ + ${SCOPY_CURRENT_BINARY_PATH} +) \ No newline at end of file diff --git a/iio-widgets/CMakeLists.txt b/iio-widgets/CMakeLists.txt index 36f3664efa..147005adba 100644 --- a/iio-widgets/CMakeLists.txt +++ b/iio-widgets/CMakeLists.txt @@ -93,3 +93,9 @@ endforeach() target_link_libraries(${PROJECT_NAME} PUBLIC ${SCOPY_QT_LIBRARIES} ${IIO_LIBRARIES} scopy-gui scopy-iioutil) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SCOPY_DLL_PATH} RUNTIME DESTINATION ${SCOPY_DLL_PATH}) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + $ + ${SCOPY_CURRENT_BINARY_PATH} +) \ No newline at end of file diff --git a/iioutil/CMakeLists.txt b/iioutil/CMakeLists.txt index 41fee4c796..c41030d325 100644 --- a/iioutil/CMakeLists.txt +++ b/iioutil/CMakeLists.txt @@ -79,3 +79,9 @@ target_include_directories( target_link_libraries(${PROJECT_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Widgets ${IIO_LIBRARIES} ${LIBSERIALPORT_LIBRARIES}) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SCOPY_DLL_PATH} RUNTIME DESTINATION ${SCOPY_DLL_PATH}) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + $ + ${SCOPY_CURRENT_BINARY_PATH} +) \ No newline at end of file diff --git a/pluginbase/CMakeLists.txt b/pluginbase/CMakeLists.txt index 29b6d83b54..21f8848c64 100644 --- a/pluginbase/CMakeLists.txt +++ b/pluginbase/CMakeLists.txt @@ -73,3 +73,9 @@ endforeach() target_link_libraries(${PROJECT_NAME} PUBLIC ${SCOPY_QT_LIBRARIES} ${IIO_LIBRARIES} scopy-common) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SCOPY_DLL_PATH} RUNTIME DESTINATION ${SCOPY_DLL_PATH}) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + $ + ${SCOPY_CURRENT_BINARY_PATH} +) \ No newline at end of file From 3b82d92f537b74bc34f6e43e3963b8596a0bba95 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 26 Jun 2024 09:07:19 +0800 Subject: [PATCH 13/93] admt: Added historical graph Signed-off-by: John Lloyd Juanillo --- .../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 292fe36ac2754a130c6897fb2d5f6c966f864775 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 9 Jul 2024 11:03:43 +0800 Subject: [PATCH 14/93] admt: Implemented GUI interface and controller Signed-off-by: John Lloyd Juanillo --- 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 c42ce799a1a2c47deed82a7184e1494e3b32b0af Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 9 Jul 2024 16:29:47 +0800 Subject: [PATCH 15/93] 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 --- 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 082b2bd7b5c8512262f13750ec306a2a1eaed8ca Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 16 Jul 2024 10:08:37 +0800 Subject: [PATCH 16/93] admt: Added calibration tab - Created method for calibration widget - Removed initial plot and data for acquisition tab Signed-off-by: John Lloyd Juanillo --- .../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 c11588f2a9ec9e1c9f23b4a7cccc1a6ea33dd2b5 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 18 Jul 2024 16:03:02 +0800 Subject: [PATCH 17/93] admt: Implemented export and import raw calibration data Signed-off-by: John Lloyd Juanillo --- .../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 e3138d90ac15d08e9aaba42fa2b2a987fe32b76d Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 23 Jul 2024 10:30:34 +0800 Subject: [PATCH 18/93] admt: Implemented calibration routine in controller - Renamed acquisition labels Signed-off-by: John Lloyd Juanillo --- 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 e51d571e82b13dbb2ae9b1a00f4bc19f90990921 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 31 Jul 2024 11:10:45 +0800 Subject: [PATCH 19/93] admt: Layout for motor controls - Added custom spinbox widget - Styled line edits and combo boxes Signed-off-by: John Lloyd Juanillo --- 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 | 9 +- plugins/admt/src/harmoniccalibration.cpp | 652 ++++++++++++------ .../admt/src/widgets/horizontalspinbox.cpp | 157 +++++ 10 files changed, 697 insertions(+), 200 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/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 index deb4ca6b8c..fa99638ef0 100644 --- a/plugins/admt/res/resources.qrc +++ b/plugins/admt/res/resources.qrc @@ -1,2 +1,7 @@ - - \ No newline at end of file + + + 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 c2fe9a130239f53583f05f6693251158c79aa5f0 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 9 Aug 2024 11:02:16 +0800 Subject: [PATCH 20/93] admt: Added stepper motor control for calibration Signed-off-by: John Lloyd Juanillo --- 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 995ed2fd8757fa8b09ea4e9ceb8df79356c0ffc1 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 15 Aug 2024 13:57:36 +0800 Subject: [PATCH 21/93] 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 --- 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 578d08df7d8dbf1e73119f8a7a61db26668bda02 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 15 Aug 2024 14:39:21 +0800 Subject: [PATCH 22/93] admt: Added read device registry Signed-off-by: John Lloyd Juanillo --- 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 574d31544eedb3833ca981941cf1835463cfa047 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 29 Aug 2024 14:47:33 +0800 Subject: [PATCH 23/93] 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 --- .../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 bfa930cc8fbde0d589b6cb23f1325a15706d38e1 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 2 Sep 2024 15:26:18 +0800 Subject: [PATCH 24/93] admt: Added registers tab - Fixed calibration graph sizing behavior Signed-off-by: John Lloyd Juanillo --- .../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 631978146ee2b0194165c37745c5d5eebe0477b5 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 5 Sep 2024 12:48:53 +0800 Subject: [PATCH 25/93] 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 --- 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 c4fcd2a5690595126545eb03918cdde3ce842749 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 6 Sep 2024 14:42:33 +0800 Subject: [PATCH 26/93] admt: Added calibration graph toggles Signed-off-by: John Lloyd Juanillo --- .../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 9ea492e074355ee724f83bc6ff2f44aa15b6a1a8 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 9 Sep 2024 14:27:09 +0800 Subject: [PATCH 27/93] 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 --- 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 07499ac1365eaddc03194d4cf669e719bbfc5bfd Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 10 Sep 2024 14:05:41 +0800 Subject: [PATCH 28/93] admt: Implement compatible selected plugin Signed-off-by: John Lloyd Juanillo --- 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 fa0ae6f1b55165fd93b18862efc1096912e6c64f Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 10 Sep 2024 14:11:25 +0800 Subject: [PATCH 29/93] admt: Adjusted UI - Set spacing from 10 to 8 - Reduced margin from MenuControlButton Signed-off-by: John Lloyd Juanillo --- 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 7e1f45fbf8ab6c3610bbade664d094c2de716f3a Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 11 Sep 2024 14:35:35 +0800 Subject: [PATCH 30/93] admt: Set debug to false Signed-off-by: John Lloyd Juanillo --- 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 f8e54a3e67143625d46441f53bac8fb6eb262787 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 25 Sep 2024 10:41:44 +0800 Subject: [PATCH 31/93] 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 --- 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 44e8003567739af0da9c912b1f3f2c94faf2b610 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Wed, 25 Sep 2024 15:18:00 +0800 Subject: [PATCH 32/93] Update admtcontroller.cpp - Fixed calculation of angular error. - Abstracted functions for FFT of both pre and post angle error ffts. --- 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 c8b07ea7671c949b659eb13f74310081f83647d0 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 26 Sep 2024 09:33:39 +0800 Subject: [PATCH 33/93] admt: Implemented sequence read and write - Modified get and set register maps - Renamed sequence dropdown items Signed-off-by: John Lloyd Juanillo --- 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 8c92443bcadc6ee23e7c3e7ef9af2e390982ec82 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 26 Sep 2024 10:34:11 +0800 Subject: [PATCH 34/93] admt: Corrected string output for binary and hex values Signed-off-by: John Lloyd Juanillo --- .../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 c94c7a694408577b84c2ec821d9d5d1ae4a6429a Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 26 Sep 2024 15:17:03 +0800 Subject: [PATCH 35/93] admt: Fixed pre-calibration FFT calculation Signed-off-by: John Lloyd Juanillo --- 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 bf8133b52d2410b2b10d93de8cf44ecbad85640d Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 26 Sep 2024 15:29:49 +0800 Subject: [PATCH 36/93] admt: Fixed replot pre-calibration FFT graph after clear Signed-off-by: John Lloyd Juanillo --- 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 f740677c6a0aecbaabe0977901192f1fb9f1898a Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 27 Sep 2024 13:45:48 +0800 Subject: [PATCH 37/93] admt: Implemented GMR reset Signed-off-by: John Lloyd Juanillo --- 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 a4774baf79b822660793c09268367c1ed4fa28ca Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 7 Oct 2024 09:33:49 +0800 Subject: [PATCH 38/93] admt: Added min and max for line edit - Added digio register bit mapping and unwrap angles Signed-off-by: John Lloyd Juanillo --- 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 cc87dc8b3a2f640aad1733b6f20b30c9897cbf4b Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Mon, 7 Oct 2024 10:19:35 +0800 Subject: [PATCH 39/93] Update admtcontroller.cpp - Updated angle error calculation to take into account unwrapped angles for expected values. --- 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 40/93] Update admtcontroller.cpp - Added option to change value for computation based on voltage level. --- 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 355f9ea6c23aeb4aab2f10fce871a0d11d114967 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 8 Oct 2024 13:56:00 +0800 Subject: [PATCH 41/93] admt: Implemented GPIO Control - Added device identifiers Signed-off-by: John Lloyd Juanillo --- 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 d6d1669d0c51ce66cdf93683e81a7aae6cca632b Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 10 Oct 2024 09:29:05 +0800 Subject: [PATCH 42/93] 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 --- 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 c27de5ac9ea928b6e02514a322cdf49dc0f04b6d Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 10 Oct 2024 10:05:11 +0800 Subject: [PATCH 43/93] Update admtcontroller.cpp - Updated Angle error calculation. - Updated FFT calculation. --- 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 7fb980661523f14d8dc7736441a53069b2ed731c Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 10 Oct 2024 11:30:12 +0800 Subject: [PATCH 44/93] admt: Fixed controls for post calibration data - Fixed references for controller Signed-off-by: John Lloyd Juanillo --- 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 9b07a7fccf080e2d23c7c54e15ef7f09cb2d752b Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 10 Oct 2024 12:07:17 +0800 Subject: [PATCH 45/93] Update admtcontroller.cpp - fixed loading of value of correct fft magnitude. --- 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 eb8a263c255d0acf2c70966a901212553421fadd Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 10 Oct 2024 16:06:42 +0800 Subject: [PATCH 46/93] Update admtcontroller.cpp - Normalize the fft based on the original length. --- 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 bad4d54cdbab208e09e05c9799e89b42270cfb0c Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Fri, 11 Oct 2024 09:10:36 +0800 Subject: [PATCH 47/93] 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. --- 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 cc191b30fe15ba479d5f7491f1dba356495fa741 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 14 Oct 2024 10:31:03 +0800 Subject: [PATCH 48/93] 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 --- 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 c0bdba71f11fa1d5bd2a09deaa1061ba98bc2fd4 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 15 Oct 2024 13:57:18 +0800 Subject: [PATCH 49/93] =?UTF-8?q?Wrap=20angle=20errors=20to=20[-=CF=80,=20?= =?UTF-8?q?=CF=80]=20range?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 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 50/93] Update admtcontroller.cpp Updated Calculate_Angle_Error --- 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 fe18eacfe674b3eb96a7b3202b0b431bfe7b7d2e Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Wed, 16 Oct 2024 10:25:57 +0800 Subject: [PATCH 51/93] Update admtcontroller.cpp Adjusted FFT function to mostly reflect original C# code and implementation. --- 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 5d57caa087eb2d72f13d2fdf1342ae4cc9bef94f Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 16 Oct 2024 10:44:21 +0800 Subject: [PATCH 52/93] Refactor angle error calculations and FFT in ADMTController --- 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 b2ecf9ffa06a53b13343138fd0a7ef47d1af29a3 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Wed, 16 Oct 2024 10:48:51 +0800 Subject: [PATCH 53/93] Update admtcontroller.cpp adjusted code for handing FFT to reuse old function available. --- 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 0e66c72e51c0da4e7abf9efe7a737ee5a43b9435 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Wed, 16 Oct 2024 12:32:04 +0800 Subject: [PATCH 54/93] Update admtcontroller.cpp code cleanup --- 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 c0e5839492ca9d059682c000dc041a0f53c626b3 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Wed, 16 Oct 2024 12:50:17 +0800 Subject: [PATCH 55/93] Update admtcontroller.cpp Refactored calibrate to retain implementation based on C# code. --- 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 aa16da0f6cc1ff9c956d2675b8ef40c5de70620c Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 17 Oct 2024 16:28:31 +0800 Subject: [PATCH 56/93] Revert "Update admtcontroller.cpp" This reverts commit c0e5839492ca9d059682c000dc041a0f53c626b3. --- 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 2274dc57e2bedd05924d894709ace807e0f01590 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 17 Oct 2024 16:28:56 +0800 Subject: [PATCH 57/93] Revert "Update admtcontroller.cpp" This reverts commit 0e66c72e51c0da4e7abf9efe7a737ee5a43b9435. --- 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 31c24243c130481af781d86ee616ca1cb17d0f07 Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 17 Oct 2024 16:29:00 +0800 Subject: [PATCH 58/93] Revert "Update admtcontroller.cpp" This reverts commit b2ecf9ffa06a53b13343138fd0a7ef47d1af29a3. --- 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 6975b2a4f45e1e7d820602e8cac18ebb48a4316a Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 17 Oct 2024 16:29:05 +0800 Subject: [PATCH 59/93] Revert "Refactor angle error calculations and FFT in ADMTController" This reverts commit 5d57caa087eb2d72f13d2fdf1342ae4cc9bef94f. --- 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 e9eae825349b4c3c9c7194520b44a56dbba24c1e Mon Sep 17 00:00:00 2001 From: JDalenaJ Date: Thu, 17 Oct 2024 16:29:11 +0800 Subject: [PATCH 60/93] Revert "Update admtcontroller.cpp" This reverts commit fe18eacfe674b3eb96a7b3202b0b431bfe7b7d2e. --- 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 b89654f8cebd8361c5abcaf4318e4ea64c7f7cde Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 22 Oct 2024 11:53:56 +0800 Subject: [PATCH 61/93] admt: Fixed admtcontroller.h Signed-off-by: John Lloyd Juanillo --- 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 ac61bac6ec988ad148cd043ca7a4c0f46bd5e707 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 30 Oct 2024 11:21:47 +0800 Subject: [PATCH 62/93] admt: Adjusted UI to hide and show specific fault registers based on sequence mode Signed-off-by: John Lloyd Juanillo --- .../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 87298fa6659cf0c7a54021eafe5181876760d412 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 31 Oct 2024 14:56:44 +0800 Subject: [PATCH 63/93] admt: Included motor controls in acquisition tab - Changed timer to concurrent Signed-off-by: John Lloyd Juanillo --- .../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 cfed47fc504997d95e1ef7ca1d7e1f6bbf17ab66 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 4 Nov 2024 10:50:48 +0800 Subject: [PATCH 64/93] admt: Merge to latest dev build - Removed Sismograph Signed-off-by: John Lloyd Juanillo --- plugins/CMakeLists.txt | 7 +- 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(+), 343 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 3da3722433..cfad0c99ad 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -24,7 +24,6 @@ project(scopy-plugins VERSION 0.1 LANGUAGES CXX) message(STATUS "Plugins folder: " ${SCOPY_PLUGIN_BUILD_PATH}) message(STATUS "Plugins folder after install: " ${SCOPY_PLUGIN_INSTALL_PATH}) -option(ENABLE_PLUGIN_ADMT "Enable ADMT plugin" ON) option(ENABLE_PLUGIN_M2K "Enable m2k plugin" ON) option(ENABLE_PLUGIN_TEST "Enable test plugin" OFF) option(ENABLE_PLUGIN_REGMAP "Enable regmap plugin" ON) @@ -34,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}) @@ -126,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 322096c64cc4f886de9ebe51182f54b4106b92d7 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 4 Nov 2024 12:12:56 +0800 Subject: [PATCH 65/93] admt: Hide MT Diagnostic indicator and register Signed-off-by: John Lloyd Juanillo --- 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 2cfe8913e0fc8cb1d0d332cf579b834af25eaba9 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 4 Nov 2024 13:38:28 +0800 Subject: [PATCH 66/93] admt: Hide registers on sequence mode Signed-off-by: John Lloyd Juanillo --- .../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 eb676abc3ace64501085dda3c2f1e52bbe125ebd Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 5 Nov 2024 11:46:20 +0800 Subject: [PATCH 67/93] admt: Updated graph style Signed-off-by: John Lloyd Juanillo --- .../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 05fa3707499ae13d5761dd4403577a88a7efe180 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 6 Nov 2024 09:08:41 +0800 Subject: [PATCH 68/93] admt: Add read all registers - Changed register block widget to include CNVPAGE Signed-off-by: John Lloyd Juanillo --- 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 de0b902c4a53af1cd8c6213f1f114f38faf03d52 Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Tue, 12 Nov 2024 11:33:42 +0800 Subject: [PATCH 69/93] admt: Reverted changes to calibration samples graph Signed-off-by: dpineda2 --- 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 ba825b3e9c279a4cb4d086ca6f9e32263f604983 Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Wed, 13 Nov 2024 07:28:13 +0800 Subject: [PATCH 70/93] admt: Initial implement of style helper Signed-off-by: dpineda2 --- 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 e8147218d5f9026df921e435a8da4c913c4877b9 Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Wed, 13 Nov 2024 09:22:28 +0800 Subject: [PATCH 71/93] admt: Included import samples in calibration data - Initialized acquisition graph axes Signed-off-by: dpineda2 --- .../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 813a5760d28521c3b5a12b72dcedcaa922972011 Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Wed, 13 Nov 2024 14:22:38 +0800 Subject: [PATCH 72/93] admt: Initial implement of acquisition graph data Signed-off-by: dpineda2 --- .../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 55814c9e6330ea48748d225c6e82c11f7a62e083 Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Fri, 15 Nov 2024 16:07:41 +0800 Subject: [PATCH 73/93] admt: Added state for MT Diagnostics - Updated import sample behavior - Changed calibration UI timer rate Signed-off-by: dpineda2 --- .../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 9607812c755a70ce28091fc9613babfad60bcef1 Mon Sep 17 00:00:00 2001 From: dpineda2 Date: Fri, 15 Nov 2024 16:19:52 +0800 Subject: [PATCH 74/93] admt: Removed resizing acquisition list Signed-off-by: dpineda2 --- 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 c227e440b0cf1f4341e229a5b65379abe0279783 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 25 Nov 2024 10:01:54 +0800 Subject: [PATCH 75/93] admt: Improved stability for applying sequence Signed-off-by: John Lloyd Juanillo --- 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 83801bfa4ca7467d6a92428384e52819d1a7f4ef Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 25 Nov 2024 10:24:12 +0800 Subject: [PATCH 76/93] admt: Write zeros to fault register before read Signed-off-by: John Lloyd Juanillo --- 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 5dd5dcc1b191386f963f4a49a17e9084f218f128 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Tue, 26 Nov 2024 10:26:11 +0800 Subject: [PATCH 77/93] admt: Added fine control for DIGIOEN register Signed-off-by: John Lloyd Juanillo --- 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 6059ae75d0c79a37a84b318c9107a543b613183c Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 27 Nov 2024 14:31:00 +0800 Subject: [PATCH 78/93] admt: Applied fixes for calibration Signed-off-by: John Lloyd Juanillo --- .../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 ada74cc46c87f64bc8d07d5781057fb4ed8cc053 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 2 Dec 2024 12:39:18 +0800 Subject: [PATCH 79/93] admt: Implemented multi-channel acquisition graph Signed-off-by: John Lloyd Juanillo --- 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 786f4cf07f55cc50079fbd301ba6198e4e4f16e9 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 5 Dec 2024 15:16:32 +0800 Subject: [PATCH 80/93] admt: Fixed crashing issue when calibrating - Adjusted graph behavior for acquisition tab - Adjusted layout for calibration Signed-off-by: John Lloyd Juanillo --- 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 80e15c373eae56c3eff9aa04d103dfa331cc3d04 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 8 Jan 2025 07:54:46 +0800 Subject: [PATCH 81/93] 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 --- 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 9257431390e8642a651034c184790550b01fc9a1 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 8 Jan 2025 17:03:36 +0800 Subject: [PATCH 82/93] 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 --- .../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 6c7b05c00e7a719e160517a777db4117be86d9e1 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 10 Jan 2025 14:59:26 +0800 Subject: [PATCH 83/93] admt: Implemented device status fault monitoring - Added disconnect method for separate threads Signed-off-by: John Lloyd Juanillo --- 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 f7b34b202ce7dab95ba51f7352cf012b46df0d8c Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 15 Jan 2025 12:30:13 +0800 Subject: [PATCH 84/93] admt: Code cleanup Signed-off-by: John Lloyd Juanillo --- 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 f3cb3b90f4949e0403f23fbca1adf446cc199b4c Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 15 Jan 2025 16:12:11 +0800 Subject: [PATCH 85/93] admt: Added disable states for tab widget while calibrating Signed-off-by: John Lloyd Juanillo --- .../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 63037029482ec59aec58a058d2f56e4365ad7bff Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Thu, 16 Jan 2025 14:14:41 +0800 Subject: [PATCH 86/93] 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 --- .../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 c87a533abbf9b0410721c37191a42395545b605f Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 17 Jan 2025 17:21:26 +0800 Subject: [PATCH 87/93] admt: Applied latest dev branch - Applied new style method Signed-off-by: John Lloyd Juanillo --- .../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 0020c5790d2ba9376fa5ee9a459e07c8d20a5341 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Fri, 17 Jan 2025 17:36:22 +0800 Subject: [PATCH 88/93] admt: File cleanup Signed-off-by: John Lloyd Juanillo --- CMakeLists.txt | 24 +++++++++++ docs/local-windows-build-readme.md | 64 ------------------------------ 2 files changed, 24 insertions(+), 64 deletions(-) delete mode 100644 docs/local-windows-build-readme.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 07adce76c0..0b6c1a545d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -279,3 +279,27 @@ install(TARGETS ${PROJECT_NAME} BUNDLE DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) if(QT_VERSION_MAJOR EQUAL 6) qt_finalize_executable(${PROJECT_NAME}) endif() + +# make uninstall +add_custom_target("uninstall" COMMENT "Uninstall installed files") +add_custom_command( + TARGET "uninstall" + POST_BUILD + COMMENT "Uninstall files with install_manifest.txt" + COMMAND xargs rm -vf < install_manifest.txt || echo Nothing in install_manifest.txt to be uninstalled! +) + +# CPack config +set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") +set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") +set(CPACK_GENERATOR "ZIP") + +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}") + +set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/package") +set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY OFF) +set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF) +set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) +set(CPACK_SET_DESTDIR ON) +set(CPACK_COMPONENTS_ALL ${SCOPY_PDK}) +include(CPack) \ No newline at end of file diff --git a/docs/local-windows-build-readme.md b/docs/local-windows-build-readme.md deleted file mode 100644 index d8b08378aa..0000000000 --- a/docs/local-windows-build-readme.md +++ /dev/null @@ -1,64 +0,0 @@ -This is a guide for installing the dependencies and setting up the environment for SCOPYv2 development. It is recommended to do these steps on a virtual machine since this has the potential to ruin the configuration of the system. The commands shown in this guide came from the [ci-for-scopy2](https://github.com/analogdevicesinc/scopy-mingw-build-deps/blob/ci-for-scopy2/docker/Dockerfile) dockerfile which can be visited and used as a reference. Most of the content of this guide is tailored fit to be executed using CMD or Windows Command Prompt which explains why there are some commands that are slightly different from the ones in the dockerfile. - -## Build prerequisites -- [Visual Studio Code](https://code.visualstudio.com/download) -- [LibIIO v0.25](https://github.com/analogdevicesinc/libiio/releases/download/v0.25/libiio-0.25.gb6028fd-setup.exe) -- [MSYS2](https://www.msys2.org/) (Use default installation settings. **Do not change the directory locations.** Uncheck Run MSYS2 now after installation.) - -> If running Virtual Machines (e.g. VirtualBox, Hyper-V, VMWare, etc.) Open **Microsoft Store** and search for **OpenCL, OpenGL, and Vulkan Compatibility Pack**. This would install the packages needed in rendering the graphics of the software. Without this, Scopy would just crash. - -## Build instructions -1. Create folder with the following directory *C:\msys64\home\docker* - -2. Make a **backup** of your user PATH variable. - - > To make a backup, open run window using keyboard command **`WIN`**+**`R`** > Type **`SystemPropertiesAdvanced.exe`** and press the **`ENTER`** key > *System Properties* window will appear > Under the *Advanced* tab, click **`Environment Variables...`** > Under *User variables for (your user name)* find and click on *Path* and click **`Edit...`** > Then click **`Edit text...`** > copy and store the variable value in your preferred text editor > Save and close all opened windows. - -3. Execute the following commands using Windows Command prompt *(CMD)* and **not MINGW64**: - - ```sh - cd C:/msys64/home/docker/ - set PATH=%PATH%;C:\msys64\bin;C:\msys64\mingw64\bin;C:\msys64\usr\bin - setx HOME C:\msys64\home\docker - setx CHERE_INVOKING yes - setx MSYSTEM MINGW64 - C:\msys64\usr\bin\bash.exe -lc " " - C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Syyu" - C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Sy msys2-keyring" - C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Su" - C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Syuu" & C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Syuu" & C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Scc " - C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm --needed -Sy git" - C:\msys64\usr\bin\bash.exe -lc "git clone https://github.com/analogdevicesinc/scopy-mingw-build-deps --branch ci-for-scopy2" - ``` -4. Check if **scopy-mingw-build-deps** directory is at *C:\msys64\home\\(your user name)\\*, if it is then move it to *C:\msys64\home\docker\\* - -5. Continue to run commands - ```sh - C:\msys64\usr\bin\bash.exe -lc "cd /home/docker/scopy-mingw-build-deps && ls && echo Building for x86_64 && ./init_staging.sh x86_64 OFF" - C:\msys64\usr\bin\bash.exe -lc "cd /home/docker/scopy-mingw-build-deps && source build.sh && install_tools && install_deps && recurse_submodules" - C:\msys64\home\docker\scopy-mingw-build-deps\is.exe /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART /LOG=C:\msys64\home\docker\iss.log /DIR=C:\innosetup - C:\msys64\usr\bin\bash.exe -lc "cd /home/docker/scopy-mingw-build-deps && source build.sh && build_deps" - ``` - -6. Clone **scopy** using tag **dev** to the directory: *C:\msys64\home\docker* - - ```sh - C:\msys64\usr\bin\bash.exe -lc "git clone https://github.com/analogdevicesinc/scopy/ --branch dev" - ``` - -7. Check if **scopy** directory is at *C:\msys64\home\\(your user name)*, if it is then move it to *C:\msys64\home\docker\\* - -8. Install GDB for build debugging - ```sh - C:\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -S mingw-w64-x86_64-gdb" - ``` - -9. In VS Code, install [**C/C++ Extension Pack**](vscode:extension/ms-vscode.cpptools-extension-pack) - -10. Open Scopy folder in VS Code - - > When opening Scopy folder for the first time, a popup may appear to ask to trust the authors of the files in this folder. Simply click on **`Yes, I trust the authors`** - -11. In VS Code, go to the toolbar on your left and locate CMake tool. On the **PROJECT OUTLINE** dropdown, click on the icon for *Configure All Projects*. This will instruct CMake to build the scripts necessary in building the source code. - -12. Under the **PROJECT STATUS** dropdown in CMake tool, click on the icon for *Build* to build the project. \ No newline at end of file From 9623c06a883413c34738ae77221814d3a003ce6e Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Wed, 22 Jan 2025 16:25:06 +0800 Subject: [PATCH 89/93] admt: Added spinbox to new style property - Adjusted calibration tab UI elements Signed-off-by: John Lloyd Juanillo --- 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 d6cc3503fed70b4698b7ecefe35be13d9735ec2d Mon Sep 17 00:00:00 2001 From: "U-ANALOG\\JJuanill" Date: Fri, 31 Jan 2025 14:00:22 +0800 Subject: [PATCH 90/93] admt: Replaced timers with threads for utility tab - Added style for checkbox LED Signed-off-by: U-ANALOG\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 5e2b1750e302ef4196eac2e62f4624aa912c2e06 Mon Sep 17 00:00:00 2001 From: "U-ANALOG\\JJuanill" Date: Fri, 31 Jan 2025 15:00:23 +0800 Subject: [PATCH 91/93] admt: Added license headers Signed-off-by: U-ANALOG\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 17309a8677645ffdc9a1aa6732195378e27b1327 Mon Sep 17 00:00:00 2001 From: "U-ANALOG\\JJuanill" Date: Fri, 31 Jan 2025 15:05:55 +0800 Subject: [PATCH 92/93] admt: Cleanup license headers for remaining files Signed-off-by: U-ANALOG\JJuanill --- plugins/admt/test/CMakeLists.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/plugins/admt/test/CMakeLists.txt b/plugins/admt/test/CMakeLists.txt index b26ba3bfe4..2b852586f3 100644 --- a/plugins/admt/test/CMakeLists.txt +++ b/plugins/admt/test/CMakeLists.txt @@ -1,3 +1,23 @@ +# +# 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) From 53dac5277f497e317f8f304cf41bb7f8cdd15db8 Mon Sep 17 00:00:00 2001 From: John Lloyd Juanillo Date: Mon, 3 Feb 2025 14:34:20 +0800 Subject: [PATCH 93/93] admt: Added regmap debug method Signed-off-by: John Lloyd Juanillo --- 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