diff --git a/.gitignore b/.gitignore index 8279d75..860bed0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -## Ignore Visual Studio temporary files, build results, and +## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore diff --git a/CMakeLists.txt b/CMakeLists.txt index fed96cd..9f0f6df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,11 +2,11 @@ # 并包含子项目。 # message(STATUS "CMake version: ${CMAKE_VERSION}") -cmake_minimum_required(VERSION 3.1.0) +cmake_minimum_required(VERSION 3.14.0) project(handdleai VERSION 0.1.0) string(TIMESTAMP RUN_TIME) message( " project start : " ${RUN_TIME}) - +add_compile_definitions(NOMINMAX) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) set(CMAKE_DISABLE_SOURCE_CHANGES ON) @@ -302,15 +302,4 @@ add_compile_options("$<$:/utf-8>") string(TIMESTAMP RUN_TIME) message( " project end : " ${RUN_TIME} "TYPE:"${CMAKE_BUILD_TYPE}) -execute_process( - COMMAND git rev-parse --short HEAD - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE GIT_COMMIT_HASH - OUTPUT_STRIP_TRAILING_WHITESPACE -) -configure_file( - ${CMAKE_SOURCE_DIR}/git_version.h.in - ${CMAKE_BINARY_DIR}/git_version.h - @ONLY -) diff --git a/configSettingWidget.h b/configSettingWidget.h deleted file mode 100644 index c8826e8..0000000 --- a/configSettingWidget.h +++ /dev/null @@ -1,393 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "git_version.h" -#include -#include -#include -#include - -class configSettingWidget :public QWidget{ - Q_OBJECT -public: - - QVBoxLayout* m_layout; - QScrollArea* scrollArea; - QWidget* contentWidget; - QHBoxLayout* btnLayout; - std::vectorbtns; - QLabel* icon, * Title; - int currentPageIndex = 0; - configSettingWidget(appConfig* _configIn):_config(_configIn){ - QPalette palette; - palette.setColor(QPalette::WindowText, Qt::white); - QFont font("微软雅黑", 24, QFont::Bold); - QFont font2("微软雅黑", 8, QFont::Bold); - - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - this->setObjectName("configSettingWidget"); - this->setStyleSheet(R"( - QWidget#configSettingWidget { - background: rgb(40, 45, 50); - } - )"); - - // 创建主布局 - QVBoxLayout* mainLayout = new QVBoxLayout(this); - mainLayout->setContentsMargins(0, 0, 0, 0); - mainLayout->setSpacing(0); - - // 创建滚动区域 - scrollArea = new QScrollArea(); - scrollArea->setObjectName("configScrollArea"); - scrollArea->setStyleSheet(R"( - QScrollArea#configScrollArea { - border: none; - background: transparent; - } - QScrollBar:vertical { - background: rgb(60, 65, 70); - width: 12px; - border-radius: 6px; - } - QScrollBar::handle:vertical { - background: rgb(100, 105, 110); - border-radius: 6px; - min-height: 20px; - } - QScrollBar::handle:vertical:hover { - background: rgb(120, 125, 130); - } - )"); - scrollArea->setWidgetResizable(true); - scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - - // 创建内容容器 - contentWidget = new QWidget(); - contentWidget->setObjectName("contentWidget"); - contentWidget->setStyleSheet("QWidget#contentWidget { background: transparent; }"); - - m_layout = new QVBoxLayout(contentWidget); - m_layout->setContentsMargins(20, 20, 20, 20); - m_layout->setSpacing(15); - m_layout->setAlignment(Qt::AlignLeft|Qt::AlignTop); - - // 创建标题区域容器 - QWidget* titleWidget = new QWidget(); - titleWidget->setObjectName("titleWidget"); - titleWidget->setStyleSheet(R"( - QWidget#titleWidget { - background: rgb(50, 55, 60); - border-radius: 10px; - padding: 15px; - } - )"); - - QVBoxLayout* titleContainerLayout = new QVBoxLayout(titleWidget); - titleContainerLayout->setContentsMargins(15, 15, 15, 15); - titleContainerLayout->setSpacing(10); - - // 主标题和版本信息布局 - QHBoxLayout* titleLayout = new QHBoxLayout(); - titleLayout->setContentsMargins(0, 0, 0, 0); - - Title = new QLabel(QString::fromStdString(Translation::getInstance().translate("Setting"))); - Title->setFont(font); - Title->setPalette(palette); - Title->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); - - QLabel* versionShow = new QLabel(QString(u8"当前版本: v%1 | 提交版本: %2").arg(QString::fromStdString(softwareVersion)).arg(GIT_COMMIT_HASH)); - versionShow->setFont(font2); - versionShow->setPalette(palette); - versionShow->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - versionShow->setStyleSheet("color: rgb(180, 180, 180);"); - - titleLayout->addWidget(Title); - titleLayout->addStretch(); - titleLayout->addWidget(versionShow); - - titleContainerLayout->addLayout(titleLayout); - m_layout->addWidget(titleWidget); - //语言设置 - { - // 创建语言设置分组容器 - QGroupBox* languageGroupBox = new QGroupBox(QString::fromStdString(Translation::getInstance().translate("Language Settings"))); - languageGroupBox->setObjectName("languageGroupBox"); - languageGroupBox->setStyleSheet(R"( - QGroupBox#languageGroupBox { - background: rgb(50, 55, 60); - border-radius: 10px; - font-family: "微软雅黑"; - font-size: 14px; - font-weight: bold; - color: white; - padding-top: 20px; - } - QGroupBox#languageGroupBox::title { - subcontrol-origin: margin; - left: 10px; - padding: 0 10px 0 10px; - } - )"); - - QVBoxLayout* languageMainLayout = new QVBoxLayout(languageGroupBox); - languageMainLayout->setContentsMargins(15, 15, 15, 15); - languageMainLayout->setSpacing(10); - - QHBoxLayout* languageSelectLayout = new QHBoxLayout(); - languageSelectLayout->setSpacing(15); - - QLabel* languageSelectLabel = new QLabel(u8"选择语言/Language/Bahasa:"); - languageSelectLabel->setFont(font2); - languageSelectLabel->setPalette(palette); - languageSelectLabel->setMinimumWidth(200); - - QComboBox* languageSelect = new QComboBox(); - languageSelect->setMinimumWidth(150); - languageSelect->setStyleSheet(R"( - QComboBox { - background-color: rgb(70, 75, 80); - border: 2px solid rgb(100, 105, 110); - border-radius: 5px; - padding: 5px; - color: white; - font-family: "微软雅黑"; - font-size: 12px; - } - QComboBox:hover { - border-color: rgb(120, 125, 130); - } - QComboBox::drop-down { - border: none; - } - QComboBox::down-arrow { - image: url(:/icons/down-arrow.png); - } - )"); - - auto languagesKeys = _configIn->_translation->getSections(); - int index = 0; - for (int i = 0; i < languagesKeys.size(); i++) { - languageSelect->addItem(QString::fromStdString(languagesKeys[i])); - if (languagesKeys[i] == _configIn->_translation->getCurrentLanguage()) - index = i; - } - languageSelect->setCurrentIndex(index); - - QLabel* languageSelectTip = new QLabel(); - languageSelectTip->setFont(font2); - languageSelectTip->setPalette(palette); - languageSelectTip->setStyleSheet("color: rgb(255, 200, 100);"); - - languageSelectLayout->addWidget(languageSelectLabel); - languageSelectLayout->addWidget(languageSelect); - languageSelectLayout->addStretch(); - languageSelectLayout->addWidget(languageSelectTip); - - languageMainLayout->addLayout(languageSelectLayout); - - connect(languageSelect, &QComboBox::currentTextChanged, [=](const QString& str) { - _configIn->_translation->setLanguage(str.toStdString()); - languageSelectTip->setText(QString::fromStdString(Translation::getInstance().translate("will change after restart"))); - }); - - m_layout->addWidget(languageGroupBox); - } - //控制台 - { - // 创建控制台设置分组容器 - QGroupBox* consoleGroupBox = new QGroupBox(QString::fromStdString(Translation::getInstance().translate("Window Settings"))); - consoleGroupBox->setObjectName("consoleGroupBox"); - consoleGroupBox->setStyleSheet(R"( - QGroupBox#consoleGroupBox { - background: rgb(50, 55, 60); - border-radius: 10px; - font-family: "微软雅黑"; - font-size: 14px; - font-weight: bold; - color: white; - padding-top: 20px; - } - QGroupBox#consoleGroupBox::title { - subcontrol-origin: margin; - left: 10px; - padding: 0 10px 0 10px; - } - )"); - - QVBoxLayout* consoleMainLayout = new QVBoxLayout(consoleGroupBox); - consoleMainLayout->setContentsMargins(15, 15, 15, 15); - consoleMainLayout->setSpacing(10); - - // 添加说明文字 - QLabel* consoleDescription = new QLabel(QString::fromStdString(Translation::getInstance().translate("Control the visibility of the debug console window"))); - consoleDescription->setFont(font2); - consoleDescription->setPalette(palette); - consoleDescription->setStyleSheet("color: rgb(180, 180, 180);"); - consoleMainLayout->addWidget(consoleDescription); - - QHBoxLayout* consoletLayout = new QHBoxLayout(); - consoletLayout->setSpacing(15); - - fancyButtonText* showConsoleBtn = new fancyButtonText(QString::fromStdString(Translation::getInstance().translate("showConsole")), 120, 35, ""); - showConsoleBtn->setStyleSheet(R"( - fancyButtonText { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 rgb(80, 180, 80), stop:1 rgb(60, 140, 60)); - border-radius: 8px; - color: white; - font-weight: bold; - } - fancyButtonText:hover { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 rgb(100, 200, 100), stop:1 rgb(80, 160, 80)); - } - )"); - - fancyButtonText* hideConsoleBtn = new fancyButtonText(QString::fromStdString(Translation::getInstance().translate("hideConsole")), 120, 35, ""); - hideConsoleBtn->setStyleSheet(R"( - fancyButtonText { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 rgb(180, 80, 80), stop:1 rgb(140, 60, 60)); - border-radius: 8px; - color: white; - font-weight: bold; - } - fancyButtonText:hover { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 rgb(200, 100, 100), stop:1 rgb(160, 80, 80)); - } - )"); - - fancyButtonText* setResolutionBtn = new fancyButtonText( u8"设置1920x1040"); - setResolutionBtn->setStyleSheet(R"( - fancyButtonText { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 rgb(80, 130, 180), stop:1 rgb(60, 100, 140)); - border-radius: 8px; - color: white; - font-weight: bold; - } - fancyButtonText:hover { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 rgb(100, 150, 200), stop:1 rgb(80, 120, 160)); - } - )"); - - consoletLayout->addWidget(showConsoleBtn); - consoletLayout->addWidget(hideConsoleBtn); - consoletLayout->addWidget(setResolutionBtn); - consoletLayout->addStretch(); - - consoleMainLayout->addLayout(consoletLayout); - - connect(showConsoleBtn, &QPushButton::clicked, [=]() { - ShowWindow(_config->consoleHandle, SW_SHOW); - }); - - connect(hideConsoleBtn, &QPushButton::clicked, [=]() { - ShowWindow(_config->consoleHandle, SW_HIDE); - }); - - connect(setResolutionBtn, &QPushButton::clicked, [=]() { - // 获取当前窗口的顶级窗口 - QWidget* topWidget = this; - while (topWidget->parentWidget()) { - topWidget = topWidget->parentWidget(); - } - - // 设置窗口大小为1920x1080 - topWidget->resize(1920, 1080); - - // 可选:将窗口居中显示 - QScreen* screen = QApplication::primaryScreen(); - if (screen) { - QRect screenGeometry = screen->geometry(); - int x = (screenGeometry.width() - 1920) / 2; - int y = (screenGeometry.height() - 1080) / 2; - if (x >= 0 && y >= 0) { - topWidget->move(x, y); - } - } - }); m_layout->addWidget(consoleGroupBox); - } - // 硬件信息区域 - { - // 创建硬件信息分组容器 - QGroupBox* hardwareGroupBox = new QGroupBox(QString::fromStdString(Translation::getInstance().translate("Hardware Information"))); - hardwareGroupBox->setObjectName("hardwareGroupBox"); - hardwareGroupBox->setStyleSheet(R"( - QGroupBox#hardwareGroupBox { - background: rgb(50, 55, 60); - border-radius: 10px; - font-family: "微软雅黑"; - font-size: 14px; - font-weight: bold; - color: white; - padding-top: 20px; - } - QGroupBox#hardwareGroupBox::title { - subcontrol-origin: margin; - left: 10px; - padding: 0 10px 0 10px; - } - )"); - - QVBoxLayout* hardwareMainLayout = new QVBoxLayout(hardwareGroupBox); - hardwareMainLayout->setContentsMargins(15, 15, 15, 15); - hardwareMainLayout->setSpacing(10); - - // 设置硬件信息组件的样式 - _hardwareInfoWidget.setStyleSheet(R"( - QWidget { - background: transparent; - color: white; - font-family: "微软雅黑"; - } - QLabel { - color: rgb(220, 220, 220); - font-size: 12px; - } - )"); - - hardwareMainLayout->addWidget(&_hardwareInfoWidget); - m_layout->addWidget(hardwareGroupBox); - } - - // 添加底部伸缩空间 - m_layout->addStretch(); - - // 设置滚动区域 - scrollArea->setWidget(contentWidget); - mainLayout->addWidget(scrollArea); - - } -protected: - -private: - appConfig* _config; - //hardwareInfoWidget _hardwareInfoWidget; - //std::vector> privateJsondatas;//路径与数据 - //std::vector> privateWidgets;//路径与数据 - //std::vectorjsonLayouts; -}; -#pragma once \ No newline at end of file diff --git a/eui_581.zip b/eui_581.zip deleted file mode 100644 index 11f5ebe..0000000 Binary files a/eui_581.zip and /dev/null differ diff --git a/git_version.h.in b/git_version.h.in deleted file mode 100644 index 76a8ef3..0000000 --- a/git_version.h.in +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef GIT_VERSION_H -#define GIT_VERSION_H -#define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@" -#endif \ No newline at end of file diff --git a/include/generalJsonParsing.hpp b/include/generalJsonParsing.hpp index d416e7a..171d010 100644 --- a/include/generalJsonParsing.hpp +++ b/include/generalJsonParsing.hpp @@ -1,5 +1,7 @@ -#include +#pragma once +#include #include +#include // 读取json文件,不按顺序 static nlohmann::json readJsonFromPath(std::string path) @@ -121,6 +123,4 @@ static void printNlohmannJson(nlohmann::json input, int depth = 0) else if (input.is_null()) { std::cout << indent_str << "null\n"; } -} - -#pragma once \ No newline at end of file +} \ No newline at end of file diff --git a/include/global.h b/include/global.h index 0331dd3..1a2e036 100644 --- a/include/global.h +++ b/include/global.h @@ -7,8 +7,11 @@ #include #include #include +#include +#include + #pragma execution_character_set("utf-8") -const std::string softwareVersion = "20251108-2.1.8"; +const std::string softwareVersion = "20251116-2.2.0"; const std::string euiJsonVersion = "1.0.6"; #define globalDatabasePth "./sqlDatabase/eui_db.db" //全局数据库路径 #define saveImgEnable 1 @@ -100,18 +103,6 @@ static cv::Mat qImageToCvMat(const QImage& inImage) } return cv::Mat(); } -template -T getMax(const T& a, const T& b) { - return (a > b) ? a : b; -} -template -T getMin(const T& a, const T& b) { - return (a < b) ? a : b; -} -template -T getAbs(const T& value) { - return (value < 0) ? -value : value; -} static void cvMatToQPixMap(cv::Mat& src,QPixmap& pixmap) { pixmap = QPixmap::fromImage(cvMatToQImage(src)); @@ -158,6 +149,25 @@ static std::string getCurrentDateTime() { ss << std::put_time(localTime, "%H-%M-%S") << "-" << std::setfill('0') << std::setw(2) << ms.count(); return ss.str(); } + +static void createDirectoryIfNotExists(const std::string& path) { + // 检查路径是否存在 + if (!std::filesystem::exists(path)) { + // 创建路径 + try { + std::filesystem::create_directories(path); + //std::cout << "已创建文件夹: " << path << std::endl; + } + catch (...) { + qCritical() << "创建文件夹失败!" << QString::fromStdString(path); + } + } +} +static void createDirectoryIfNotExists(const QString& path) { + QDir dir; + dir.mkpath(path); +} + Q_DECLARE_METATYPE(cv::Mat*) Q_DECLARE_METATYPE(cv::Mat) Q_DECLARE_METATYPE(std::string) diff --git a/include/interface.h b/include/interface.h index d2ae433..de56579 100644 --- a/include/interface.h +++ b/include/interface.h @@ -1,21 +1,84 @@ +#pragma once #include -#include #include + +enum initStatus { + NotInit, + InitFailure, + InitOK +}; + +struct showImgPack { + cv::Mat img; + QString name = ""; + QString type; + showImgPack() {}; + showImgPack(QString name, QString type) : type(type), name(name) {} +}; + +enum valueType { + finsShort, + finsFloat +}; + +// PLC 值查看器的配置结构体 +struct PlcValueViewerStruct { + QString valueName; + int valueAddr; + valueType type = finsShort; + QVariant value = -999; +}; + +class bSignalHub :public QObject{ + Q_OBJECT +public: + explicit bSignalHub(QObject* parent = nullptr) : QObject(parent) {} + // 禁止拷贝 + Q_DISABLE_COPY(bSignalHub) +signals: + // 汇总数据 + void summaryData_addData(QString window, double data); + // 日志相关 + void loadingWindow_appendInitLog(const QString& text, const QColor& color); + void loadingWindow_modifyLog(int col, const QString& text, const QColor& color); + void loadingWindow_clearLog(); + // 登录结果 + void initResult(initStatus result); + // 图像显示 + void displayWidget_sendImg(showImgPack pack); + //数据到界面 + void pieWidgetAddNG(); + void pieWidgetAddOK(); + void histogramWidgetAddData(std::vector); + void setPlcConnectionError(); + void setPlcConnectionOk(); + void setCamConnectionError(); + void setCamConnectionOk(); + void waveFormAddData(QString windowName, double value); + //排障 + void runCommand_addBtn(const QString& btnName, const QString& tip, const QString& uuid); + void runCommand_addPlcValueViewer(QString groupName, std::vector> viewerNameAndAddress); + void runCommand_refeshPlcValueViewer(int address, QString value); + void saveMissionJson(); + + //性能监测 + void sendTriggerManagerLoopData(int loopCounterPerMin, int maxInterval); +}; class IBackend :public QThread { Q_OBJECT public: + bSignalHub _signalHub; virtual ~IBackend() = default; - virtual void init(SQLiteDB* ,qtFuncBridge*,nlohmann::ordered_json& json) = 0; + virtual void init(SQLiteDB* ,nlohmann::ordered_json& json) = 0; virtual void cleanup() = 0; - virtual nlohmann::ordered_json getJson() = 0; - virtual void getAllParams(std::vector>* params) = 0; - virtual void editParam(QString name, QVariant value) = 0; + virtual nlohmann::ordered_json getBackendJson() = 0; public slots: virtual bool excuteCliCommand(const QString& command) = 0; virtual bool excuteCliCommandPreset(const QString& uuid) = 0; virtual void triggerAndCaptureImage(std::string cameraName, std::vector* mats) = 0; virtual void getCameraNames(std::vector* cameraNames) = 0; - + virtual void getAllParams(std::vector>* params) = 0; + virtual void editParam(QString group, QString name, QVariant value) = 0; }; extern "C" { @@ -24,4 +87,5 @@ extern "C" { } typedef IBackend* (*CreateBackendFunc)(); typedef void (*ReleaseBackendFunc)(IBackend*); -#pragma once \ No newline at end of file + + diff --git a/include/pluginBase.h b/include/pluginBase.h deleted file mode 100644 index 54ab790..0000000 --- a/include/pluginBase.h +++ /dev/null @@ -1,28 +0,0 @@ - -class Event; -enum pluginState -{ - running, - stop -}; -class IPlugin { -public: - std::string name; - virtual ~IPlugin() {}; - virtual void onEvent(const Event& event) {}; - virtual void init() {}; - virtual bool start() { return true; }; - virtual bool stop() { return true; } - virtual pluginState getState() { return pluginState::running; }; -}; - -class Event { -public: - enum EventType { EVENT_TYPE_A, EVENT_TYPE_B }; - Event(EventType type, int data) : type(type), data(data) {} - EventType type; - int data; -}; - - -#pragma once \ No newline at end of file diff --git a/include/qtBridge.h b/include/qtBridge.h deleted file mode 100644 index d5d4eaf..0000000 --- a/include/qtBridge.h +++ /dev/null @@ -1,119 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -enum initStatus{ - NotInit, - InitFailure, - InitOK -}; - -// 展示图片所需的打包结构体,用于在跨线程信号中携带图像与元信息 -struct showImgPack{ - cv::Mat img; - QString name = ""; - QString type; - showImgPack() {}; - showImgPack(QString name,QString type) : type(type), name(name) {} -}; - -enum valueType { - finsShort, - finsFloat -}; - -// PLC 值查看器的配置结构体 -struct PlcValueViewerStruct { - QString valueName; - int valueAddr; - valueType type = finsShort; - QVariant value = -999; -}; - -class qtFuncBridge : public QObject { - Q_OBJECT -public: - // 获取单例实例(线程不安全的延迟初始化,适用于主线程初始化) - static qtFuncBridge* getInstance() { - static qtFuncBridge* s_instance = nullptr; - if (!s_instance) { - // intentionally leaked: lives for application lifetime - s_instance = new qtFuncBridge(nullptr); - } - return s_instance; - } - - // 禁止拷贝 - Q_DISABLE_COPY(qtFuncBridge) - -signals: - // 日志相关 - void loadingWindow_appendInitLog(const QString& text, const QColor& color); - void loadingWindow_modifyLog(int col, const QString& text, const QColor& color); - void loadingWindow_clearLog(); - - // 登录结果 - void initResult(initStatus result); - - // 图像显示 - void displayWidget_sendImg(showImgPack pack); - - // 汇总数据 - void summaryData_addData(QString window, double data); - - //数据到界面 - void pieWidgetAddNG(); - void pieWidgetAddOK(); - void histogramWidgetAddData(std::vector); - void setPlcConnectionError(); - void setPlcConnectionOk(); - void setCamConnectionError(); - void setCamConnectionOk(); - void waveFormAddData(QString windowName, double value); - /////////////////////////////////////////////// - // 切换界面 - void switchMainStakedWidget(int index); - - // UI 效果 - void passWordEditShake(); - - // 加载窗口状态图标 - void loadingWindow_SetLoadingIcon(); - void loadingWindow_SetErrorIcon(); - void loadingWindow_SetErrorText(QString text); - - // 警告日志 - void loadingWindow_appendWarningLog(QString text); - void loadingWindow_clearWarningLog(); - ////////////////////////////////////////////////////////////// - void restartInit(); - - //排障 - void runCommand_addBtn(const QString& btnName, const QString& tip, const QString& uuid); - void runCommand_addPlcValueViewer(QString groupName, std::vector> viewerNameAndAddress); - void runCommand_refeshPlcValueViewer(int address,QString value); - - //性能监测 - void sendTriggerManagerLoopData(int loopCounterPerMin,int maxInterval); - - void triggerAndCaptureImage(std::string cameraName, std::vector* mats); - void getCameraNames(std::vector* cameraNames); - void getAllParams(std::vector>* params); - void editParam(QString name, QVariant value); - void saveMissionJson(); -private: - explicit qtFuncBridge(QObject* parent = nullptr) : QObject(parent) {} - ~qtFuncBridge() = default; -}; - diff --git a/include/simpleAlgo.h b/include/simpleAlgo.h index 2e15925..70dd8f5 100644 --- a/include/simpleAlgo.h +++ b/include/simpleAlgo.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #pragma once using namespace HalconCpp; @@ -88,16 +89,16 @@ static cv::Mat cutImg2Cls(cv::Rect boundingBox, cv::Mat imgInput, cv::Size targe // 以目标框中心为正方形中心,边长为 max(max(w,h),128) const cv::Point mid(boundingBox.x + boundingBox.width / 2, boundingBox.y + boundingBox.height / 2); - const int sideLength = getMax(getMax(boundingBox.width, boundingBox.height), 128); + const int sideLength = std::max(std::max(boundingBox.width, boundingBox.height), 128); // 期望在原图上的 ROI(可能越界) cv::Rect expectRect(mid.x - sideLength / 2, mid.y - sideLength / 2, sideLength, sideLength); // 计算需要的边界填充(反射填充) - const int left = getMax(0, -expectRect.x); - const int top = getMax(0, -expectRect.y); - const int right = getMax(0, expectRect.x + expectRect.width - imgInput.cols); - const int bottom = getMax(0, expectRect.y + expectRect.height - imgInput.rows); + const int left = std::max(0, -expectRect.x); + const int top = std::max(0, -expectRect.y); + const int right = std::max(0, expectRect.x + expectRect.width - imgInput.cols); + const int bottom = std::max(0, expectRect.y + expectRect.height - imgInput.rows); cv::Mat padded; if (left || top || right || bottom) { @@ -126,7 +127,7 @@ static std::vector cutImg2ClsVec(cv::Rect boundingBox, cv::Mat imgInput const int w = boundingBox.width; const int h = boundingBox.height; - const int minSide = getMin(w, h); + const int minSide = std::min(w, h); if (minSide <= 0) { std::cerr << "Bounding box has zero width or height." << std::endl; return result; @@ -622,7 +623,7 @@ static cv::Rect doMatchTemplate(const cv::Mat& templateImg, const cv::Mat& srcIm static bool isContoursOverlap(const std::vector& contour1, const std::vector& contour2, double thresholdPercent = 0) { cv::Rect rect1 = cv::boundingRect(contour1); cv::Rect rect2 = cv::boundingRect(contour2); - cv::Size tempImgSize(getMax(rect1.x + rect1.width, rect2.x + rect2.width), getMax(rect1.y + rect1.height, rect2.y + rect2.height)); + cv::Size tempImgSize(std::max(rect1.x + rect1.width, rect2.x + rect2.width), std::max(rect1.y + rect1.height, rect2.y + rect2.height)); cv::Mat binaryImage = cv::Mat::zeros(tempImgSize, CV_8U); // 画出目标轮廓 @@ -651,7 +652,7 @@ static bool isRectOverlap(const cv::Rect& rect1, const cv::Rect& rect2, double t cv::Rect intersection = rect1 & rect2; if (thresholdPercent != 0)//如果有阈值 { - int maxCnotourArea = getMax(rect1.area(), rect2.area()); + int maxCnotourArea = std::max(rect1.area(), rect2.area()); if (intersection.area() / maxCnotourArea < thresholdPercent) return false; } @@ -740,7 +741,7 @@ static cv::Mat tiledImages(std::vector& imgs) int matWidth = 0, matHeight = 0; for (auto& mat : imgs) { - matHeight = getMax(mat.rows, matHeight); + matHeight = std::max(mat.rows, matHeight); matWidth += mat.cols; } cv::Mat showMat(matHeight, matWidth, CV_8UC3); @@ -806,7 +807,7 @@ static void denoiseImage(const cv::Mat& inputMat, cv::Mat& outputMat, int kernel } // 兜底:使用可分离高斯滤波,适合较大核或需要指定平滑强度的场景 - const double sigmaChecked = getMax(0.0, sigma); + const double sigmaChecked = std::max(0.0, sigma); cv::GaussianBlur(inputMat, outputMat, cv::Size(k, k), sigmaChecked, sigmaChecked, cv::BORDER_DEFAULT); } diff --git a/include/simpleTools/writeExcel.cpp b/include/simpleTools/writeExcel.cpp index 045e6aa..db013e8 100644 --- a/include/simpleTools/writeExcel.cpp +++ b/include/simpleTools/writeExcel.cpp @@ -12,9 +12,9 @@ // std::vector < std::pair> // sonMerges = writeExcelLoop(sheet, input.nexCols[i], depth + 1, cols + depthCount); // mergeStr.insert(mergeStr.end(), sonMerges.begin(), sonMerges.end()); -// depthCount += getMax((int)input.nexCols[i].nexCols.size(), 1); +// depthCount += std::max((int)input.nexCols[i].nexCols.size(), 1); // } -// std::string endUnit = char(65 + depth) + std::to_string(cols + getMax(depthCount - 1, 0)); +// std::string endUnit = char(65 + depth) + std::to_string(cols + std::max(depthCount - 1, 0)); // sheet.cell(startUnit).value() = input.text; // mergeStr.push_back(std::make_pair(startUnit, endUnit)); // return mergeStr; diff --git a/include/sql/qSqlBase.h b/include/sql/qSqlBase.h index 65d02f5..bf894a5 100644 --- a/include/sql/qSqlBase.h +++ b/include/sql/qSqlBase.h @@ -32,8 +32,8 @@ class SQLiteDB { public: QSqlDatabase db; - // 新增:全局互斥锁,保护所有数据库操作 - mutable QMutex db_mutex; + // 改为递归互斥锁,解决嵌套调用问题 + mutable QRecursiveMutex db_mutex; SQLiteDB(const QString& dbPath) : dbPath(dbPath) { @@ -41,9 +41,8 @@ public: } ~SQLiteDB() { disconnect(); }; - // 所有公有方法加锁保护 - bool execute(const QString& queryStr, const QVariantList& args = {}) { - QMutexLocker lock(&db_mutex); + // 添加内部无锁版本,避免嵌套锁问题 + bool execute_unsafe(const QString& queryStr, const QVariantList& args = {}) { QSqlQuery query(db); query.prepare(queryStr); @@ -59,8 +58,7 @@ public: return true; } - QList> query(const QString& queryStr, const QVariantList& args = {}) { - QMutexLocker lock(&db_mutex); + QList> query_unsafe(const QString& queryStr, const QVariantList& args = {}) { QList> results; QSqlQuery query(db); query.prepare(queryStr); @@ -86,6 +84,17 @@ public: return results; } + // 公有方法保持加锁保护 + bool execute(const QString& queryStr, const QVariantList& args = {}) { + QMutexLocker lock(&db_mutex); + return execute_unsafe(queryStr, args); + } + + QList> query(const QString& queryStr, const QVariantList& args = {}) { + QMutexLocker lock(&db_mutex); + return query_unsafe(queryStr, args); + } + bool createTable(const QString& tableName, const QList>& columns) { QMutexLocker lock(&db_mutex); if (columns.empty()) { @@ -101,22 +110,18 @@ public: QString sql = QString("CREATE TABLE IF NOT EXISTS \"%1\" (%2)") .arg(tableName) .arg(columnDefinitions.join(", ")); - QSqlQuery query(db); - bool res = query.exec(sql); - return res; + + return execute_unsafe(sql); } std::vector getTables() { QMutexLocker lock(&db_mutex); std::vector tables; QString sql = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';"; - QSqlQuery query(db); - if (!query.exec(sql)) { - qDebug() << "getTables failed:" << query.lastError().text(); - return tables; - } - while (query.next()) { - tables.push_back(query.value(0).toString()); + + auto result = query_unsafe(sql); + for (const auto& row : result) { + tables.push_back(row.value("name").toString()); } return tables; } @@ -124,7 +129,7 @@ public: bool dropTable(const QString& tableName) { QMutexLocker lock(&db_mutex); QString sql = QString("DROP TABLE IF EXISTS %1").arg(tableName); - return execute(sql); + return execute_unsafe(sql); } bool addColumn(const QString& tableName, const QString& columnName, const QString& columnType) { @@ -135,12 +140,9 @@ public: } QString sql = QString("ALTER TABLE \"%1\" ADD COLUMN \"%2\" %3").arg(tableName, columnName, columnType); - - QSqlQuery query(db); - query.prepare(sql); - - if (!query.exec()) { - qDebug() << "Add column failed:" << query.lastError().text(); + + if (!execute_unsafe(sql)) { + qDebug() << "Add column failed"; return false; } @@ -152,13 +154,48 @@ public: QMutexLocker lock(&db_mutex); QString sql = QString("SELECT name FROM sqlite_master WHERE type='table' AND name='%1';").arg(tableName); - QList> result = query(sql); + QList> result = query_unsafe(sql); return !result.isEmpty(); } - bool _insert(const QString& tableName, - const std::map& data) { + // 添加批量操作支持,减少锁竞争 + bool batchInsert(const QString& tableName, const std::vector>& dataList) { + if (dataList.empty()) { + qDebug() << "Batch insert failed: data is empty."; + return false; + } + QMutexLocker lock(&db_mutex); + + // 开始事务 + if (!execute_unsafe("BEGIN TRANSACTION;")) { + return false; + } + + bool allSuccess = true; + for (const auto& data : dataList) { + if (!_insert_unsafe(tableName, data)) { + allSuccess = false; + break; + } + } + + if (allSuccess) { + execute_unsafe("COMMIT;"); + } else { + execute_unsafe("ROLLBACK;"); + } + + return allSuccess; + } + + bool _insert(const QString& tableName, const std::map& data) { + QMutexLocker lock(&db_mutex); + return _insert_unsafe(tableName, data); + } + +private: + bool _insert_unsafe(const QString& tableName, const std::map& data) { if (data.empty()) { qDebug() << "Insert failed: data is empty."; return false; @@ -169,53 +206,51 @@ public: return false; } - QStringList columns, values; + QStringList columns, placeholders; + QVariantList values; + for (const auto& pair : data) { columns << pair.first; - values << "'" + pair.second.toString().replace("'", "''") + "'"; + placeholders << "?"; + values << pair.second; } QString sql = QString("INSERT INTO \"%1\" (%2) VALUES (%3)") .arg(tableName) .arg(columns.join(", ")) - .arg(values.join(", ")); + .arg(placeholders.join(", ")); - qDebug() << "Generated SQL: " << sql; - - QSqlQuery query(db); - - if (!db.isOpen()) { - qDebug() << "Database is not open!"; - return false; - } - - if (!query.exec(sql)) { - qDebug() << "Insert failed:" << query.lastError().text(); - return false; - } - - return true; + return execute_unsafe(sql, values); } +public: bool _update(const QString& tableName, const std::map& data, const std::map& conditions) { QMutexLocker lock(&db_mutex); + return _update_unsafe(tableName, data, conditions); + } + +private: + bool _update_unsafe(const QString& tableName, + const std::map& data, + const std::map& conditions) { if (data.empty() || conditions.empty()) { qDebug() << "Update failed: data or conditions are empty."; return false; } - QStringList setClauses; + QStringList setClauses, whereClauses; + QVariantList values; + for (const auto& pair : data) { - QString value = pair.second.toString().replace("'", "''"); - setClauses << QString("%1 = '%2'").arg(pair.first).arg(value); + setClauses << QString("%1 = ?").arg(pair.first); + values << pair.second; } - QStringList whereClauses; for (const auto& pair : conditions) { - QString conditionValue = pair.second.toString().replace("'", "''"); - whereClauses << QString("%1 = '%2'").arg(pair.first).arg(conditionValue); + whereClauses << QString("%1 = ?").arg(pair.first); + values << pair.second; } QString sql = QString("UPDATE \"%1\" SET %2 WHERE %3") @@ -223,175 +258,147 @@ public: .arg(setClauses.join(", ")) .arg(whereClauses.join(" AND ")); - qDebug() << "Generated SQL: " << sql; - - QSqlQuery query(db); - - if (!db.isOpen()) { - qDebug() << "Database is not open!"; - return false; - } - - if (!query.exec(sql)) { - qDebug() << "Update failed:" << query.lastError().text(); - return false; - } - - return true; + return execute_unsafe(sql, values); } - bool _delete(const QString& tableName, - const std::map& conditions) { - QMutexLocker lock(&db_mutex); +public: + bool _delete(const QString& tableName, const std::map& conditions) { + QMutexLocker lock(&db_mutex); + return _delete_unsafe(tableName, conditions); + } + +private: + bool _delete_unsafe(const QString& tableName, const std::map& conditions) { if (conditions.empty()) { qDebug() << "Delete failed: conditions are empty."; return false; } QStringList whereClauses; + QVariantList values; + for (const auto& pair : conditions) { - whereClauses << QString("%1 = :%2").arg(pair.first).arg(pair.first + "_condition"); + whereClauses << QString("%1 = ?").arg(pair.first); + values << pair.second; } QString sql = QString("DELETE FROM \"%1\" WHERE %2") .arg(tableName) .arg(whereClauses.join(" AND ")); - QSqlQuery query(db); - query.prepare(sql); - - for (const auto& pair : conditions) { - query.bindValue(":" + pair.first + "_condition", QVariant::fromValue(pair.second)); - } - - if (!query.exec()) { - qDebug() << "Delete failed:" << query.lastError().text(); - return false; - } - - return true; + return execute_unsafe(sql, values); } +public: std::vector> _search(const QString& tableName, const QStringList& columns, const std::map& conditions = {}) { - QMutexLocker lock(&db_mutex); + QMutexLocker lock(&db_mutex); + return _search_unsafe(tableName, columns, conditions); + } + +private: + std::vector> _search_unsafe(const QString& tableName, + const QStringList& columns, + const std::map& conditions = {}) { + QStringList selectColumns = columns.isEmpty() ? QStringList("*") : columns; - QString sql = QString("SELECT %1 FROM \"%2\"").arg(selectColumns.join(", "), tableName); - + + QVariantList values; if (!conditions.empty()) { QStringList whereClauses; for (const auto& pair : conditions) { - QString value = pair.second.toString().replace("'", "''"); - whereClauses << QString("%1 = '%2'").arg(pair.first).arg(value); + whereClauses << QString("%1 = ?").arg(pair.first); + values << pair.second; } sql += " WHERE " + whereClauses.join(" AND "); } - qDebug() << "Generated SQL: " << sql; - - QSqlQuery query(db); - - if (!db.isOpen()) { - qDebug() << "Database is not open!"; - return {}; - } - - if (!query.exec(sql)) { - qDebug() << "Search failed:" << query.lastError().text(); - return {}; - } - + auto result = query_unsafe(sql, values); std::vector> results; - while (query.next()) { - std::map row; - for (int i = 0; i < query.record().count(); ++i) { - row[query.record().fieldName(i)] = query.value(i); + + for (const auto& row : result) { + std::map rowMap; + for (auto it = row.begin(); it != row.end(); ++it) { + rowMap[it.key()] = it.value(); } - results.push_back(row); + results.push_back(rowMap); } return results; } +public: QList> queryTabelData(const QString& tableName) { - QMutexLocker lock(&db_mutex); + QMutexLocker lock(&db_mutex); QString sql = QString("SELECT * FROM \"%1\"").arg(tableName); - return query(sql); + return query_unsafe(sql); } - bool exportTableToCSV(const QString& tableName, const QString& filePath, std::mutex& _mutex) { - QMutexLocker lock(&db_mutex); + // 移除外部 mutex 参数,避免锁顺序问题 + bool exportTableToCSV(const QString& tableName, const QString& filePath) { + QMutexLocker lock(&db_mutex); using namespace std::chrono; auto start = high_resolution_clock::now(); - QString csvFileName = filePath; QString sql = QString("SELECT * FROM \"%1\"").arg(tableName); - QSqlQuery query(db); - - if (!query.exec(sql)) { - qCritical() << "Query execution failed: " << query.lastError().text(); - return false; - } - - if (!query.next()) { + + auto result = query_unsafe(sql); + if (result.isEmpty()) { qDebug() << "No data found in table" << tableName; return false; } - QFile file(csvFileName); + QFile file(filePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - qCritical() << "Failed to open file" << csvFileName; + qCritical() << "Failed to open file" << filePath; return false; } QTextStream out(&file); - QSqlRecord record = query.record(); - QStringList columns; - for (int i = 0; i < record.count(); ++i) { - columns << record.fieldName(i); - } + // 写入表头 + if (!result.isEmpty()) { + QStringList columns = result.first().keys(); + out << columns.join(",") << "\n"; - out << columns.join(",") << "\n"; - - do { - QStringList values; - for (const auto& column : columns) { - values << query.value(column).toString(); + // 写入数据 + for (const auto& row : result) { + QStringList values; + for (const auto& column : columns) { + values << row.value(column).toString(); + } + out << values.join(",") << "\n"; } - out << values.join(",") << "\n"; - } while (query.next()); + } file.close(); auto end = high_resolution_clock::now(); auto duration = duration_cast(end - start); - qDebug() << csvFileName << "EXPORT CSV COST: " << duration.count() << "ms"; + qDebug() << filePath << "EXPORT CSV COST: " << duration.count() << "ms"; return true; } bool setWALMode(bool enableWAL = true, int busyTimeoutMs = 3000) { - QMutexLocker lock(&db_mutex); + QMutexLocker lock(&db_mutex); if (!db.isOpen()) { qWarning() << "Database is not open, cannot set WAL mode."; return false; } - QSqlQuery pragma(db); - QString mode = enableWAL ? "WAL" : "DELETE"; - if (!pragma.exec(QString("PRAGMA journal_mode=%1;").arg(mode))) { - qWarning() << "Failed to set journal_mode:" << pragma.lastError().text(); + if (!execute_unsafe(QString("PRAGMA journal_mode=%1;").arg(mode))) { + qWarning() << "Failed to set journal_mode"; return false; } qDebug() << "SQLite journal_mode set to" << mode; if (enableWAL) { - pragma.exec("PRAGMA synchronous=NORMAL;"); + execute_unsafe("PRAGMA synchronous=NORMAL;"); } - pragma.exec(QString("PRAGMA busy_timeout=%1;").arg(busyTimeoutMs)); + execute_unsafe(QString("PRAGMA busy_timeout=%1;").arg(busyTimeoutMs)); return true; } @@ -416,23 +423,18 @@ private: qDebug() << "Connected to SQLite database:" << dbPath; - { - QSqlQuery pragma(db); - - if (!pragma.exec("PRAGMA journal_mode=WAL;")) { - qWarning() << "Failed to enable WAL mode:" << pragma.lastError().text(); - } - else { - qDebug() << "SQLite WAL mode enabled."; - } - pragma.exec("PRAGMA synchronous=NORMAL;"); - pragma.exec("PRAGMA busy_timeout=3000;"); + // 设置 WAL 模式和其他 PRAGMA + if (!execute_unsafe("PRAGMA journal_mode=WAL;")) { + qWarning() << "Failed to enable WAL mode"; + } else { + qDebug() << "SQLite WAL mode enabled."; } + execute_unsafe("PRAGMA synchronous=NORMAL;"); + execute_unsafe("PRAGMA busy_timeout=3000;"); - createTable("setting", - { - {"id","INTEGER PRIMARY KEY AUTOINCREMENT"} , - }); + createTable("setting", { + {"id","INTEGER PRIMARY KEY AUTOINCREMENT"} + }); return true; } @@ -449,161 +451,93 @@ private: QString dbPath; }; -class CsvWriter : public QThread{ +class CsvWriter : public QThread { public: - CsvWriter(SQLiteDB* dbIn):db(dbIn){ - try{ - m_json = readJsonFromPath("./sqldrivers/sqliteCfg.json"); - for (auto& data : m_json["数据列表"]) { - db_InitColumns.append({ QString::fromStdString(data),"TEXT" }); - } - for (auto& data : m_json["链接到UI表格数据列表"].items()) { - csvAndChartLink[QString::fromStdString(data.key())] = QString::fromStdString(data.value()); - } - if (m_json["新增数据列表"].size() > 0) { - for (auto& data : m_json["新增数据列表"]) { - db_newCol.append({ QString::fromStdString(data),"TEXT" }); - } - m_json["新增数据列表"].clear(); - saveJsonFromPath("./sqldrivers/sqliteCfg.json", m_json); - } - for (auto& data : m_json["判断NG依据数据列表"]) { - isNgDepends.push_back(QString::fromStdString(data)); - } - } - catch (const std::exception&){ - std::cerr << "readJsonFromPath error" << std::endl; - } - init(); + CsvWriter(SQLiteDB* dbIn, QList>externalInitDataVec = QList>()) : db(dbIn) { + db_InitColumns.append(externalInitDataVec); } - ~CsvWriter(){ - //stopAutoExport(); + ~CsvWriter() { + // 确保线程安全退出 + if (isRunning()) { + quit(); + wait(5000); // 等待最多5秒 + } } - std::mapcsvAndChartLink; + std::map csvAndChartLink; SQLiteDB* db; void addData(QString snCode, std::map data) { if (snCode.isEmpty()) { - qWarning() << "addtData: snCode is empty."; + qWarning() << "addData: snCode is empty."; return; } if (data.empty()) { - qWarning() << "addtData: data is empty."; + qWarning() << "addData: data is empty."; return; } - QMutexLocker locker(&queueLock); - queue.enqueue(std::make_pair(snCode, data)); - this->start(); + + { + QMutexLocker locker(&queueLock); + queue.enqueue(std::make_pair(snCode, data)); + } + + if (!isRunning()) { + start(); + } } bool isNewData(const QString& snCode) { - QMutexLocker locker(&db->db_mutex); - auto res = db->_search(getCurrentProcessCsvName(), {}, { {"条码",snCode} }); + auto res = db->_search(getCurrentProcessCsvName(), {}, { {"条码", snCode} }); return res.empty(); } + bool isNgData(const QString& snCode) { - QMutexLocker locker(&db->db_mutex); - auto res = db->_search(getCurrentProcessCsvName(), {}, { {"条码",snCode} }); - if (res.empty() == true) + auto res = db->_search(getCurrentProcessCsvName(), {}, { {"条码", snCode} }); + if (res.empty()) { return false; - for (auto& data : isNgDepends) { - if (res[0][data].toString() == "NG") + } + + for (const auto& data : isNgDepends) { + if (res[0][data].toString() == "NG") { return true; + } } return false; } - void run() override{ - while (queue.size() > 0) { +protected: + void run() override { + while (true) { std::pair> val; + + // 从队列获取数据 { QMutexLocker locker(&queueLock); + if (queue.isEmpty()) { + break; + } val = queue.dequeue(); } + try { - auto snCode = val.first; - auto data = val.second; - QString currentProcessCsvName = getCurrentProcessCsvName(); - if (currentProcessCsvName != currentProcessCsvNameCache) { - QMutexLocker locker(&db->db_mutex); - if (!db->createTable(currentProcessCsvName, db_InitColumns)) { - qWarning() << "addtData: Failed to create table:" << currentProcessCsvName; - return; - } - currentProcessCsvNameCache = currentProcessCsvName; - } - QList tableColumns; - { - QMutexLocker locker(&db->db_mutex); - QSqlQuery colQuery(db->db); - QString colSql = QString("PRAGMA table_info(\"%1\")").arg(currentProcessCsvName); - if (colQuery.exec(colSql)) { - while (colQuery.next()) { - tableColumns.append(colQuery.value(1).toString()); - } - } - } - for (const auto& kv : data) { - if (!tableColumns.contains(kv.first)) { - if (!db->addColumn(currentProcessCsvName, kv.first, "TEXT")) { - qWarning() << "addtData: Failed to add column:" << kv.first << "to table:" << currentProcessCsvName; - } - } - } - std::vector> res; - { - res = db->_search(currentProcessCsvName, {}, { {"条码",snCode} }); - } - QString nowTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"); - bool opResult = false; - if (res.empty()) { - std::vector> lastRes; - { - lastRes = db->_search(getLastProcessCsvName(), {}, { {"条码",snCode} }); - } - if (lastRes.empty()) { - std::map insertData = data; - insertData["条码"] = snCode; - insertData["创建时间"] = nowTime; - insertData["修改时间"] = nowTime; - opResult = db->_insert(currentProcessCsvName, insertData); - if (!opResult) { - qWarning() << "addtData: Insert failed for table:" << currentProcessCsvName << "snCode:" << snCode; - } - } - else { - std::map updateData = data; - updateData["修改时间"] = nowTime; - opResult = db->_update(getLastProcessCsvName(), updateData, { {"条码",snCode} }); - if (!opResult) { - qWarning() << "addtData: Update failed for table:" << getLastProcessCsvName() << "snCode:" << snCode; - } - } - } - else { - std::map updateData = data; - updateData["修改时间"] = nowTime; - opResult = db->_update(getCurrentProcessCsvName(), updateData, { {"条码",snCode} }); - if (!opResult) { - qWarning() << "addtData: Update failed for table:" << getCurrentProcessCsvName() << "snCode:" << snCode; - } - } + processData(val.first, val.second); } catch (const std::exception& ex) { - qCritical() << "addtData: Exception caught:" << ex.what(); + qCritical() << "addData: Exception caught:" << ex.what(); } catch (...) { - qCritical() << "addtData: Unknown exception caught."; + qCritical() << "addData: Unknown exception caught."; } } } private: + // 统一锁顺序:先队列锁,再数据库锁 QMutex queueLock; - QQueue>> queue; + QQueue>> queue; std::vector isNgDepends; - QQueue> > addDataCacheQueue; + std::mutex _mutex; int m_intervalMs = 10000; QElapsedTimer timer; @@ -615,21 +549,100 @@ private: {"创建时间", "TEXT"}, {"修改时间", "TEXT"}, {"CT", "TEXT"}, + {"算法结果", "TEXT"}, + {"AI检测结果", "TEXT"}, }; - void init(){ + void processData(const QString& snCode, const std::map& data) { + QString currentProcessCsvName = getCurrentProcessCsvName(); + + // 确保表存在 + if (currentProcessCsvName != currentProcessCsvNameCache) { + if (!db->createTable(currentProcessCsvName, db_InitColumns)) { + qWarning() << "addData: Failed to create table:" << currentProcessCsvName; + return; + } + currentProcessCsvNameCache = currentProcessCsvName; + } + + // 检查并添加缺失的列 + ensureColumns(currentProcessCsvName, data); + + QString nowTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"); + + // 检查数据是否存在 + auto res = db->_search(currentProcessCsvName, {}, { {"条码", snCode} }); + + if (res.empty()) { + // 检查上一个班次的数据 + auto lastRes = db->_search(getLastProcessCsvName(), {}, { {"条码", snCode} }); + + if (lastRes.empty()) { + // 插入新数据 + std::map insertData = data; + insertData["条码"] = snCode; + insertData["创建时间"] = nowTime; + insertData["修改时间"] = nowTime; + + if (!db->_insert(currentProcessCsvName, insertData)) { + qWarning() << "addData: Insert failed for table:" << currentProcessCsvName << "snCode:" << snCode; + } + } else { + // 更新上一个班次的数据 + std::map updateData = data; + updateData["修改时间"] = nowTime; + + if (!db->_update(getLastProcessCsvName(), updateData, { {"条码", snCode} })) { + qWarning() << "addData: Update failed for table:" << getLastProcessCsvName() << "snCode:" << snCode; + } + } + } else { + // 更新当前数据 + std::map updateData = data; + updateData["修改时间"] = nowTime; + + if (!db->_update(getCurrentProcessCsvName(), updateData, { {"条码", snCode} })) { + qWarning() << "addData: Update failed for table:" << getCurrentProcessCsvName() << "snCode:" << snCode; + } + } + } + + void ensureColumns(const QString& tableName, const std::map& data) { + // 获取当前表的列信息 + QList tableColumns; + auto columnsResult = db->query("PRAGMA table_info(\"" + tableName + "\")"); + + for (const auto& row : columnsResult) { + tableColumns.append(row.value("name").toString()); + } + + // 添加缺失的列 + for (const auto& kv : data) { + if (!tableColumns.contains(kv.first)) { + if (!db->addColumn(tableName, kv.first, "TEXT")) { + qWarning() << "addData: Failed to add column:" << kv.first << "to table:" << tableName; + } + } + } + } + + void init() { std::lock_guard locker(_mutex); + if (!db->createTable(getLastProcessCsvName(), db_InitColumns)) { qDebug() << "Failed to create table " << getLastProcessCsvName(); } + currentProcessCsvNameCache = getCurrentProcessCsvName(); if (!db->createTable(currentProcessCsvNameCache, db_InitColumns)) { qDebug() << "Failed to create table " << currentProcessCsvNameCache; } - for (auto& data : db_newCol) { + + for (const auto& data : db_newCol) { db->addColumn(getLastProcessCsvName(), data.first, data.second); db->addColumn(getCurrentProcessCsvName(), data.first, data.second); } + timer.start(); } @@ -639,52 +652,48 @@ private: int minute = currentDateTime.time().minute(); bool isDayShift = (hour > 8 || (hour == 8 && minute >= 30)) && (hour < 20 || (hour == 20 && minute <= 30)); bool isDayBefore = hour <= 8 || (hour == 8 && minute <= 29); + QString dateStr; - if (isDayBefore == true) + if (isDayBefore) { dateStr = currentDateTime.addDays(-1).toString("yyyy-MM-dd"); - else + } else { dateStr = currentDateTime.toString("yyyy-MM-dd"); - if (isDayShift) { - return (dateStr + "白班"); - } - else { - return (dateStr + "夜班"); } + + return dateStr + (isDayShift ? "白班" : "夜班"); } QString getLastProcessCsvName() { QDateTime currentDateTime = QDateTime::currentDateTime(); int hour = currentDateTime.time().hour(); int minute = currentDateTime.time().minute(); - bool isDayShift = (hour == 8 && minute >= 30) && (hour == 20 && minute <= 30); - bool isDayBefore = hour == 20 && minute <= 30; + bool isDayShift = (hour >= 8 && minute >= 30) && (hour <= 20 && minute <= 30); + bool isDayBefore = hour <= 20 && minute <= 30; + QDateTime lastShiftDateTime; if (isDayBefore) { lastShiftDateTime = currentDateTime.addDays(-1); - } - else + } else { lastShiftDateTime = currentDateTime; + } + QString dateStr = lastShiftDateTime.toString("yyyy-MM-dd"); - if (isDayShift) { - return (dateStr + "夜班"); - } - else { - return (dateStr + "白班"); - } + return dateStr + (isDayShift ? "夜班" : "白班"); } - void exportCsv(){ + void exportCsv() { QString name = getLastProcessCsvName(); - db->exportTableToCSV(name, "./csv/"+ name +".csv", _mutex); + db->exportTableToCSV(name, "./csv/" + name + ".csv"); + name = getCurrentProcessCsvName(); - db->exportTableToCSV(name, "./csv/" + name + ".csv", _mutex); + db->exportTableToCSV(name, "./csv/" + name + ".csv"); + QString currentProcessCsvName = getCurrentProcessCsvName(); - if (currentProcessCsvName != currentProcessCsvNameCache) - if (!db->createTable(currentProcessCsvName, db_InitColumns)) { - return; - } - else + if (currentProcessCsvName != currentProcessCsvNameCache) { + if (db->createTable(currentProcessCsvName, db_InitColumns)) { currentProcessCsvNameCache = currentProcessCsvName; + } + } } }; diff --git a/include/subModuleBase.h b/include/subModuleBase.h index 9f0300a..6d1d391 100644 --- a/include/subModuleBase.h +++ b/include/subModuleBase.h @@ -5,6 +5,8 @@ #include #include #include +#include + class dsModuleBase { public: diff --git a/include/sxGlobal.h b/include/sxGlobal.h index 515b08c..27ccc88 100644 --- a/include/sxGlobal.h +++ b/include/sxGlobal.h @@ -103,7 +103,7 @@ public: /// 算法函数 /// void init(std::string cameraNameIn, QString viewerNameIN, std::vector addressIN, int oneTriggerCaptrueTimesIN, - paramTemplte* detParamsIn, ServiceManager* _serviceManagerIn, qtFuncBridge* bridgeIn, + paramTemplte* detParamsIn, ServiceManager* _serviceManagerIn, bSignalHub* bridgeIn, typename detCallbackChain::processAlgoCallback _processAlgoCallback, QString saveObjectNameIN = "") { viewerName = viewerNameIN; @@ -138,7 +138,7 @@ public: std::string sn; for (auto& snAddr : address[batteryOffset].snAddr) { - sn.append(_serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snAddr, false, false, -1)); + sn.append(_serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snAddr, true, false, -1)); if (snAddr != address[batteryOffset].snAddr.back()) { sn.append("_"); } @@ -150,13 +150,12 @@ public: QString::fromStdString(cameraName), sn, oneTriggerCaptrueTimes, camera->config.oriSaveFormat);//创建数据包 QString saveObjectName = ""; data->saveObjectName = saveObjectName; - for (int i = 0; i < oneTriggerCaptrueTimes; i++) - camera->captureImage(data);//拍照 + camera->captureImage(data);//拍照 generalDet->ansyncProcess(data, address[batteryOffset], ("D" + address[0].completeAddr + "_1"));//处理算法 并在取到图片后发送完成信号 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); } private: QString saveObjectName = ""; - qtFuncBridge* bridge; + bSignalHub* bridge; ServiceManager* _serviceManager = nullptr; }; \ No newline at end of file diff --git a/include/yhGlobal.h b/include/yhGlobal.h index f999c2c..0ef7fe0 100644 --- a/include/yhGlobal.h +++ b/include/yhGlobal.h @@ -55,6 +55,24 @@ public: //算法回调函数需要包含完整的算法流程以及发送信号,发送ui图表,捕获异常,处理异常等操作 //并且注意 异常可能会导致运行不到发送信号的函数,请在处理异常时发送异常结果 + + +void generalExceptionResume(std::shared_ptr data, yh_581_address address, QString why = "") { + qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode) << why; + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + textPainter.putText(Paint, why.toStdString(), cv::Point(500, 50), cv::Scalar(0, 255, 0)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->resultImgs.push_back(Paint); + if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool()) + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + else + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//结果反馈 +} static bool generalAlgoTest(std::shared_ptr data, detParams* _detParams, yh_581_address address) { try { qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; @@ -82,9 +100,9 @@ static bool generalAlgoTest(std::shared_ptr data, detParams* _detParam else src1.copyTo(Paint); - TextRendererZH textPainter(Paint.cols, Paint.rows, 15); - textPainter.putText(Paint, "划伤", cv::Point(10,10), cv::Scalar(0, 255, 0)); - cv::putText(Paint, "pos:" + data->additional["触发地址"].toString().toStdString(), cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 0, 0), 2); + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + textPainter.putText(Paint, "OK", cv::Point(10,10), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.123");//发送数据1 data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2)+ "_0.456");//发送数据2 data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 @@ -96,8 +114,8 @@ static bool generalAlgoTest(std::shared_ptr data, detParams* _detParam data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送异常结果 return false; } -template +template //此类适用于单相机多触发地址需要联合判断的情况的情况 比如顶盖焊,包膜,入壳机台 //例触发地址有4个,输入信号为 1 0 0 1 则触发1和4的地址拍照检测,2和3拍照取图并废弃 class _581_Union_triggerTemplate { @@ -122,7 +140,7 @@ public: /// 算法函数 /// void init(std::string cameraNameIn, QString viewerNameIN, int startAddr, int triggerCount,int oneTriggerCaptrueTimesIN, - paramTemplte* detParamsIn, ServiceManager* _serviceManagerIn, qtFuncBridge* bridgeIn, + paramTemplte* detParamsIn, ServiceManager* _serviceManagerIn, bSignalHub* bridgeIn, typename detCallbackChain::processAlgoCallback _processAlgoCallback, QString saveObjectNameIN = "") { viewerName = viewerNameIN; @@ -175,8 +193,7 @@ public: QString::fromStdString(cameraName), sn, oneTriggerCaptrueTimes, camera->config.oriSaveFormat);//创建数据包 data->saveObjectName = saveObjectName; - for(int i=0;i< oneTriggerCaptrueTimes;i++) - camera->captureImage(data);//拍照 + camera->captureImage(data);//拍照 generalDet->ansyncProcess(data, address[batteryOffset]);//处理算法 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); @@ -190,7 +207,7 @@ public: } private: QString saveObjectName = ""; - qtFuncBridge* bridge; + bSignalHub* bridge; ServiceManager* _serviceManager = nullptr; }; @@ -219,7 +236,7 @@ public: /// 算法函数 /// void init(std::string cameraNameIn, QString viewerNameIN, int startAddr, int triggerCount, int oneTriggerCaptrueTimesIN, - paramTemplte2* detParamsIn, ServiceManager* _serviceManagerIn, qtFuncBridge* bridgeIn, + paramTemplte2* detParamsIn, ServiceManager* _serviceManagerIn, bSignalHub* bridgeIn, typename detCallbackChain::processAlgoCallback _processAlgoCallback, QString saveObjectNameIN = "") { viewerName = viewerNameIN; @@ -263,14 +280,13 @@ public: QString::fromStdString(cameraName), sn, oneTriggerCaptrueTimes, camera->config.oriSaveFormat);//创建数据包 data->saveObjectName = saveObjectName; - for (int i = 0; i < oneTriggerCaptrueTimes; i++) - camera->captureImage(data);//拍照 + camera->captureImage(data);//拍照 generalDet->ansyncProcess(data, address[batteryOffset]);//处理算法 data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图")); } private: QString saveObjectName = ""; - qtFuncBridge* bridge; + bSignalHub* bridge; ServiceManager* _serviceManager = nullptr; }; \ No newline at end of file diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 8fb6cfc..0000000 --- a/readme.txt +++ /dev/null @@ -1,3 +0,0 @@ -展图时,如果图像的长宽超过5000像素时会被压缩一半,直到长宽不超过5000 -3D相机连接示例 -算法回调函数需要包含完整的算法流程以及发送信号,发送ui图表等操作 \ No newline at end of file diff --git a/rpcModule/rpc_finsTcp/CMakeLists.txt b/rpcModule/rpc_finsTcp/CMakeLists.txt index 33c8bb1..c7632c9 100644 --- a/rpcModule/rpc_finsTcp/CMakeLists.txt +++ b/rpcModule/rpc_finsTcp/CMakeLists.txt @@ -28,12 +28,11 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "./*.h" ) FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") #find_package(Qt5 COMPONENTS Core REQUIRED) diff --git a/src/Core/CMakeLists.txt b/src/Core/CMakeLists.txt index 9a59a5b..92f3dc8 100644 --- a/src/Core/CMakeLists.txt +++ b/src/Core/CMakeLists.txt @@ -19,8 +19,6 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/service ${CMAKE_CURRENT_SOURCE_DIR}/front - ${CMAKE_CURRENT_SOURCE_DIR}/handleAi - ${CMAKE_CURRENT_SOURCE_DIR}/additionalFunc ${CMAKE_CURRENT_SOURCE_DIR}/logger ${CMAKE_CURRENT_SOURCE_DIR}/simpleTools ${CMAKE_CURRENT_SOURCE_DIR}/uiModule @@ -38,7 +36,7 @@ add_compile_options(/utf-8) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) find_package(Qt5 COMPONENTS ${qtlist} REQUIRED ) @@ -52,10 +50,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp") FILE(GLOB_RECURSE APP_HEADERPP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp" ) FILE(GLOB_RECURSE APP_HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE(GLOB_RECURSE APP_SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") -FILE(GLOB_RECURSE APP_UI_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.ui") FILE(GLOB_RECURSE APP_UI_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cc") -INCLUDE_DIRECTORIES(${CMAEK_CURRENT_BINARY_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) set(RESOURCES_DIR ${CMAKE_SOURCE_DIR}/resources/resources.qrc) set(WIN_RC_DIR ${CMAKE_SOURCE_DIR}/resources/ff.rc) # 生成动态库(DLL/.so/.dylib) @@ -69,18 +66,10 @@ add_library(${CURRENT_FOLDER} SHARED ${APP_UI_FILES} ${WIN_RC_DIR} ${RESOURCES_DIR} - ${PROJECT_ROOT_PATH}/include/qtBridge.h ${PROJECT_ROOT_PATH}/include/interface.h ${CORE_HEADER_FILES} ) -# 让外部项目可以使用库 -#target_include_directories(${CURRENT_FOLDER}_shared PUBLIC ${CMAKE_SOURCE_DIR}) -# 设置 Windows 平台导出符号(仅在 SHARED 时生效) -# if(WIN32) -# target_compile_definitions(${CURRENT_FOLDER}_shared PRIVATE EXPORTING_SHARED) -# endif() - SET(ALL_DLL ${ENV_TARGET} ${lib_list} diff --git a/src/Core/backendInterface.cpp b/src/Core/backendInterface.cpp index d0e1666..9bbf06a 100644 --- a/src/Core/backendInterface.cpp +++ b/src/Core/backendInterface.cpp @@ -7,38 +7,43 @@ Backend::~Backend() { safeShutdownDelete(_serviceManager._triggerManager); safeShutdownDelete(_serviceManager._cameraManager); } -void Backend::init(SQLiteDB* db, qtFuncBridge* bridgeIn, nlohmann::ordered_json& json) { +void Backend::init(SQLiteDB* db, nlohmann::ordered_json& json) { if (initOnce == false) { - emit bridgeIn->loadingWindow_appendInitLog(u8"核心加载成功,正在初始化", QColor("white")); + emit _signalHub.loadingWindow_appendInitLog(u8"核心加载成功,正在初始化", QColor("white")); qDebug() << "核心加载成功,正在初始化"; - sqlDatabase = db; - bridge = bridgeIn; - missionJson = json; - _paramSyncManager = new paramSyncManager(missionJson["missionSettings"]); - + backendJson = json; + _paramSyncManager = new paramSyncManager(&_signalHub,backendJson["missionSettings"]); cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_ERROR); - _csvWriter = new CsvWriter(sqlDatabase); + + QList>externalInitDataVec; + if (backendJson.find("SQL") != backendJson.end()) { + for (auto it = backendJson["SQL"].begin(); it != backendJson["SQL"].end(); it++) { + externalInitDataVec.append(std::make_pair(QString::fromStdString(it.key()), QString::fromStdString(it.value().dump()))); + } + } + _csvWriter = new CsvWriter(sqlDatabase, externalInitDataVec); + _serviceManager._detDataManager = new detDataManager(); - _missionResultHandle = new missionResultHandle(bridge); + _missionResultHandle = new missionResultHandle(&_signalHub); _serviceManager._missionResultHandle = _missionResultHandle; _serviceManager.dataBase = sqlDatabase; _serviceManager._csvWriter = _csvWriter; _serviceManager._paramSyncManager = _paramSyncManager; //CLI 只在首次初始化创建 - //connect(bridge, &qtFuncBridge::restartInit, this, &Backend::restartInit); - _cliManager = new CLIManager(&_serviceManager, bridge); + //connect(bridge, &bSignalHub::restartInit, this, &Backend::restartInit); + _cliManager = new CLIManager(&_serviceManager, &_signalHub); initOnce = true; } // 创建/重建需要的服务模块,避免重复创建 if (!_serviceManager._imgSaveThreadManager) { - _serviceManager._imgSaveThreadManager = new imgSaveThreadManager(missionJson["imgSaveBasePath"],_paramSyncManager); + _serviceManager._imgSaveThreadManager = new imgSaveThreadManager(backendJson["imgSaveBasePath"],_paramSyncManager); } if (!_serviceManager._cameraManager) { - _serviceManager._cameraManager = new cameraManager(missionJson, bridge); + _serviceManager._cameraManager = new cameraManager(backendJson, &_signalHub); } if (!_serviceManager._triggerManager) { - _serviceManager._triggerManager = new triggerManager(&_serviceManager, bridge, missionJson["Triggers"]); + _serviceManager._triggerManager = new triggerManager(&_serviceManager, &_signalHub, backendJson["Triggers"]); } this->start(); @@ -54,24 +59,24 @@ void Backend::run() { triggerInitResult = waitrForInitResult(_serviceManager._triggerManager); if (cameraInitResult == true && triggerInitResult == true) { - emit bridge->loadingWindow_appendInitLog("初始化Mission中...", "yellow"); - bool res = _missionLoader.loadMission(missionJson["missionDllPath"]); + emit _signalHub.loadingWindow_appendInitLog("初始化Mission中...", "yellow"); + bool res = _missionLoader.loadMission(backendJson["missionDllPath"]); if (res == false) { - emit bridge->loadingWindow_appendInitLog("初始化Mission失败!请检查路径是否正确.", "red"); - emit bridge->initResult(InitFailure); + emit _signalHub.loadingWindow_appendInitLog("初始化Mission失败!请检查路径是否正确.", "red"); + emit _signalHub.initResult(InitFailure); return; } - _missionLoader.getmission(missionJson["missionDllPath"])->initBasic( + _missionLoader.getmission(backendJson["missionDllPath"])->initBasic( &_serviceManager, - missionJson["missionSettings"], bridge + backendJson["missionSettings"], &_signalHub ); - _cliManager->initBasicPreset(_missionLoader.getmission(missionJson["missionDllPath"])); + _cliManager->initBasicPreset(_missionLoader.getmission(backendJson["missionDllPath"])); _serviceManager._detDataManager->setTriggerManager(_serviceManager._triggerManager); initJsonRpc(); - emit bridge->initResult(InitOK); + emit _signalHub.initResult(InitOK); } else { - emit bridge->initResult(InitFailure); + emit _signalHub.initResult(InitFailure); } } void Backend::restartInit() { diff --git a/src/Core/basic/cachePool.hpp b/src/Core/basic/cachePool.hpp deleted file mode 100644 index ebbe653..0000000 --- a/src/Core/basic/cachePool.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include -#include -#include -#include - -template -class LRUCache { -public: - LRUCache(size_t capacity) : capacity_(capacity) { - assert(capacity > 0); - } - - std::shared_ptr get(const Key& key) { - auto it = cache_.find(key); - if (it == cache_.end()) { - std::shared_ptr ptr(new Value()); - put(key, ptr); - return ptr; - } - touch(it); - return it->second.first; - } -private: - void put(const Key& key, const std::shared_ptr& value) { - auto it = cache_.find(key); - if (it != cache_.end()) { - touch(it); - it->second.first = value; - } - else { - if (cache_.size() == capacity_) { - cache_.erase(usage_.back()); - usage_.pop_back(); - } - usage_.push_front(key); - cache_[key] = { value, usage_.begin() }; - } - } - typedef typename std::list::iterator ListIt; - std::unordered_map, ListIt>> cache_; - std::list usage_; - size_t capacity_; - - void touch(typename std::unordered_map, ListIt>>::iterator it) { - usage_.erase(it->second.second); - usage_.push_front(it->first); - it->second.second = usage_.begin(); - } -}; - - -#pragma once \ No newline at end of file diff --git a/src/Core/handleAi/handleAiModel.h b/src/Core/handleAi/handleAiModel.h deleted file mode 100644 index 7989118..0000000 --- a/src/Core/handleAi/handleAiModel.h +++ /dev/null @@ -1,264 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -const bool enableHandleAiModel = true; // 是否启用HandleAI模型 -class handleAiModelSeg { -public: - bool initFlag = false; - std::string path; - int gpuIndex = 0,batchSize = 64; - QMutex gpuMutex; - handleAiModelSeg(std::string pathIn, int gpuIndexIn, int batchSizeIn = 64){ - path = pathIn; - gpuIndex = gpuIndexIn; - batchSize = batchSizeIn; - }; - std::string init() { - segPtr = handdleAI::CreateSegObjS((char*)path.c_str(), batchSize, gpuIndex); - initFlag = true; - return path; - } - bool destroy(){ - if (segPtr == nullptr) - return false; - handdleAI::DestroySegObj(segPtr); - return true; - } - cv::Mat Evaluate(cv::Mat& input){ - QMutexLocker locker(&gpuMutex); - return segPtr->Evaluate(input); - } - handdleAI::pSegmentation* segPtr = nullptr; -}; -class handleAiModelCls{ - -public: - bool initFlag = false; - std::string path; - int gpuIndex = 0, batchSize = 1; - QMutex gpuMutex; - handleAiModelCls(std::string pathIn, int gpuIndexIn, int batchSizeIn = 1){ - path = pathIn; - gpuIndex = gpuIndexIn; - batchSize = batchSizeIn; - }; - std::string init(){ - clsPtr = handdleAI::CreateClsObjV3((char*)path.c_str(), gpuIndex, batchSize); - initFlag = true; - return path; - } - bool destroy(){ - if (clsPtr == nullptr) - return false; - handdleAI::DestroyClsObj(clsPtr); - return true; - } - int Evaluate(cv::Mat& input){ - QMutexLocker locker(&gpuMutex); - return clsPtr->Evaluate(input); - } - handdleAI::pClassification* clsPtr = nullptr; -}; -class handleAiModelDet{ -public: - bool initFlag = false; - std::string path; - int gpuIndex = 0,batchSize = 1; - QMutex gpuMutex; - handleAiModelDet(std::string pathIn, int gpuIndexIn,int batchSizeIn = 1){ - path = pathIn; - gpuIndex = gpuIndexIn; - batchSize = batchSizeIn; - }; - std::string init(){ - detPtr = handdleAI::CreateDetObjS((char*)path.c_str(), batchSize, gpuIndex); - initFlag = true; - return path; - } - bool destroy(){ - if (detPtr == nullptr || path=="") - return false; - handdleAI::DestroyDetObj(detPtr); - return true; - } - bool Evaluate(cv::Mat& input, std::vector& result){ - QMutexLocker locker(&gpuMutex); - result=detPtr->Evaluate(input); - return true; - } - handdleAI::pDetection* detPtr = nullptr; -}; -class handleAiModelManager :public serviceModule{ - -public: - enum type{ - seg, cls, det - }; - std::string basePath; - handleAiModelManager(nlohmann::ordered_json& json, qtFuncBridge* bridgeIn) - :bridge(bridgeIn){ - try { - handleAiJson = json["handleAiModel"]; - nlohmann::json segJson = handleAiJson["seg"]; - for(auto& segModel : segJson.items()){ - std::string keyName = segModel.key(); - std::string modelPath = segModel.value()["modelPath"]; - int gpuIndex = segModel.value()["gpuIndex"]; - insertSegModelPath(keyName, modelPath, gpuIndex); - } - nlohmann::json detJson = handleAiJson["det"]; - for (auto& detModel : detJson.items()){ - std::string keyName = detModel.key(); - std::string modelPath = detModel.value()["modelPath"]; - int gpuIndex = detModel.value()["gpuIndex"]; - insertDetModelPath(keyName, modelPath, gpuIndex); - } - nlohmann::json clsJson = handleAiJson["cls"]; - for (auto& clsModel : clsJson.items()){ - std::string keyName = clsModel.key(); - std::string modelPath = clsModel.value()["modelPath"]; - int gpuIndex = clsModel.value()["gpuIndex"]; - insertClsModelPath(keyName, modelPath, gpuIndex); - } - } - catch (const std::exception& e) { - std::cerr << "handleAiModelManager读取配置文件异常: " << e.what() << std::endl; - } - }; - handleAiModelSeg* insertSegModelPath(std::string keyName,std::string modelPath ,int gpuIndex){ - auto mapResult = segModels.find(keyName); - if (mapResult != segModels.end())//已有数据 - return nullptr; - handleAiModelSeg* segModel = new handleAiModelSeg(modelPath, gpuIndex); - segModels.insert(std::make_pair(keyName, segModel)); - return segModel; - } - handleAiModelDet* insertDetModelPath(std::string keyName, std::string modelPath, int gpuIndex){ - auto mapResult = detModels.find(keyName); - if (mapResult != detModels.end())//已有数据 - return nullptr; - handleAiModelDet* detModel = new handleAiModelDet(modelPath, gpuIndex); - detModels.insert(std::make_pair(keyName, detModel)); - return detModel; - } - handleAiModelCls* insertClsModelPath(std::string keyName, std::string modelPath, int gpuIndex){ - auto mapResult = clsModels.find(keyName); - if (mapResult != clsModels.end())//已有数据 - return nullptr; - handleAiModelCls* clsModel = new handleAiModelCls(modelPath, gpuIndex); - clsModels.insert(std::make_pair(keyName, clsModel)); - return clsModel; - } - // - handleAiModelSeg* getSegModel(std::string modelName){ - auto mapResult = segModels.find(modelName); - if (mapResult == segModels.end())//没有数据 - return nullptr; - return mapResult->second; - } - handleAiModelDet* getDetModel(std::string modelName){ - auto mapResult = detModels.find(modelName); - if (mapResult == detModels.end())//已有数据 - return nullptr; - return mapResult->second; - } - handleAiModelCls* getClsModel(std::string modelName){ - auto mapResult = clsModels.find(modelName); - if (mapResult == clsModels.end())//已有数据 - return nullptr; - return mapResult->second; - } - - //handdleAI::pSegmentation* insertSegModelAndInit(std::string modelPath, int gpuIndex, int batchSize = 64) { - // std::string uuid = QUuid().createUuid().toString().toStdString(); - // handleAiModelSeg* segModel = new handleAiModelSeg(modelPath, gpuIndex, batchSize); - // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[SEG]检测模型初始化中..."), "white"); - // //segModel->init(); - // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[SEG]初始化成功..."), "white"); - // segModels.insert(std::make_pair(uuid, segModel)); - // return segModel->segPtr; - //} - //handdleAI::pClassification* insertClsModelAndInit(std::string modelPath, int gpuIndex, int batchSize = 1) { - // std::string uuid = QUuid().createUuid().toString().toStdString(); - // handleAiModelCls* clsModel = new handleAiModelCls(modelPath, gpuIndex, batchSize); - // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[CLS]检测模型初始化中..."), "white"); - // //clsModel->init(); - // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[CLS]初始化成功..."), "white"); - // clsModels.insert(std::make_pair(uuid, clsModel)); - // return clsModel->clsPtr; - //} - //handdleAI::pDetection* insertDetModelAndInit(std::string modelPath, int gpuIndex, int batchSize = 1) { - // std::string uuid = QUuid().createUuid().toString().toStdString(); - // handleAiModelDet* detModel = new handleAiModelDet(modelPath, gpuIndex, batchSize); - // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[DET]检测模型初始化中..."), "white"); - // //detModel->init(); - // bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[DET]初始化成功..."), "white"); - // detModels.insert(std::make_pair(uuid, detModel)); - // return detModel->detPtr; - //} - void run(){ - if (enableHandleAiModel == true) { - std::vector> futures; - for (auto& model : segModels){ - if (model.second->initFlag == true) continue; - futures.push_back(std::async(std::launch::async, &handleAiModelSeg::init, model.second)); - emit bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); - } - for (auto& model : clsModels){ - if (model.second->initFlag == true) continue; - futures.push_back(std::async(std::launch::async, &handleAiModelCls::init, model.second)); - emit bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); - } - for (auto& model : detModels){ - if (model.second->initFlag == true) continue; - futures.push_back(std::async(std::launch::async, &handleAiModelDet::init, model.second)); - emit bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white"); - } - for (int i = 0; i < futures.size(); i++){ - futures[i].wait(); - std::string result = futures[i].get(); - emit bridge->loadingWindow_appendInitLog( - QString::fromStdString(fileManager::getFileName(result)) + "成功( " + QString::number(i + 1) + "/" + QString::number(futures.size()) + ")", "green"); - qDebug() << QString::fromStdString(fileManager::getFileName(result) + "成功"); - std::cout << fileManager::getFileName(result) + "成功" << std::endl; - } - status = InitOK; - } - else { - status = InitOK; - } - - - - } - ~handleAiModelManager(){ - if (enableHandleAiModel) { - for (auto& model : detModels) - model.second->destroy(); - for (auto& model : segModels) - model.second->destroy(); - for (auto& model : clsModels) - model.second->destroy(); - } - - } -private: - std::unordered_map segModels; - std::unordered_map clsModels; - std::unordered_map detModels; - int gpuCnt = 1;//gpu数量 - nlohmann::json handleAiJson; - qtFuncBridge* bridge; -}; - -#pragma once \ No newline at end of file diff --git a/src/core/additionalFunc/generalDataCollation.h b/src/core/additionalFunc/generalDataCollation.h deleted file mode 100644 index e7310ac..0000000 --- a/src/core/additionalFunc/generalDataCollation.h +++ /dev/null @@ -1,2 +0,0 @@ - -class \ No newline at end of file diff --git a/src/core/additionalFunc/manualDetThread.cpp b/src/core/additionalFunc/manualDetThread.cpp deleted file mode 100644 index 2cadc8a..0000000 --- a/src/core/additionalFunc/manualDetThread.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include - -void manualDetThread::initialization(detProcess* _appCore) -{ - //_detDataManager = &_appCore->_detDataManager; - //_threadManager = &_appCore->_threadManager; -} \ No newline at end of file diff --git a/src/core/additionalFunc/manualDetThread.h b/src/core/additionalFunc/manualDetThread.h deleted file mode 100644 index 5dfe0f7..0000000 --- a/src/core/additionalFunc/manualDetThread.h +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include -//#include -//#include - -class detProcess; -class manualDetThread :public QThread -{ - Q_OBJECT -public: - detDataManager* _detDataManager; - detThreadManager* _threadManager; - //检测参数 - std::vector imgPathStr; - int algoIndex = 0; - int Pos = 0; - manualDetThread() - { - //_appConfig = &_core._appConfig; - } - void initialization(detProcess* _appCore); - void run() - { - //emit _core._qtFunc.uiModuleHistoryListWidget_reset(); - int pathCount = imgPathStr.size(); - std::vector> mats; - std::vector>files(imgPathStr.size(),std::vector());//1层目录 2层文件名 - - for (int index = 0; index < imgPathStr.size(); index++) - { - fileManager::getAllFiles(imgPathStr[index], files[index], "jpg"); - fileManager::getAllFiles(imgPathStr[index], files[index], "bmp"); - fileManager::getAllFiles(imgPathStr[index], files[index], "tiff"); - fileManager::getAllFiles(imgPathStr[index], files[index], "png"); - } - - int filesMax = 0; - for (auto vec : files) - filesMax = getMax(filesMax, (int)vec.size()); - - for (int i = 0 ;i < filesMax;i++) - { - //std::shared_ptr data = _detDataManager->createDetData("Manual", "Manual", 0); - //data->algoThreadIndex = algoIndex; - //data->oriImgMutex.lock(); - //for(int o = 0 ; o < pathCount;o++) - //{ - // if(i >= files[0].size()) - // data->oriImgs.push_back(cv::Mat()); - // else - // data->oriImgs.push_back(cv::imread(files[0][i], cv::IMREAD_UNCHANGED)); - //} - //data->oriImgMutex.unlock(); - //_threadManager->addTask(data);//添加任务 - ////emit _core._qtFunc.uiModuleLocationMap_SetProductSignStatus(Pos, 1); - //Pos++; - //QThread::msleep(500); - } - emit finishImgReadSignal(); - } - void startDet(std::vector path,int index) - { - Pos = 0; - //emit _core._qtFunc.uiModuleLocationMap_ResetToDefault(); - imgPathStr = path; - algoIndex = index; - this->start(); - } -public slots: - void startManualDetSlot(std::vector path, int index) - { - startDet(path, index); - } -signals: - void finishImgReadSignal(); -}; -#pragma once \ No newline at end of file diff --git a/src/core/backendInterface.h b/src/core/backendInterface.h index c49783d..0960e74 100644 --- a/src/core/backendInterface.h +++ b/src/core/backendInterface.h @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -10,7 +10,6 @@ #include #include #include - class Backend : public IBackend { public: CsvWriter* _csvWriter = nullptr; @@ -22,7 +21,7 @@ public: ~Backend(); //重新初始化时禁止调用此函数 - void init(SQLiteDB* db, qtFuncBridge* bridgeIn, nlohmann::ordered_json& json) override; + void init(SQLiteDB* db, nlohmann::ordered_json& json) override; // 重新初始化 void restartInit(); void run(); @@ -56,21 +55,22 @@ public: } bool waitrForInitResult(serviceModule* ptr, int overtimeS = 999999); - + // 初始化RPC服务器 void initJsonRpc(); - nlohmann::ordered_json getJson() { - missionJson["missionSettings"] = _paramSyncManager->toJson(); - return missionJson; - } - void editParam(QString name, QVariant value) { - _paramSyncManager->edit(name, value); - } - void getAllParams(std::vector>* params) { - auto allParams = _paramSyncManager->getAllParams(); - params->swap(allParams); + nlohmann::ordered_json getBackendJson() { + backendJson["missionSettings"] = _paramSyncManager->toJson(); + return backendJson; } public slots: + void editParam(QString group, QString name, QVariant value) { + _paramSyncManager->edit(group, name, value); + qDebug() << name << "更改为" << value; + } + void getAllParams(std::vector>* params) { + auto allParams = _paramSyncManager->getAllParams(); + params->swap(allParams); + } void triggerAndCaptureImage(std::string cameraName, std::vector* mats) { if (cameraInitResult == false) { qCritical() << "[Error]调用triggerAndCaptureImage时相机未初始化!"; @@ -113,12 +113,10 @@ public slots: } private: bool initOnce = false; - nlohmann::ordered_json missionJson; + nlohmann::ordered_json backendJson; SQLiteDB* sqlDatabase; - qtFuncBridge* bridge; MissionLoader _missionLoader; // 任务加载器,用于加载任务配置 bool cameraInitResult = false, triggerInitResult = false; - }; #pragma once diff --git a/src/core/service/CLIManager.h b/src/core/service/CLIManager.h index 7d7bc5f..703c19a 100644 --- a/src/core/service/CLIManager.h +++ b/src/core/service/CLIManager.h @@ -4,27 +4,27 @@ #include #include -class algoManager { -public: - void registerAlgo(const std::string& algoName, std::function, handleAiModelManager*)> algoFunc) { - algoMap[algoName] = algoFunc; - } - void lstAlgos() const { - if(algoMap.empty()) { - std::cout << "No algorithms registered." << std::endl; - return; - } - for (const auto& algo : algoMap) { - std::cout << "Algorithm: " << algo.first << std::endl; - } - } -private: - std::unordered_map,handleAiModelManager*)>> algoMap; -}; +//class algoManager { +//public: +// void registerAlgo(const std::string& algoName, std::function, handleAiModelManager*)> algoFunc) { +// algoMap[algoName] = algoFunc; +// } +// void lstAlgos() const { +// if(algoMap.empty()) { +// std::cout << "No algorithms registered." << std::endl; +// return; +// } +// for (const auto& algo : algoMap) { +// std::cout << "Algorithm: " << algo.first << std::endl; +// } +// } +//private: +// std::unordered_map,handleAiModelManager*)>> algoMap; +//}; class CLIManager { public: - CLIManager(ServiceManager* _serviceManagerIn,qtFuncBridge* bridgeIn) + CLIManager(ServiceManager* _serviceManagerIn,bSignalHub* bridgeIn) :_serviceManager(_serviceManagerIn), bridge(bridgeIn) {} ~CLIManager() {} bool cliCommand(const QString& command) { @@ -169,7 +169,7 @@ public: } private: mission* _mission; - qtFuncBridge* bridge; + bSignalHub* bridge; QMap presets; ServiceManager* _serviceManager; enum CommandType { diff --git a/src/core/service/backStruct.h b/src/core/service/backStruct.h deleted file mode 100644 index ad4a911..0000000 --- a/src/core/service/backStruct.h +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -//#include - - -static void createDirectoryIfNotExists(const std::string& path) { - // 检查路径是否存在 - if (!std::filesystem::exists(path)) { - // 创建路径 - try { - std::filesystem::create_directories(path); - //std::cout << "已创建文件夹: " << path << std::endl; - } - catch (...) { - qCritical() << "创建文件夹失败!" << QString::fromStdString(path); - } - } -} -static void createDirectoryIfNotExists(const QString& path) { - QDir dir; - dir.mkpath(path); -} - -#pragma once \ No newline at end of file diff --git a/src/core/service/cameraManager.cpp b/src/core/service/cameraManager.cpp index 2b4dc0e..9b0e766 100644 --- a/src/core/service/cameraManager.cpp +++ b/src/core/service/cameraManager.cpp @@ -20,15 +20,44 @@ static MV_CC_DEVICE_INFO_LIST QByteArrayToMV_CC_DeviceInfoList(const QByteArray& } return deviceInfoList; } -static MV_CC_DEVICE_INFO_LIST searchMvDevice() + +static QByteArray MV_GENTL_IF_INFO_LISTToQByteArray(const MV_GENTL_IF_INFO_LIST& deviceInfoList) { + QByteArray byteArray; + byteArray.resize(sizeof(MV_GENTL_IF_INFO_LIST)); + memcpy(byteArray.data(), &deviceInfoList, sizeof(MV_GENTL_IF_INFO_LIST)); + return byteArray; +} +static MV_GENTL_IF_INFO_LIST QByteArrayToMV_GENTL_IF_INFO_LIST(const QByteArray& byteArray) { + MV_GENTL_IF_INFO_LIST deviceInfoList; + if (byteArray.size() == sizeof(MV_GENTL_IF_INFO_LIST)) { + memcpy(&deviceInfoList, byteArray.constData(), sizeof(MV_GENTL_IF_INFO_LIST)); + } + else { + qDebug() << "Invalid size of QByteArray for MV_GENTL_IF_INFO_LIST!"; + } + return deviceInfoList; +} + +static MV_CC_DEVICE_INFO_LIST searchMV_CC_DEVICE_INFO_LIST() { MV_CC_DEVICE_INFO_LIST m_stDevList; memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList); return m_stDevList; } - -camera::camera(cameraStruct configIn, int indexIn, qtFuncBridge* bridgeIn){ +static MV_GENTL_IF_INFO_LIST searchMV_GENTL_IF_INFO_LIST() +{ + MV_GENTL_IF_INFO_LIST m_stIFList; + const char* chCtiPath = "MvFGProducerXoF.cti";//.cti文件路径 + int nRet = 0; + nRet = MV_CC_EnumInterfacesByGenTL(&m_stIFList, chCtiPath); + if (nRet != MV_OK) + { + qDebug() << "EnumInterfacsByGenTL fail"; + } + return m_stIFList; +} +camera::camera(cameraStruct configIn, int indexIn, bSignalHub* bridgeIn){ bridge = bridgeIn; config = configIn; cameraName = QString::fromStdString(config.key); @@ -47,37 +76,15 @@ void camera::run(){ QMutexLocker locker(&mutex); data = requestQueue.dequeue(); } + if(data->oriImgs.size() >=data->imgAmountMin)continue; QMutexLocker locker2(&data->oriImgMutex); while (1) { trigger(); getCameraImg(data->oriImgs, data->imgAmountMin); if (data->oriImgs.size() >= data->imgAmountMin) { qDebug() << data->uuid << " Min:" << data->imgAmountMin << " Get:" << data->oriImgs.size(); - //if (lastUpdateTime.elapsed() > 200) {//显示在界面 - // lastUpdateTime.start(); // 记录本次更新时间 - // for (int i = 0; i < data->oriImgs.size(); i++) { - // QPixmap pixmap; - // cvMatToQPixMap(data->oriImgs[i], pixmap); - // showImgPack* pack = new showImgPack( - // config._cameraStruct.imageShowList[imgShowCnt].first, - // config._cameraStruct.imageShowList[imgShowCnt].second - // ); - // pack->img = pixmap; - // emit bridge->displayWidget_sendImg(pack); - - // imgShowCnt++; - // if (imgShowCnt >= config._cameraStruct.imageShowList.size()) - // imgShowCnt = 0; - // } - - //} - //else { - // showLost++; - // qDebug() << config.dllPath << "Lost show"; - //} break; } - QThread::msleep(1); } } @@ -119,8 +126,11 @@ void cameraManager::run(){ #pragma endregion //非海康相机可跳过 - MV_CC_DEVICE_INFO_LIST m_stDevList = searchMvDevice(); - QByteArray mvDevices = "deviceList" + MV_CC_DeviceInfoListToQByteArray(m_stDevList); + MV_CC_DEVICE_INFO_LIST m_stDevList = searchMV_CC_DEVICE_INFO_LIST(); + QByteArray mvDevices1 = "deviceList" + MV_CC_DeviceInfoListToQByteArray(m_stDevList); + + MV_GENTL_IF_INFO_LIST m_stIFList = searchMV_GENTL_IF_INFO_LIST(); + QByteArray mvDevices2 = "deviceList" + MV_GENTL_IF_INFO_LISTToQByteArray(m_stIFList); for (auto i = 0; i < _cameraStructs.size(); i++) { auto& m_module = _cameraStructs[i]; @@ -136,14 +146,28 @@ void cameraManager::run(){ m_module.module_ptr->writeData(vec_mat, m_keyByte); //初始化相机 //非海康相机可跳过 for (int i = 0; i < m_stDevList.nDeviceNum; i++){ + std::string userDefineName = static_cast((LPCSTR)m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chUserDefinedName); + if(userDefineName == "") + userDefineName = static_cast((LPCSTR)m_stDevList.pDeviceInfo[i]->SpecialInfo.stUsb3VInfo.chUserDefinedName); + std::string serialNumber = static_cast((LPCSTR)m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chSerialNumber); - if (!serialNumber.compare(m_module.connectionName) || !userDefineName.compare(m_module.connectionName)){ - m_module.module_ptr->writeData(vec_mat, mvDevices); + if (serialNumber == "") + serialNumber = static_cast((LPCSTR)m_stDevList.pDeviceInfo[i]->SpecialInfo.stUsb3VInfo.chSerialNumber); + + if (m_module.connectionName.find(serialNumber) != std::string::npos || m_module.connectionName.find(userDefineName) != std::string::npos){ + m_module.module_ptr->writeData(vec_mat, mvDevices1); + break; + } + } + for(int i = 0; i < m_stIFList.nInterfaceNum; i++) { + std::string serialNumber = static_cast((LPCSTR)m_stIFList.pIFInfo[i]->chInterfaceID); + std::string userDefineName = static_cast((LPCSTR)m_stIFList.pIFInfo[i]->chInterfaceID); + if (m_module.connectionName.find(serialNumber) != std::string::npos || m_module.connectionName.find(userDefineName) != std::string::npos) { + m_module.module_ptr->writeData(vec_mat, mvDevices1); break; } } - } status = NotInit; diff --git a/src/core/service/cameraManager.h b/src/core/service/cameraManager.h index 60223bf..f9d7e0a 100644 --- a/src/core/service/cameraManager.h +++ b/src/core/service/cameraManager.h @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include typedef dsModuleBase* (*CreateFunction)(); typedef void (*ReleaseFunction)(dsModuleBase* animal); @@ -38,7 +38,7 @@ public: QString cameraName; int imgShowCnt = 0; cameraStruct config; - camera(cameraStruct configIn, int indexIn, qtFuncBridge* bridgeIn); + camera(cameraStruct configIn, int indexIn, bSignalHub* bridgeIn); ~camera(){ runFlag = false; this->terminate(); @@ -102,7 +102,7 @@ public: writeData("clearCache"); } private: - qtFuncBridge* bridge; + bSignalHub* bridge; QByteArray readData(const std::string& str){ QByteArray byteArray(QByteArray::fromStdString(str)); std::vector camera_mat; @@ -129,7 +129,7 @@ private: class cameraManager : public serviceModule{ Q_OBJECT public: - cameraManager(nlohmann::ordered_json& json, qtFuncBridge* bridgeIn) { + cameraManager(nlohmann::ordered_json& json, bSignalHub* bridgeIn) { bridge = bridgeIn; auto cameraJson = json["CameraSetting"]; for (auto data : cameraJson){ @@ -167,7 +167,7 @@ public: private: bool initFlag = false; std::vector _cameraStructs;//相机配置结构体 - qtFuncBridge* bridge; + bSignalHub* bridge; bool loadModule(cameraStruct& _cameraStruct); std::vector vec_mat;//没啥用,一直保持为空就好 diff --git a/src/core/service/detCallbackChain.hpp b/src/core/service/detCallbackChain.hpp index a9ccdcb..614a089 100644 --- a/src/core/service/detCallbackChain.hpp +++ b/src/core/service/detCallbackChain.hpp @@ -15,7 +15,7 @@ class detCallbackChain { public: enum class State { Idle, algoEvaluate, resultHandle, Finished }; using processAlgoCallback = std::function, handleAiModelsTemplate*, addressTemplate)>; - detCallbackChain(ServiceManager* _ServiceManagerIn, handleAiModelsTemplate* _handleAiModelsTemplateIn, qtFuncBridge* bridgeIn) + detCallbackChain(ServiceManager* _ServiceManagerIn, handleAiModelsTemplate* _handleAiModelsTemplateIn, bSignalHub* bridgeIn) : _imgSaveThreadManager(_ServiceManagerIn->_imgSaveThreadManager), _handleAiModels(_handleAiModelsTemplateIn), _triggerManager(_ServiceManagerIn->_triggerManager), @@ -46,7 +46,7 @@ public: if (data->resultImgs.size() > 0) { for (int i = 0; i < data->resultImgs.size() && i < data->resultImgShowSet.size(); i++) { - auto pack = data->resultImgShowSet[getMin(i, (int)data->resultImgShowSet.size() - 1)]; + auto pack = data->resultImgShowSet[std::min(i, (int)data->resultImgShowSet.size() - 1)]; int resizeRate = qMax(data->resultImgs[i].cols / uiShowImgCompressThreshold, data->resultImgs[i].rows / uiShowImgCompressThreshold) ; resizeRate = std::pow(2, resizeRate); if (resizeRate > 1) { @@ -63,7 +63,7 @@ public: bool algoEvaluate(std::shared_ptr data, handleAiModelsTemplate* model, addressTemplate address = addressTemplate()) { std::chrono::steady_clock::time_point algoStartTime = std::chrono::steady_clock::now(); - bool result; + bool result = true; try { result = _processAlgoCallback(data, model, address); } @@ -99,15 +99,16 @@ public: // 通用的检测结果处理 void detectionResultHandle(std::shared_ptr data) { //计算处理总耗时(CT) - QString totalCtStr = "algoCT->" + QString::number(data->algoTime) + "ms|SN" + QString::fromStdString(data->SNcode); + QString totalCtStr = data->uuid + QString::fromStdString(data->SNcode) + "algoCT->" + QString::number(data->algoTime) + "ms|SN" + QString::fromStdString(data->SNcode); qDebug() << totalCtStr; //std::cout << totalCtStr.toStdString() << std::endl; - // 将耗时数据保存入数据库或日志 - data->sqlVec.push_back({ "SN", data->SNcode }); - data->sqlVec.push_back({ "totalCt", std::to_string(data->algoTime) + "ms" }); + // 将耗时数据等保存入数据库或日志 + data->sqlVec.insert({ "CT", QString::number(data->algoTime) + "ms" }); + data->sqlVec.insert({ "算法结果", data->halconOK == false ? "NG" : "OK" }); + data->sqlVec.insert({ "AI检测结果", data->aiDetOK == false ? "NG" : "OK" }); + data->service->_csvWriter->addData(QString::fromStdString(data->SNcode), data->sqlVec); // 异步保存检测图像 std::thread([this,data] {_imgSaveThreadManager->saveImage(data); }).detach(); - //std::thread([this,data] {_imgSaveThreadManager->saveRes(data); }).detach(); } #pragma region 注册回调函数 @@ -123,7 +124,7 @@ private: handleAiModelsTemplate* _handleAiModels = nullptr; triggerManager* _triggerManager = nullptr; processAlgoCallback _processAlgoCallback; - qtFuncBridge* bridge = nullptr; + bSignalHub* bridge = nullptr; ServiceManager* _serviceManager = nullptr; }; #pragma once \ No newline at end of file diff --git a/src/core/service/detData.h b/src/core/service/detData.h index 8736fba..5a9634d 100644 --- a/src/core/service/detData.h +++ b/src/core/service/detData.h @@ -5,7 +5,6 @@ #include #include #include -#include #include #include enum saveMode { @@ -17,7 +16,6 @@ class camera; class detData; class detDataManager; class ServiceManager; -using algoEvaluateCallback = std::function,handleAiModelManager*)>; class detData{ public: std::chrono::steady_clock::time_point startTime = std::chrono::high_resolution_clock::now(); @@ -59,8 +57,8 @@ public: bool halconOK = true; //结果图展示预设 std::vector< showImgPack>resultImgShowSet; - //需要存入的SQL数据 - std::vector> sqlVec; + //打包存入的SQL数据 + std::map sqlVec; #pragma endregion QMap additional;//自定义参数 detData() {} diff --git a/src/core/service/imgSaveThreadManager.h b/src/core/service/imgSaveThreadManager.h index 220d207..ac50b40 100644 --- a/src/core/service/imgSaveThreadManager.h +++ b/src/core/service/imgSaveThreadManager.h @@ -6,9 +6,9 @@ #include #include #include -#include #include #include +#include enum imgSaveThreadType { oriImg, resImg, @@ -87,7 +87,7 @@ public: QDateTime now = QDateTime::currentDateTime(); result.replace("{yyyy-MM-dd}", now.toString("yyyy-MM-dd")); result.replace("{HH-mm-ss}", now.toString("HH-mm-ss")); - result.replace("{timestamp}", QString::number(now.toMSecsSinceEpoch())); + result.replace("{ms}", QString("%1").arg(now.time().msec(), 3, 10, QChar('0'))); // 替换图片类型占位符 static const QMap typeMap{ @@ -172,7 +172,7 @@ public: private: QString defaultPath = "{imgSaveRootDir}/{yyyy-MM-dd}/{saveObjectName}{imageType}/{HH}H/{processResult}/{SN}/"; - QString defaultFileName = "{SN}_{cameraName}_{index}_{HH-mm-ss}"; + QString defaultFileName = "{SN}_{cameraName}_{imageType}_{index}_{HH-mm-ss}-{ms}"; }; struct saveJob { saveJob(std::string jobNameIn) :jobName(jobNameIn) {} @@ -254,19 +254,19 @@ public: imgSaveThreadManager(std::string pathIn, paramSyncManager* paramSyncManagerIn) { _ImageSavePathFormatter.rootDir = QString::fromStdString(pathIn); _paramSyncManager = paramSyncManagerIn; - saveOri = _paramSyncManager->get("存储原图", true).toBool(); - saveRes = _paramSyncManager->get("存储结果图", true).toBool(); - saveSeg = _paramSyncManager->get("存储Seg图", true).toBool(); - saveCls = _paramSyncManager->get("存储Cls图", true).toBool(); + saveOri = _paramSyncManager->get("通用设置", "存储原图", true).toBool(); + saveRes = _paramSyncManager->get("通用设置", "存储结果图", true).toBool(); + saveSeg = _paramSyncManager->get("通用设置", "存储Seg图", true).toBool(); + saveCls = _paramSyncManager->get("通用设置", "存储Cls图", true).toBool(); } ~imgSaveThreadManager() {}; imgSaveThread saveThread; void saveImage(std::shared_ptr data) { if (getParamTimer.elapsed() > 5000) { - saveOri = _paramSyncManager->get("存储原图", true).toBool(); - saveRes = _paramSyncManager->get("存储结果图", true).toBool(); - saveSeg = _paramSyncManager->get("存储Seg图", true).toBool(); - saveCls = _paramSyncManager->get("存储Cls图", true).toBool(); + saveOri = _paramSyncManager->get("通用设置", "存储原图", true).toBool(); + saveRes = _paramSyncManager->get("通用设置", "存储结果图", true).toBool(); + saveSeg = _paramSyncManager->get("通用设置", "存储Seg图", true).toBool(); + saveCls = _paramSyncManager->get("通用设置", "存储Cls图", true).toBool(); getParamTimer.restart(); } diff --git a/src/core/service/missionBase.hpp b/src/core/service/missionBase.hpp index 2cd6b79..259b19b 100644 --- a/src/core/service/missionBase.hpp +++ b/src/core/service/missionBase.hpp @@ -1,13 +1,12 @@ #pragma once -//#include -#include +#include #include #include #include #include #include #include -#include +#include #include #include #include @@ -18,26 +17,23 @@ class mission public: bool initBasic(ServiceManager* _serviceManagerIN, nlohmann::ordered_json& _missionJson, - qtFuncBridge* bridgeIn) { + bSignalHub* bridgeIn) { _serviceManager = _serviceManagerIN; bridge = bridgeIn; reloadConfig(_missionJson); initCustom(); return true; }; - virtual bool processAlgo(std::shared_ptr data, handleAiModelManager* _handleAiModelManager) { return true; }; + //virtual bool processAlgo(std::shared_ptr data, handleAiModelManager* _handleAiModelManager) { return true; }; virtual QString command(QString& command) { return "NG"; }; - void reloadConfig(nlohmann::ordered_json& _missionJson) { - onConfigReloaded(); - } - void reloadConfig() { + void reloadConfig(nlohmann::ordered_json& _missionJson = nlohmann::ordered_json()) { onConfigReloaded(); } protected: //供子类继承 virtual void onConfigReloaded() = 0; virtual bool initCustom() = 0; - qtFuncBridge* bridge = nullptr; + bSignalHub* bridge = nullptr; ServiceManager* _serviceManager = nullptr; }; static QString snHex(QString sn) diff --git a/src/core/service/missionResultHandle.h b/src/core/service/missionResultHandle.h index 9587962..f1ec346 100644 --- a/src/core/service/missionResultHandle.h +++ b/src/core/service/missionResultHandle.h @@ -1,9 +1,9 @@ -#include +#include //为了更集中方便的展示检测结果到主页面 class missionResultHandle { public: - missionResultHandle(qtFuncBridge* qtBridgeIn) { + missionResultHandle(bSignalHub* qtBridgeIn){ qtBridge = qtBridgeIn; } void toBarChart(std::string SN,bool isNG,std::vector defectAndNum) { @@ -18,6 +18,9 @@ public: void toWaveForm(QString windowName, double value) { emit qtBridge->waveFormAddData(windowName, value); } + void addSqlData(QString snCode, std::map data) { + _csvWriter->addData(snCode, data); + } void test() { QThread::msleep(1000); emit qtBridge->pieWidgetAddNG(); @@ -34,6 +37,7 @@ public: emit qtBridge->histogramWidgetAddData({ }); } private: - qtFuncBridge* qtBridge; + bSignalHub* qtBridge; + CsvWriter* _csvWriter; }; #pragma once \ No newline at end of file diff --git a/src/core/service/paramSyncManager.h b/src/core/service/paramSyncManager.h index 0571f7d..d5bf681 100644 --- a/src/core/service/paramSyncManager.h +++ b/src/core/service/paramSyncManager.h @@ -1,5 +1,4 @@ #pragma once - #include #include #include @@ -9,44 +8,61 @@ #include #include #include +#include -class paramSyncManager { + +class paramSyncManager :public QObject{ + Q_OBJECT public: + std::vector missionKey; // 构造函数:从JSON数据初始化参数 - explicit paramSyncManager(const nlohmann::ordered_json& json = nlohmann::ordered_json::object()) { + explicit paramSyncManager(bSignalHub* _signalHub,const nlohmann::ordered_json& json = nlohmann::ordered_json::object() + ):_signalHub(_signalHub){ loadFromJson(json); } - // 获取参数值,如果不存在则返回默认值 - QVariant get(QString name, QVariant defaultValue) { - QMutexLocker locker(&globalMutex); - if (map.contains(name)) { - return map[name]; + //获取参数值,如果不存在则返回默认值 + QVariant get(QString group, QString name, QVariant defaultValue) { + QString fullKey; + { + QMutexLocker locker(&globalMutex); + //构建键名(group.name) + fullKey = group + "." + name; + + if (map.contains(fullKey)) { + return map[fullKey]; + } + map.insert(fullKey, defaultValue); } - map.insert(name, defaultValue); + + emit _signalHub->saveMissionJson(); return defaultValue; } - // 编辑/设置参数值 - void edit(const QString& name, const QVariant& target) { - QMutexLocker locker(&globalMutex); - if (map.contains(name)) { - map[name] = target; - } else { - // 如果参数不存在,创建新的参数项 - map.insert(name, target); + //编辑/设置分组参数值 + void edit(const QString& group, const QString& name, const QVariant& target) { + QString fullKey = group + "." + name; + { + QMutexLocker locker(&globalMutex); + if (map.contains(fullKey)) { + map[fullKey] = target; + } + else { + map.insert(fullKey, target); + } } + emit _signalHub->saveMissionJson(); } - // 检查参数是否存在 - bool contains(const QString& name) const { + //检查参数是否存在 + bool contains(const QString& fullKey) const { QMutexLocker locker(&globalMutex); - return map.contains(name); + return map.contains(fullKey); } - // 移除参数 - bool remove(const QString& name) { + //移除参数 + bool remove(const QString& fullKey) { QMutexLocker locker(&globalMutex); - return map.remove(name) > 0; + return map.remove(fullKey) > 0; } // 获取所有参数名 @@ -59,52 +75,128 @@ public: std::vector> getAllParams() { QMutexLocker locker(&globalMutex); std::vector> result; - result.reserve(map.size()); - for (auto it = map.cbegin(); it != map.cend(); ++it) { - result.emplace_back(it.key(), it.value()); + updateJsonFromMap(); + for (auto it = json.begin(); it != json.end(); ++it) { + if (it->is_object()) { + std::string groupKey = it.key(); + for (auto it = json[groupKey].begin(); it != json[groupKey].end(); ++it) { + QString key = QString::fromStdString(it.key()); + QVariant value = jsonToQVariant(it.value()); + result.emplace_back(QString::fromStdString(groupKey) + "." + key, value); + } + } } return result; } + + // 获取指定分组的所有参数 + std::vector> getGroupParams(const QString& group) { + QMutexLocker locker(&globalMutex); + std::vector> result; + QString prefix = group + "."; + + for (auto it = map.begin(); it != map.end(); ++it) { + if (it.key().startsWith(prefix)) { + QString paramName = it.key().mid(prefix.length()); + result.emplace_back(paramName, it.value()); + } + } + + return result; + } + + // 获取分组列表 + std::vector getGroups() const { + QMutexLocker locker(&globalMutex); + return missionKey; + } + + // 获取指定索引的分组名 + QString getGroup(int index) const { + QMutexLocker locker(&globalMutex); + if (index >= 0 && index < missionKey.size()) { + return missionKey[index]; + } + return QString(); + } // 从JSON加载数据 - void loadFromJson(const nlohmann::ordered_json& json) { + void loadFromJson(const nlohmann::ordered_json& jsonInput){ QMutexLocker locker(&globalMutex); + json = jsonInput; map.clear(); + missionKey.clear(); - if (!json.is_object()) { + if (!jsonInput.is_object()) { qDebug() << "Invalid JSON format for paramSyncManager"; return; } - - for (auto it = json.begin(); it != json.end(); ++it) { - QString key = QString::fromStdString(it.key()); - QVariant value = jsonToQVariant(it.value()); - - map.insert(key, value); + + for (auto missionIt = jsonInput.begin(); missionIt != jsonInput.end(); ++missionIt) { + if (missionIt->is_object()) { + QString groupName = QString::fromStdString(missionIt.key()); + missionKey.push_back(groupName); + + const auto& innerObject = *missionIt; + for (auto innerIt = innerObject.begin(); innerIt != innerObject.end(); ++innerIt) { + QString key = groupName + "." + QString::fromStdString(innerIt.key()); + QVariant value = jsonToQVariant(innerIt.value()); + map.insert(key, value); + } + } } } - // 导出为JSON - nlohmann::ordered_json toJson() const { + // 将当前 map 值合并回初始 json 并导出 + // 规则:map 中的键覆盖 json 中的同名键;json 中原有但未出现在 map 中的键保留 + // 将当前 map 值合并回 json 并导出 + nlohmann::ordered_json toJson() { QMutexLocker locker(&globalMutex); - nlohmann::ordered_json result = nlohmann::ordered_json::object(); - - for (auto it = map.begin(); it != map.end(); ++it) { - result[it.key().toStdString()] = qVariantToJson(it.value()); - } - - return result; + updateJsonFromMap(); + return json; } - + //遍历 map,重新构建嵌套的 JSON 结构 + void updateJsonFromMap() { + nlohmann::ordered_json newJson; + for (auto it = map.begin(); it != map.end(); ++it) { + QString key = it.key(); + + //解析键名,判断是否包含分组 + QStringList parts = key.split('.'); + if (parts.size() == 2) { + QString group = parts[0]; + QString paramName = parts.mid(1).join('.'); + + //确保组存在 + if (newJson.find(group.toStdString()) == newJson.end()) { + newJson[group.toStdString()] = nlohmann::ordered_json::object(); + } + //添加参数到组 + newJson[group.toStdString()][paramName.toStdString()] = qVariantToJson(it.value()); + } + else { + newJson[key.toStdString()] = qVariantToJson(it.value()); + } + } + missionKey.clear(); + for (auto it = newJson.begin(); it != newJson.end(); ++it) { + missionKey.push_back(QString::fromStdString(it.key())); + } + json = newJson; + } + // 清空所有参数 void clear() { QMutexLocker locker(&globalMutex); map.clear(); + json = nlohmann::ordered_json::object(); + missionKey.clear(); } private: - - QMap map; + bSignalHub* _signalHub; + QMap map;//存储当前最新参数值 + nlohmann::ordered_json json; mutable QMutex globalMutex; // 保护整个map的全局互斥锁 // 辅助方法:将JSON值转换为QVariant @@ -115,6 +207,8 @@ private: return QVariant(json.get()); } else if (json.is_number_integer()) { return QVariant(json.get()); + } else if (json.is_number_unsigned()) { + return QVariant(static_cast(json.get())); } else if (json.is_number_float()) { return QVariant(json.get()); } else if (json.is_string()) { @@ -136,6 +230,12 @@ private: return variant.toBool(); case QVariant::Int: return variant.toInt(); + case QVariant::UInt: + return static_cast(variant.toUInt()); + case QVariant::LongLong: + return static_cast(variant.toLongLong()); + case QVariant::ULongLong: + return static_cast(variant.toULongLong()); case QVariant::Double: return variant.toDouble(); case QVariant::String: @@ -149,3 +249,4 @@ private: } }; + diff --git a/src/core/service/serviceManager.h b/src/core/service/serviceManager.h index 4e67cce..b861f31 100644 --- a/src/core/service/serviceManager.h +++ b/src/core/service/serviceManager.h @@ -11,7 +11,6 @@ public: detDataManager* _detDataManager = nullptr;// 检测数据管理器 需要初始化 imgSaveThreadManager* _imgSaveThreadManager = nullptr;// 保存图像线程 需要初始化 triggerManager* _triggerManager = nullptr;// 触发管理器 - //handleAiModelManager* _handleAiModelManager = nullptr;// 模型管理器 cameraManager* _cameraManager = nullptr; SQLiteDB* dataBase = nullptr; CsvWriter* _csvWriter = nullptr; diff --git a/src/core/service/serviceModule.h b/src/core/service/serviceModule.h index f45f711..3d97f36 100644 --- a/src/core/service/serviceModule.h +++ b/src/core/service/serviceModule.h @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include // 使用 moveToThread 模式的通用服务基类 diff --git a/src/core/service/triggerManager.cpp b/src/core/service/triggerManager.cpp index 9e5a157..80d715c 100644 --- a/src/core/service/triggerManager.cpp +++ b/src/core/service/triggerManager.cpp @@ -1,11 +1,10 @@ #include #include -#include #include #include +#include +triggerManager::triggerManager(ServiceManager* _serviceManager, bSignalHub* bridgeIn,nlohmann::ordered_json& triggerJson){ -triggerManager::triggerManager(ServiceManager* _serviceManager, qtFuncBridge* bridgeIn,nlohmann::ordered_json& triggerJson) -{ bridge = bridgeIn; dManager = _serviceManager->_detDataManager; _cameraManager = _serviceManager->_cameraManager; @@ -20,8 +19,10 @@ triggerManager::triggerManager(ServiceManager* _serviceManager, qtFuncBridge* br triggerFileName = QString::fromStdString(triggerJson["moduleName"]); IpAndPort = QString::fromStdString(triggerJson["initStr"]); - heartBeatIntervalMS = triggerJson["heartBeatIntervalMS"]; - sleepIntervalMS = triggerJson["sleepIntervalMS"]; + + heartBeatIntervalMS = triggerJson.value("heartBeatIntervalMS",1); + sleepIntervalMS = triggerJson.value("sleepIntervalMS", 1); + std::vector heartbeats = triggerJson["heartBeatCmd"]; for (auto& cmd : heartbeats) { heartBeatCmds.push_back(QString::fromStdString(cmd)); @@ -73,7 +74,7 @@ bool triggerManager::connectHost(){ if (createFun && releaseFun) { trigger = createFun(); - destory_finstcp = releaseFun; + destoryRpcFunc = releaseFun; trigger->writeData(vec_mat, QByteArray(IpAndPort.toUtf8())); initFailure = trigger->initParas(QByteArray()); emit bridge->loadingWindow_appendInitLog(triggerFileName + "连接到" + IpAndPort,"white"); @@ -153,7 +154,6 @@ void triggerManager::decodeCameraCMD(readAllStruct& _struct, QByteArray byte) checkPlcValueViewer(_struct, byte); } - void triggerManager::checkCallback(readAllStruct _struct, QByteArray& byteArray) {//检查是否符合回调函数的触发条件 QMutexLocker locer(&mutex); for (auto callback : triggerCallbackFuncs[_struct.readAllCmd]) @@ -250,7 +250,7 @@ void triggerManager::checkPlcValueViewer(readAllStruct& _struct, QByteArray& byt if (newValue != data.value) { data.value = newValue; - if (data.type == finsFloat) + if (data.type == finsFloat) emit bridge->runCommand_refeshPlcValueViewer(data.valueAddr, QString::number(data.value.toDouble(), 'f', 4)); else @@ -259,4 +259,5 @@ void triggerManager::checkPlcValueViewer(readAllStruct& _struct, QByteArray& byt } } -} \ No newline at end of file +} + diff --git a/src/core/service/triggerManager.h b/src/core/service/triggerManager.h index 0f729e9..09d5f35 100644 --- a/src/core/service/triggerManager.h +++ b/src/core/service/triggerManager.h @@ -3,12 +3,11 @@ #include #include #include -#include #include #include #include #include -#include // for std::thread used in async callbacks +#include #define debugTesting 0 using triggerCallback = std::function; @@ -19,7 +18,7 @@ class detDataManager; class lightSourceManager; class ServiceManager; -// 将此静态函数加入到类 triggerManager 的合适位置(如 private 部分) +//从fins中读取浮点型 static float readFinsFloatFromQByteArray(const QByteArray& buf, int startByteIndex, bool highLowConversion) { if (buf.isEmpty()) { return 0.0f; @@ -55,6 +54,18 @@ static float readFinsFloatFromQByteArray(const QByteArray& buf, int startByteInd std::memcpy(&value, &raw, sizeof(float)); return value; } +//将字符串转换为供发送的语句 +static QByteArray convertStringForFins(const QString& text) { + QByteArray sendText; + for (int i = 0; i < text.size() / 2; i ++) + sendText += QByteArray::number(text[i * 2].unicode() + text[i * 2 + 1].unicode() * 256) + ","; + + if (text.size() % 2 == 1) + sendText += QByteArray::number(text[text.size() - 1].unicode()); + else + sendText.chop(1); + return sendText; +} //防止重复触发 class triggerLockerT { public: @@ -104,7 +115,7 @@ public: this->stop(); delete trigger; } - triggerManager(ServiceManager*, qtFuncBridge* bridgeIn, nlohmann::ordered_json& triggerJson); + triggerManager(ServiceManager*, bSignalHub* bridgeIn, nlohmann::ordered_json& triggerJson); bool connectHost(); void run(); void stop(){ @@ -321,9 +332,7 @@ public: std::map> triggerCallbackFuncs; //联合条件的触发器注册 - bool registerUnionCallback(std::vector> triggerAddressAndValue, - conditionMode mode, - uniontriggerCallback func, std::string funcName) { + bool registerUnionCallback(std::vector> triggerAddressAndValue,conditionMode mode,uniontriggerCallback func, std::string funcName) { QMutexLocker locer(&mutex); if (triggerAddressAndValue.size() < 2) { qCritical() << "联合触发器至少需要两个条件"; @@ -372,7 +381,7 @@ public: std::vectorplcValueViewerDatas; private: QElapsedTimer lostConnectionCountTimer,lostConnectionRePrintTimer; - qtFuncBridge* bridge; + bSignalHub* bridge; bool libLoadedflag = false; QLibrary* m_lib = nullptr; //detProcess* _detProcess; @@ -409,11 +418,14 @@ private: int heartBeatIntervalMS = 800; int heartBeatCmdCnt = 0; std::vector heartBeatCmds; - ReleaseRpcModuleBaseFunction destory_finstcp; //释放 rpcModuleBase* trigger = nullptr; bool isConnected = true; bool runFlag = true; bool init = false; std::vector vec_mat;//没啥用,一直保持为空就好 + + typedef rpcModuleBase* (*CreateRpcModuleBaseFunction)(); + typedef void (*ReleaseRpcModuleBaseFunction)(rpcModuleBase* ptr); + ReleaseRpcModuleBaseFunction destoryRpcFunc; //释放 }; #pragma once \ No newline at end of file diff --git a/src/core/struct.h b/src/core/struct.h deleted file mode 100644 index 0805c39..0000000 --- a/src/core/struct.h +++ /dev/null @@ -1,254 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -struct productSignStruct -{ - cv::Rect posRect; - std::string sign; -}; -struct productDataStruct -{ - std::string name; - std::string customerPartNumber; - std::string foxconnPartNumber; - int indexOfArm = 0; - cv::Vec3d basePos; - cv::Vec3d baseRad; - std::string imgPosPath; - int connectorAmout = 0; - int halconAlgoIndex = -1; - bool isBackExist = false; - int backArmIndex = 0; - //int为步骤数 std::string为指令 - std::unordered_map >cameraSetting; - //int为步骤数 第二个int为光源亮度 max255 - std::unordered_maplightSetting; - - //这两个bool值为true时根据codedAlgoIndex的值进到写死的检测代码中 - //启用之后下面的handleAiSimpleDet只会用于初始化模型! - bool disableHandleAiConfig = false; - bool enableCodedAlgo = false; - int codedAlgoIndex = -1; - - std::unordered_map productSign; -}; -struct perConnector -{ - bool aiOk = false,halconOk = false; - double maxPinDetValue = -1; - std::string name; - std::string resultStr; - std::string showStr; - std::string timeStr; -}; -class productCacheBase -{ -public: - productCacheBase() - { - startTimePoint = std::chrono::high_resolution_clock::now(); - //creatTime = getCurrentDateTime(); - } - void writeProductData(std::string SNin, productDataStruct&_productDataStructIn) - { - endTimePoint = std::chrono::high_resolution_clock::now(); - SN = SNin; - connectorAmount = _productDataStructIn.connectorAmout; - partNumber = _productDataStructIn.foxconnPartNumber; - } - void saveData(std::string path) - { - //endTimePoint = std::chrono::high_resolution_clock::now(); - ////测试时间 - //customExcelStruct dataSave(creatTime); - ////"耗时" - //dataSave.nexCols.push_back(customExcelStruct(calculateDuration(startTimePoint, endTimePoint))); - ////"SN" - //dataSave.nexCols[0] - // .nexCols.push_back(customExcelStruct(SN)); - ////"机种槽数" - //dataSave.nexCols[0] - // .nexCols[0] - // .nexCols.push_back(customExcelStruct(std::to_string(connectorAmount))); - ////"Part Number" - //dataSave.nexCols[0] - // .nexCols[0] - // .nexCols[0] - // .nexCols.push_back(customExcelStruct(partNumber)); - ////"连接器编号" - //dataSave.nexCols[0] - // .nexCols[0] - // .nexCols[0] - // .nexCols[0] - // .nexCols.push_back(customExcelStruct(connectorCode)); - ////"不良点数" - //dataSave.nexCols[0] - // .nexCols[0] - // .nexCols[0] - // .nexCols[0] - // .nexCols[0] - // .nexCols.push_back(customExcelStruct(std::to_string(ngCount))); - //for (auto connectorResult : connectorResults) - //{ - // //"Pin编号" - // customExcelStruct connector(connectorResult.name); - // //"Pin结果" - // std::string pinResult; - // if (connectorResult.aiOk == true && connectorResult.halconOk == true) - // pinResult = "OK"; - // else - // { - // if (connectorResult.aiOk == false) - // pinResult += "aiNG;"; - // if (connectorResult.halconOk == false) - // pinResult += "halconNG"; - // } - // connector.nexCols.push_back(customExcelStruct(pinResult)); - // //"Pin测试值" - // connector.nexCols[0] - // .nexCols.push_back(customExcelStruct(std::to_string(connectorResult.maxPinDetValue))); - // //测试结果 - // connector.nexCols[0] - // .nexCols[0] - // .nexCols.push_back(customExcelStruct(connectorResult.resultStr)); - // //汇总 - // dataSave.nexCols[0] - // .nexCols[0] - // .nexCols[0] - // .nexCols[0] - // .nexCols[0] - // .nexCols[0] - // .nexCols.push_back(connector); - //} - //writeExcel(path, "Sheet1", titles, dataSave); - } - std::vector connectorResults; - std::string creatTime; - std::chrono::steady_clock::time_point startTimePoint; - std::chrono::steady_clock::time_point endTimePoint; - std::string SN = "NULL"; - int ngCount = -1; - int ngPinCount = -1; - //从配置文件获取 - int connectorAmount = -1; - std::string partNumber = "NULL"; - std::string connectorCode = "NULL"; - - -private: - std::string calculateDuration(const std::chrono::steady_clock::time_point& start, const std::chrono::steady_clock::time_point& end) { - auto duration = std::chrono::duration_cast(end - start); - auto minutes = std::chrono::duration_cast(duration); - auto seconds = duration - minutes; - - std::ostringstream oss; - oss << minutes.count() << "分:" << std::setw(2) << std::setfill('0') << seconds.count() << "秒"; - - return oss.str(); - } - std::vector titles = { - "测试时间", "耗时", "SN", - "机种槽数", "Part Number", - "连接器编号", "不良点数", "Pin编号", - "Pin结果", "Pin测试值", "测试结果" }; - -}; - - -class switchProductWidgetDataPtr -{ -public: - productDataStruct getCurrentProductData() { - productDataStruct result; - if (mutex == nullptr) - return result; - if (productDatasPtr == nullptr) - return result; - - mutex->lock(); - result = productDatasPtr->at(currentProductIndex); - mutex->unlock(); - return result; - } - std::vector getAllProductData() { - std::vector result; - if (mutex == nullptr) - return result; - if (productDatasPtr == nullptr) - return result; - - mutex->lock(); - result = *productDatasPtr; - mutex->unlock(); - return result; - } - int currentProductIndex = 0;//switchProductWidget - std::vector* productDatasPtr = nullptr;//appConfig - std::mutex* mutex = nullptr;//appConfig -}; -struct lightSourceStruct -{ - std::string deviceName; - std::string comName; - int baudRate; - std::string initStr; -}; -struct triggerStruct -{ - std::string key; - std::string initStr; - std::string heartCmd; - std::string readAllCmd; - std::string moduleName; - int sleepTime; - int readNum; - std::string writeType; - int startPos; -}; - -struct sqlConfigStruct -{ - std::unordered_mapdatas; -}; -struct _952BiaoDingSwitchData -{ - QMutex mutex; - int modeIn;//0 normal 1 biaoding - double in_OutOffset; - double in_InnerOffset; - double _3d_threshold; -}; - -#include -#pragma execution_character_set("utf-8") - -typedef dsModuleBase* (*CreateFunction)(); -typedef void (*ReleaseFunction)(dsModuleBase* animal); -typedef rpcModuleBase* (*CreateRpcModuleBaseFunction)(); -typedef void (*ReleaseRpcModuleBaseFunction)(rpcModuleBase* animal); -typedef struct { - QString m_stationKy; - QString key; // 相机名称 - QString moduleName; // 模块名称 - QString task_thread_index = "-1";// 存储当前算法属于那个任务线程 - QByteArray m_initByte; // 传递初始化参数 - dsModuleBase* module_ptr = nullptr; // 存储模块指针 - ReleaseFunction destory_ptr; // 释放 - int showIndex; -}MyModule; - -typedef struct { - QString retFlag; // 判断结果 Camera 表示图片 AI表示 结果信息: - QString name; // key 示例:camera1 - QString taskName; // 任务名 - cv::Mat mat; - QByteArray byte; - int showIndex; -}dataPack; - -#pragma once \ No newline at end of file diff --git a/src/cutImage/CMakeLists.txt b/src/cutImage/CMakeLists.txt new file mode 100644 index 0000000..92e41bf --- /dev/null +++ b/src/cutImage/CMakeLists.txt @@ -0,0 +1,69 @@ +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) +STRING(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) +set(DLL_NAMES "halcon" "opencv" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${ENV_INCLUDE} + ${PROJECT_ROOT_PATH}/lib/${CMAKE_BUILD_TYPE} +) + +link_directories ( + ${ENV_LIB} +) +add_compile_options(/utf-8) +# qt引用 +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +find_package(Qt5 COMPONENTS ${qtlist} REQUIRED ) +foreach(item ${qtlist}) + list(APPEND lib_list Qt5::${item}) +endforeach() + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp") + + +FILE(GLOB_RECURSE APP_HEADERPP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp" ) +FILE(GLOB_RECURSE APP_HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) +FILE(GLOB_RECURSE APP_SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) +set(RESOURCES_DIR ${CMAKE_SOURCE_DIR}/resources/resources.qrc) +set(WIN_RC_DIR ${CMAKE_SOURCE_DIR}/resources/ff.rc) +include_directories(${CMAKE_BINARY_DIR}) +add_executable( ${CURRENT_FOLDER} + ${APP_HEADERPP_FILES} + ${APP_HEADER_FILES} + ${APP_SRC_FILES} + ${BREAKPAD_WINDOWS_CC_FILES} + ${APP_UI_FILES} + ${WIN_RC_DIR} + ${RESOURCES_DIR} ) +# 添加预处理定义 + +SET(ALL_DLL + ${ENV_TARGET} + ${lib_list} +) +#add_custom_target( +# run_cmd ALL +# COMMAND cmd /c "${ENVPATH}/qt5/bin/moc.exe ${PROJECT_ROOT_PATH}/include/frontendSignalHub.h -o ${CMAKE_CURRENT_SOURCE_DIR}/moc_qtBridge.cpp" +# COMMENT "Running command on every build" +#) +message("all_lib :" ${ALL_DLL}) +target_link_libraries(${CURRENT_FOLDER} ${ALL_DLL} ) +string(TIMESTAMP RUN_TIME) +message("C++ Standard: ${CMAKE_CXX_STANDARD}") +message( " model end : " ${CURRENT_FOLDER}:${RUN_TIME}) \ No newline at end of file diff --git a/src/cutImage/baoMo.hpp b/src/cutImage/baoMo.hpp new file mode 100644 index 0000000..7d7872f --- /dev/null +++ b/src/cutImage/baoMo.hpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +using namespace std; + + +void baomoXiaDMianCut(const std::string path, const std::string format, const std::string outputPath,cv::Size fillter) { + //int + handdleAI::pSegmentation* seg = handdleAI::CreateSegObjS("./cutImgFiles/baoMoXiaDaMian_seg.BHD", 1, 0); + std::vector images; + cv::glob(path + "/*." + format, images, false); + for (size_t i = 0; i < images.size(); i++) { + std::string filePath = outputPath + "/" + std::to_string(i) + "/"; + createDirectoryIfNotExists(QString::fromStdString(filePath)); + cv::Mat srcImage = cv::imread(images[i], -1); + cv::Mat Paint; + if (srcImage.cols == 1) + cv::cvtColor(srcImage, Paint, cv::COLOR_GRAY2BGR); + else + srcImage.copyTo(Paint); + + if (srcImage.empty()) { + std::cout << "ͼƬΪ¿գ¡" << std::endl; + continue; + } + auto SegResult = ~seg->Evaluate(srcImage); + std::vector> contours; + cv::findContours(SegResult,contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + for (int ii = 0; ii < contours.size(); ii++) { + cv::Rect rect = cv::boundingRect(contours[i]); + if (rect.width > fillter.width || rect.height > fillter.height) { + cv::putText(Paint, std::to_string(i), cv::Point(rect.x + rect.width / 2, rect.y + rect.height / 2), 1, 2, cv::Scalar(255, 255, 255), 5); + cv::rectangle(Paint, rect, cv::Scalar(0, 0, 255), 3); + auto imgs = cutImg2ClsVec(rect, srcImage); + for (int o = 0; o < imgs.size(); o++) { + cv::imwrite(filePath + "/" + std::to_string(ii) + "_" + std::to_string(o) + "CLS.bmp",imgs[o]); + } + } + } + cv::imwrite(filePath + "/Paint.bmp", Paint); + } +} \ No newline at end of file diff --git a/src/cutImage/main.cpp b/src/cutImage/main.cpp new file mode 100644 index 0000000..9d8e7c8 --- /dev/null +++ b/src/cutImage/main.cpp @@ -0,0 +1,7 @@ +#include + +int main(int argc, char* argv[]) +{ + //baomoXiaDMianCut( + return 1; +} \ No newline at end of file diff --git a/src/launcher/CMakeLists.txt b/src/launcher/CMakeLists.txt index d5fdb58..1059325 100644 --- a/src/launcher/CMakeLists.txt +++ b/src/launcher/CMakeLists.txt @@ -20,17 +20,10 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/appConfig ${CMAKE_CURRENT_SOURCE_DIR}/appConfig/spdlog - ${CMAKE_CURRENT_SOURCE_DIR}/GUI/algo ${CMAKE_CURRENT_SOURCE_DIR}/GUI/appConfig - ${CMAKE_CURRENT_SOURCE_DIR}/GUI/back - ${CMAKE_CURRENT_SOURCE_DIR}/GUI/front - ${CMAKE_CURRENT_SOURCE_DIR}/GUI/handleAi + ${CMAKE_CURRENT_SOURCE_DIR}/GUI/pages ${CMAKE_CURRENT_SOURCE_DIR}/GUI/halconAlgo - ${CMAKE_CURRENT_SOURCE_DIR}/GUI/simpleTools ${CMAKE_CURRENT_SOURCE_DIR}/GUI/uiModule - ${CMAKE_CURRENT_SOURCE_DIR}/GUI/basic - ${CMAKE_CURRENT_SOURCE_DIR}/GUI/python - ${CMAKE_CURRENT_SOURCE_DIR}/GUI/pluginManager ) link_directories ( @@ -41,7 +34,7 @@ add_compile_options(/utf-8) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) find_package(Qt5 COMPONENTS ${qtlist} REQUIRED ) @@ -55,9 +48,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp") FILE(GLOB_RECURSE APP_HEADERPP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp" ) FILE(GLOB_RECURSE APP_HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE(GLOB_RECURSE APP_SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") -FILE(GLOB_RECURSE APP_UI_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.ui") -INCLUDE_DIRECTORIES(${CMAEK_CURRENT_BINARY_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) set(RESOURCES_DIR ${CMAKE_SOURCE_DIR}/resources/resources.qrc) set(WIN_RC_DIR ${CMAKE_SOURCE_DIR}/resources/ff.rc) include_directories(${CMAKE_BINARY_DIR}) @@ -69,7 +61,7 @@ add_executable( ${CURRENT_FOLDER} ${APP_UI_FILES} ${WIN_RC_DIR} ${RESOURCES_DIR} - ${PROJECT_ROOT_PATH}/include/qtBridge.h) + ${PROJECT_ROOT_PATH}/include/interface.h) # 添加预处理定义 SET(ALL_DLL @@ -78,7 +70,7 @@ SET(ALL_DLL ) #add_custom_target( # run_cmd ALL -# COMMAND cmd /c "${ENVPATH}/qt5/bin/moc.exe ${PROJECT_ROOT_PATH}/include/qtBridge.h -o ${CMAKE_CURRENT_SOURCE_DIR}/moc_qtBridge.cpp" +# COMMAND cmd /c "${ENVPATH}/qt5/bin/moc.exe ${PROJECT_ROOT_PATH}/include/frontendSignalHub.h -o ${CMAKE_CURRENT_SOURCE_DIR}/moc_qtBridge.cpp" # COMMENT "Running command on every build" #) message("all_lib :" ${ALL_DLL}) diff --git a/src/launcher/GUI/JsonEditorDialog.h b/src/launcher/GUI/JsonEditorDialog.h index e2a6121..496795a 100644 --- a/src/launcher/GUI/JsonEditorDialog.h +++ b/src/launcher/GUI/JsonEditorDialog.h @@ -1,5 +1,5 @@ #pragma once - +#include #include #include #include @@ -40,7 +40,7 @@ class JsonParamTableEditor : public QDialog { public: explicit JsonParamTableEditor(QWidget* parent = nullptr) : QDialog(parent) { - this->setWindowTitle("JSON 表格编辑器"); + this->setWindowTitle(TR("JSON Table Editor")); this->resize(700, 450); setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint);// 去掉边框 //setAttribute(Qt::WA_TranslucentBackground); // 背景透明 @@ -76,7 +76,7 @@ public: m_tableView->setFocusPolicy(Qt::NoFocus); //设置表头 - m_tableModel->setHorizontalHeaderLabels({ "选项", "值" }); + m_tableModel->setHorizontalHeaderLabels({ TR("Option"), TR("Value") }); //设置表格属性 m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); @@ -85,8 +85,8 @@ public: m_tableView->setColumnWidth(1, 200);// 选项列宽度 - fancyButtonText* okBtn = new fancyButtonText("保存", 70, 22, ""); - fancyButtonText* cancelBtn = new fancyButtonText("取消", 70, 22, ""); + fancyButtonText* okBtn = new fancyButtonText(TR("Save"), 70, 22, ""); + fancyButtonText* cancelBtn = new fancyButtonText(TR("Cancel"), 70, 22, ""); connect(okBtn, &QPushButton::clicked, this, &JsonParamTableEditor::onAccept); connect(cancelBtn, &QPushButton::clicked, this, &QDialog::reject); @@ -222,20 +222,20 @@ private slots: for (int row = 0; row < m_tableModel->rowCount(); ++row) { QStandardItem* keyItem = m_tableModel->item(row, 0); if (!keyItem) { - QMessageBox::warning(this, "错误", QString("第 %1 行数据不完整").arg(row + 1)); + QMessageBox::warning(this, TR("Error"), QString(TR("Row %1 data is incomplete")).arg(row + 1)); return; } QString key = keyItem->text().trimmed(); if (key.isEmpty()) { - QMessageBox::warning(this, "错误", QString("第 %1 行 key 为空").arg(row + 1)); + QMessageBox::warning(this, TR("Error"), QString(TR("Row %1 key is empty")).arg(row + 1)); return; } //获取原始类型 std::string keyStd = key.toStdString(); if (m_originalTypes.find(keyStd) == m_originalTypes.end()) { - QMessageBox::warning(this, "错误", QString("第 %1 行找不到原始类型信息").arg(row + 1)); + QMessageBox::warning(this, TR("Error"), QString(TR("Original type information not found for row %1")).arg(row + 1)); return; } @@ -245,7 +245,7 @@ private slots: nlohmann::json convertedValue; QString errorMsg; if (!getValueFromEditor(keyStd, expectedType, convertedValue, errorMsg)) { - QMessageBox::critical(this, "类型验证失败",QString("第 %1 行值验证失败:\n%2").arg(row + 1).arg(errorMsg)); + QMessageBox::critical(this, TR("Type Validation Failed"), QString(TR("Row %1 value validation failed:\n%2")).arg(row + 1).arg(errorMsg)); return; } result[keyStd] = convertedValue; @@ -318,7 +318,7 @@ private: updateModelData(key, value ? "true" : "false"); return true; } - errorMsg = "布尔值控件类型错误"; + errorMsg = TR("Boolean control type mismatch"); return false; } case JsonValueType::Number: { @@ -336,7 +336,7 @@ private: } return true; } - errorMsg = "数字控件类型错误"; + errorMsg = TR("Number control type mismatch"); return false; } case JsonValueType::String: { @@ -347,7 +347,7 @@ private: updateModelData(key, value); return true; } - errorMsg = "字符串控件类型错误"; + errorMsg = TR("String control type mismatch"); return false; } default: @@ -361,7 +361,7 @@ private: } } catch (const std::exception& e) { - errorMsg = QString("获取值错误: %1").arg(e.what()); + errorMsg = QString(TR("Get value error: %1")).arg(e.what()); return false; } } @@ -447,19 +447,19 @@ private: QString generateTypeHint(JsonValueType type) { switch (type) { case JsonValueType::String: - return "输入字符串值(不需要引号)"; + return TR("Enter a string value (no quotes required)"); case JsonValueType::Number: - return "输入数字值(整数或小数)"; + return TR("Enter a numeric value (integer or decimal)"); case JsonValueType::Boolean: - return "输入布尔值(true 或 false)"; + return TR("Enter a boolean value (true or false)"); case JsonValueType::Array: - return "输入JSON数组格式,如:[1,2,3] 或 [\"a\",\"b\"]"; + return "输入JSON数组格式,如:[1, 2, 3] or [\"a\",\"b\"]"; case JsonValueType::Object: - return "输入JSON对象格式,如:{\"key\":\"value\"}"; + return "输入JSON对象格式,如: {\"key\":\"value\"}"; case JsonValueType::Null: - return "空值(输入 null)"; + return TR("Null (enter null)"); default: - return "请输入有效的JSON值"; + return TR("Please enter a valid JSON value"); } } @@ -470,7 +470,7 @@ private: // 长度检查 if (trimmedInput.size() > 10240) { - errorMsg = "输入值过大(超过10240字符)"; + errorMsg = TR("Input value too large (exceeds 10240 characters)"); return false; } @@ -494,7 +494,7 @@ private: result = doubleVal; return true; } - errorMsg = "无效的数字格式"; + errorMsg = TR("Invalid numeric format"); return false; } @@ -506,7 +506,7 @@ private: result = false; return true; } - errorMsg = "布尔值只能是 true 或 false"; + errorMsg = TR("Boolean must be true or false"); return false; case JsonValueType::Null: @@ -514,7 +514,7 @@ private: result = nullptr; return true; } - errorMsg = "空值只能是 null"; + errorMsg = TR("Null value must be null"); return false; case JsonValueType::Array: @@ -528,23 +528,23 @@ private: return false; } if (expectedType == JsonValueType::Object && !result.is_object()) { - errorMsg = "期望对象格式,如:{\"key\":\"value\"}"; + errorMsg = "期望对象格式,如:{key:value}"; return false; } return true; } default: - errorMsg = "未知的数据类型"; + errorMsg = TR("Unknown data type"); return false; } } catch (const nlohmann::json::parse_error& e) { - errorMsg = QString("JSON解析错误: %1").arg(e.what()); + errorMsg = QString(TR("JSON parse error: %1")).arg(e.what()); return false; } catch (const std::exception& e) { - errorMsg = QString("转换错误: %1").arg(e.what()); + errorMsg = QString(TR("Conversion error: %1")).arg(e.what()); return false; } } @@ -556,17 +556,17 @@ class JsonEditorGeneral : public QDialog { public: explicit JsonEditorGeneral(QWidget* parent = nullptr) : QDialog(parent) { - setWindowTitle("通用 JSON 编辑"); + setWindowTitle(TR("General JSON Editor")); m_textEdit = new QPlainTextEdit(this); - QPushButton* okBtn = new QPushButton("确定", this); - QPushButton* cancelBtn = new QPushButton("取消", this); + QPushButton* okBtn = new QPushButton(TR("OK"), this); + QPushButton* cancelBtn = new QPushButton(TR("Cancel"), this); connect(okBtn, &QPushButton::clicked, this, &JsonEditorGeneral::onAccept); connect(cancelBtn, &QPushButton::clicked, this, &QDialog::reject); QVBoxLayout* mainLayout = new QVBoxLayout(this); - mainLayout->addWidget(new QLabel("请输入 JSON:")); + mainLayout->addWidget(new QLabel(TR("Please enter JSON:"))); mainLayout->addWidget(m_textEdit); QHBoxLayout* btnLayout = new QHBoxLayout(); @@ -589,12 +589,12 @@ private slots: QString text = m_textEdit->toPlainText().trimmed(); if (text.isEmpty()) { - QMessageBox::warning(this, "警告", "JSON 内容不能为空"); + QMessageBox::warning(this, TR("Warning"), TR("JSON content cannot be empty")); return; } if (text.size() > 102400) { - QMessageBox::warning(this, "警告", "JSON 内容过大,可能导致崩溃"); + QMessageBox::warning(this, TR("Warning"), TR("JSON content is too large and may cause a crash")); return; } @@ -604,7 +604,7 @@ private slots: accept(); } catch (const std::exception& e) { - QMessageBox::critical(this, "解析错误", QString("JSON 解析失败:\n%1").arg(e.what())); + QMessageBox::critical(this, TR("Parse Error"), QString(TR("JSON parse failed:\n%1")).arg(e.what())); } } diff --git a/src/launcher/GUI/base_page.h b/src/launcher/GUI/base_page.h deleted file mode 100644 index c30cef6..0000000 --- a/src/launcher/GUI/base_page.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include - - -class BasePage :public QWidget -{ - Q_OBJECT -public: - QVBoxLayout* m_layout = new QVBoxLayout(this); - QLabel* m_title; - QIcon m_toolbarIcon; - BasePage() - { - QPalette palette; - palette.setColor(QPalette::WindowText, Qt::white); - QFont font("微软雅黑", 24, QFont::Bold); - QFont font2("微软雅黑", 108, QFont::Bold); - - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - this->setMaximumSize(9999, 9999); - this->setObjectName("pageBaseWidget "); - - m_layout->setContentsMargins(0, 0, 0, 0); - m_layout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - - m_title = new QLabel(u8"基础界面"); - m_title->setFont(font); - m_title->setPalette(palette); - m_title->setAlignment(Qt::AlignLeft); - - m_layout->addWidget(m_title); - } -}; \ No newline at end of file diff --git a/src/launcher/GUI/front/pages/manualDetWidget.h b/src/launcher/GUI/front/pages/manualDetWidget.h deleted file mode 100644 index 785614f..0000000 --- a/src/launcher/GUI/front/pages/manualDetWidget.h +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class manualDetWidget : public QWidget{ - Q_OBJECT - -public: - int componentsWidth = 500; - QVBoxLayout* Layout = new QVBoxLayout(this); - QHBoxLayout* btnLayout = new QHBoxLayout(this); - QHBoxLayout* mainLayout = new QHBoxLayout(this); - QVBoxLayout* leftMainLayout = new QVBoxLayout(this); - QVBoxLayout* rightMainLayout = new QVBoxLayout(this); - - std::vectorbtns; - QLabel* icon, * Title; - QStackedWidget* widgets = new QStackedWidget(); - - QLineEdit* imgPathEdit1 = new QLineEdit(this); - QLineEdit* imgPathEdit2 = new QLineEdit(this); - QComboBox* algoSelect = new QComboBox(this); - QTextEdit* logWidget = new QTextEdit(this); - //manualDetThread* _manualDetThread = new manualDetThread(imgPathEdit, algoSelect, logWidget); - fancyButtonText* startEvaluateBtn = new fancyButtonText("检测",100,60,""); - void titleInit(){ - QPalette palette; - palette.setColor(QPalette::WindowText, Qt::white); - QFont font("微软雅黑", 24, QFont::Bold); - QFont font2("微软雅黑", 108, QFont::Bold); - - widgets->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - widgets->setMaximumSize(9999, 9999); - - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - this->setMaximumSize(9999, 9999); - this->setObjectName("manualDetWidget"); - - Layout->setContentsMargins(0, 0, 0, 0); - Layout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - - Title = new QLabel(u8"手动检测界面(不支持中文路径"); - Title->setFont(font); - Title->setPalette(palette); - Title->setAlignment(Qt::AlignLeft); - - - Layout->addWidget(Title); - - btnLayout->setContentsMargins(0, 0, 0, 0); - btnLayout->setAlignment(Qt::AlignLeft); - } - void mainWidgetInit(){ - QPalette palette; - palette.setColor(QPalette::WindowText, Qt::white); - QFont font("微软雅黑", 18, QFont::Bold); - QFont font2("微软雅黑", 108, QFont::Bold); - - { - QLabel* strLabel = new QLabel(u8"图片路径1:"); - strLabel->setFont(font); - strLabel->setPalette(palette); - strLabel->setAlignment(Qt::AlignLeft); - leftMainLayout->addWidget(strLabel); - - imgPathEdit1->setFont(font); - imgPathEdit1->setPalette(palette); - imgPathEdit1->setAlignment(Qt::AlignLeft); - imgPathEdit1->setFixedWidth(componentsWidth); - leftMainLayout->addWidget(imgPathEdit1); - } - { - QLabel* strLabel = new QLabel(u8"图片路径2:"); - strLabel->setFont(font); - strLabel->setPalette(palette); - strLabel->setAlignment(Qt::AlignLeft); - leftMainLayout->addWidget(strLabel); - - imgPathEdit2->setFont(font); - imgPathEdit2->setPalette(palette); - imgPathEdit2->setAlignment(Qt::AlignLeft); - imgPathEdit2->setFixedWidth(componentsWidth); - leftMainLayout->addWidget(imgPathEdit2); - } - - - QLabel* strLabel2 = new QLabel(u8"选择算法"); - strLabel2->setFont(font); - strLabel2->setPalette(palette); - strLabel2->setAlignment(Qt::AlignLeft); - leftMainLayout->addWidget(strLabel2); - - algoSelect->setFont(font); - algoSelect->setPalette(palette); - algoSelect->setFixedWidth(componentsWidth); - algoSelect->addItem("2D"); - algoSelect->addItem("3D"); - leftMainLayout->addWidget(algoSelect); - - leftMainLayout->addWidget(startEvaluateBtn); - } - manualDetWidget(){ - titleInit(); - mainWidgetInit(); - logWidget->setReadOnly(true); - rightMainLayout->addWidget(logWidget); - - Layout->addLayout(btnLayout); - Layout->addLayout(mainLayout); - mainLayout->addLayout(leftMainLayout); - leftMainLayout->setAlignment(Qt::AlignTop); - mainLayout->addLayout(rightMainLayout); - - connect(startEvaluateBtn, &QPushButton::clicked, this, [=]() { manualStartSlot(); }); - connect(startEvaluateBtn, &QPushButton::clicked, this, [=]() {startEvaluateBtn->setDisabled(true); }); - //connect(_manualDetThread, &manualDetThread::finishImgReadSignal,this, &manualDetWidget::finishImgReadSlot); - } - ~manualDetWidget() - { - //delete _manualDetThread; - } -public slots: - void manualStartSlot() - { - std::vectorpath; - //if (imgPathEdit1->text().toStdString().compare("")) - path.push_back((imgPathEdit1->text().toStdString())); - //if (imgPathEdit2->text().toStdString().compare("")) - path.push_back((imgPathEdit2->text().toStdString())); - emit startManualDetSignal(path, algoSelect->currentIndex()); - } - void finishImgReadSlot() - { - startEvaluateBtn->setEnabled(true); - } -signals: - void startManualDetSignal(std::vector path, int index); -}; - -#pragma once \ No newline at end of file diff --git a/src/launcher/GUI/front/ui_mainwindow.h b/src/launcher/GUI/front/ui_mainwindow.h deleted file mode 100644 index b97b993..0000000 --- a/src/launcher/GUI/front/ui_mainwindow.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************** -** Form generated from reading UI file 'mainwindow.ui' -** -** Created by: Qt User Interface Compiler version 5.14.2 -** -** WARNING! All changes made in this file will be lost when recompiling UI file! -********************************************************************************/ - -#ifndef UI_MAINWINDOW_H -#define UI_MAINWINDOW_H - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class Ui_MainWindow -{ -public: - QWidget *centralwidget; - QGridLayout *gridLayout; - - void setupUi(QMainWindow *MainWindow) - { - if (MainWindow->objectName().isEmpty()) - MainWindow->setObjectName(QString::fromUtf8("MainWindow")); - MainWindow->resize(800, 600); - centralwidget = new QWidget(MainWindow); - centralwidget->setObjectName(QString::fromUtf8("centralwidget")); - gridLayout = new QGridLayout(centralwidget); - gridLayout->setSpacing(0); - gridLayout->setObjectName(QString::fromUtf8("gridLayout")); - gridLayout->setContentsMargins(5, 5, 5, 5); - MainWindow->setCentralWidget(centralwidget); - - retranslateUi(MainWindow); - - QMetaObject::connectSlotsByName(MainWindow); - } // setupUi - - void retranslateUi(QMainWindow *MainWindow) - { - MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr)); - } // retranslateUi - -}; - -namespace Ui { - class MainWindow: public Ui_MainWindow {}; -} // namespace Ui - -QT_END_NAMESPACE - -#endif // UI_MAINWINDOW_H diff --git a/src/launcher/GUI/front/loadingWidget.h b/src/launcher/GUI/loadingWidget.h similarity index 89% rename from src/launcher/GUI/front/loadingWidget.h rename to src/launcher/GUI/loadingWidget.h index e65b5d7..77b2e3f 100644 --- a/src/launcher/GUI/front/loadingWidget.h +++ b/src/launcher/GUI/loadingWidget.h @@ -1,4 +1,5 @@ -#include +#include +#include #include #include #include @@ -8,7 +9,7 @@ #include #include #include -#include +#include class MainWindow; class loadingWidget : public QWidget { public: @@ -18,11 +19,11 @@ public: QMovie* movie = nullptr; QTextEdit* initLog = nullptr; QTextEdit* consoleLog = nullptr; - fancyButtonText* retryBtn = new fancyButtonText("重试", 100, 50, "重新进行初始化"); - fancyButtonText* manualBtn = new fancyButtonText("离线模式", 180, 50, "离线模式"); + fancyButtonText* retryBtn = new fancyButtonText(TR("Retry"), 100, 50, TR("Reinitialize")); + fancyButtonText* manualBtn = new fancyButtonText(TR("Offline Mode"), 180, 50, TR("Offline Mode")); QGridLayout* glayout = new QGridLayout(this); QGridLayout* logLayout = new QGridLayout(this); - loadingWidget(qtFuncBridge* bridgeIn){ + loadingWidget(fSignalHub* bridgeIn){ bridge = bridgeIn; glayout->setAlignment(Qt::AlignCenter); connect(retryBtn, &QPushButton::clicked, [=]() @@ -52,11 +53,11 @@ public: "border: 0px solid red;" "border-radius: 0px;")); initLog->setReadOnly(true); - QFont font("微软雅黑", 8); + QFont font("Microsoft YaHei", 8); - initLog->setFont(font); - initLog->setTextColor(Qt::white); - initLog->append("正在初始化..."); + initLog->setFont(font); + initLog->setTextColor(Qt::white); + initLog->append(TR("Initializing...")); logLayout->addWidget(initLog, 0, 0); @@ -68,10 +69,10 @@ public: "border-radius: 0px;")); consoleLog->setReadOnly(true); consoleLog->setFixedWidth(720); - QFont font2("微软雅黑", 7); - consoleLog->setFont(font2); - consoleLog->setTextColor(Qt::white); - consoleLog->append("控制台日志..."); + QFont font2("Microsoft YaHei", 7); + consoleLog->setFont(font2); + consoleLog->setTextColor(Qt::white); + consoleLog->append(TR("Console Log...")); logLayout->addWidget(consoleLog, 1, 0,Qt::AlignCenter|Qt::AlignTop); //重试或者离线模式等按钮 @@ -191,6 +192,6 @@ protected: private: QPixmap screenshot_; QMutex mutex; - qtFuncBridge* bridge; + fSignalHub* bridge; }; #pragma once \ No newline at end of file diff --git a/src/launcher/GUI/front/loginWindow.h b/src/launcher/GUI/loginWindow.h similarity index 89% rename from src/launcher/GUI/front/loginWindow.h rename to src/launcher/GUI/loginWindow.h index fb0114f..7133a7e 100644 --- a/src/launcher/GUI/front/loginWindow.h +++ b/src/launcher/GUI/loginWindow.h @@ -1,4 +1,5 @@ -#include +#include +#include #include #include #include @@ -31,15 +32,15 @@ public: palette.setColor(QPalette::WindowText, Qt::white); layout= new QVBoxLayout(this); - button = new fancyButtonText("确定", 100, 40, ""); + button = new fancyButtonText(TR("Confirm"), 100, 40, ""); - label=new QLabel("欢迎!"); + label=new QLabel(TR("Welcome!")); label->setAlignment(Qt::AlignHCenter); label->setFont(QFont("Microsoft YaHei", 30, QFont::Bold)); label->setPalette(palette); comboBox= new QComboBox; - comboBox->addItems({ u8"工程师",u8"售后",u8"调试" }); + comboBox->addItems({ TR("Engineer"),TR("After-sales"),TR("Debug") }); comboBox->setFont(QFont("Microsoft YaHei", 14)); comboBox->setStyleSheet("QComboBox { padding-left: 4px; padding-right: 4px; }" "QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: right; }" @@ -56,7 +57,7 @@ public: passwordEdit.setFont(QFont("Microsoft YaHei", 12, QFont::Bold)); layout->addWidget(&passwordEdit); - exitBtn = new fancyButtonText(u8"退出", 100, 40, ""); + exitBtn = new fancyButtonText(TR("Exit"), 100, 40, ""); QObject::connect(exitBtn, &QPushButton::clicked, [=]() { exit(0); }); diff --git a/src/launcher/GUI/mainwindow.cpp b/src/launcher/GUI/mainwindow.cpp index 9cf588f..1824ea6 100644 --- a/src/launcher/GUI/mainwindow.cpp +++ b/src/launcher/GUI/mainwindow.cpp @@ -1,5 +1,4 @@ #include "mainwindow.h" -#include "ui_mainwindow.h" #include #include #include @@ -10,15 +9,14 @@ #include -MainWindow::MainWindow(appConfig* configIn, qtFuncBridge*bridgeIn, nlohmann::ordered_json& jsonIn) - : ui(new Ui::MainWindow), - bridge(bridgeIn),config(configIn),json(jsonIn), +MainWindow::MainWindow(appConfig* configIn, fSignalHub*bridgeIn, nlohmann::ordered_json& jsonIn) + :bridge(bridgeIn),config(configIn),json(jsonIn), _SummuaryDataPage(configIn,jsonIn["sublUiSetting"]), _loadingWidget(bridgeIn){ + topBar = new topMenuBar(this,configIn,this); leftBar = new leftMenuBar(this); // 将菜单栏添加到MainWindow的布局中 - ui->setupUi(this); this->setWindowFlags(Qt::FramelessWindowHint); // 设置无边框的样式 setMouseTracking(true);//鼠标追踪 this->setMinimumSize(1280, 720); @@ -56,7 +54,6 @@ MainWindow::MainWindow(appConfig* configIn, qtFuncBridge*bridgeIn, nlohmann::ord QObject::connect(_loadingWidget.manualBtn, &QPushButton::clicked, this, &MainWindow::switchToManulMode); - _displayWidget->historyImgs->hide(); #if skipLogin == 1 login(true); @@ -76,7 +73,8 @@ void MainWindow::initLeftMenuBarComponents() { registerPageBar(leftMenuBar::barPositionEnum::top, ":/icon/icon/home.png", u8"主界面", _displayWidget); //生产数据页面 - registerPageBar(leftMenuBar::barPositionEnum::top, ":/icon/icon/summary_data.png", u8"生产数据", &_SummuaryDataPage); + if(_SummuaryDataPage.widgetCounts > 0) + registerPageBar(leftMenuBar::barPositionEnum::top, ":/icon/icon/summary_data.png", u8"生产数据", &_SummuaryDataPage); //日志页面 _logWidget = new logWidget(); diff --git a/src/launcher/GUI/mainwindow.h b/src/launcher/GUI/mainwindow.h index e2ca057..6a3c9ee 100644 --- a/src/launcher/GUI/mainwindow.h +++ b/src/launcher/GUI/mainwindow.h @@ -15,20 +15,16 @@ #include #include "uiModule/components/toolBarButton.h" #include -#include "front/loginWindow.h" +#include #include -#include "front/loadingWidget.h" +#include -#include "front/pages/displayPageWidget.h" -#include "front/pages/settingWidget.h" -#include "front/pages/logPageWidget.h" -#include "front/pages/sqlControlWidget.h" -#include "front/pages/manualDetWidget.h" -#include "front/pages/historyWidget.h" -#include -#include "front/pages/pluginManagerWidget.hpp" -#include "front/pages/summaryDataPage.h" -#include +#include +#include +#include +#include +#include +#include #pragma execution_character_set("utf-8") QT_BEGIN_NAMESPACE @@ -83,9 +79,9 @@ public: layout->addWidget(rightWidget); // 左侧 - QPalette palette; - palette.setColor(QPalette::WindowText, Qt::white); - QFont font("微软雅黑", 18, QFont::Bold); + QPalette palette; + palette.setColor(QPalette::WindowText, Qt::white); + QFont font("Microsoft YaHei", 18, QFont::Bold); QLabel* factoryIconLabel = new QLabel(); factoryIconLabel->setPixmap(QPixmap(":/icon/icon/logo_Dongsheng.png")); // 设置图标 @@ -93,7 +89,7 @@ public: factoryIconLabel->setFixedSize(topBarHeight, topBarHeight); leftLayout->addWidget(factoryIconLabel); - QString title(TR("AI Detection System")); + QString title(TR("AI Detection System") + " " + QString::fromStdString(config->softwareTile)); QLabel* titleLabel = new QLabel(title); titleLabel->setFont(font); titleLabel->setPalette(palette); @@ -265,7 +261,7 @@ public: topMenuBar* topBar;//顶部栏 leftMenuBar* leftBar;//左侧栏 MainWindow(appConfig* config = nullptr, - qtFuncBridge* bridge = nullptr, + fSignalHub* bridge = nullptr, nlohmann::ordered_json& _jsonIn = nlohmann::ordered_json()); ~MainWindow(); void registerQuitFunc(std::function quitFunc) { @@ -283,13 +279,9 @@ public: settingWidget* _settingWidget; logWidget* _logWidget; sqlControlWidget* _sqlControlWidget; - manualDetWidget* _manualDetWidget; - historyWidget* _historyWidget; SummuaryDataPage _SummuaryDataPage; - pluginManagerWidget* _pluginManagerWidget = new pluginManagerWidget(); private: - Ui::MainWindow* ui; - qtFuncBridge* bridge = nullptr; + fSignalHub* bridge = nullptr; appConfig* config; nlohmann::ordered_json json; //动画效果 @@ -425,9 +417,6 @@ public slots: _loadingWidget.initLog->append(strIn); } } - void addDetHistoryData(bool isOK, historyPack _historyPack){ - _displayWidget->historyImgs->addData(isOK, _historyPack); - } void addCtData(int index, int value){ switch (index) { @@ -467,7 +456,7 @@ protected: void mouseMoveEvent(QMouseEvent* event) override { if (event->buttons() == Qt::LeftButton && isMoving) { QPoint pos = event->globalPos(); - if (getMax(getAbs(pos.x()- startPos.x()), getAbs(pos.y() - startPos.y()))>10) + if (std::max(std::abs(pos.x()- startPos.x()), std::abs(pos.y() - startPos.y()))>10) if(lastWindowMoveTime.elapsed()> freshDelay)//每秒刷新100次 { lastWindowMoveTime.restart(); diff --git a/src/launcher/GUI/mainwindow.ui b/src/launcher/GUI/mainwindow.ui deleted file mode 100644 index 25fa117..0000000 --- a/src/launcher/GUI/mainwindow.ui +++ /dev/null @@ -1,38 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 800 - 600 - - - - MainWindow - - - - - 5 - - - 5 - - - 5 - - - 5 - - - 0 - - - - - - - diff --git a/src/launcher/GUI/front/pages/displayPageWidget.h b/src/launcher/GUI/pages/displayPageWidget.h similarity index 82% rename from src/launcher/GUI/front/pages/displayPageWidget.h rename to src/launcher/GUI/pages/displayPageWidget.h index e6dc997..33a7bf0 100644 --- a/src/launcher/GUI/front/pages/displayPageWidget.h +++ b/src/launcher/GUI/pages/displayPageWidget.h @@ -183,12 +183,9 @@ public: ImageWidgetManager _ImageWidgetManager; summaryDataManager* _summaryDataManager; dsStatsWidget* _dsStatsWidget; - historyShowListWidget* historyImgs = new historyShowListWidget(); dayNightShiftHistogramWidget* _dayNightShiftHistogramWidget; userSwitch* _userSwitch; softwareDataDisplay* _softwareDataDisplay; - calibration* _calibration; - cameraRealTimeCapture* _cameraRealTimeCapture; runCommandWidget* _runCommandWidget; LogWindow* log = new LogWindow(); displayWidget(appConfig* config) :m_config(config){ @@ -225,16 +222,10 @@ public: //Layout->setColumnStretch(2, 1); leftItemInit(config); rightItemInit1(); - rightItemInit2(); - connectFunc(); //historyImgs->addData(true, "D:/CCD/yuantu/2024-06-04/23H/TEST/1 (1).bmp", QPixmap("D:/CCD/yuantu/2024-06-04/23H/TEST/1 (1).bmp")); } void rightItemInit1(){ - QVBoxLayout* hLayout = new QVBoxLayout(rightWidget1); - hLayout->addWidget(historyImgs); - } - void rightItemInit2(){ QVBoxLayout* hLayout = new QVBoxLayout(rightWidget2); { @@ -292,43 +283,6 @@ public: QWidget* titleWidget = new QWidget(this); QFont font3("微软雅黑", 10, QFont::Bold); -#pragma region 日志分析按钮 - { - _toolBarWidget->createToolButton(QIcon(":/TongYongUiIcon/TongYongUiIcon/4.LogAnalyze.png"), - QString::fromStdString(trans.translate("Log")), - [=]() { - emit changeStackWidget(2); - }); - } -#pragma endregion -#pragma region 打开配置文件按钮 - { - /*QVBoxLayout* btnLayout = new QVBoxLayout(); - QPushButton* btn = new QPushButton(this); - btn->setIcon(QIcon(":/TongYongUiIcon/TongYongUiIcon/9.paramSetting.png")); - btn->setFixedSize(QSize(50, 50)); - btn->setIconSize(QSize(25, 25)); - btn->setStyleSheet(R"( - QPushButton { - background-color: transparent; - border: none; - } - QPushButton:hover { - background-color: black; - border-radius: 5px; - } - )"); - QLabel* text = new QLabel(config->_translation->translate("SettingJson")); - text->setFont(font3); - text->setPalette(palette); - btnLayout->addWidget(btn); - btnLayout->addWidget(text); - titleLayout->addLayout(btnLayout); - connect(btn, &QPushButton::clicked, [=]() { - QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(config->settingJsonPath))); - });*/ - } -#pragma endregion #pragma region 结果图查看按钮 { _toolBarWidget->createToolButton(QIcon(":/TongYongUiIcon/TongYongUiIcon/23.1.imageView.png"), @@ -345,7 +299,8 @@ public: [this]() { paramTableEditor* dlg = new paramTableEditor(this); std::vector> params; - emit qtFuncBridge::getInstance()->getAllParams(¶ms); + auto b = fSignalHub::getInstance(); + emit fSignalHub::getInstance()->getAllParams(¶ms); dlg->setParams(params); dlg->show(); }, Auth::UserLevel::ADMIN); @@ -363,34 +318,24 @@ public: } #pragma endregion #pragma region 相机实时取流 - { - _cameraRealTimeCapture = new cameraRealTimeCapture(); - _toolBarWidget->createToolButton(QIcon(":/TongYongUiIcon/TongYongUiIcon/0.cameraModule.png"), - QString::fromStdString("相机实时取流"), - [=]() { - _cameraRealTimeCapture->show(); - }, Auth::UserLevel::ADMIN); - } + //{ + // _cameraRealTimeCapture = new cameraRealTimeCapture(); + // _toolBarWidget->createToolButton(QIcon(":/TongYongUiIcon/TongYongUiIcon/0.cameraModule.png"), + // QString::fromStdString("相机实时取流"), + // [=]() { + // _cameraRealTimeCapture->show(); + // }, Auth::UserLevel::ADMIN); + //} #pragma endregion #pragma region 九点标定引导按钮 - { - _calibration = new calibration(); - _toolBarWidget->createToolButton(QIcon(":/icon/icon/jiuDianBiaoDingBiaoDing.png"), - QString::fromStdString("九点标定"), - [=]() { - _calibration->show(); - }, Auth::UserLevel::ADMIN); - } -#pragma endregion -#pragma region 标定板标定 - { - //_calibration = new calibration(); - _toolBarWidget->createToolButton(QIcon(":/icon/icon/biaoDingBanBiaoDing.png"), - QString::fromStdString("标定板标定"), - [=]() { - //_calibration->show(); - }, Auth::UserLevel::ADMIN); - } + //{ + // _calibration = new calibration(); + // _toolBarWidget->createToolButton(QIcon(":/icon/icon/jiuDianBiaoDingBiaoDing.png"), + // QString::fromStdString("九点标定"), + // [=]() { + // _calibration->show(); + // }, Auth::UserLevel::ADMIN); + //} #pragma endregion #pragma region 读取bin目录下的tools文件夹并展示 { @@ -421,11 +366,6 @@ public: //leftWidget->setMaximumWidth(width / 1.2); //rightWidget->setMaximumWidth(width / 2); } - void connectFunc(){ - QObject::connect(historyImgs, &historyShowListWidget::itemClickSignal, - this, &displayWidget::historyClick); - - } public slots: diff --git a/src/launcher/GUI/front/pages/historyWidget.h b/src/launcher/GUI/pages/historyWidget.h similarity index 100% rename from src/launcher/GUI/front/pages/historyWidget.h rename to src/launcher/GUI/pages/historyWidget.h diff --git a/src/launcher/GUI/front/pages/logPageWidget.h b/src/launcher/GUI/pages/logPageWidget.h similarity index 96% rename from src/launcher/GUI/front/pages/logPageWidget.h rename to src/launcher/GUI/pages/logPageWidget.h index 5b57dd8..361f233 100644 --- a/src/launcher/GUI/front/pages/logPageWidget.h +++ b/src/launcher/GUI/pages/logPageWidget.h @@ -55,7 +55,7 @@ public: logWidget() { QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); - QFont font("微软雅黑", 24, QFont::Bold); + QFont font("Microsoft YaHei", 24, QFont::Bold); // 初始化批量处理定时器 batchUpdateTimer = new QTimer(this); @@ -73,7 +73,7 @@ public: Layout->setContentsMargins(0, 0, 0, 0); Layout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - Title = new QLabel(u8"日志"); + Title = new QLabel(TR("Log")); Title->setFont(font); Title->setPalette(palette); Title->setAlignment(Qt::AlignLeft); @@ -104,8 +104,8 @@ public: stdConsoleOutput.setStyleSheet(textEditStyle); qtConsoleOutput.setStyleSheet(textEditStyle); - addLogWidget(u8"控制台", &stdConsoleOutput, logType::stdConsle); - addLogWidget(u8"QT日志", &qtConsoleOutput, logType::qtConsle); + addLogWidget(TR("Console"), &stdConsoleOutput, logType::stdConsle); + addLogWidget(TR("System Log"), &qtConsoleOutput, logType::qtConsle); btns[0]->pressed(); Layout->addWidget(widgets); @@ -118,7 +118,7 @@ public: void addLogWidget(QString btnText, QPlainTextEdit* textWidget, logType type) { QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); - QFont font2("微软雅黑", 8); + QFont font2("Microsoft YaHei", 8); int index = btns.size(); gradientButton* btn = new gradientButton(160, 50, btnText, ""); @@ -144,8 +144,8 @@ public: QHBoxLayout* toolHLayout2 = new QHBoxLayout(); widgetLayout->addLayout(toolHLayout2); - QPushButton* openDirBtn = new QPushButton("打开日志文件夹"); - QPushButton* autoScrollBtn = new QPushButton("自动滚动"); + QPushButton* openDirBtn = new QPushButton(TR("Open Log Folder")); + QPushButton* autoScrollBtn = new QPushButton(TR("Auto Scroll")); autoScrollBtn->setCheckable(true); autoScrollBtn->setChecked(true); diff --git a/src/launcher/GUI/front/pages/pluginManagerWidget.hpp b/src/launcher/GUI/pages/pluginManagerWidget.hpp similarity index 100% rename from src/launcher/GUI/front/pages/pluginManagerWidget.hpp rename to src/launcher/GUI/pages/pluginManagerWidget.hpp diff --git a/src/launcher/GUI/front/pages/settingWidget.h b/src/launcher/GUI/pages/settingWidget.h similarity index 84% rename from src/launcher/GUI/front/pages/settingWidget.h rename to src/launcher/GUI/pages/settingWidget.h index 2d3148a..578121e 100644 --- a/src/launcher/GUI/front/pages/settingWidget.h +++ b/src/launcher/GUI/pages/settingWidget.h @@ -19,8 +19,7 @@ #include #include #include -#include "git_version.h" -#include +#include #include #include #include @@ -37,6 +36,8 @@ public: std::vectorbtns; QLabel* icon, * Title; int currentPageIndex = 0; + calibration _calibration; + cameraRealTimeCapture _cameraRealTimeCapture; settingWidget(appConfig* _configIn):_config(_configIn){ QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); @@ -116,7 +117,7 @@ public: Title->setPalette(palette); Title->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); - QLabel* versionShow = new QLabel(QString(u8"当前版本: v%1 | 提交版本: %2").arg(QString::fromStdString(softwareVersion)).arg(GIT_COMMIT_HASH)); + QLabel* versionShow = new QLabel(QString(TR("Current version: v%1")).arg(QString::fromStdString(softwareVersion))); versionShow->setFont(font2); versionShow->setPalette(palette); versionShow->setAlignment(Qt::AlignRight | Qt::AlignVCenter); @@ -131,13 +132,13 @@ public: //语言设置 { // 创建语言设置分组容器 - QGroupBox* languageGroupBox = new QGroupBox(QString::fromStdString(Translation::getInstance().translate("Language Settings"))); + QGroupBox* languageGroupBox = new QGroupBox(TR("Language Settings")); languageGroupBox->setObjectName("languageGroupBox"); languageGroupBox->setStyleSheet(R"( QGroupBox#languageGroupBox { background: rgb(50, 55, 60); border-radius: 10px; - font-family: "微软雅黑"; + font-family: "Microsoft YaHei"; font-size: 14px; font-weight: bold; color: white; @@ -157,7 +158,7 @@ public: QHBoxLayout* languageSelectLayout = new QHBoxLayout(); languageSelectLayout->setSpacing(15); - QLabel* languageSelectLabel = new QLabel(u8"选择语言/Language/Bahasa:"); + QLabel* languageSelectLabel = new QLabel(TR("Select Language / Language / Bahasa:")); languageSelectLabel->setFont(font2); languageSelectLabel->setPalette(palette); languageSelectLabel->setMinimumWidth(200); @@ -216,7 +217,7 @@ public: //控制台 { // 创建控制台设置分组容器 - QGroupBox* consoleGroupBox = new QGroupBox(QString::fromStdString(Translation::getInstance().translate("Window Settings"))); + QGroupBox* consoleGroupBox = new QGroupBox(TR("Window Settings")); consoleGroupBox->setObjectName("consoleGroupBox"); consoleGroupBox->setStyleSheet(R"( QGroupBox#consoleGroupBox { @@ -240,7 +241,7 @@ public: consoleMainLayout->setSpacing(10); // 添加说明文字 - QLabel* consoleDescription = new QLabel(QString::fromStdString(Translation::getInstance().translate("Control the visibility of the debug console window"))); + QLabel* consoleDescription = new QLabel(TR("Control the visibility of the debug console window")); consoleDescription->setFont(font2); consoleDescription->setPalette(palette); consoleDescription->setStyleSheet("color: rgb(180, 180, 180);"); @@ -279,7 +280,7 @@ public: } )"); - fancyButtonText* setResolutionBtn = new fancyButtonText(u8"设置1920x1040"); + fancyButtonText* setResolutionBtn = new fancyButtonText(TR("Set 1920x1040")); setResolutionBtn->setStyleSheet(R"( fancyButtonText { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, @@ -303,11 +304,11 @@ public: connect(showConsoleBtn, &QPushButton::clicked, [=]() { ShowWindow(_config->consoleHandle, SW_SHOW); - }); + }); connect(hideConsoleBtn, &QPushButton::clicked, [=]() { ShowWindow(_config->consoleHandle, SW_HIDE); - }); + }); connect(setResolutionBtn, &QPushButton::clicked, [=]() { // 获取当前窗口的顶级窗口 @@ -315,10 +316,10 @@ public: while (topWidget->parentWidget()) { topWidget = topWidget->parentWidget(); } - + // 设置窗口大小为1920x1040 topWidget->resize(1920, 1040); - + // 可选:将窗口居中显示 QScreen* screen = QApplication::primaryScreen(); if (screen) { @@ -327,7 +328,7 @@ public: int y = (screenGeometry.height() - 1080) / 2; topWidget->move(x, y); } - }); + }); m_layout->addWidget(consoleGroupBox); } @@ -352,7 +353,7 @@ public: padding: 0 10px 0 10px; } )"); - + QVBoxLayout* hardwareMainLayout = new QVBoxLayout(hardwareGroupBox); hardwareMainLayout->setContentsMargins(15, 15, 15, 15); hardwareMainLayout->setSpacing(10); @@ -373,7 +374,51 @@ public: hardwareMainLayout->addWidget(&_hardwareInfoWidget); m_layout->addWidget(hardwareGroupBox); }*/ + //小工具 + { + // 创建控制台设置分组容器 + QGroupBox* GroupBox = new QGroupBox(TR("Toolbox")); + GroupBox->setObjectName("toolsGroupBox"); + GroupBox->setStyleSheet(R"( + QGroupBox#toolsGroupBox { + background: rgb(50, 55, 60); + border-radius: 10px; + font-family: "微软雅黑"; + font-size: 14px; + font-weight: bold; + color: white; + padding-top: 20px; + } + QGroupBox#toolsGroupBox::title { + subcontrol-origin: margin; + left: 10px; + padding: 0 10px 0 10px; + } + )"); + QVBoxLayout* consoleMainLayout = new QVBoxLayout(GroupBox); + consoleMainLayout->setContentsMargins(15, 15, 15, 15); + consoleMainLayout->setSpacing(10); + { + fancyButtonText* btn = new fancyButtonText(TR("Nine-Point Calibration")); + QObject::connect(btn, &QPushButton::clicked, &_calibration, &QWidget::show); + consoleMainLayout->addWidget(btn); + } + { + fancyButtonText* btn = new fancyButtonText(TR("Camera Real-time Capture (soft-trigger only)")); + QObject::connect(btn, &QPushButton::clicked, &_cameraRealTimeCapture, &QWidget::show); + consoleMainLayout->addWidget(btn); + } + { + fancyButtonText* btn = new fancyButtonText(TR("Open Config File")); + consoleMainLayout->addWidget(btn); + connect(btn, &QPushButton::clicked, [=]() { + QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(appConfig::getInstance().missionJsonPath))); + }); + consoleMainLayout->addWidget(btn); + } + m_layout->addWidget(GroupBox); + } // 添加底部伸缩空间 m_layout->addStretch(); diff --git a/src/launcher/GUI/front/pages/sqlControlWidget.h b/src/launcher/GUI/pages/sqlControlWidget.h similarity index 83% rename from src/launcher/GUI/front/pages/sqlControlWidget.h rename to src/launcher/GUI/pages/sqlControlWidget.h index f4c0a21..65a0b3b 100644 --- a/src/launcher/GUI/front/pages/sqlControlWidget.h +++ b/src/launcher/GUI/pages/sqlControlWidget.h @@ -14,8 +14,8 @@ class sqliteReader : public QWidget{ Q_OBJECT public: - sqliteReader(SQLiteDB* dbIn):db(dbIn) { - QFont font("微软雅黑", 12, QFont::Bold); + sqliteReader(SQLiteDB* dbIn):db(dbIn) { + QFont font("Microsoft YaHei", 12, QFont::Bold); QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); @@ -24,7 +24,7 @@ public: layout->addLayout(vLayout); //1-1-1 - QLabel* showLabel = new QLabel(u8"班次"); + QLabel* showLabel = new QLabel(TR("Shift")); showLabel->setFont(font); showLabel->setPalette(palette); vLayout->addWidget(showLabel); @@ -43,7 +43,7 @@ public: connect(refreshBtn, &QPushButton::clicked, this, [=]() {refreshTable(); }); - QLabel* showLabel2 = new QLabel(u8"SN查询"); + QLabel* showLabel2 = new QLabel(TR("SN Search")); showLabel2->setFont(font); showLabel2->setPalette(palette); vLayout->addWidget(showLabel2); @@ -101,9 +101,9 @@ public: // 打开文件管理器,默认文件名为表名.csv QString filePath = QFileDialog::getSaveFileName( this, - u8"导出为CSV", + TR("Export as CSV"), QDir::homePath() + "/" + tableName + ".csv", - u8"CSV文件 (*.csv)" + TR("CSV File (*.csv)") ); if (filePath.isEmpty()) { @@ -113,15 +113,14 @@ public: // 导出数据 bool success = false; if (db) { - std::mutex mutex; - success = db->exportTableToCSV(tableName, filePath, mutex); + success = db->exportTableToCSV(tableName, filePath); } // 提示导出结果 if (success) { - QMessageBox::information(this, u8"导出成功", u8"数据已成功导出到:\n" + filePath); + QMessageBox::information(this, TR("Export Successful"), TR("Data successfully exported to:\n") + filePath); } else { - QMessageBox::warning(this, u8"导出失败", u8"导出CSV文件失败,请检查路径或数据库状态。"); + QMessageBox::warning(this, TR("Export Failed"), TR("Failed to export CSV. Please check the path or database status.")); } } @@ -131,9 +130,9 @@ private: QComboBox* tableSelectComboBox = new QComboBox(); QVBoxLayout* layout = new QVBoxLayout(this); QTableView* tableWidget = new QTableView(); - fancyButtonText* refreshBtn = new fancyButtonText(u8"刷新", 80, 25, ""); - fancyButtonText* searchSnBtn = new fancyButtonText(u8"查询", 80, 25, ""); - fancyButtonText* dumpToCsvBtn = new fancyButtonText(u8"导出", 80, 25, ""); + fancyButtonText* refreshBtn = new fancyButtonText(TR("Refresh"), 80, 25, ""); + fancyButtonText* searchSnBtn = new fancyButtonText(TR("Search"), 80, 25, ""); + fancyButtonText* dumpToCsvBtn = new fancyButtonText(TR("Export"), 80, 25, ""); protected: void showEvent(QShowEvent* event) override { QWidget::showEvent(event); @@ -149,7 +148,7 @@ public: QStackedWidget* widgets = new QStackedWidget(); sqliteReader _sqliteReader; QTableWidget* sqlWidget = new QTableWidget(); - QLabel* disconnnectedLabel = new QLabel("服务已离线"); + QLabel* disconnnectedLabel = new QLabel(TR("Service is offline")); sqlControlWidget(appConfig* _configIN):_sqliteReader(_configIN->dataBase){ this->setObjectName("sqlControlWidget"); @@ -161,8 +160,8 @@ public: )"); QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); - QFont font("微软雅黑", 24, QFont::Bold); - QFont font2("微软雅黑", 108, QFont::Bold); + QFont font("Microsoft YaHei", 24, QFont::Bold); + QFont font2("Microsoft YaHei", 108, QFont::Bold); widgets->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); widgets->setMaximumSize(9999, 9999); @@ -174,7 +173,7 @@ public: Layout->setContentsMargins(0, 0, 0, 0); Layout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - Title = new QLabel(u8"数据库操作界面"); + Title = new QLabel(TR("Database Operations")); Title->setFont(font); Title->setPalette(palette); Title->setAlignment(Qt::AlignLeft); diff --git a/src/launcher/GUI/front/pages/summaryDataPage.h b/src/launcher/GUI/pages/summaryDataPage.h similarity index 93% rename from src/launcher/GUI/front/pages/summaryDataPage.h rename to src/launcher/GUI/pages/summaryDataPage.h index e10483a..4dc27c7 100644 --- a/src/launcher/GUI/front/pages/summaryDataPage.h +++ b/src/launcher/GUI/pages/summaryDataPage.h @@ -15,20 +15,21 @@ public: QStackedWidget* stackedWidgets; QHBoxLayout* btnLayout; int currentPageIndex = 0; + int widgetCounts = 0; SummuaryDataPage(appConfig*config, nlohmann::ordered_json& json) :m_config(config),m_json(json){ QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); - QFont font("微软雅黑", 24, QFont::Bold); - QFont font2("微软雅黑", 108, QFont::Bold); + QFont font("Microsoft YaHei", 24, QFont::Bold); + QFont font2("Microsoft YaHei", 108, QFont::Bold); this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - this->setObjectName(u8"生产数据采集"); + this->setObjectName(TR("Production Data Collection")); m_layout->setContentsMargins(0, 0, 0, 0); m_layout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - m_title = new QLabel(u8"生产数据采集"); + m_title = new QLabel(TR("Production Data Collection")); m_title->setFont(font); m_title->setPalette(palette); m_title->setAlignment(Qt::AlignLeft); @@ -54,6 +55,7 @@ public: for(auto& jsonData : it.value()) { if (jsonData.at("widgetType") == "WaveFormWidget") { addPlot(jsonData, page, QString::fromStdString(pageName)); + widgetCounts++; } } diff --git a/src/launcher/GUI/paramEditorDialog.h b/src/launcher/GUI/paramEditorDialog.h index fd679e2..4fd03aa 100644 --- a/src/launcher/GUI/paramEditorDialog.h +++ b/src/launcher/GUI/paramEditorDialog.h @@ -23,23 +23,264 @@ #include #include #include +#include +#include +#include class paramTableEditor : public QDialog { Q_OBJECT - public: explicit paramTableEditor(QWidget* parent = nullptr) : QDialog(parent) { - this->setWindowTitle("JSON 表格编辑器"); - this->resize(700, 450); - setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint);// 去掉边框 - //setAttribute(Qt::WA_TranslucentBackground); // 背景透明 + this->setWindowTitle("参数编辑器"); + this->resize(900, 500); + setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint); this->setObjectName("paramTableEditor"); this->setStyleSheet(QString("QDialog#paramTableEditor {background-color: rgb(%1);border: 2px solid #000000;border-radius: 6px;}").arg(sColor_Blue)); + + //创建主水平布局 + QHBoxLayout* mainLayout = new QHBoxLayout(this); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + + //创建侧边栏 + createSidebar(); + + //创建分隔线 + m_dividerLine = new QFrame(this); + m_dividerLine->setFrameShape(QFrame::VLine); + m_dividerLine->setFrameShadow(QFrame::Sunken); + m_dividerLine->setStyleSheet("background-color: #555555;"); + m_dividerLine->setFixedWidth(1); + + //创建内容区域 + createContentArea(); + + //组装布局 + mainLayout->addWidget(m_sidebarWidget); + mainLayout->addWidget(m_dividerLine); + mainLayout->addWidget(m_contentWidget, 1); //内容区域占据剩余空间 + } + + void setParams(std::vector> params) { + //保存所有参数 + for(auto& data : params) { + m_allParams.insert(data.first, data.second); + } + //生成参数修改控件的缓存 + //for (auto& it = params.begin(); it != params.end(); it++) { + // m_paramsEditItemsCache.insert(it->first, createEditorWidget(it->second, it->second.type())); + //} + //清空现有数据 + m_tableModel->setRowCount(0); + m_editorWidgets.clear(); + m_sidebarList->clear(); + + if (params.size() == 0) return; + + //提取分组信息 + QSet groups; + QMap> groupedParams; + + for (auto& data : params) { + const QString& fullKey = data.first; + QString groupName = "默认分组"; + + //解析分组名 + int firstDotIndex = fullKey.indexOf('.'); + if (firstDotIndex != -1) { + groupName = fullKey.left(firstDotIndex); + } + + groups.insert(groupName); + groupedParams[groupName].push_back(fullKey); + } + + //添加分组到侧边栏 + QStringList groupList = groups.values(); + groupList.sort(); + + //添加"所有参数"选项 + m_sidebarList->addItem("所有参数"); + for (const QString& group : groupList) { + m_sidebarList->addItem(group); + } + + //保存分组参数 + m_groupedParamsNames = groupedParams; + for (auto& it = params.begin(); it != params.end(); it++) { + m_groupedParamsNames["所有参数"].push_back(it->first); + } - m_tableView = new QTableView(this); - m_tableModel = new QStandardItemModel(0, 2, this);// 2列:选项、值 + //默认显示所有参数 + displayGroupParams("所有参数"); + + if (m_sidebarList->count() > 0) { + m_sidebarList->setCurrentRow(0); + } + } + +private slots: + void onAccept() { + //更新当前数据 + for (auto& it : m_editorWidgets) { + auto expectedType = m_originalTypes[it.first]; + // 从编辑器获取值 + QVariant convertedValue; + QString errorMsg; + if (!getValueFromEditor(it.first, expectedType, convertedValue, errorMsg)) { + qCritical() << (this, "本地类型验证失败", QString("%1值验证失败:\n%2").arg(it.first).arg(errorMsg)); + continue; + } + if (m_allParams.contains(it.first)) { + m_allParams[it.first] = convertedValue; + } + } + std::vector> result; + + for (auto& it = m_allParams.begin(); it != m_allParams.end(); it++) { + //解析分组组名和参数名 + QString group, name; + int dotIndex = it.key().indexOf('.'); + if (dotIndex != -1) { + group = it.key().left(dotIndex); + name = it.key().mid(dotIndex + 1); + } + else { + group = "默认分组"; + name = it.key(); + } + emit fSignalHub::getInstance()->editParam(group, name, it.value()); + //QStandardItem* keyItem = m_tableModel->item(row, 0); + //if (!keyItem) { + // QMessageBox::warning(this, "错误", QString("第 %1 行数据不完整").arg(row + 1)); + // return; + //} + + //QString fullKey = keyItem->data(Qt::UserRole).toString();//获取完整键名 + //if (fullKey.isEmpty()) { + // QMessageBox::warning(this, "错误", QString("第 %1 行 key 为空").arg(row + 1)); + // return; + //} + + //// 获取原始类型 + //if (m_originalTypes.find(fullKey) == m_originalTypes.end()) { + // QMessageBox::warning(this, "错误", QString("第 %1 行找不到原始类型信息").arg(row + 1)); + // return; + //} + + //auto expectedType = m_originalTypes[fullKey]; + + //// 从编辑器获取值 + //QVariant convertedValue; + //QString errorMsg; + //if (!getValueFromEditor(fullKey, expectedType, convertedValue, errorMsg)) { + // QMessageBox::critical(this, "类型验证失败", QString("第 %1 行值验证失败:\n%2").arg(row + 1).arg(errorMsg)); + // return; + //} + + // 发送参数编辑信号 + //emit fSignalHub::getInstance()->editParam(group, name, convertedValue); + } + this->close(); + delete this; + } + + void onSidebarItemClicked(QListWidgetItem* item) { + if (!item) return; + + QString groupName = item->text(); + displayGroupParams(groupName); + } + +private: + QTableView* m_tableView; + QStandardItemModel* m_tableModel; + nlohmann::json m_originalJson; + std::map m_originalTypes; + std::map m_editorWidgets; + + //左侧边栏相关成员 + QWidget* m_sidebarWidget; + QWidget* m_contentWidget; + QListWidget* m_sidebarList; + QFrame* m_dividerLine; + + // 参数数据 + QMap m_allParams; + QMap> m_groupedParamsNames;//分组 名字 + //QMap m_paramsEditItemsCache; + + + void createSidebar() { + m_sidebarWidget = new QWidget(this); + m_sidebarWidget->setObjectName("sidebar"); + m_sidebarWidget->setFixedWidth(180); + m_sidebarWidget->setStyleSheet(QString(R"( + QWidget#sidebar { + background-color: rgb(%1); + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; + } + )").arg(sColor_BlueWithBlack)); + + QVBoxLayout* sidebarLayout = new QVBoxLayout(m_sidebarWidget); + sidebarLayout->setContentsMargins(8, 8, 8, 8); + sidebarLayout->setSpacing(10); + + //左侧边栏标题 + QLabel* sidebarTitle = new QLabel("参数分组"); + sidebarTitle->setStyleSheet("color: white; font-weight: bold; font-size: 14px; padding: 5px;"); + sidebarTitle->setAlignment(Qt::AlignCenter); + + //侧边栏列表样式 + m_sidebarList = new QListWidget(); + m_sidebarList->setStyleSheet(R"( + QListWidget { + background-color: #3a3a3a; + border: 1px solid #555555; + border-radius: 3px; + color: white; + outline: none; + font-size: 12px; + } + QListWidget::item { + padding: 8px; + border-bottom: 1px solid #555555; + border-radius: 2px; + margin: 2px; + } + QListWidget::item:selected { + background-color: #0078d4; + color: white; + border: 1px solid #005a9e; + } + QListWidget::item:hover { + background-color: #555555; + } + )"); + connect(m_sidebarList, &QListWidget::itemClicked, this, ¶mTableEditor::onSidebarItemClicked); + + sidebarLayout->addWidget(sidebarTitle); + sidebarLayout->addWidget(m_sidebarList); + } + + void createContentArea() { + m_contentWidget = new QWidget(this); + m_contentWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + QVBoxLayout* contentLayout = new QVBoxLayout(m_contentWidget); + contentLayout->setContentsMargins(10, 10, 10, 10); + contentLayout->setSpacing(10); + + // 当前分组标签 + m_currentGroupLabel = new QLabel("所有参数"); + m_currentGroupLabel->setStyleSheet("color: white; font-weight: bold; font-size: 16px; padding: 5px;"); + contentLayout->addWidget(m_currentGroupLabel); + + m_tableView = new QTableView(); + m_tableModel = new QStandardItemModel(0, 2, this); m_tableView->setModel(m_tableModel); m_tableView->setCornerButtonEnabled(false); @@ -60,21 +301,20 @@ public: m_tableView->setItemDelegateForColumn(0, new QStyledItemDelegate(m_tableView)); m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); m_tableView->setSelectionMode(QAbstractItemView::SingleSelection); - m_tableView->setColumnWidth(0, 240); // 可根据实际调整 + m_tableView->setColumnWidth(0, 280); // 禁止第一列选中 - m_tableView->setColumnHidden(0, false); // 显示第一列 + m_tableView->setColumnHidden(0, false); m_tableView->setFocusPolicy(Qt::NoFocus); - //设置表头 - m_tableModel->setHorizontalHeaderLabels({ "选项", "值" }); + // 设置表头 + m_tableModel->setHorizontalHeaderLabels({ "参数名", "值" }); - //设置表格属性 + // 设置表格属性 m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); m_tableView->setAlternatingRowColors(true); m_tableView->horizontalHeader()->setStretchLastSection(true); - m_tableView->setColumnWidth(1, 200);// 选项列宽度 - + m_tableView->setColumnWidth(1, 250); fancyButtonText* okBtn = new fancyButtonText("保存", 70, 22, ""); fancyButtonText* cancelBtn = new fancyButtonText("取消", 70, 22, ""); @@ -87,10 +327,9 @@ public: btnLayout->addWidget(okBtn); btnLayout->addWidget(cancelBtn); - QVBoxLayout* mainLayout = new QVBoxLayout(this); - mainLayout->addWidget(m_tableView); - mainLayout->addLayout(btnLayout); - + contentLayout->addWidget(m_tableView, 1); // 表格占据大部分空间 + contentLayout->addLayout(btnLayout); + m_tableView->setStyleSheet(QString(R"( QTableView { background-color: rgb(%1); @@ -111,7 +350,7 @@ public: } QTableCornerButton::section { background: transparent; -border: none; + border: none; } )").arg(sColor_Blue)); @@ -135,7 +374,7 @@ border: none; "QHeaderView {" "background-color: rgb(%1);" "}" - ).arg(sColor_Blue));; + ).arg(sColor_Blue)); m_tableView->setCornerButtonEnabled(false); // 强制隐藏交叉方块区域 @@ -143,42 +382,72 @@ border: none; m_tableView->horizontalHeader()->height() - 1); m_tableView->verticalHeader()->setFixedWidth( m_tableView->verticalHeader()->width() - 1); - } - void setParams(std::vector> params) { - m_tableModel->setRowCount(0); - m_editorWidgets.clear(); - - if (params.size() == 0) return; + void displayGroupParams(const QString& groupName) { + //更新当前分组标签 + m_currentGroupLabel->setText(groupName); + // 清空表格 + m_tableModel->setRowCount(0); + for(auto& it:m_editorWidgets) { + auto expectedType = m_originalTypes[it.first]; + // 从编辑器获取值 + QVariant convertedValue; + QString errorMsg; + if (!getValueFromEditor(it.first, expectedType, convertedValue, errorMsg)) { + qCritical()<<(this, "本地类型验证失败", QString("%1值验证失败:\n%2").arg(it.first).arg(errorMsg)); + continue; + } + if(m_allParams.contains(it.first)) { + m_allParams[it.first] = convertedValue; + } + } + m_editorWidgets.clear(); + + if (!m_groupedParamsNames.contains(groupName)) { + return; + } + + const auto& params = m_groupedParamsNames[groupName]; int row = 0; + for (auto data : params) { m_tableModel->insertRow(row); - const QString& key = data.first; - const QVariant& value = data.second; + const QString& fullKey = data; + const QVariant& value = m_allParams[fullKey]; + QString displayName = fullKey; + //分组显示,去掉分组前缀 + if (groupName != "所有参数") { + int dotIndex = fullKey.indexOf('.'); + if (dotIndex != -1) { + displayName = fullKey.mid(dotIndex + 1); + } + } // 设置键名(不可编辑) - QStandardItem* keyItem = new QStandardItem(key); + QStandardItem* keyItem = new QStandardItem(displayName); keyItem->setEditable(false); keyItem->setBackground(QColor(60, 60, 60)); keyItem->setForeground(QColor(255, 255, 255)); + keyItem->setData(fullKey, Qt::UserRole);//存储完整键名 + keyItem->setToolTip(fullKey);//提示显示完整键名 m_tableModel->setItem(row, 0, keyItem); - // 确定类型(内部使用,不显示) - m_originalTypes[key] = value.type(); + //确定类型(内部使用,不显示) + m_originalTypes[fullKey] = value.type(); //为特定类型创建专用编辑器控件 QWidget* editorWidget = createEditorWidget(value, value.type()); if (editorWidget) { m_tableView->setIndexWidget(m_tableModel->index(row, 1), editorWidget); - m_editorWidgets[key] = editorWidget; + m_editorWidgets[fullKey] = editorWidget; } else { // 默认为文本显示 - QString valueText= value.toString(); + QString valueText = value.toString(); QStandardItem* valueItem = new QStandardItem(valueText); valueItem->setToolTip(generateTypeHint(value.type())); m_tableModel->setItem(row, 1, valueItem); @@ -187,64 +456,10 @@ border: none; } } -signals: - -private slots: - void onAccept() { - std::vector> result; - - for (int row = 0; row < m_tableModel->rowCount(); ++row) { - QStandardItem* keyItem = m_tableModel->item(row, 0); - if (!keyItem) { - QMessageBox::warning(this, "错误", QString("第 %1 行数据不完整").arg(row + 1)); - return; - } - - QString key = keyItem->text().trimmed(); - if (key.isEmpty()) { - QMessageBox::warning(this, "错误", QString("第 %1 行 key 为空").arg(row + 1)); - return; - } - - //获取原始类型 - if (m_originalTypes.find(key) == m_originalTypes.end()) { - QMessageBox::warning(this, "错误", QString("第 %1 行找不到原始类型信息").arg(row + 1)); - return; - } - - auto expectedType = m_originalTypes[key]; - - //从编辑器获取值 - QVariant convertedValue; - QString errorMsg; - if (!getValueFromEditor(key, expectedType, convertedValue, errorMsg)) { - QMessageBox::critical(this, "类型验证失败",QString("第 %1 行值验证失败:\n%2").arg(row + 1).arg(errorMsg)); - return; - } - //esult[keyStd] = convertedValue; - //result.push_back({ key, convertedValue }); - emit qtFuncBridge::getInstance()->editParam(key, convertedValue); - } - emit qtFuncBridge::getInstance()->saveMissionJson(); - this->close(); - delete this; - //qDebug() << "Result JSON: " << QString::fromStdString(result.dump(4)); - - //emit jsonAccepted(result); - //accept(); - } - -private: - QTableView* m_tableView; - QStandardItemModel* m_tableModel; - nlohmann::json m_originalJson; // 保存原始JSON以便类型检查 - std::map m_originalTypes;// 保存每个键的原始类型 - std::map m_editorWidgets;// 保存每个键对应的编辑器控件 - // 根据类型创建不同的编辑器控件 QWidget* createEditorWidget(const QVariant& value, QVariant::Type type) { switch (type) { - case QVariant::Type::Bool:{ + case QVariant::Type::Bool: { CircularSwitch* switchBtn = new CircularSwitch(); switchBtn->setChecked(value.toBool()); switchBtn->setToolTip(generateTypeHint(type)); @@ -262,6 +477,7 @@ private: QDoubleSpinBox* spinBox = new QDoubleSpinBox(); spinBox->setMaximumWidth(160); spinBox->setDecimals(3);//显示小位数 + spinBox->setRange(-1e6, 1e6); spinBox->setValue(value.toDouble()); spinBox->setToolTip(generateTypeHint(type)); return spinBox; @@ -272,7 +488,7 @@ private: lineEdit->setToolTip(generateTypeHint(type)); return lineEdit; } - // 其他类型仍使用文本显示 + // 其他类型仍使用文本显示 default: return nullptr; } @@ -317,7 +533,7 @@ private: updateModelData(key, QString::number(value)); return true; } - errorMsg = "数字控件INT类型错误"; + errorMsg = "数字控件DOUBLE类型错误"; return false; } case QVariant::Type::String: { @@ -331,15 +547,14 @@ private: errorMsg = "字符串控件类型错误"; return false; } - //default: - // // 其他类型使用默认文本处理 - // return validateAndConvertValue(getTextFromCell(key), expectedType, result, errorMsg); } } - //else { - // // 没有专用编辑器控件,使用默认文本处理 - // return validateAndConvertValue(getTextFromCell(key), expectedType, result, errorMsg); - //} + else { + //没有专用编辑器控件,从单元格获取文本值 + QString valueText = getTextFromCell(key); + result = valueText; + return true; + } } catch (const std::exception& e) { errorMsg = QString("获取值错误: %1").arg(e.what()); @@ -352,7 +567,7 @@ private: void updateModelData(const QString& key, const QString& value) { for (int row = 0; row < m_tableModel->rowCount(); ++row) { QStandardItem* keyItem = m_tableModel->item(row, 0); - if (keyItem && keyItem->text() == key) { + if (keyItem && keyItem->data(Qt::UserRole).toString() == key) { QStandardItem* valueItem = m_tableModel->item(row, 1); if (valueItem) { valueItem->setText(value); @@ -363,11 +578,11 @@ private: } // 从单元格获取文本值(用于没有专用编辑器的类型) - QString getTextFromCell(const std::string& key) { + QString getTextFromCell(const QString& key) { //查找键对应的行 for (int row = 0; row < m_tableModel->rowCount(); ++row) { QStandardItem* keyItem = m_tableModel->item(row, 0); - if (keyItem && keyItem->text().toStdString() == key) { + if (keyItem && keyItem->data(Qt::UserRole).toString() == key) { QStandardItem* valueItem = m_tableModel->item(row, 1); if (valueItem) { return valueItem->text(); @@ -377,142 +592,23 @@ private: } return ""; } - - // 获取类型的显示名称 - //QString getTypeDisplayName(JsonValueType type) { - // switch (type) { - // case JsonValueType::String: return "字符串"; - // case JsonValueType::Number: return "数字"; - // case JsonValueType::Boolean: return "布尔"; - // case JsonValueType::Array: return "数组"; - // case JsonValueType::Object: return "对象"; - // case JsonValueType::Null: return "空值"; - // default: return "未知"; - // } - //} - - // 格式化值用于显示 - /*QString formatValueForDisplay(const QVariant& value, QVariant::Type type) { - switch (type) { - case QVariant::Type::String: - return QString::fromStdString(value.get()); - case QVariant::Type::Int: - if (value.is_number_integer()) { - return QString::number(value.get()); - } else { - return QString::number(value.get()); - } - case JsonValueType::Boolean: - return value.get() ? "true" : "false"; - case JsonValueType::Array: - case JsonValueType::Object: - return QString::fromStdString(value.dump()); - case JsonValueType::Null: - return "null"; - default: - return QString::fromStdString(value.dump()); - } - }*/ - + // 生成类型提示 QString generateTypeHint(QVariant::Type type) { switch (type) { - case QVariant::Type::String: - return "输入字符串值(不需要引号)"; - case QVariant::Type::Int: - return "输入数字值(整数)"; - case QVariant::Type::Double: - return "输入数字值(小数)"; - case QVariant::Type::Bool: - return "输入布尔值(true 或 false)"; - default: - return "请输入有效的JSON值"; + case QVariant::Type::String: + return "输入字符串值(不需要引号)"; + case QVariant::Type::Int: + return "输入数字值(整数)"; + case QVariant::Type::Double: + return "输入数字值(小数)"; + case QVariant::Type::Bool: + return "输入布尔值(true 或 false)"; + default: + return "请输入有效的JSON值"; } } - - // 验证并转换值 - //bool validateAndConvertValue(const QString& input, JsonValueType expectedType, - // nlohmann::json& result, QString& errorMsg) { - // QString trimmedInput = input.trimmed(); - // - // // 长度检查 - // if (trimmedInput.size() > 10240) { - // errorMsg = "输入值过大(超过10240字符)"; - // return false; - // } - // - // try { - // switch (expectedType) { - // case JsonValueType::String: - // result = trimmedInput.toStdString(); - // return true; - // - // case JsonValueType::Number: { - // bool ok; - // // 先尝试整数 - // int64_t intVal = trimmedInput.toLongLong(&ok); - // if (ok) { - // result = intVal; - // return true; - // } - // // 再尝试浮点数 - // double doubleVal = trimmedInput.toDouble(&ok); - // if (ok && !std::isnan(doubleVal) && !std::isinf(doubleVal)) { - // result = doubleVal; - // return true; - // } - // errorMsg = "无效的数字格式"; - // return false; - // } - // - // case JsonValueType::Boolean: - // if (trimmedInput.toLower() == "true") { - // result = true; - // return true; - // } else if (trimmedInput.toLower() == "false") { - // result = false; - // return true; - // } - // errorMsg = "布尔值只能是 true 或 false"; - // return false; - // - // case JsonValueType::Null: - // if (trimmedInput.toLower() == "null") { - // result = nullptr; - // return true; - // } - // errorMsg = "空值只能是 null"; - // return false; - // - // case JsonValueType::Array: - // case JsonValueType::Object: { - // // 对于数组和对象,尝试解析JSON - // result = nlohmann::json::parse(trimmedInput.toStdString()); - // - // // 验证类型是否匹配 - // if (expectedType == JsonValueType::Array && !result.is_array()) { - // errorMsg = "期望数组格式,如:[1,2,3]"; - // return false; - // } - // if (expectedType == JsonValueType::Object && !result.is_object()) { - // errorMsg = "期望对象格式,如:{\"key\":\"value\"}"; - // return false; - // } - // return true; - // } - // - // default: - // errorMsg = "未知的数据类型"; - // return false; - // } - // } - // catch (const nlohmann::json::parse_error& e) { - // errorMsg = QString("JSON解析错误: %1").arg(e.what()); - // return false; - // } - // catch (const std::exception& e) { - // errorMsg = QString("转换错误: %1").arg(e.what()); - // return false; - // } - //} -}; + +private: + QLabel* m_currentGroupLabel; //当前分组标签 +}; \ No newline at end of file diff --git a/src/launcher/GUI/pluginManager/pluginManager.h b/src/launcher/GUI/pluginManager/pluginManager.h deleted file mode 100644 index 4799c82..0000000 --- a/src/launcher/GUI/pluginManager/pluginManager.h +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -static std::string config_path = "./config/pluginConfig.json"; -struct PluginData -{ - std::string plugin_name = "ERROR"; - std::string plugin_path; - bool disabled; - bool auto_run; - nlohmann::json plugin_setting; - - IPlugin* plugin_ptr; - HMODULE HMODULE_; -}; -class EventManager { -public: - void subscribe(Event::EventType type, IPlugin* listener) { - listeners[type].push_back(listener); - } - - void unsubscribe(Event::EventType type, IPlugin* listener) { - auto& lst = listeners[type]; - lst.erase(std::remove(lst.begin(), lst.end(), listener), lst.end()); - } - - void publish(const Event& event) { - for (auto listener : listeners[event.type]) { - listener->onEvent(event); - } - } - -private: - std::unordered_map> listeners; -}; -class PluginManager { -public: - PluginManager() - { - init(); - } - void init() { - LoadJson(config_path); - for (auto& plugin_data : plugin_list) - { - LoadPlugin(plugin_data.second.plugin_path); - } - }; - PluginData LoadPlugin(std::string& plugin_path); - void LoadPlugin(PluginData& plugin_data); - void RemovePlugin(PluginData& plugin_data); - - void LoadJson(std::string path = config_path); - void SaveJson(std::string path = config_path); - void LoadAllPlugin(); - - std::vector getList() { - std::vector result; - for (auto& plugin : plugin_list){ - result.push_back(plugin.second); - } - return result; - } -private: - QMutex mutex; - QMutex jsonMutex; - std::unordered_mapplugin_list;//key路径 -}; -#pragma once \ No newline at end of file diff --git a/src/launcher/GUI/pluginManager/pluginManger.cpp b/src/launcher/GUI/pluginManager/pluginManger.cpp deleted file mode 100644 index bc6793a..0000000 --- a/src/launcher/GUI/pluginManager/pluginManger.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include -#include -#include -#include -#include -#include - -typedef IPlugin* (*CreatePluginFunc)(); -typedef void (*DestroyPluginFunc)(IPlugin*); -PluginData PluginManager::LoadPlugin(std::string& plugin_path) -{ - - PluginData plugin_data; - auto it = plugin_list.find(plugin_path); - if (it != plugin_list.end()) - { - plugin_data.plugin_name = "exist"; - return plugin_data; - } - - CreatePluginFunc createPluginFunc; - DestroyPluginFunc destroyPluginFunc; - HMODULE dllHandle = LoadLibrary(plugin_path.c_str()); - if (dllHandle == nullptr) { - std::cerr << "Failed to load DLL: " << plugin_path << std::endl; - plugin_data.plugin_name = "dll handle error"; - return plugin_data; - } - - // 获取工厂函数 - createPluginFunc = (CreatePluginFunc)GetProcAddress(dllHandle, "createPlugin"); - destroyPluginFunc = (DestroyPluginFunc)GetProcAddress(dllHandle, "destroyPlugin"); - - if (!createPluginFunc || !destroyPluginFunc) { - std::cerr << "Failed to get functions from DLL" << std::endl; - FreeLibrary(dllHandle); - dllHandle = nullptr; - plugin_data.plugin_name = "none func found"; - return plugin_data; - } - auto plugin_ptr = createPluginFunc(); - - //插入插件数据 - plugin_data.plugin_name = plugin_ptr->name; - plugin_data.plugin_path = plugin_path; - plugin_data.disabled = true; - plugin_data.auto_run = false; - plugin_data.plugin_ptr = plugin_ptr; - plugin_data.HMODULE_ = dllHandle; - plugin_list.insert(std::make_pair(plugin_data.plugin_path, plugin_data)); - - SaveJson(); - return plugin_data; - // 创建插件实例 - //plugin_data.plugin_ptr = createPluginFunc(); - //plugin_data.HMODULE_ = dllHandle; - //pluginList.emplace_back(plugin, dllHandle); -} -void PluginManager::LoadPlugin(PluginData& plugin_data) -{ - - CreatePluginFunc createPluginFunc; - DestroyPluginFunc destroyPluginFunc; - HMODULE dllHandle = LoadLibrary(plugin_data.plugin_path.c_str()); - if (dllHandle == nullptr) { - std::cerr << "Failed to load DLL: " << plugin_data.plugin_path << std::endl; - return; - } - - // 获取工厂函数 - createPluginFunc = (CreatePluginFunc)GetProcAddress(dllHandle, "createPlugin"); - destroyPluginFunc = (DestroyPluginFunc)GetProcAddress(dllHandle, "destroyPlugin"); - - if (!createPluginFunc || !destroyPluginFunc) { - std::cerr << "Failed to get functions from DLL" << std::endl; - FreeLibrary(dllHandle); - dllHandle = nullptr; - return; - } - - // 创建插件实例 - plugin_data.plugin_ptr = createPluginFunc(); - plugin_data.HMODULE_ = dllHandle; - //pluginList.emplace_back(plugin, dllHandle); -} -void PluginManager::RemovePlugin(PluginData& plugin_data) { - if (plugin_list.size() == 0) - return; - QMutexLocker locker(&mutex); - IPlugin* plugin = plugin_data.plugin_ptr; - HMODULE hDll = plugin_data.HMODULE_; - - auto destroyPlugin = (void (*)(IPlugin*))GetProcAddress(hDll, "destroyPlugin"); - if (destroyPlugin) { - destroyPlugin(plugin); - } - - FreeLibrary(hDll); - auto it = plugin_list.find(plugin_data.plugin_path); - if (it != plugin_list.end()) - plugin_list.erase(it); - SaveJson(); -} - -void PluginManager::LoadJson(std::string path) -{ - QMutexLocker locker(&jsonMutex); - try{ - nlohmann::json jsonObj = readJsonFromPath(path); - for (auto it = jsonObj.begin(); it != jsonObj.end(); ++it){ - PluginData data; - data.plugin_name = it.key(); - auto value = it.value(); - data.plugin_path = value["path"]; - data.disabled = value["disabled"]; - data.auto_run = value["autoRun"]; - data.plugin_setting = value["pluginSetting"]; - plugin_list.insert(std::make_pair(data.plugin_path, data)); - } - std::vectorvec; - /* for (auto& json : jsonObj) - vec.push_back(json.) ;*/ - } - catch (...){ - - } -} -void PluginManager::SaveJson(std::string path) { - QMutexLocker locker(&jsonMutex); - nlohmann::json jsonObj; - for (auto& it : plugin_list) { - nlohmann::json obj; - obj["path"] = it.second.plugin_path; - obj["disabled"] = it.second.disabled; - obj["autoRun"] = it.second.auto_run; - obj["pluginSetting"] = it.second.plugin_setting; - jsonObj[it.second.plugin_name] = obj; - } - saveJsonFromPath(path, jsonObj); -} -void PluginManager::LoadAllPlugin() { - for (auto& data : plugin_list) - { - LoadPlugin(data.second); - } -} \ No newline at end of file diff --git a/src/launcher/GUI/uiModule/components/fancyProcessBar.h b/src/launcher/GUI/uiModule/components/fancyProcessBar.h index 34dfada..05104fe 100644 --- a/src/launcher/GUI/uiModule/components/fancyProcessBar.h +++ b/src/launcher/GUI/uiModule/components/fancyProcessBar.h @@ -48,8 +48,8 @@ public: } void addData(int value) { - maxValue = getMax(value, maxValue); - minValue = getMin(value, minValue); + maxValue = std::max(value, maxValue); + minValue = std::min(value, minValue); currentValue = value; if((maxValue - minValue) ==0) setProgress(1); diff --git a/src/launcher/GUI/uiModule/uiChart_WaveForm.h b/src/launcher/GUI/uiModule/uiChart_WaveForm.h index b515dab..9c0634b 100644 --- a/src/launcher/GUI/uiModule/uiChart_WaveForm.h +++ b/src/launcher/GUI/uiModule/uiChart_WaveForm.h @@ -19,12 +19,12 @@ public: m_title(new QLabel(this)), m_plot(new QCustomPlot(this)) { - QString title = QString::fromStdString(json.value("key", "默认标题")); + QString title = QString::fromStdString(json.value("key", "Default Title")); m_limitHigh = json.value("limitHigh", 100.0); m_limitLow = json.value("limitLow", 0.0); m_maxPoints = json.value("maxPoints", 50); - QFont font("微软雅黑", 24, QFont::Bold); + QFont font("Microsoft YaHei", 24, QFont::Bold); QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); @@ -81,7 +81,7 @@ public: // 文本提示 m_tracerText = new QCPItemText(m_plot); m_tracerText->setColor(Qt::white); // 文字颜色 - m_tracerText->setFont(QFont("微软雅黑", 10, QFont::Bold)); + m_tracerText->setFont(QFont("Microsoft YaHei", 10, QFont::Bold)); m_tracerText->position->setType(QCPItemPosition::ptPlotCoords); m_tracerText->setBrush(QBrush(QColor(0, 0, 0, 150))); // 半透明背景 m_tracerText->setPadding(QMargins(5, 2, 5, 2)); // 留点内边距 @@ -89,7 +89,7 @@ public: // 绑定鼠标移动事件 connect(m_plot, &QCustomPlot::mouseMove, this, &WaveFormWidget::onMouseMoveInPlot); - if (title.contains("对齐度")) { + if (title.contains("对齐度")) { auto fixedTicker = QSharedPointer(new QCPAxisTickerFixed); fixedTicker->setTickStep(0.1); fixedTicker->setScaleStrategy(QCPAxisTickerFixed::ssNone); // 不自动放大 @@ -160,7 +160,7 @@ public: protected: void contextMenuEvent(QContextMenuEvent* event) override { QMenu menu(this); - menu.addAction("编辑参数", this, &WaveFormWidget::editJsonParameters); + menu.addAction(TR("Edit Parameters"), this, &WaveFormWidget::editJsonParameters); menu.exec(event->globalPos()); } @@ -204,7 +204,7 @@ private slots: m_tracer->updatePosition(); m_tracer->setVisible(true); - m_tracerText->setText(QString("%1\n值:%2") + m_tracerText->setText(QString("%1\nValue: %2") .arg(static_cast(std::round(x))) .arg(y, 0, 'f', 2)); m_tracerText->setVisible(true); diff --git a/src/launcher/GUI/uiModule/uiModule_OnceDataDisplay.h b/src/launcher/GUI/uiModule/uiModule_OnceDataDisplay.h deleted file mode 100644 index 40f96c4..0000000 --- a/src/launcher/GUI/uiModule/uiModule_OnceDataDisplay.h +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include -class OnceDataDisplay :public QWidget -{ -public: - QVBoxLayout* layout; - QLabel* title; - QLabel* widthValueLabel; - QLabel* heightValueLabel; - QWidget* dataPanel; - OnceDataDisplay() - { - this->setObjectName("OnceDataDisplay"); - this->setStyleSheet("QWidget#OnceDataDisplay {" - " border: 2px solid white;" - " border-radius: 10px;" - "}"); - layout = new QVBoxLayout(); - layout->setAlignment(Qt::AlignTop); - this->setLayout(layout); - - title = new QLabel(u8"本次运行数据"); - QFont font("微软雅黑", 16, QFont::Bold); - QPalette palette; - palette.setColor(QPalette::WindowText, Qt::white); - - title->setFont(font); - title->setPalette(palette); - title->setAlignment(Qt::AlignCenter); - title->setObjectName("titleLabel"); - title->setStyleSheet("QLabel#titleLabel {" - " border: 4px solid white;" - " border-radius: 12px;" - "}"); - - dataPanel = new QWidget; - dataPanel->setObjectName("dataPanel"); - dataPanel->setStyleSheet("QWidget#dataPanel {" - " border: 2px solid white;" - " border-radius: 3px;" - "}"); - QVBoxLayout* dataPanelVboxLayout = new QVBoxLayout(); - dataPanel->setLayout(dataPanelVboxLayout); - QFont font2("微软雅黑", 8, QFont::Bold); - - QHBoxLayout* widthVLayout = new QHBoxLayout(); - QLabel* widthTextLabel = new QLabel(u8"长度"); - widthValueLabel = new QLabel(u8"待读取"); - widthVLayout->addWidget(widthTextLabel); - widthVLayout->addWidget(widthValueLabel); - widthTextLabel->setPalette(palette); - widthValueLabel->setPalette(palette); - - QHBoxLayout* heightVLayout = new QHBoxLayout(); - QLabel* heightTextLabel = new QLabel(u8"宽度:"); - heightValueLabel = new QLabel(u8"待读取"); - heightVLayout->addWidget(heightTextLabel); - heightVLayout->addWidget(heightValueLabel); - heightTextLabel->setPalette(palette); - heightValueLabel->setPalette(palette); - - dataPanelVboxLayout->addLayout(widthVLayout); - dataPanelVboxLayout->addLayout(heightVLayout); - - layout->addWidget(title); - layout->addWidget(dataPanel); - } -}; - -#pragma once \ No newline at end of file diff --git a/src/launcher/GUI/uiModule/uiModule_calibration.h b/src/launcher/GUI/uiModule/uiModule_calibration.h index 1d68270..f9d9ae3 100644 --- a/src/launcher/GUI/uiModule/uiModule_calibration.h +++ b/src/launcher/GUI/uiModule/uiModule_calibration.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include //标定数据结构 @@ -305,7 +305,7 @@ public: calibration() { this->setWindowTitle("九点标定"); this->setFixedSize(1980, 1000); - m_qtFuncBridge = qtFuncBridge::getInstance(); + m_fSignalHub = fSignalHub::getInstance(); #pragma region 主界面 @@ -749,7 +749,7 @@ private: QPixmap CameraCapture() { // 模拟相机拍照 std::vector imgs; - emit m_qtFuncBridge->triggerAndCaptureImage("Camera1", &imgs); + emit m_fSignalHub->triggerAndCaptureImage("Camera1", &imgs); int cnt = 0; while (imgs.size() == 0 && cnt < 30) { QThread::msleep(100); @@ -847,7 +847,7 @@ protected: } private: - qtFuncBridge* m_qtFuncBridge; + fSignalHub* m_fSignalHub; QVector m_points; QPushButton* m_captureBtn; QPushButton* m_prevBtn; diff --git a/src/launcher/GUI/uiModule/uiModule_cameraRealTimeCapture.h b/src/launcher/GUI/uiModule/uiModule_cameraRealTimeCapture.h index 7778dc6..5b7a98b 100644 --- a/src/launcher/GUI/uiModule/uiModule_cameraRealTimeCapture.h +++ b/src/launcher/GUI/uiModule/uiModule_cameraRealTimeCapture.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include @@ -28,7 +28,7 @@ public: while (m_runFlag == true) { QMutexLocker locker(mutex); std::vector mats; - emit qtFuncBridge::getInstance()->triggerAndCaptureImage(cameraName, &mats); + emit fSignalHub::getInstance()->triggerAndCaptureImage(cameraName, &mats); for (auto mat : mats) { auto pixmap = cvMatToQPixMap(mat); showImageLabel->setPixmap(pixmap.scaled(showImageLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); @@ -57,14 +57,14 @@ public: QComboBox* cameraSelectBox = new QComboBox(); vLayout2->addWidget(cameraSelectBox, 0, Qt::AlignTop); - QPushButton* refreshCameraBtn = new QPushButton("刷新相机"); + QPushButton* refreshCameraBtn = new QPushButton(TR("Refresh Cameras")); vLayout2->addWidget(refreshCameraBtn, 0, Qt::AlignTop); - QPushButton* startGrabbing = new QPushButton("开始取流"); + QPushButton* startGrabbing = new QPushButton(TR("Start Grabbing")); startGrabbing->setDisabled(true); vLayout2->addWidget(startGrabbing, 0, Qt::AlignTop); - QPushButton* saveImageBtn = new QPushButton("保存图像"); + QPushButton* saveImageBtn = new QPushButton(TR("Save Image")); saveImageBtn->setDisabled(true); vLayout2->addWidget(saveImageBtn, 0, Qt::AlignTop); @@ -73,7 +73,7 @@ public: startGrabbing->setEnabled(true); saveImageBtn->setEnabled(true); std::vector < std::string> cameraNamesVec; - emit qtFuncBridge::getInstance()->getCameraNames(&cameraNamesVec); + emit fSignalHub::getInstance()->getCameraNames(&cameraNamesVec); for (auto cameraName : cameraNamesVec) { cameraSelectBox->addItem(QString::fromStdString(cameraName)); } @@ -82,20 +82,20 @@ public: QLabel* showNowTimeImageLabel = new QLabel; vLayout2->addWidget(showNowTimeImageLabel, 1, Qt::AlignTop); - showNowTimeImageLabel->setText("实时取流"); + showNowTimeImageLabel->setText(TR("Real-time Grabbing")); showNowTimeImageLabel->setStyleSheet(" border - radius: 10px; border: 1px solid rgb(70, 75, 80);"); showNowTimeImageLabel->setFixedSize(800, 800); _GrabbingThread = new GrabbingThread(showNowTimeImageLabel,&mutex); connect(startGrabbing, &QPushButton::clicked, [=]() { - if (_GrabbingThread->isRunning() == false) { + if (_GrabbingThread->isRunning() == false) { showNowTimeImageLabel->clear(); _GrabbingThread->setCameraName(cameraSelectBox->currentText().toStdString()); _GrabbingThread->start(); - startGrabbing->setText("停止取流"); + startGrabbing->setText(TR("Stop Grabbing")); } else { _GrabbingThread->stop(); - startGrabbing->setText("开始取流"); + startGrabbing->setText(TR("Start Grabbing")); } }); connect(this, &cameraRealTimeCapture::close, [=]() { @@ -107,20 +107,33 @@ public: connect(saveImageBtn, &QPushButton::clicked, [=]() { QMutexLocker locker(&mutex); const QPixmap* pix = showNowTimeImageLabel->pixmap(); - if (!pix || pix->isNull()) { - QMessageBox::warning(this, "提示", "没有可保存的图像"); + if (!pix || pix->isNull()) { + QMessageBox::warning(this, TR("Notice"), TR("No image available to save")); return; } QString ts = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmsszzz"); QString suggested = QString("snapshot_%1.png").arg(ts); - QString filePath = QFileDialog::getSaveFileName(this, "保存图像", QDir::homePath() + "/" + suggested, + QString filePath = QFileDialog::getSaveFileName(this, TR("Save Image"), QDir::homePath() + "/" + suggested, "PNG (*.png);;JPEG (*.jpg *.jpeg);;BMP (*.bmp)"); if (filePath.isEmpty()) return; if (!pix->save(filePath)) { - QMessageBox::warning(this, "保存失败", "无法保存图像到所选位置"); + QMessageBox::warning(this, TR("Save Failed"), TR("Unable to save image to selected location")); } }); #pragma endregion } +protected: + void closeEvent(QCloseEvent* event) override { + // 安全停止取流线程 + if (_GrabbingThread && _GrabbingThread->isRunning()) { + _GrabbingThread->stop(); + _GrabbingThread->wait(500); // 给线程一点时间退出 + } + // 复位按钮文本(如果按钮仍存在) + if (auto btn = this->findChild("btn_startGrabbing")) { + btn->setText(TR("Start Grabbing")); + } + QWidget::closeEvent(event); + } }; \ No newline at end of file diff --git a/src/launcher/GUI/uiModule/uiModule_cpkCalculate.h b/src/launcher/GUI/uiModule/uiModule_cpkCalculate.h index d241987..bec3115 100644 --- a/src/launcher/GUI/uiModule/uiModule_cpkCalculate.h +++ b/src/launcher/GUI/uiModule/uiModule_cpkCalculate.h @@ -20,7 +20,7 @@ public: layout->setAlignment(Qt::AlignTop); title = new QLabel(Name); - QFont font("微软雅黑", 14, QFont::Bold); + QFont font("Microsoft YaHei", 14, QFont::Bold); title->setFont(font); QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); @@ -33,8 +33,8 @@ public: calwidget = new QWidget(); QHBoxLayout* hLayout1 = new QHBoxLayout(calwidget); - QFont font2("微软雅黑", 26, QFont::Bold); - QFont font3("微软雅黑", 7, QFont::Bold); + QFont font2("Microsoft YaHei", 26, QFont::Bold); + QFont font3("Microsoft YaHei", 7, QFont::Bold); //MIN QLabel* minLabel = new QLabel("MIN("); @@ -47,11 +47,11 @@ public: QVBoxLayout* vLayout1 = new QVBoxLayout(); QHBoxLayout* topLayout1 = new QHBoxLayout(); - QLabel* uslLabel = new QLabel(QString::number(USL) + "(规格上限)"); + QLabel* uslLabel = new QLabel(QString::number(USL) + TR(" (Spec Upper Limit)")); uslLabel->setFont(font3); uslLabel->setPalette(palette); - QLabel* avgLabel = new QLabel("-" + QString::number(USL) + u8"(均值)"); + QLabel* avgLabel = new QLabel("-" + QString::number(USL) + TR(" (Mean)")); avgLabel->setFont(font3); avgLabel->setPalette(palette); @@ -62,7 +62,7 @@ public: line->setPalette(palette); line->setFixedHeight(5); - QLabel* deviationLabel = new QLabel(u8"(标准差)"); + QLabel* deviationLabel = new QLabel(TR("(Std Dev)")); deviationLabel->setFont(font3); deviationLabel->setPalette(palette); deviationLabel->setAlignment(Qt::AlignCenter); @@ -87,11 +87,11 @@ public: QVBoxLayout* vLayout1 = new QVBoxLayout(); QHBoxLayout* topLayout1 = new QHBoxLayout(); - QLabel* uslLabel = new QLabel(QString::number(USL) + "(均值)"); + QLabel* uslLabel = new QLabel(QString::number(USL) + TR(" (Mean)")); uslLabel->setFont(font3); uslLabel->setPalette(palette); - QLabel* avgLabel = new QLabel("-" + QString::number(USL) + u8"(规格下限)"); + QLabel* avgLabel = new QLabel("-" + QString::number(USL) + TR(" (Spec Lower Limit)")); avgLabel->setFont(font3); avgLabel->setPalette(palette); @@ -142,8 +142,8 @@ public: "}"); layout = new QVBoxLayout(this); - title = new QLabel("CPK计算"); - QFont font("微软雅黑", 16, QFont::Bold); + title = new QLabel(TR("CPK Calculation")); + QFont font("Microsoft YaHei", 16, QFont::Bold); QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); @@ -158,10 +158,10 @@ public: title->setFixedHeight(40); layout->addWidget(title); - window1 = new perCpkWidget("cpk长度"); + window1 = new perCpkWidget(TR("CPK Length")); layout->addWidget(window1); - window2 = new perCpkWidget("cpk宽度"); + window2 = new perCpkWidget(TR("CPK Width")); layout->addWidget(window2); } ~cpkCalculatePanel() diff --git a/src/launcher/GUI/uiModule/uiModule_dumpToExcel.h b/src/launcher/GUI/uiModule/uiModule_dumpToExcel.h index 3e9a66c..6945d16 100644 --- a/src/launcher/GUI/uiModule/uiModule_dumpToExcel.h +++ b/src/launcher/GUI/uiModule/uiModule_dumpToExcel.h @@ -27,7 +27,7 @@ public: { int time1 = startTimeEdit->time().hour() * 60 + startTimeEdit->time().minute(); int time2 = endTimeEdit->time().hour() * 60 + startTimeEdit->time().minute(); - return { getMax(time1,time2),getMax(time1,time2) }; + return { std::max(time1,time2),std::max(time1,time2) }; } QTime getStartTime() const { @@ -43,11 +43,11 @@ private: void setupUi() { QVBoxLayout* layout = new QVBoxLayout(this); - QLabel* startLabel = new QLabel("开始时间:", this); + QLabel* startLabel = new QLabel(TR("Start Time:"), this); startTimeEdit = new QDateTimeEdit(this); startTimeEdit->setDisplayFormat("HH:mm"); - QLabel* endLabel = new QLabel("结束时间:", this); + QLabel* endLabel = new QLabel(TR("End Time:"), this); endTimeEdit = new QDateTimeEdit(this); endTimeEdit->setDisplayFormat("HH:mm"); @@ -77,7 +77,7 @@ public: TimeRangeSelectorWidget* timeSelector; dumpToExcel() { - showMainWidgetBtn = new QPushButton(u8"导出数据为表格"); + showMainWidgetBtn = new QPushButton(TR("Export Data to Table")); showMainWidgetBtn->setStyleSheet("color: white;"); mainWidget = new QWidget; QHBoxLayout* layout = new QHBoxLayout; @@ -90,7 +90,7 @@ public: dateWIdget = new QWidget(); QVBoxLayout* layoutTemp = new QVBoxLayout(); dateWIdget->setLayout(layoutTemp); - QLabel* labelTemp = new QLabel(u8"请选择日期"); + QLabel* labelTemp = new QLabel(TR("Please select a date")); labelTemp->setAlignment(Qt::AlignCenter); layoutTemp->addWidget(labelTemp); layoutTemp->addWidget(calendarW); @@ -103,11 +103,11 @@ public: QVBoxLayout* layoutTemp = new QVBoxLayout(); controlPanel->setLayout(layoutTemp); - QLabel* title = new QLabel(u8"导出选项"); + QLabel* title = new QLabel(TR("Export Options")); title->setAlignment(Qt::AlignCenter); QLabel* space = new QLabel(); - QLabel* selectFolderLabel = new QLabel(u8"选择导出路径"); + QLabel* selectFolderLabel = new QLabel(TR("Select Export Path")); QHBoxLayout* layoutTemp2 = new QHBoxLayout(); openPathSelectBtn = new QPushButton("..."); @@ -119,8 +119,8 @@ public: filePathLineEdit = new QLineEdit("D://"); layoutTemp2->addWidget(filePathLineEdit); - dumpToCsvWithDateLimitBtn = new QPushButton(u8"导出指定时间段数据为csv表格"); - dumpToCsvBtn = new QPushButton(u8"导出数据为CSV表格"); + dumpToCsvWithDateLimitBtn = new QPushButton(TR("Export specified time-range data to CSV")); + dumpToCsvBtn = new QPushButton(TR("Export data to CSV")); layoutTemp->addWidget(title); //layoutTemp->addWidget(data); @@ -173,8 +173,8 @@ public: if (res.rowDatas.size() == 0) { tV->clearAllData(); - tV->Init({u8"搜索结果"}); - std::vector strVec({ "找不到数据" }); + tV->Init({TR("Search Results")}); + std::vector strVec({ TR("No data found") }); tV->addRowDataValue(strVec); return; } @@ -246,7 +246,7 @@ public: #pragma region if (res.rowDatas.size() == 0) { - QMessageBox::critical(nullptr, "Error", u8"检索不到数据!"); + QMessageBox::critical(nullptr, "Error", TR("No data found!")); return; } #pragma endregion 没有数据的对策 @@ -285,11 +285,11 @@ public: } stream << "\n"; } - qDebug() << "CSV文件保存成功"; + qDebug() << TR("CSV file saved successfully"); } else { - qDebug() << "无法创建CSV文件"; - QMessageBox::critical(nullptr, "Error", u8"没有权限或空间不足!"); + qDebug() << TR("Unable to create CSV file"); + QMessageBox::critical(nullptr, "Error", TR("No permission or insufficient space!")); } } else { @@ -315,12 +315,12 @@ public: } system(command.c_str()); #pragma endregion 打开文件夹 - QMessageBox::information(nullptr, "Success", u8"成功!"); - qDebug() << "CSV文件保存成功"; + QMessageBox::information(nullptr, "Success", TR("Export succeeded!")); + qDebug() << TR("CSV file saved successfully"); return; } else { - qDebug() << "无法打开CSV文件"; + qDebug() << TR("Unable to open CSV file"); #pragma region std::string command = "explorer /select, \"" + fileName.toStdString() + "\""; size_t pos = 0; @@ -329,7 +329,7 @@ public: } system(command.c_str()); #pragma endregion 打开文件夹 - QMessageBox::critical(nullptr, "Error", u8"文件已存在且无法被写入!"); + QMessageBox::critical(nullptr, "Error", TR("File already exists and cannot be written!")); } } } @@ -352,7 +352,7 @@ public: stream << QString::fromStdString(data.value) << ","; stream << "\n"; } - qDebug() << "CSV文件保存成功"; + qDebug() << TR("CSV file saved successfully"); } else { qDebug() << "无法创建CSV文件"; @@ -381,7 +381,7 @@ public: return; } else { - qDebug() << "无法打开CSV文件"; + qDebug() << TR("Unable to open CSV file"); #pragma region std::string command = "explorer /select, \"" + fileName.toStdString() + "\""; size_t pos = 0; @@ -390,7 +390,7 @@ public: } system(command.c_str()); #pragma endregion 打开文件夹 - QMessageBox::critical(nullptr, "Error", u8"文件已存在且无法被写入!"); + QMessageBox::critical(nullptr, "Error", TR("File already exists and cannot be written!")); } } #pragma endregion 不需要判断时间的循环 diff --git a/src/launcher/GUI/uiModule/uiModule_historyListWidget.h b/src/launcher/GUI/uiModule/uiModule_historyListWidget.h index f285bb9..18dbf2d 100644 --- a/src/launcher/GUI/uiModule/uiModule_historyListWidget.h +++ b/src/launcher/GUI/uiModule/uiModule_historyListWidget.h @@ -20,12 +20,12 @@ public: QLabel* fileNameLabel = new QLabel(this); QLabel* imgShow = new QLabel(); - historyItemWidget(QString title, QSize parentSize, historyPack historyPackIn) + historyItemWidget(QString title, QSize parentSize, historyPack historyPackIn) { - if (historyPackIn.img.isNull()) - return; - _historyPack = historyPackIn; - QFont font(u8"微软雅黑", 12, QFont::Bold); + if (historyPackIn.img.isNull()) + return; + _historyPack = historyPackIn; + QFont font("Microsoft YaHei", 12, QFont::Bold); this->setObjectName("historyItemWidget"); QVBoxLayout* vlayout = new QVBoxLayout(); resultLabel->setText(title); @@ -125,15 +125,15 @@ class historyShowListWidget : public QWidget { Q_OBJECT public: - QLabel* title = new QLabel(u8"历史记录"); + QLabel* title = new QLabel(TR("History")); QListWidget* showDataListWidget = new QListWidget(); QVBoxLayout* layout = new QVBoxLayout(this); historyShowListSubThread _historyShowListSubThread; - historyShowListWidget() + historyShowListWidget() { QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); - QFont font(u8"微软雅黑", 16, QFont::Bold); + QFont font("Microsoft YaHei", 16, QFont::Bold); QHBoxLayout* hLayout = new QHBoxLayout(); title->setPalette(palette); diff --git a/src/launcher/GUI/uiModule/uiModule_imageView.h b/src/launcher/GUI/uiModule/uiModule_imageView.h index 982786b..f2f6698 100644 --- a/src/launcher/GUI/uiModule/uiModule_imageView.h +++ b/src/launcher/GUI/uiModule/uiModule_imageView.h @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -211,7 +212,7 @@ protected: // deleteAllRect(); // if (width != 0 && height != 0) { - // double scaleRate = getMax(width == 0 ? 1.0 : rect().width() / width,height == 0 ? 1.0 : rect().height() / height); + // double scaleRate = std::max(width == 0 ? 1.0 : rect().width() / width,height == 0 ? 1.0 : rect().height() / height); // scale(scaleRate, scaleRate); // centerOn(startPos + QPointF(width / 2, height / 2)); // } @@ -412,12 +413,12 @@ public: )" ); zoombtn->setIcon(QPixmap(":icon/icon/fullscreen.png")); - zoombtn->setToolTip("放大窗口"); + zoombtn->setToolTip(TR("Zoom In")); hLayout->addWidget(zoombtn); connect(zoombtn, &QPushButton::clicked, this, &ImageWidget::toggleZoom); - label = new QLabel(u8"相机标签"); + label = new QLabel(TR("Camera Label")); label->setAlignment(Qt::AlignLeft); label->setFont(font); label->setPalette(palette); @@ -595,29 +596,20 @@ public slots: // 保存原始状态 originalSize = this->size(); - // 在网格布局中重新放置,占据更多空间 + // 在网格布局中重新放置,占据整个布局 parentGridLayout->removeWidget(this); - //计算父布局的总行数和总列数 - int maxRowSpan = parentGridLayout->rowCount();// 父布局总行数 - int maxColSpan = parentGridLayout->columnCount();// 父布局总列数 - //放大后的跨度 - int zoomColSize = maxColSpan - 1; - int zoomRowSize = maxRowSpan - 1; - if (originalRow >= zoomRowSize -1 || originalColumn >= zoomColSize -1) { - int x = qMax(0, originalRow - (zoomRowSize - 1)); - int y = qMax(0, originalColumn - (zoomColSize - 1)); - parentGridLayout->addWidget(this, x, y, zoomRowSize, zoomColSize); - } - else{ - parentGridLayout->addWidget(this, originalRow, originalColumn, zoomRowSize, zoomColSize); - } + int maxRowSpan = std::max(1, parentGridLayout->rowCount()); + int maxColSpan = std::max(1, parentGridLayout->columnCount()); + + // 直接从(0,0)开始,跨越整个网格,避免计算产生的0或负跨度 + parentGridLayout->addWidget(this, 0, 0, maxRowSpan, maxColSpan); this->raise(); // 更新按钮状态 isZoomed = true; zoombtn->setIcon(QIcon(":/icon/icon/fullscreen-exit.png")); - zoombtn->setToolTip("缩小窗口"); + zoombtn->setToolTip(TR("Zoom Out")); // 强制更新布局 parentGridLayout->update(); @@ -629,12 +621,16 @@ public slots: // 恢复原始布局位置 parentGridLayout->removeWidget(this); - parentGridLayout->addWidget(this, originalRow, originalColumn, originalRowSpan, originalColumnSpan); + parentGridLayout->addWidget(this, + std::max(0, originalRow), + std::max(0, originalColumn), + std::max(1, originalRowSpan), + std::max(1, originalColumnSpan)); //更新按钮状态 isZoomed = false; zoombtn->setIcon(QIcon(":/icon/icon/fullscreen.png")); - zoombtn->setToolTip("放大窗口"); + zoombtn->setToolTip(TR("Zoom In")); //强制更新布局 parentGridLayout->update(); diff --git a/src/launcher/GUI/uiModule/uiModule_kakong.h b/src/launcher/GUI/uiModule/uiModule_kakong.h deleted file mode 100644 index 2595a23..0000000 --- a/src/launcher/GUI/uiModule/uiModule_kakong.h +++ /dev/null @@ -1,620 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -static QString convertSecondsToDateTime(unsigned long long seconds) { - // 将秒数转换为时间点 - std::chrono::seconds sec(seconds); - std::chrono::time_point timePoint(sec); - - // 转换为时间戳 - auto time = std::chrono::system_clock::to_time_t(timePoint); - - // 使用 QDateTime 来格式化时间 - QDateTime dateTime = QDateTime::fromTime_t(static_cast(time)); - - // 将时间转换为指定格式的 QString - QString formattedDateTime = dateTime.toString("yyyy-MM-dd hh:mm:ss"); - - return formattedDateTime; -} -struct kaKongData -{ - QString Name; - int type = 0; - unsigned long long startTimeM = 0; - unsigned long long keepTime = 0; - bool banBie = false; - bool baiBan = false; - bool yeBan = false; - - bool louDong = false; - int louDongMin = 0; - int louDongMax = 0; - - bool louCeng = false; - int louCengMin = 0; - int louCengMax = 0; - - bool xianTi = false; - int xianTiMin = 0; - int xianTiMax = 0; - - bool jiTai = false; - int jiTaiHaoMin = 0; - int jiTaiHaoMax = 0; - - bool riQi = false; - int riQiMin = 0; - int riQiMax = 0; -}; -class CustomWidget : public QWidget { -public: - CustomWidget(QWidget* parent = nullptr) : QWidget(parent) {} - -protected: - void paintEvent(QPaintEvent* event) override { - Q_UNUSED(event); - - QPainter painter(this); - painter.setPen(Qt::black); // 设置画笔颜色为黑色 - painter.drawRect(rect().adjusted(0, 0, -1, -1)); // 绘制边框 - } -}; -class kakongSonWidget -{ - -public: - QWidget* widget; - QCheckBox* checkBox; - QCheckBox* baiBan; - QCheckBox* yeBanBan; - kakongSonWidget(QString title) - { - widget = new CustomWidget(); - QVBoxLayout* layout = new QVBoxLayout(); - widget->setLayout(layout); - { - QHBoxLayout* hLayout = new QHBoxLayout(); - QLabel* label = new QLabel(title); - checkBox = new QCheckBox(); - QLabel* label2 = new QLabel(u8"启用"); - hLayout->addWidget(label); - hLayout->addWidget(checkBox); - hLayout->addWidget(label2); - layout->addLayout(hLayout); - } - { - baiBan = new QCheckBox(); - QLabel* label = new QLabel(u8"白班"); - QHBoxLayout* hLayout = new QHBoxLayout(); - hLayout->addWidget(baiBan); - hLayout->addWidget(label); - layout->addLayout(hLayout); - } - { - yeBanBan = new QCheckBox(); - QLabel* label = new QLabel(u8"夜班"); - QHBoxLayout* hLayout = new QHBoxLayout(); - hLayout->addWidget(yeBanBan); - hLayout->addWidget(label); - layout->addLayout(hLayout); - } - QLineEdit* lineEdit = new QLineEdit(); - } -}; -class kakongSonWidget2 -{ - -public: - QWidget* widget; - QCheckBox* checkBox; - QLineEdit* minLineEdit; - QLineEdit* maxLineEdit; - kakongSonWidget2(QString title) - { - widget = new CustomWidget(); - QVBoxLayout* layout = new QVBoxLayout(); - widget->setLayout(layout); - { - QHBoxLayout* hLayout = new QHBoxLayout(); - QLabel* label = new QLabel(title); - checkBox = new QCheckBox(); - QLabel* label2 = new QLabel(u8"启用"); - hLayout->addWidget(label); - hLayout->addWidget(checkBox); - hLayout->addWidget(label2); - layout->addLayout(hLayout); - } - { - QLabel* label = new QLabel(u8"最小"); - minLineEdit = new QLineEdit(); - minLineEdit->setFixedWidth(60); - QHBoxLayout* hLayout = new QHBoxLayout(); - hLayout->addWidget(label); - hLayout->addWidget(minLineEdit); - layout->addLayout(hLayout); - } - { - QLabel* label = new QLabel(u8"最大"); - maxLineEdit =new QLineEdit(); - maxLineEdit->setFixedWidth(60); - QHBoxLayout* hLayout = new QHBoxLayout(); - hLayout->addWidget(label); - hLayout->addWidget(maxLineEdit); - layout->addLayout(hLayout); - } - QLineEdit* lineEdit = new QLineEdit(); - } -}; -class kakong -{ -public: - - QWidget *widget; - QHBoxLayout* layout; - QLineEdit* lineEdit; - QSpinBox* spinBox; - QLabel* icon; - - QLabel* restTimeH; - QLabel* restTimeM; - QLabel* restTimeS; - - QLabel* startTime; - QListWidget* listWidget; - QPushButton* saveBtn; - QPushButton* cancelBtn; - bool tikTok = false; - QList< kaKongData>datas; - kakongSonWidget* banBieWidget; - kakongSonWidget2* louDongWidget; - kakongSonWidget2* louCengWidget; - kakongSonWidget2* xianTiWidget; - kakongSonWidget2* jiTaiWidget; - kakongSonWidget2* riQiWidget; - - unsigned long long nowStartTimeM = 0; - unsigned long long nowKeepTime = 0; - - QPushButton* clearBtn; - QPushButton* delBtn; - QPushButton* cancelBtn2; - int currentIndex = -1; - - QPushButton* cnc3btn; - QPushButton* cnc5btn; - QPushButton* cnc6btn; - void loadDataFromJson() - { - QList dataList; - - // 打开 JSON 文件并读取数据 - QFile file(".\\config\\kakong.json"); - if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - QByteArray jsonData = file.readAll(); - file.close(); - - // 解析 JSON 数据 - QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData); - if (jsonDoc.isArray()) { - QJsonArray dataArray = jsonDoc.array(); - - // 逐个读取 JSON 数组中的对象,并添加到 dataList 中 - for (const QJsonValue& value : dataArray) { - if (value.isObject()) { - QJsonObject obj = value.toObject(); - kaKongData data; - data.Name = obj["Name"].toString(); - data.type = obj["type"].toInt(); - data.startTimeM = obj["startTimeM"].toVariant().toULongLong(); - data.keepTime = obj["keepTime"].toVariant().toULongLong(); - data.banBie = obj["banBie"].toBool(); - data.baiBan = obj["baiBan"].toBool(); - data.yeBan = obj["yeBan"].toBool(); - data.louDong = obj["louDong"].toBool(); - data.louDongMin = obj["louDongMin"].toInt(); - data.louDongMax = obj["louDongMax"].toInt(); - data.louCeng = obj["louCeng"].toBool(); - data.louCengMin = obj["louCengMin"].toInt(); - data.louCengMax = obj["louCengMax"].toInt(); - data.xianTi = obj["xianTi"].toBool(); - data.xianTiMin = obj["xianTiMin"].toInt(); - data.xianTiMax = obj["xianTiMax"].toInt(); - data.jiTai = obj["jiTai"].toBool(); - data.jiTaiHaoMin = obj["jiTaiHaoMin"].toInt(); - data.jiTaiHaoMax = obj["jiTaiHaoMax"].toInt(); - data.riQi = obj["riQi"].toBool(); - data.riQiMin = obj["riQiMin"].toInt(); - data.riQiMax = obj["riQiMax"].toInt(); - - dataList.append(data); - } - } - } - else { - qDebug() << "JSON 文件不是一个数组。"; - } - } - else { - qDebug() << "无法打开文件:" ; - } - - datas = dataList; - reFreshList(); - } - - void saveToJson() - { - QJsonArray dataArray; - - // 将数据列表转换为 JSON 数组 - for (const kaKongData& data : datas) { - QJsonObject obj; - obj["Name"] = data.Name; - obj["type"] = data.type; - obj["startTimeM"] = static_cast(data.startTimeM); - obj["keepTime"] = static_cast(data.keepTime); - obj["banBie"] = data.banBie; - obj["baiBan"] = data.baiBan; - obj["yeBan"] = data.yeBan; - obj["louDong"] = data.louDong; - obj["louDongMin"] = data.louDongMin; - obj["louDongMax"] = data.louDongMax; - obj["louCeng"] = data.louCeng; - obj["louCengMin"] = data.louCengMin; - obj["louCengMax"] = data.louCengMax; - obj["xianTi"] = data.xianTi; - obj["xianTiMin"] = data.xianTiMin; - obj["xianTiMax"] = data.xianTiMax; - obj["jiTai"] = data.jiTai; - obj["jiTaiHaoMin"] = data.jiTaiHaoMin; - obj["jiTaiHaoMax"] = data.jiTaiHaoMax; - obj["riQi"] = data.riQi; - obj["riQiMin"] = data.riQiMin; - obj["riQiMax"] = data.riQiMax; - - dataArray.append(obj); - } - - // 创建 JSON 文档 - QJsonDocument doc(dataArray); - - // 将 JSON 数据保存到文件 - QFile file(".\\config\\kakong.json"); - if (file.open(QIODevice::WriteOnly)) { - file.write(doc.toJson()); - file.close(); - qDebug() << "数据已保存到文件:" << ".\\config\\kakong.json"; - } - else { - qDebug() << "无法打开文件进行保存:" << ".\\config\\kakong.json"; - } - } - kakong() - { - - widget = new QWidget(); - QVBoxLayout* Vlayout = new QVBoxLayout(); - layout = new QHBoxLayout(); - widget->setLayout(layout); - layout->addLayout(Vlayout); - /// - QHBoxLayout* hLayout = new QHBoxLayout(); - QLabel* label = new QLabel(u8"配方"); - lineEdit=new QLineEdit(); - QLabel* label2 = new QLabel(u8"卡控时间"); - spinBox = new QSpinBox(); - QLabel* label3 = new QLabel(u8"小时|有效时间"); - restTimeH =new QLabel(u8"0"); - QLabel* label4 = new QLabel(u8"小时"); - restTimeM = new QLabel(u8"0"); - QLabel* label6 = new QLabel(u8"分钟"); - restTimeS = new QLabel(u8"0"); - QLabel* label7 = new QLabel(u8"秒"); - icon= new QLabel(); - icon->setFixedHeight(20); - icon->setFixedWidth(20); - setIconColor(true); - QLabel* label5 = new QLabel(u8"开始时间"); - startTime = new QLabel(u8"0"); - hLayout->addWidget(label); - hLayout->addWidget(lineEdit); - hLayout->addWidget(label2); - hLayout->addWidget(spinBox); - hLayout->addWidget(label3); - hLayout->addWidget(restTimeH); - hLayout->addWidget(label4); - hLayout->addWidget(restTimeM); - hLayout->addWidget(label6); - hLayout->addWidget(restTimeS); - hLayout->addWidget(label7); - hLayout->addWidget(icon); - hLayout->addWidget(label5); - hLayout->addWidget(startTime); - Vlayout->addLayout(hLayout); - { - QHBoxLayout* hLayout2 = new QHBoxLayout(); - cnc3btn = new QPushButton(u8"cnc3"); - cnc3btn->setDisabled(true); - cnc5btn = new QPushButton(u8"cnc5"); - cnc6btn = new QPushButton(u8"cnc6"); - cnc3btn->setFixedWidth(120); - cnc5btn->setFixedWidth(120); - cnc6btn->setFixedWidth(120); - hLayout2->addWidget(cnc3btn); - hLayout2->addWidget(cnc5btn); - hLayout2->addWidget(cnc6btn); - hLayout2->setAlignment(Qt::AlignLeft); - Vlayout->addLayout(hLayout2); - } - { - QHBoxLayout* hLayout2 = new QHBoxLayout(); - banBieWidget = new kakongSonWidget(u8"班别"); - hLayout2->addWidget(banBieWidget->widget); - louDongWidget = new kakongSonWidget2(u8"楼栋"); - hLayout2->addWidget(louDongWidget->widget); - louCengWidget = new kakongSonWidget2(u8"楼层"); - hLayout2->addWidget(louCengWidget->widget); - xianTiWidget = new kakongSonWidget2(u8"线体"); - hLayout2->addWidget(xianTiWidget->widget); - jiTaiWidget = new kakongSonWidget2(u8"机台号"); - hLayout2->addWidget(jiTaiWidget->widget); - riQiWidget = new kakongSonWidget2(u8"日期"); - hLayout2->addWidget(riQiWidget->widget); - Vlayout->addLayout(hLayout2); - } - { - QHBoxLayout* hLayout2 = new QHBoxLayout(); - saveBtn = new QPushButton(u8"保存"); - cancelBtn = new QPushButton(u8"取消"); - saveBtn->setFixedWidth(120); - cancelBtn->setFixedWidth(120); - hLayout2->addWidget(saveBtn); - - hLayout2->addWidget(cancelBtn); - Vlayout->addLayout(hLayout2); - } - //////////// - { - QVBoxLayout*vlayout2 = new QVBoxLayout(); - QLabel* label = new QLabel(u8"配方管理"); - listWidget= new QListWidget(); - clearBtn = new QPushButton(u8"清空"); - delBtn = new QPushButton(u8"删除"); - cancelBtn2 = new QPushButton(u8"取消配方"); - vlayout2->addWidget(label); - vlayout2->addWidget(listWidget); - QHBoxLayout* hLayout2 = new QHBoxLayout(); - hLayout2->addWidget(clearBtn); - hLayout2->addWidget(delBtn); - vlayout2->addLayout(hLayout2); - vlayout2->addWidget(cancelBtn); - layout->addLayout(vlayout2); - } - loadDataFromJson(); - } - ~kakong() - { - saveToJson(); - } - void timerTask() - { - auto currentTime = std::chrono::system_clock::now(); - auto currentTimeStamp = std::chrono::time_point_cast(currentTime).time_since_epoch().count(); - unsigned long long nowTime = static_cast(currentTimeStamp); - int time = (nowKeepTime + nowStartTimeM) - nowTime; - if (time > 0) - { - int resH = time / 3600; - int resM = (time - resH * 3600) / 60; - int resS = (time - resH * 3600 - resM * 60) % 3600; - restTimeH->setText(QString::number(resH)); - restTimeM->setText(QString::number(resM)); - restTimeS->setText(QString::number(resS)); - } - else - { - setIconColor(true); - restTimeH->setText("0"); - restTimeM->setText("0"); - restTimeS->setText("0"); - } - } - void setIconColor(bool setRed) - { - if(setRed ==true) - icon->setStyleSheet("background-color: red;"); - else - icon->setStyleSheet("background-color: green;"); - } - void reFreshList() - { - listWidget->clear(); - for (auto data : datas) - { - listWidget->addItem(data.Name); - } - } - void listSelect(int row) - { - currentIndex = row; - auto currentTime = std::chrono::system_clock::now(); - auto currentTimeStamp = std::chrono::time_point_cast(currentTime).time_since_epoch().count(); - unsigned long long nowTime = static_cast(currentTimeStamp); - { - int time = datas[row].startTimeM; - startTime->setText(convertSecondsToDateTime(time)); - } - nowStartTimeM = datas[row].startTimeM; - nowKeepTime = datas[row].keepTime; - switch (datas[row].type) - { - case 1: - cnc3btn->setDisabled(true); - break; - case 2: - cnc5btn->setDisabled(true); - break; - case 3: - cnc6btn->setDisabled(true); - break; - } - if (datas[row].keepTime + datas[row].startTimeM < nowTime)//超过时间 - setIconColor(true); - else//有效 - { - setIconColor(false); - int time = (datas[row].keepTime + datas[row].startTimeM) - nowTime; - int resH = time / 3600; - int resM = (time- resH*3600) / 60; - int resS = (time - resH * 3600- resM*60) % 3600; - restTimeH->setText(QString::number(resH)); - restTimeM->setText(QString::number(resM)); - restTimeS->setText(QString::number(resS)); - } - lineEdit->setText(datas[row].Name); - - if (datas[row].banBie == true) - { - banBieWidget->checkBox->setChecked(true); - if (datas[row].baiBan == true) - banBieWidget->baiBan->setChecked(true); - if (datas[row].yeBan == true) - banBieWidget->yeBanBan->setChecked(true); - } - if (datas[row].louDong == true) - { - louDongWidget->checkBox->setChecked(true); - louDongWidget->minLineEdit->setText(QString::number(datas[row].louDongMin)); - louDongWidget->maxLineEdit->setText(QString::number(datas[row].louDongMax)); - } - if (datas[row].louCeng == true) - { - louCengWidget->checkBox->setChecked(true); - louCengWidget->minLineEdit->setText(QString::number(datas[row].louCengMin)); - louCengWidget->maxLineEdit->setText(QString::number(datas[row].louCengMax)); - } - if (datas[row].xianTi == true) - { - xianTiWidget->checkBox->setChecked(true); - xianTiWidget->minLineEdit->setText(QString::number(datas[row].xianTiMin)); - xianTiWidget->maxLineEdit->setText(QString::number(datas[row].xianTiMax)); - } - if (datas[row].jiTai == true) - { - jiTaiWidget->checkBox->setChecked(true); - jiTaiWidget->minLineEdit->setText(QString::number(datas[row].jiTaiHaoMin)); - jiTaiWidget->maxLineEdit->setText(QString::number(datas[row].jiTaiHaoMax)); - } - if (datas[row].riQi == true) - { - riQiWidget->checkBox->setChecked(true); - riQiWidget->minLineEdit->setText(QString::number(datas[row].riQiMin)); - riQiWidget->maxLineEdit->setText(QString::number(datas[row].riQiMax)); - } - } - void saveFunc() - { - auto currentTime = std::chrono::system_clock::now(); - auto currentTimeStamp = std::chrono::time_point_cast(currentTime).time_since_epoch().count(); - kaKongData newData; - newData.startTimeM = static_cast(currentTimeStamp); - newData.Name = lineEdit->text(); - newData.keepTime = spinBox->value() * 60 * 60; - if (cnc3btn->isEnabled() == false) - newData.type = 1; - else if (cnc5btn->isEnabled() == false) - newData.type = 2; - else if (cnc6btn->isEnabled() == false) - newData.type = 3; - if (banBieWidget->checkBox->isChecked() == true) - { - newData.banBie = true; - if (banBieWidget->baiBan->isChecked() == true) - newData.baiBan = true; - if (banBieWidget->yeBanBan->isChecked() == true) - newData.yeBan = true; - } - if (louDongWidget->checkBox->isChecked() == true) - { - newData.louDong = true; - newData.louDongMin = louDongWidget->minLineEdit->text().toInt(); - newData.louDongMax = louDongWidget->maxLineEdit->text().toInt(); - } - if (louCengWidget->checkBox->isChecked() == true) - { - newData.louCeng = true; - newData.louCengMin = louCengWidget->minLineEdit->text().toInt(); - newData.louCengMax = louCengWidget->maxLineEdit->text().toInt(); - } - if (xianTiWidget->checkBox->isChecked() == true) - { - newData.xianTi = true; - newData.xianTiMin = xianTiWidget->minLineEdit->text().toInt(); - newData.xianTiMax = xianTiWidget->maxLineEdit->text().toInt(); - } - if (jiTaiWidget->checkBox->isChecked() == true) - { - newData.jiTai = true; - newData.jiTaiHaoMin = jiTaiWidget->minLineEdit->text().toInt(); - newData.jiTaiHaoMax = jiTaiWidget->maxLineEdit->text().toInt(); - } - if (riQiWidget->checkBox->isChecked() == true) - { - newData.riQi = true; - newData.riQiMin = riQiWidget->minLineEdit->text().toInt(); - newData.riQiMax = riQiWidget->maxLineEdit->text().toInt(); - } - setIconColor(false); - datas.push_back(newData); - reFreshList(); - } - void delData() - { - if (currentIndex > 0) - { - nowStartTimeM = 0; - nowKeepTime = 0; - datas.removeAt(currentIndex); - reFreshList(); - } - } - void clearData() - { - listWidget->clear(); - currentIndex = -1; - datas.clear(); - nowStartTimeM = 0; - nowKeepTime = 0; - } - void cancelData() - { - nowStartTimeM = 0; - nowKeepTime = 0; - } - void cncSwitchTo3() - { - cnc3btn->setDisabled(true); - cnc5btn->setEnabled(true); - cnc6btn->setEnabled(true); - } - void cncSwitchTo5() - { - cnc5btn->setDisabled(true); - cnc3btn->setEnabled(true); - cnc6btn->setEnabled(true); - } - void cncSwitchTo6() - { - cnc6btn->setDisabled(true); - cnc5btn->setEnabled(true); - cnc3btn->setEnabled(true); - } -}; diff --git a/src/launcher/GUI/uiModule/uiModule_menuListWdiget.h b/src/launcher/GUI/uiModule/uiModule_menuListWdiget.h index 9ba0443..3d83758 100644 --- a/src/launcher/GUI/uiModule/uiModule_menuListWdiget.h +++ b/src/launcher/GUI/uiModule/uiModule_menuListWdiget.h @@ -16,14 +16,14 @@ public: QLabel* dirLabel = new QLabel(); toolItemWidget(QString title) { - QFont font("微软雅黑", 24, QFont::Bold); + QFont font("Microsoft YaHei", 24, QFont::Bold); QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); - returnBtn = new fancyButton(40,40, QIcon(":/icon/icon/rollback.png"),"返回上一级"); + returnBtn = new fancyButton(40,40, QIcon(":/icon/icon/rollback.png"),TR("Go Back")); layout->addWidget(returnBtn); - - homeBtn = new fancyButton(40, 40, QIcon(":/icon/icon/home2.png"), "返回目录"); + + homeBtn = new fancyButton(40, 40, QIcon(":/icon/icon/home2.png"), TR("Back to Menu")); layout->addWidget(homeBtn); dirLabel->setText(title); @@ -86,7 +86,7 @@ public: QString path; for (auto p : pathList) path.append(p + "/"); - QFont font("微软雅黑", 18, QFont::Bold); + QFont font("Microsoft YaHei", 18, QFont::Bold); std::vector result = fileManager::getAllDirs(path); for (auto dirName : result) { diff --git a/src/launcher/GUI/uiModule/uiModule_runCommand.h b/src/launcher/GUI/uiModule/uiModule_runCommand.h index 537cdc0..9cede67 100644 --- a/src/launcher/GUI/uiModule/uiModule_runCommand.h +++ b/src/launcher/GUI/uiModule/uiModule_runCommand.h @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include @@ -61,7 +61,7 @@ class runCommandWidget : public QDialog { public: explicit runCommandWidget(QWidget* parent = nullptr) : QDialog(parent) { - this->setWindowTitle("执行命令"); + this->setWindowTitle(TR("Execute Command")); this->setObjectName("runCommandWidget"); this->setStyleSheet(QString("QDialog#runCommandWidget {background-color: rgb(%1);border: 2px solid #000000;border-radius: 6px;}").arg(sColor_Blue)); @@ -99,10 +99,10 @@ public slots: connect(funcBtn, &fancyButtonText::clicked, this, [this, uuid]() { QMessageBox::StandardButton reply; reply = QMessageBox::question( - this, // 父窗口 - "提示", // 标题 - "确定要执行此操作吗?", // 内容 - QMessageBox::Yes | QMessageBox::No // 按钮 + this, // parent + TR("Confirm"), // title + TR("Are you sure you want to execute this action?"), // content + QMessageBox::Yes | QMessageBox::No // buttons ); if (reply == QMessageBox::Yes) { emit excuteCommandPreset(uuid); diff --git a/src/launcher/GUI/uiModule/uiModule_softwareDataDisplay.h b/src/launcher/GUI/uiModule/uiModule_softwareDataDisplay.h index aff8368..26d7098 100644 --- a/src/launcher/GUI/uiModule/uiModule_softwareDataDisplay.h +++ b/src/launcher/GUI/uiModule/uiModule_softwareDataDisplay.h @@ -12,7 +12,7 @@ class softwareDataDisplay : public QWidget { Q_OBJECT public: softwareDataDisplay(QWidget* parent = nullptr) : QWidget(parent) { - QFont font("微软雅黑", 12); + QFont font("Microsoft YaHei", 12); QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); QHBoxLayout* layout = new QHBoxLayout(this); @@ -56,7 +56,7 @@ public: runStateIconLabel->setPixmap(scaledPixmap); runStateIconLabel->setFixedSize(25, 25); - runStateText = new QLabel("正在检测..."); + runStateText = new QLabel(TR("Detecting...")); runStateText->setFont(font); runStateText->setPalette(palette); @@ -105,15 +105,15 @@ private slots: runStateText->setStyleSheet(QString("QLabel { %1 }").arg(colorStyle)); // 设置工具提示显示详细信息 - QString tooltip = QString("系统状态: %1\n"); + QString tooltip = QString(TR("System status: %1\n")); runStateText->setToolTip(tooltip); } void onMonitorError(const QString& error) { - runStateText->setText("监控异常"); - runStateText->setStyleSheet("QLabel { color: #999; }"); - runStateText->setToolTip(QString("监控错误: %1").arg(error)); + runStateText->setText(TR("Monitoring Error")); + runStateText->setStyleSheet("QLabel { color: #999; }"); + runStateText->setToolTip(QString(TR("Monitor error: %1")).arg(error)); } public slots: void onTriggerSateChanged(int loopCounterPerMin, int maxInterval) { diff --git a/src/launcher/GUI/uiModule/uiModule_summaryDataManager.h b/src/launcher/GUI/uiModule/uiModule_summaryDataManager.h index ac0423b..5448340 100644 --- a/src/launcher/GUI/uiModule/uiModule_summaryDataManager.h +++ b/src/launcher/GUI/uiModule/uiModule_summaryDataManager.h @@ -33,7 +33,7 @@ public: vlayout1->setContentsMargins(0, 0, 0, 0); { QHBoxLayout* tempLayout = new QHBoxLayout(); - QLabel* tempLabel = new QLabel(dataName + u8"OK数量:"); + QLabel* tempLabel = new QLabel(dataName + TR(" OK Count:")); tempLabel->setFont(font); tempLabel->setPalette(palette); @@ -46,7 +46,7 @@ public: } { QHBoxLayout* tempLayout = new QHBoxLayout(); - QLabel* tempLabel = new QLabel(dataName + u8"NG数量:"); + QLabel* tempLabel = new QLabel(dataName + TR(" NG Count:")); tempLabel->setFont(font); tempLabel->setPalette(palette); @@ -59,7 +59,7 @@ public: } { QHBoxLayout* tempLayout = new QHBoxLayout(); - QLabel* tempLabel = new QLabel(dataName + u8"总数量:"); + QLabel* tempLabel = new QLabel(dataName + TR(" Total Count:")); tempLabel->setFont(font); tempLabel->setPalette(palette); @@ -123,11 +123,11 @@ public: FrequencyBar* _3DCtBar; summaryDataManager() { - QPalette palette; - palette.setColor(QPalette::WindowText, Qt::white); - QFont font("微软雅黑", 14, QFont::Bold); - QFont font2("微软雅黑", 20, QFont::Bold); - widget = new fancyWidget(u8" 运行数据"); + QPalette palette; + palette.setColor(QPalette::WindowText, Qt::white); + QFont font("Microsoft YaHei", 14, QFont::Bold); + QFont font2("Microsoft YaHei", 20, QFont::Bold); + widget = new fancyWidget(TR(" Run Data")); /* fancyButtonText* resetBtn = new fancyButtonText(80,40,u8"重置", u8"重置跑料数据"); QObject::connect(resetBtn, &QPushButton::clicked, this, &summaryDataManager::resetAllValue); diff --git a/src/launcher/GUI/uiModule/uiModule_userSwitch.h b/src/launcher/GUI/uiModule/uiModule_userSwitch.h index 3d79760..7db6208 100644 --- a/src/launcher/GUI/uiModule/uiModule_userSwitch.h +++ b/src/launcher/GUI/uiModule/uiModule_userSwitch.h @@ -18,9 +18,9 @@ #include #include #include -#include -#include "../appConfig/appConfig.h" -#include "../appConfig/translation.h" +#include +#include +#include // Translation helper macro @@ -70,9 +70,6 @@ private slots: stopAutoLogout(); - QMessageBox::information(nullptr, TR("Auto Logout"), - TR("Login time exceeded 3 minutes, auto logout")); - emit userLoggedOut(); } diff --git a/src/launcher/appConfig/appConfig.cpp b/src/launcher/appConfig/appConfig.cpp index 7b14aa6..daba531 100644 --- a/src/launcher/appConfig/appConfig.cpp +++ b/src/launcher/appConfig/appConfig.cpp @@ -13,8 +13,7 @@ void appConfig::parsingSettingJson() exit(1); } objectSelect = settingJson["objectSelect"]; - loginPassWord = settingJson["loginPassWord"]; - + missionJsonPath = appWorkPath.string() + "/config/" + objectSelect + ".json"; if (QFile(QString::fromStdString(missionJsonPath)).exists() == false) { diff --git a/src/launcher/appConfig/appConfig.h b/src/launcher/appConfig/appConfig.h index 0797e4b..edd6b13 100644 --- a/src/launcher/appConfig/appConfig.h +++ b/src/launcher/appConfig/appConfig.h @@ -3,9 +3,10 @@ #include #include #include -#include -#include -class appConfig{ +#include "translation.h" +#include "auth.hpp" +class appConfig : public QObject{ + Q_OBJECT private: // 私有构造函数 appConfig() = default; @@ -19,7 +20,6 @@ public: static appConfig instance; return instance; } - bool exitWithRestart = false; void parsingSettingJson(); void loadSetting() { parsingSettingJson(); @@ -28,6 +28,7 @@ public: // 当前语言会自动从JSON中的current_language字段读取 std::cout << "当前语言/Current language: " << _translation->getCurrentLanguage() << std::endl; } + } void saveSettingJson() { saveJsonFromPath("./config/setting.json", settingJson); @@ -36,6 +37,7 @@ public: trans->saveToFile("./config/translation.json"); } + bool exitWithRestart = false; std::string missionJsonPath; nlohmann::ordered_json missionJson; std::string imgSavePath;//原图存储路径 @@ -43,13 +45,11 @@ public: SQLiteDB* dataBase = nullptr; std::vector< viewerStruct>viewDatas; std::string softwareTile;//软件标题 - Auth::UserManager Authorization; private: nlohmann::json settingJson; std::string jsonVersion; std::string objectSelect; - std::string loginPassWord; Translation* _translation; }; #pragma once \ No newline at end of file diff --git a/src/launcher/appConfig/appExternalConfig.hpp b/src/launcher/appConfig/appExternalConfig.hpp deleted file mode 100644 index 93f88ac..0000000 --- a/src/launcher/appConfig/appExternalConfig.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#include - -class appExternalConfig { -public: - void parse() - { - - } - -private: - //std::unordered_map dataMap; - //std::string configPath = "./config/externalData.json"; -}; -#pragma once \ No newline at end of file diff --git a/src/launcher/appConfig/auth.hpp b/src/launcher/appConfig/auth.hpp index ae2e32e..cae97ff 100644 --- a/src/launcher/appConfig/auth.hpp +++ b/src/launcher/appConfig/auth.hpp @@ -316,9 +316,9 @@ namespace Auth { std::cerr << errorMessage << std::endl; // 显示权限不足的弹窗 - QMessageBox::warning(nullptr, - "权限不足", - QString("您没有足够的权限执行此操作。\n\n需要权限级别: %1\n当前权限级别: %2") + QMessageBox::warning(nullptr, + TR("Insufficient permissions"), + QString(TR("You do not have sufficient permissions to perform this action.\n\nRequired level: %1\nCurrent level: %2")) .arg(QString::fromStdString(userLevelToString(requiredLevel))) .arg(QString::fromStdString(userLevelToString(currentUserLevel)))); } @@ -333,9 +333,9 @@ namespace Auth { std::cerr << errorMessage << std::endl; // 显示权限不足的弹窗(指定父窗口) - QMessageBox::warning(parent, - QString::fromLocal8Bit("权限不足"), - QString::fromLocal8Bit("您没有足够的权限执行此操作。\n\n需要权限级别: %1\n当前权限级别: %2") + QMessageBox::warning(parent, + TR("Insufficient permissions"), + QString(TR("You do not have sufficient permissions to perform this action.\n\nRequired level: %1\nCurrent level: %2")) .arg(QString::fromStdString(userLevelToString(requiredLevel))) .arg(QString::fromStdString(userLevelToString(currentUserLevel)))); } diff --git a/src/launcher/appCore.hpp b/src/launcher/appCore.hpp index 248ce56..a409a72 100644 --- a/src/launcher/appCore.hpp +++ b/src/launcher/appCore.hpp @@ -7,16 +7,15 @@ #include // #include "interface.h" -#include +#include //#include #define HIDE_CONSOLE 1 class backEnd { public: - IBackend* backend = nullptr; + IBackend* backendPtr = nullptr; HMODULE hDll; - bool loadCore(SQLiteDB* db, qtFuncBridge* bridgeIn, nlohmann::ordered_json& jsonIn) { - bridge = bridgeIn; + bool loadCore() { hDll = LoadLibrary("core.dll"); if (!hDll) { std::cerr << "Failed to load Core DLL!" << std::endl; @@ -27,31 +26,34 @@ public: ReleaseBackend = (ReleaseBackendFunc)GetProcAddress(hDll, "ReleaseBackend"); if (CreateBackend && ReleaseBackend) { - backend = CreateBackend(); + backendPtr = CreateBackend(); } else { std::cerr << "Failed to get Core function pointers!" << std::endl; exit(1); } - backend->init(db,bridgeIn, jsonIn); return true; } + bool initCore(SQLiteDB* db, nlohmann::ordered_json& backendJson) { + backendPtr->init(db, backendJson); + return true; + } void releaseCore(nlohmann::ordered_json& json) { - if (backend != nullptr) { - json = backend->getJson(); - backend->cleanup(); - ReleaseBackend(backend); - backend = nullptr; + if (backendPtr != nullptr) { + json = backendPtr->getBackendJson(); + backendPtr->cleanup(); + ReleaseBackend(backendPtr); + backendPtr = nullptr; } FreeLibrary(hDll); } void excuteCli(const QString& str) { - if(backend != nullptr) - backend->excuteCliCommand(str); + if(backendPtr != nullptr) + backendPtr->excuteCliCommand(str); } private: - qtFuncBridge* bridge; + fSignalHub* bridge; CreateBackendFunc CreateBackend; ReleaseBackendFunc ReleaseBackend; }; @@ -60,8 +62,7 @@ class appCore : public QObject{ public: backEnd _backEnd; logService* _logService = logService::getInstance(); - //systemStateMonitor* _systemStateMonitor = &systemStateMonitor::getInstance(); - + appCore() { initConfig(); } diff --git a/src/launcher/frontendSignalHub.h b/src/launcher/frontendSignalHub.h new file mode 100644 index 0000000..7affa1d --- /dev/null +++ b/src/launcher/frontendSignalHub.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +class fSignalHub : public QObject { + Q_OBJECT +public: + // 获取单例实例 + static fSignalHub* getInstance(fSignalHub* instance = nullptr) { + static fSignalHub* s_instance = nullptr; + if (instance) { + // 如果传入了实例,则设置为单例实例 + s_instance = instance; + } + if (!s_instance) { + // 如果没有传入实例且单例未初始化,则创建一个默认实例 + s_instance = new fSignalHub(nullptr); + } + return s_instance; + } + + // 禁止拷贝 + Q_DISABLE_COPY(fSignalHub) +private: + explicit fSignalHub(QObject* parent = nullptr) : QObject(parent) {} + ~fSignalHub() = default; +signals: + + // 切换界面 + void switchMainStakedWidget(int index); + + // UI 效果 + void passWordEditShake(); + + // 加载窗口状态图标 + void loadingWindow_SetLoadingIcon(); + void loadingWindow_SetErrorIcon(); + void loadingWindow_SetErrorText(QString text); + + // 警告日志 + void loadingWindow_appendWarningLog(QString text); + void loadingWindow_clearWarningLog(); + ////////////////////////////////////////////////////////////// + void restartInit(); + + void triggerAndCaptureImage(std::string cameraName, std::vector* mats); + void getCameraNames(std::vector* cameraNames); + void getAllParams(std::vector>* params); + void editParam(QString group, QString name, QVariant value); + void saveMissionJson(); + +}; \ No newline at end of file diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index 3e64d05..1e60b35 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -23,7 +23,7 @@ #include // std::filesystem::path #include - +#include #pragma region 程序启动功能 // 获取当前exe文件名 std::string getCurrentExeName() { @@ -109,7 +109,7 @@ bool checkResourceExists(const QString& resourcePath) { } } -void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge* bridge) { +void connectFrontSignals(appCore* _core, MainWindow* _MainWindow, fSignalHub* bridge) { QObject::connect(_core->_logService->getLogWidget(), &logToQtWidget::stdLogSignal, _MainWindow->_logWidget, &logWidget::recvStdLogMsg); QObject::connect(_core->_logService->getLogWidget(), &logToQtWidget::qtLogSignal, @@ -120,78 +120,90 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge* _MainWindow, [=](const QString& text) {_MainWindow->_loadingWidget.appendConsoleLog(text); }); //BackEnd To Front //等待界面 - QObject::connect(bridge, &qtFuncBridge::loadingWindow_appendInitLog, - _MainWindow, [=](const QString& text, const QColor& color) {_MainWindow->_loadingWidget.appendInitLog(text, color); }); - QObject::connect(bridge, &qtFuncBridge::loadingWindow_modifyLog, - _MainWindow, [=](int col, const QString& text, const QColor& color) {_MainWindow->_loadingWidget.modifyLog(col, text, color); }); - QObject::connect(bridge, &qtFuncBridge::loadingWindow_clearLog, - _MainWindow, [=]() {_MainWindow->_loadingWidget.clearLog(); }); - QObject::connect(bridge, &qtFuncBridge::pieWidgetAddNG, - _MainWindow, [=]() {_MainWindow->_displayWidget->_dsStatsWidget->addNg(); }); - QObject::connect(bridge, &qtFuncBridge::pieWidgetAddOK, - _MainWindow, [=]() {_MainWindow->_displayWidget->_dsStatsWidget->addOK(); }); - QObject::connect(bridge, &qtFuncBridge::histogramWidgetAddData, - _MainWindow, [=](std::vectordefects) - {_MainWindow->_displayWidget->_dayNightShiftHistogramWidget->addDefect(defects); }); - QObject::connect(bridge, &qtFuncBridge::waveFormAddData, - _MainWindow, [=](QString windowName, double value) - {_MainWindow->_SummuaryDataPage.addData(windowName, value); }); - QObject::connect(bridge, &qtFuncBridge::setPlcConnectionError, - _MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setPlcDisconnected(); }); - QObject::connect(bridge, &qtFuncBridge::setPlcConnectionOk, - _MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setPlcConnected(); }); - QObject::connect(bridge, &qtFuncBridge::setCamConnectionError, - _MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setCamDisconnected(); }); - QObject::connect(bridge, &qtFuncBridge::setCamConnectionOk, - _MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setCamConnected(); }); - //登录界面 - QObject::connect(bridge, &qtFuncBridge::initResult, - _MainWindow, &MainWindow::recvInitFinished); - QObject::connect(bridge, &qtFuncBridge::initResult, - _core, &appCore::recvInitFinished); - //展示界面//主界面 - QObject::connect(bridge, &qtFuncBridge::displayWidget_sendImg, - _MainWindow, &MainWindow::recvPixmapImageWidget); //波形图 - QObject::connect(bridge, &qtFuncBridge::summaryData_addData, - _MainWindow, &MainWindow::slot_summaryData_addData); - - //排障 - QObject::connect(bridge, &qtFuncBridge::runCommand_addBtn, - _MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::addBtn); - QObject::connect(_MainWindow->_displayWidget->_runCommandWidget, - &runCommandWidget::excuteCommandPreset, - [=](QString uuid) {_core->_backEnd.backend->excuteCliCommandPreset(uuid); }); - QObject::connect(bridge, &qtFuncBridge::runCommand_addPlcValueViewer, - _MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::addPlcValueViewer); - QObject::connect(bridge, &qtFuncBridge::runCommand_refeshPlcValueViewer, - _MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::refreshPlcValueViewer); - - //性能监测 - QObject::connect(bridge, &qtFuncBridge::sendTriggerManagerLoopData, - _MainWindow->_displayWidget->_softwareDataDisplay, &softwareDataDisplay::onTriggerSateChanged); - - QObject::connect(bridge, &qtFuncBridge::triggerAndCaptureImage, - _core->_backEnd.backend, &IBackend::triggerAndCaptureImage,Qt::DirectConnection); - QObject::connect(bridge, &qtFuncBridge::getCameraNames, - _core->_backEnd.backend, &IBackend::getCameraNames, Qt::DirectConnection); - QObject::connect(bridge, &qtFuncBridge::getAllParams, - _core->_backEnd.backend, &IBackend::getAllParams, Qt::DirectConnection); - QObject::connect(bridge, &qtFuncBridge::editParam, - _core->_backEnd.backend, &IBackend::editParam, Qt::DirectConnection); - QObject::connect(bridge, &qtFuncBridge::saveMissionJson, - _core->_backEnd.backend, [=]() { - auto &config = appConfig::getInstance(); - config.missionJson["backend"] = _core->_backEnd.backend->getJson(); + QObject::connect(bridge, &fSignalHub::triggerAndCaptureImage, + _core->_backEnd.backendPtr, &IBackend::triggerAndCaptureImage,Qt::DirectConnection); + QObject::connect(bridge, &fSignalHub::getCameraNames, + _core->_backEnd.backendPtr, &IBackend::getCameraNames, Qt::DirectConnection); + QObject::connect(bridge, &fSignalHub::getAllParams, + _core->_backEnd.backendPtr, &IBackend::getAllParams, Qt::DirectConnection); + QObject::connect(bridge, &fSignalHub::editParam, + _core->_backEnd.backendPtr, &IBackend::editParam, Qt::DirectConnection); + QObject::connect(bridge, &fSignalHub::saveMissionJson, + _core,[=]() { + auto& config = appConfig::getInstance(); + config.missionJson["backend"] = _core->_backEnd.backendPtr->getBackendJson(); config.saveSettingJson(); }, Qt::DirectConnection); - QObject::connect(bridge, &qtFuncBridge::restartInit,[=]() { + QObject::connect(bridge, &fSignalHub::restartInit,[=]() { appConfig::getInstance().exitWithRestart = true; QApplication::quit(); }); } +void connectBackSignals(appCore* _core, MainWindow* _MainWindow, bSignalHub* bridge) { + //等待界面 + QObject::connect(bridge, &bSignalHub::loadingWindow_appendInitLog, + _MainWindow, [=](const QString& text, const QColor& color) {_MainWindow->_loadingWidget.appendInitLog(text, color); }); + QObject::connect(bridge, &bSignalHub::loadingWindow_modifyLog, + _MainWindow, [=](int col, const QString& text, const QColor& color) {_MainWindow->_loadingWidget.modifyLog(col, text, color); }); + QObject::connect(bridge, &bSignalHub::loadingWindow_clearLog, + _MainWindow, [=]() {_MainWindow->_loadingWidget.clearLog(); }); + QObject::connect(bridge, &bSignalHub::pieWidgetAddNG, + _MainWindow, [=]() {_MainWindow->_displayWidget->_dsStatsWidget->addNg(); }); + QObject::connect(bridge, &bSignalHub::pieWidgetAddOK, + _MainWindow, [=]() {_MainWindow->_displayWidget->_dsStatsWidget->addOK(); }); + QObject::connect(bridge, &bSignalHub::histogramWidgetAddData, + _MainWindow, [=](std::vectordefects) + {_MainWindow->_displayWidget->_dayNightShiftHistogramWidget->addDefect(defects); }); + QObject::connect(bridge, &bSignalHub::waveFormAddData, + _MainWindow, [=](QString windowName, double value) + {_MainWindow->_SummuaryDataPage.addData(windowName, value); }); + QObject::connect(bridge, &bSignalHub::setPlcConnectionError, + _MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setPlcDisconnected(); }); + QObject::connect(bridge, &bSignalHub::setPlcConnectionOk, + _MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setPlcConnected(); }); + QObject::connect(bridge, &bSignalHub::setCamConnectionError, + _MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setCamDisconnected(); }); + QObject::connect(bridge, &bSignalHub::setCamConnectionOk, + _MainWindow, [=]() {_MainWindow->_displayWidget->_toolBarWidget->_ConnectionWidget->setCamConnected(); }); + //登录界面 + QObject::connect(bridge, &bSignalHub::initResult, + _MainWindow, &MainWindow::recvInitFinished); + QObject::connect(bridge, &bSignalHub::initResult, + _core, &appCore::recvInitFinished); + //展示界面//主界面 + QObject::connect(bridge, &bSignalHub::displayWidget_sendImg, + _MainWindow, &MainWindow::recvPixmapImageWidget); + + //波形图 + QObject::connect(bridge, &bSignalHub::summaryData_addData, + _MainWindow, &MainWindow::slot_summaryData_addData); + + //排障 + QObject::connect(bridge, &bSignalHub::runCommand_addBtn, + _MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::addBtn); + QObject::connect(_MainWindow->_displayWidget->_runCommandWidget, + &runCommandWidget::excuteCommandPreset, + [=](QString uuid) {_core->_backEnd.backendPtr->excuteCliCommandPreset(uuid); }); + QObject::connect(bridge, &bSignalHub::runCommand_addPlcValueViewer, + _MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::addPlcValueViewer); + QObject::connect(bridge, &bSignalHub::runCommand_refeshPlcValueViewer, + _MainWindow->_displayWidget->_runCommandWidget, &runCommandWidget::refreshPlcValueViewer); + + //性能监测 + QObject::connect(bridge, &bSignalHub::sendTriggerManagerLoopData, + _MainWindow->_displayWidget->_softwareDataDisplay, &softwareDataDisplay::onTriggerSateChanged); + + QObject::connect(bridge, &bSignalHub::saveMissionJson, + _core,[=]() { + auto& config = appConfig::getInstance(); + config.missionJson["backend"] = _core->_backEnd.backendPtr->getBackendJson(); + config.saveSettingJson(); + }, Qt::DirectConnection); + +} int main(int argc, char* argv[]) { @@ -217,7 +229,7 @@ int main(int argc, char* argv[]) appCore _core; auto& config = appConfig::getInstance(); config.consoleHandle = hWnd; - auto bridge = qtFuncBridge::getInstance(); // 创建 C++ 对象 + auto bridge = fSignalHub::getInstance(); // 创建 C++ 对象 //检测是否已运行 if (appIsRuning() == false) exit(0); @@ -236,6 +248,7 @@ int main(int argc, char* argv[]) qRegisterMetaType>>("constvpqi"); qRegisterMetaType("PlcValueViewerStruct"); qRegisterMetaType>>("vecQStringQVarint"); + qRegisterMetaType>*>("vecQStringQVarintPtr"); #pragma endregion QApplication a(argc, argv); _core.initDatabase(); // 初始化数据库 @@ -245,8 +258,10 @@ int main(int argc, char* argv[]) w.show(); QThread::msleep(100); // 创建后端对象 - _core._backEnd.loadCore(config.dataBase,bridge, config.missionJson["backend"]); // 加载核心功能 - connectSignalAndSlot(&_core, &w, bridge); // 连接信号和槽 + _core._backEnd.loadCore(); // 加载核心功能 + connectFrontSignals(&_core, &w, bridge); // 连接前端UI的信号和槽 + connectBackSignals(&_core, &w, &_core._backEnd.backendPtr->_signalHub); // 连接前端UI的信号和槽 + _core._backEnd.initCore(config.dataBase, config.missionJson["backend"]); // 初始化核心功能 w.registerQuitFunc([&]() { auto& config = appConfig::getInstance(); _core._backEnd.releaseCore(config.missionJson["backend"]); diff --git a/src/mission/581-BaoMo-Cam1213/581-BaoMo.h b/src/mission/581-BaoMo-Cam1213/581-BaoMo.h deleted file mode 100644 index d2ee48e..0000000 --- a/src/mission/581-BaoMo-Cam1213/581-BaoMo.h +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include - -#pragma region 算法 -#include -#include -#include -using namespace HDevEngineCpp; - -#pragma endregion - - -class _581_BaoMo : public mission { -public: - using generalTrigger = _581_Union_triggerTemplate; - generalTrigger _station_1; - generalTrigger _station_2; - detParams _params; - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_602.hdpl"); - } - bool initCustom() { -#pragma region 注册触发器回调 - //generalTrigger::resultHandleCallback resultCallback_general = - // ([=](yh_581_address address, _581_Result resultData, std::shared_ptr data) { - // _serviceManager->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - // }); - _station_1.init("Camera1","包膜后底托位置度检测相机12",20200,2,1, &_params,_serviceManager,bridge, generalAlgoTest); - _station_2.init("Camera2", "包膜后底托位置度检测相机13",20400,2,1,&_params, _serviceManager, bridge, generalAlgoTest); -#pragma endregion - return true; - } - void reloadAlgo(QByteArray& byteArray) { - - } - - //9600 -}; - - - - - -#pragma once \ No newline at end of file diff --git a/src/mission/581-BaoMo-Cam1234/581-BaoMo.h b/src/mission/581-BaoMo-Cam1234/581-BaoMo.h deleted file mode 100644 index 0a9ba18..0000000 --- a/src/mission/581-BaoMo-Cam1234/581-BaoMo.h +++ /dev/null @@ -1,264 +0,0 @@ -#include -struct _581_BaoMoResult -{ - bool result = true; - std::vector < std::string> defects; -}; -class baoMoHouDaMianDetParams { -public: - handleAiModelSeg* seg; - handleAiModelCls* cls; - handleAiModelCls* cls2; -}; -//class _581Baomo_BaoMoHouShangDaMian { -//public: -// baoMoHouDaMianDetParams _detParams; -// detCallbackChain* ganeralDet; -// std::string cameraName; -// QString viewerName; -// void init(std::string cameraNameIn, QString viewerNameIN, -// ServiceManager* _serviceManagerIN, -// nlohmann::ordered_json& _missionJson, -// SQLiteDB* _SQLiteDB, qtFuncBridge* bridgeIn) { -// viewerName = viewerNameIN; -// cameraName = cameraNameIn; -// _serviceManager = _serviceManagerIN; -// _detParams.seg = _serviceManager->_handleAiModelManager->getSegModel("seg"); -// _detParams.cls = _serviceManager->_handleAiModelManager->getClsModel("cls"); -// _detParams.cls2 = _serviceManager->_handleAiModelManager->getClsModel("cls2"); -// ganeralDet = new detCallbackChain(_serviceManagerIN, &_detParams, bridgeIn); -// ganeralDet->registerProcessAlgoCallback(BaoMoHouDaMian); -// ganeralDet->registerResultHandleCallback(std::bind(&_581Baomo_BaoMoHouShangDaMian::resultHandle, this, _1, _2)); -// } -// //9200 1 -// void evaluate(int triggerPos, int triggerValue, int snPos, int dataPos, QByteArray& byteArray) { -// std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); -// auto camera = _serviceManager->_cameraManager->getCamera(cameraName); -// for (int i = 0; i < 2; i++) { -// std::shared_ptr data = _serviceManager->_detDataManager->createDetData( -// QString::number(triggerPos), sn, 1, camera->config.oriSaveFormat);//创建数据包 -// camera->captureImage(data);//拍照 -// //data->oriImgs.push_back(cv::imread("D://Image_20250809202445856.bmp", -1)); -// ganeralDet->ansyncProcess(data, "");//处理算法 -// data->resultImgShowSet.push_back(new showImgPack(viewerName, "结果图")); -// data->additional["触发地址"] = triggerPos; -// data->additional["完成信号"] = triggerPos + 98; -// data->additional["结果信号"] = triggerPos + 106; -// data->additional["数据地址"] = dataPos; -// QThread::msleep(3000); -// } -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(triggerPos + 98) + "_1");//完成信号 -// qDebug() << triggerPos << triggerValue << QString::fromUtf8("检测开始 uuid :") << "SN" << QString::fromStdString(sn);; -// } -// void resultHandle(std::shared_ptr data, _581_Result resultData) { -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["触发地址"].toInt() + 106) + "_1");//发送结果 -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["完成信号"].toInt()) + "_0");//完成信号复位 -// _serviceManager->_missionResultHandle->toBarChart(data->SNcode, resultData.result, resultData.defects); -// -// } -//private: -// -// qtFuncBridge* bridge; -// ServiceManager* _serviceManager = nullptr; -//}; -//class _581Baomo_trigger2ImgTemplate { -//public: -// detParams _detParams; -// detCallbackChain* ganeralDet; -// std::string cameraName; -// QString viewerName; -// void init(std::string cameraNameIn, QString viewerNameIN, -// ServiceManager* _serviceManagerIN, -// nlohmann::ordered_json& _missionJson, -// SQLiteDB* _SQLiteDB, qtFuncBridge* bridgeIn) { -// viewerName = viewerNameIN; -// cameraName = cameraNameIn; -// _serviceManager = _serviceManagerIN; -// ganeralDet = new detCallbackChain(_serviceManagerIN, &_detParams, bridgeIn); -// ganeralDet->registerProcessAlgoCallback(_952_15_H_Algo); -// ganeralDet->registerResultHandleCallback(std::bind(&_581Baomo_trigger2ImgTemplate::resultHandle, this, _1, _2)); -// } -// //9200 1 -// void evaluate(int triggerPos, int triggerValue, int snPos, int dataPos, QByteArray& byteArray) { -// std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); -// auto camera = _serviceManager->_cameraManager->getCamera(cameraName); -// for (int i = 0; i < 2; i++) { -// std::shared_ptr data = _serviceManager->_detDataManager->createDetData( -// QString::number(triggerPos), sn, 1, camera->config.oriSaveFormat);//创建数据包 -// camera->captureImage(data);//拍照 -// ganeralDet->ansyncProcess(data, "");//处理算法 -// data->resultImgShowSet.push_back(new showImgPack(viewerName, "结果图")); -// data->additional["触发地址"] = triggerPos; -// data->additional["完成信号"] = triggerPos + 98; -// data->additional["结果信号"] = triggerPos + 106; -// data->additional["数据地址"] = dataPos; -// } -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(triggerPos + 98) + "_1");//完成信号 -// qDebug() << triggerPos << triggerValue << QString::fromUtf8("检测开始 uuid :") << "SN" << QString::fromStdString(sn);; -// } -// void resultHandle(std::shared_ptr data, _581_Result resultData) { -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["触发地址"].toInt() + 106) + "_1");//发送结果 -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["完成信号"].toInt()) + "_0");//完成信号复位 -// -// } -//private: -// -// qtFuncBridge* bridge; -// ServiceManager* _serviceManager = nullptr; -//}; - -#include -#include -#include -using namespace HDevEngineCpp; - -_581_BaoMoResult SUB_BaoMoHouDaMian(std::shared_ptr data, cv::Mat src, cv::Mat& Paint, - baoMoHouDaMianDetParams* _detParams) { - _581_BaoMoResult aireuslt; - TextRendererZH textPainter(Paint.cols, Paint.rows, 150); - bool huaShangNg = false; - cv::Mat segImg = ~_detParams->seg->segPtr->Evaluate(src); - std::vector> contours; - cv::findContours(segImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); - bool isOK = true; - for (int i = 0; i < contours.size(); i++) { - cv::Rect rect = cv::boundingRect(contours[i]); - if (rect.width < 100 && rect.height < 100) continue; // 过滤掉小轮廓 - auto clsImgs = cutImg2ClsVec(rect, src, cv::Size(256, 256)); - bool clsIsNg = false; - for (auto& clsImg : clsImgs) { - if (_detParams->cls->Evaluate(clsImg) == 1) { // 假设1表示NG - int clsResult = _detParams->cls2->Evaluate(clsImg); - if (clsResult == 1) { - clsIsNg = true; - huaShangNg = true; - //data->clsOriginImgs.push_back({ std::to_string(i),clsImg }); - } - } - } - cv::Scalar color = cv::Scalar(0, 255, 0); - if (clsIsNg == true) { - color = cv::Scalar(0, 0, 255); - isOK = false; - cv::drawContours(Paint, contours, i, color, 2); - textPainter.putText(Paint, "划伤", cv::Point(rect.x + 10, rect.y - 20), cv::Scalar(0, 255, 0)); - } - //else { - // cv::Mat imgTmp; - // QMutexLocker locker(paintMutex); - // imgTmp.copyTo(Paint(rect)); - // cv::rectangle(Paint, rect, color, 3); - //} - - //putTextZH(Paint, "NG", cv::Point(rect.x + 10, rect.y - 20), 25, color); - } - if (huaShangNg == true) - aireuslt.defects.push_back("划伤"); - return aireuslt; -} -static bool ALGO_BaoMoHouDaMian(std::shared_ptr data, - baoMoHouDaMianDetParams* _detParams, - yh_581_address address) { - qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; - - ///////////////////取图//处理////////////////// - if (data->oriImgs.size() != 1) { - qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); - return false; - } - if (data->oriImgs[0].rows == 100) { - cv::Mat Paint; - data->oriImgs[0].copyTo(Paint); - cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); - return false; - } - - cv::Mat Paint; - //QMutex paintMutex; - clock_t start, finish; - start = clock(); - - cv::Mat src1 = data->oriImgs[0]; - cv::Mat srcHalf; - cv::resize(src1, srcHalf, cv::Size(0, 0), 0.5, 0.5); - if (srcHalf.channels() != 3) - cv::cvtColor(srcHalf, Paint, cv::COLOR_GRAY2BGR); - else - srcHalf.copyTo(Paint); - //TextRendererZH textPainter(Paint.cols, Paint.rows, 150); - //std::future <_581_Result> handleAiFuture = std::async(std::launch::async, _BaoMoHouDaMian, data, srcHalf, Paint, _detParams); - /*HalconCpp::HObject in_Image = MatToHObject(src1); - HDevEngineCpp::HDevProcedure proc("_4_Cal_Long_Coatingcover_Dist"); - HDevProcedureCall procedureCall(proc); - procedureCall.SetInputIconicParamObject("in_Image", in_Image); - procedureCall.SetInputCtrlParamTuple("in_xResolution", HTuple(0.0308812)); - procedureCall.SetInputCtrlParamTuple("in_yResolution", HTuple(0.029527)); - procedureCall.Execute(); - HTuple out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance"); - HTuple out_Line = procedureCall.GetOutputCtrlParamTuple("out_Line"); - HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); - int outFlag = out_Flag.D();*/ - //handleAiFuture.wait(); - //_result = handleAiFuture.get(); - //if (outFlag == 1) { - // for (int i = 0; i < out_Line.Length() / 4; i++) { - // cv::line(Paint, cv::Point(out_Line[i * 4 + 1].D() / 2, out_Line[i * 4].D()) / 2, - // cv::Point(out_Line[i * 4 + 3].D() / 2, out_Line[i * 4 + 2].D() / 2), - // cv::Scalar(0, 255, 0), 5); - // } - // /*out_Distance[0]: 上端盖到膜的距离< / c> - // * out_Distance[1] : 中端盖到膜的距离< / c> - // * out_Distance[2] : 下端盖到膜的距离< / c> - // * out_Distance[3] : 电芯宽度 < / c> - // * out_Distance[4] : 电芯高度< / c>*/ - // textPainter.putText(Paint, "上端盖到膜的距离:" + std::to_string(out_Distance[0].D()), cv::Point(50, 150), cv::Scalar(0, 255, 0)); - // textPainter.putText(Paint, "中端盖到膜的距离:" + std::to_string(out_Distance[1].D()), cv::Point(50, 350), cv::Scalar(0, 255, 0)); - // textPainter.putText(Paint, "下端盖到膜的距离:" + std::to_string(out_Distance[2].D()), cv::Point(50, 550), cv::Scalar(0, 255, 0)); - // textPainter.putText(Paint, "电芯宽度:" + std::to_string(out_Distance[3].D()), cv::Point(50, 750), cv::Scalar(0, 255, 0)); - // textPainter.putText(Paint, "电芯高度:" + std::to_string(out_Distance[4].D()), cv::Point(50, 950), cv::Scalar(0, 255, 0)); - //} - //else { - // textPainter.putText(Paint, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255)); - //} - data->service->_triggerManager->writeFloat("D" + address.resultAddr + "_1");//发送OK - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X - data->resultImgs.push_back(Paint); - - return false; -} - -class _581_BaoMo : public mission { -public: - using baoMoHouDaMianTrigger = _581_Union_triggerTemplate; - baoMoHouDaMianTrigger _station_1; - baoMoHouDaMianTrigger _station_2; - baoMoHouDaMianDetParams _baoMoHouDaMianDetParams; - - using generalTrigger = _581_Union_triggerTemplate; - generalTrigger _station_3; - generalTrigger _station_4; - detParams _detParams; - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_602.hdpl"); - } - bool initCustom() { -#pragma region 注册触发器回调 - _station_1.init("Camera1","包膜前外观检测大面相机1(上大面)", 18000,2, 1, &_baoMoHouDaMianDetParams,_serviceManager, bridge, ALGO_BaoMoHouDaMian); - _station_2.init("Camera2", "包膜前外观检测大面相机2(下大面)", 18200,2, 1, &_baoMoHouDaMianDetParams, _serviceManager,bridge, ALGO_BaoMoHouDaMian); - - _station_3.init("Camera3", "包膜前产品边缘检测大面相机3(下大面2)", 18400,2, 2, &_detParams,_serviceManager,bridge, generalAlgoTest); - _station_4.init("Camera4", "包膜前前产品边缘检测大面相机4(下大面2)", 18600 ,2, 2, &_detParams, _serviceManager, bridge, generalAlgoTest); -#pragma endregion - return true; - } - void reloadAlgo(QByteArray& byteArray) { - - } - - //9600 -}; - - - -#pragma once \ No newline at end of file diff --git a/src/mission/581-BaoMo-Cam5678/581-BaoMo.h b/src/mission/581-BaoMo-Cam5678/581-BaoMo.h deleted file mode 100644 index 7665f0d..0000000 --- a/src/mission/581-BaoMo-Cam5678/581-BaoMo.h +++ /dev/null @@ -1,353 +0,0 @@ -#include -#include - -struct _581_BaoMoResult -{ - bool result = true; - std::vector < std::string> defects; -}; -class baoMoHouDaMianDetParams { -public: - handleAiModelSeg* seg = nullptr; - handleAiModelCls* cls = nullptr; - handleAiModelCls* cls2 = nullptr; -}; -#pragma region 算法 -#include -#include -#include -using namespace HDevEngineCpp; -std::vector BaoMoHou_DaMianAi(std::shared_ptr data, cv::Mat src, cv::Mat& Paint, - baoMoHouDaMianDetParams* _detParams) { - if (_detParams->seg == nullptr || _detParams->cls == nullptr || _detParams->cls2 == nullptr) - return {}; - std::vector defects; - TextRendererZH textPainter(Paint.cols, Paint.rows, 150); - bool huaShangNg = false; - cv::Mat segImg = ~_detParams->seg->segPtr->Evaluate(src); - std::vector> contours; - cv::findContours(segImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); - bool isOK = true; - for (int i = 0; i < contours.size(); i++) { - cv::Rect rect = cv::boundingRect(contours[i]); - if (rect.width < 100 || rect.height < 100) continue; // 过滤掉小轮廓 - auto clsImgs = cutImg2ClsVec(rect, src, cv::Size(128, 128)); - bool clsIsNg = false; - for (auto& clsImg : clsImgs) { - if (_detParams->cls->clsPtr->Evaluate(clsImg) == 1) { // 假设1表示NG - int clsResult = _detParams->cls2->Evaluate(clsImg); - if (clsResult == 1) { - clsIsNg = true; - huaShangNg = true; - //data->clsOriginImgs.push_back({ std::to_string(i),clsImg }); - } - } - } - if (clsIsNg == true) { - cv::Scalar color = cv::Scalar(0, 0, 255); - isOK = false; - cv::drawContours(Paint, contours, i, color, 2); - textPainter.putText(Paint, "划伤", cv::Point(rect.x + 10, rect.y - 20), color); - } - //else { - // cv::Mat imgTmp; - // QMutexLocker locker(paintMutex); - // imgTmp.copyTo(Paint(rect)); - // cv::rectangle(Paint, rect, color, 3); - //} - - //putTextZH(Paint, "NG", cv::Point(rect.x + 10, rect.y - 20), 25, color); - } - if (huaShangNg == true) - defects.push_back("划伤"); - return defects; -} -#pragma endregion -#pragma region 算法 -static bool BaoMoHou_ShangDaMian(std::shared_ptr data, baoMoHouDaMianDetParams* _detParams, yh_581_address address) -{ - qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; - - ///////////////////取图//处理////////////////// - if (data->oriImgs.size() != 1) - { - qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); - return false; - } - if (data->oriImgs[0].rows == 150) { - cv::Mat Paint; - data->oriImgs[0].copyTo(Paint); - cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); - return false; - } - - cv::Mat Paint; - //QMutex paintMutex; - clock_t start, finish; - start = clock(); - - cv::Mat src1 = data->oriImgs[0]; - cv::Mat srcHalf; - cv::resize(src1, srcHalf, cv::Size(0, 0), 0.5, 0.5); - if (srcHalf.channels() != 3) - cv::cvtColor(srcHalf, Paint, cv::COLOR_GRAY2BGR); - else - srcHalf.copyTo(Paint); - TextRendererZH textPainter(Paint.cols, Paint.rows, 150); - std::future > handleAiFuture = std::async(std::launch::async, BaoMoHou_DaMianAi, data, srcHalf, Paint, _detParams); - HalconCpp::HObject in_Image = MatToHObject(src1); - HDevEngineCpp::HDevProcedure proc("_4_Cal_Long_Coatingcover_Dist"); - HDevProcedureCall procedureCall(proc); - procedureCall.SetInputIconicParamObject("in_Image", in_Image); - procedureCall.SetInputCtrlParamTuple("in_xResolution", HTuple(0.0308812)); - procedureCall.SetInputCtrlParamTuple("in_yResolution", HTuple(0.029527)); - procedureCall.Execute(); - HTuple out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance"); - HTuple out_Line = procedureCall.GetOutputCtrlParamTuple("out_Line"); - HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); - int outFlag = out_Flag.D(); - handleAiFuture.wait(); - auto defects = handleAiFuture.get(); - if (outFlag == 1) { - for (int i = 0; i < out_Line.Length() / 4; i++) { - cv::line(Paint, cv::Point(out_Line[i * 4 + 1].D(), out_Line[i * 4].D()) / 2, - cv::Point(out_Line[i * 4 + 3].D(), out_Line[i * 4 + 2].D()) / 2, - cv::Scalar(0, 255, 0), 5); - } - /*out_Distance[0]: 上端盖到膜的距离< / c> - * out_Distance[1] : 中端盖到膜的距离< / c> - * out_Distance[2] : 下端盖到膜的距离< / c> - * out_Distance[3] : 电芯宽度 < / c> - * out_Distance[4] : 电芯高度< / c>*/ - textPainter.putText(Paint, "上端盖到膜的距离:" + std::to_string(out_Distance[0].D()) + "mm", cv::Point(50, 150), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "中端盖到膜的距离:" + std::to_string(out_Distance[1].D()) + "mm", cv::Point(50, 350), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "下端盖到膜的距离:" + std::to_string(out_Distance[2].D()) + "mm", cv::Point(50, 550), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "电芯宽度:" + std::to_string(out_Distance[3].D()) + "mm", cv::Point(50, 750), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "电芯高度:" + std::to_string(out_Distance[4].D()) + "mm", cv::Point(50, 950), cv::Scalar(0, 255, 0)); - } - else { - data->halconOK = false; - textPainter.putText(Paint, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255)); - } - - data->resultImgs.push_back(Paint); - data->service->_missionResultHandle->toBarChart(data->SNcode, defects.size() == 0, defects); - data->service->_triggerManager->writeFloat("D" + address.resultAddr + "_1");//发送OK - return true; -} -//class _581Baomo_BaoMoHouShangDaMian { -//public: -// baoMoHouDaMianDetParams _detParams; -// detCallbackChain* ganeralDet; -// std::string cameraName; -// QString viewerName; -// void init(std::string cameraNameIn, QString viewerNameIN, -// ServiceManager* _serviceManagerIN, -// nlohmann::ordered_json& _missionJson, -// SQLiteDB* _SQLiteDB, qtFuncBridge* bridgeIn) { -// viewerName = viewerNameIN; -// cameraName = cameraNameIn; -// _serviceManager = _serviceManagerIN; -// _detParams.seg = _serviceManager->_handleAiModelManager->getSegModel("seg_gpu0"); -// _detParams.cls = _serviceManager->_handleAiModelManager->getClsModel("cls_gpu0"); -// _detParams.cls2 = _serviceManager->_handleAiModelManager->getClsModel("cls2_gpu0"); -// ganeralDet = new detCallbackChain(_serviceManagerIN, &_detParams, bridgeIn); -// ganeralDet->registerProcessAlgoCallback(BaoMoHou_ShangDaMian); -// ganeralDet->registerResultHandleCallback(std::bind(&_581Baomo_BaoMoHouShangDaMian::resultHandle, this, _1, _2)); -// } -// //9200 1 -// void evaluate(int triggerPos, int triggerValue, int snPos, int dataPos, QByteArray& byteArray) { -// std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); -// auto camera = _serviceManager->_cameraManager->getCamera(cameraName); -// // for (int i = 0; i < 2; i++) { -// std::shared_ptr data = _serviceManager->_detDataManager->createDetData( -// QString::number(triggerPos), sn, 1, camera->config.oriSaveFormat);//创建数据包 -// camera->captureImage(data);//拍照 -// //data->oriImgs.push_back(cv::imread("D://Image_20250809202445856.bmp", -1)); -// ganeralDet->ansyncProcess(data, "");//处理算法 -// data->resultImgShowSet.push_back(new showImgPack(viewerName, "结果图")); -// data->additional["触发地址"] = triggerPos; -// data->additional["完成信号"] = triggerPos + 98; -// data->additional["结果信号"] = triggerPos + 106; -// data->additional["数据地址"] = dataPos; -// //v } -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(triggerPos + 98) + "_1");//完成信号 -// qDebug() << triggerPos << triggerValue << QString::fromUtf8("检测开始 uuid :") << "SN" << QString::fromStdString(sn);; -// } -// void resultHandle(std::shared_ptr data, _581_BaoMoResult resultData) { -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["触发地址"].toInt() + 106) + "_1");//发送结果 -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["完成信号"].toInt()) + "_0");//完成信号复位 -// _serviceManager->_missionResultHandle->toBarChart(data->SNcode, resultData.result, resultData.defects); -// -// } -//private: -// -// qtFuncBridge* bridge; -// ServiceManager* _serviceManager = nullptr; -//}; -static bool BaoMoHou_XiaDaMian(std::shared_ptr data, baoMoHouDaMianDetParams* _detParams, yh_581_address address) -{ - qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; - - ///////////////////取图//处理////////////////// - if (data->oriImgs.size() != 1) - { - qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); - return false; - } - if (data->oriImgs[0].rows == 150) { - cv::Mat Paint; - data->oriImgs[0].copyTo(Paint); - cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); - return false; - } - - cv::Mat Paint; - //QMutex paintMutex; - clock_t start, finish; - start = clock(); - - cv::Mat src1 = data->oriImgs[0]; - cv::Mat srcHalf; - cv::resize(src1, srcHalf, cv::Size(0, 0), 0.5, 0.5); - if (srcHalf.channels() != 3) - cv::cvtColor(srcHalf, Paint, cv::COLOR_GRAY2BGR); - else - srcHalf.copyTo(Paint); - auto _result = BaoMoHou_DaMianAi(data, srcHalf, Paint, _detParams); - //TextRendererZH textPainter(Paint.cols, Paint.rows, 150); - //std::future <_581_BaoMoResult> handleAiFuture = std::async(std::launch::async, BaoMoHou_XiaMianAi, data, srcHalf, Paint, _detParams); - //HalconCpp::HObject in_Image = MatToHObject(src1); - //HDevEngineCpp::HDevProcedure proc("_4_Cal_Long_Coatingcover_Dist"); - //HDevProcedureCall procedureCall(proc); - //procedureCall.SetInputIconicParamObject("in_Image", in_Image); - //procedureCall.SetInputCtrlParamTuple("in_xResolution", HTuple(0.0308812)); - //procedureCall.SetInputCtrlParamTuple("in_yResolution", HTuple(0.029527)); - //procedureCall.Execute(); - //HTuple out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance"); - //HTuple out_Line = procedureCall.GetOutputCtrlParamTuple("out_Line"); - //HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); - //int outFlag = out_Flag.D(); - //handleAiFuture.wait(); - //_result = handleAiFuture.get(); - //if (outFlag == 1) { - // for (int i = 0; i < out_Line.Length() / 4; i++) { - // cv::line(Paint, cv::Point(out_Line[i * 4 + 1].D(), out_Line[i * 4].D()) / 2, - // cv::Point(out_Line[i * 4 + 3].D(), out_Line[i * 4 + 2].D()) / 2, - // cv::Scalar(0, 255, 0), 5); - // } - // /*out_Distance[0]: 上端盖到膜的距离< / c> - // * out_Distance[1] : 中端盖到膜的距离< / c> - // * out_Distance[2] : 下端盖到膜的距离< / c> - // * out_Distance[3] : 电芯宽度 < / c> - // * out_Distance[4] : 电芯高度< / c>*/ - // textPainter.putText(Paint, "上端盖到膜的距离:" + std::to_string(out_Distance[0].D()) + "mm", cv::Point(50, 150), cv::Scalar(0, 255, 0)); - // textPainter.putText(Paint, "中端盖到膜的距离:" + std::to_string(out_Distance[1].D()) + "mm", cv::Point(50, 350), cv::Scalar(0, 255, 0)); - // textPainter.putText(Paint, "下端盖到膜的距离:" + std::to_string(out_Distance[2].D()) + "mm", cv::Point(50, 550), cv::Scalar(0, 255, 0)); - // textPainter.putText(Paint, "电芯宽度:" + std::to_string(out_Distance[3].D()) + "mm", cv::Point(50, 750), cv::Scalar(0, 255, 0)); - // textPainter.putText(Paint, "电芯高度:" + std::to_string(out_Distance[4].D()) + "mm", cv::Point(50, 950), cv::Scalar(0, 255, 0)); - //} - //else { - // textPainter.putText(Paint, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255)); - //} - - data->resultImgs.push_back(Paint); - data->service->_triggerManager->writeFloat("D" + address.resultAddr + "_1");//发送OK - return true; -} -//class _581Baomo_BaoMoHouXiaDaMian { -//public: -// baoMoHouDaMianDetParams _detParams; -// detCallbackChain* ganeralDet; -// std::string cameraName; -// QString viewerName; -// void init(std::string cameraNameIn, QString viewerNameIN, -// ServiceManager* _serviceManagerIN, -// nlohmann::ordered_json& _missionJson, -// SQLiteDB* _SQLiteDB, qtFuncBridge* bridgeIn) { -// viewerName = viewerNameIN; -// cameraName = cameraNameIn; -// _serviceManager = _serviceManagerIN; -// _detParams.seg = _serviceManager->_handleAiModelManager->getSegModel("seg_gpu1"); -// _detParams.cls = _serviceManager->_handleAiModelManager->getClsModel("cls_gpu1"); -// _detParams.cls2 = _serviceManager->_handleAiModelManager->getClsModel("cls2_gpu1"); -// ganeralDet = new detCallbackChain(_serviceManagerIN, &_detParams, bridgeIn); -// ganeralDet->registerProcessAlgoCallback(BaoMoHou_XiaDaMian); -// ganeralDet->registerResultHandleCallback(std::bind(&_581Baomo_BaoMoHouXiaDaMian::resultHandle, this, _1, _2)); -// } -// //9200 1 -// void evaluate(int triggerPos, int triggerValue, int snPos, int dataPos, QByteArray& byteArray) { -// std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); -// auto camera = _serviceManager->_cameraManager->getCamera(cameraName); -// // for (int i = 0; i < 2; i++) { -// std::shared_ptr data = _serviceManager->_detDataManager->createDetData( -// QString::number(triggerPos), sn, 1, camera->config.oriSaveFormat);//创建数据包 -// camera->captureImage(data);//拍照 -// //data->oriImgs.push_back(cv::imread("D://Image_20250809202445856.bmp", -1)); -// ganeralDet->ansyncProcess(data, "");//处理算法 -// data->resultImgShowSet.push_back(new showImgPack(viewerName, "结果图")); -// data->additional["触发地址"] = triggerPos; -// data->additional["完成信号"] = triggerPos + 98; -// data->additional["结果信号"] = triggerPos + 106; -// data->additional["数据地址"] = dataPos; -// //v } -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(triggerPos + 98) + "_1");//完成信号 -// qDebug() << triggerPos << triggerValue << QString::fromUtf8("检测开始 uuid :") << "SN" << QString::fromStdString(sn);; -// } -// void resultHandle(std::shared_ptr data, _581_BaoMoResult resultData) { -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["触发地址"].toInt() + 106) + "_1");//发送结果 -// _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["完成信号"].toInt()) + "_0");//完成信号复位 -// _serviceManager->_missionResultHandle->toBarChart(data->SNcode, resultData.result, resultData.defects); -// -// } -//private: -// -// qtFuncBridge* bridge; -// ServiceManager* _serviceManager = nullptr; -//}; -#pragma endregion - -class _581_BaoMo : public mission { -public: - using baoMoHouShangDaMianTrigger = _581_Union_triggerTemplate; - baoMoHouShangDaMianTrigger _station_1;//shangdamian - baoMoHouShangDaMianTrigger _station_3;//shangdamian - - using baoMoHouXiaDaMianTrigger = _581_Union_triggerTemplate; - baoMoHouXiaDaMianTrigger _station_2;//xiadamian - baoMoHouXiaDaMianTrigger _station_4;//xiadamian - - baoMoHouDaMianDetParams _baoMoHouDaMianDetParams; - detParams _detParams; - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_602.hdpl"); - } - bool initCustom() { - -#pragma region 注册触发器回调 - //baoMoHouShangDaMianTrigger::resultHandleCallback resultCallback_BaoMoHouShangDaMian = - // ([=](yh_581_address address, _581_BaoMoResult resultData, std::shared_ptr data ) { - // _serviceManager->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - // _serviceManager->_missionResultHandle->toBarChart(data->SNcode, resultData.result, resultData.defects); - // }); - _station_1.init("Camera1", "包膜后大面外观检测相机5(上大面1)",18800,2,1, &_baoMoHouDaMianDetParams, _serviceManager,bridge, BaoMoHou_ShangDaMian); - _station_3.init("Camera3", "包膜后大面外观检测相机7(上大面2)", 19200, 2, 1, &_baoMoHouDaMianDetParams, _serviceManager, bridge, BaoMoHou_ShangDaMian); - - //baoMoHouXiaDaMianTrigger::resultHandleCallback resultCallback_BaoMoHouXiaDaMian = - // ([=](yh_581_address address, _581_BaoMoResult resultData, std::shared_ptr data) { - // _serviceManager->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - // _serviceManager->_missionResultHandle->toBarChart(data->SNcode, resultData.result, resultData.defects); - // }); - _station_2.init("Camera2", "包膜后大面外观检测相机6(下大面四角1)", 19000, 2, 1, &_baoMoHouDaMianDetParams, _serviceManager, bridge, BaoMoHou_XiaDaMian); - _station_4.init("Camera4", "包膜后大面外观检测相机8(下大面四角2)",19400,2,1, &_baoMoHouDaMianDetParams, _serviceManager, bridge, BaoMoHou_XiaDaMian); -#pragma endregion - return true; - } -}; - - - - - -#pragma once \ No newline at end of file diff --git a/src/mission/581-BaoMo-Cam91011/CMakeLists.txt b/src/mission/581-BaoMo-Cam91011/CMakeLists.txt deleted file mode 100644 index d94ce25..0000000 --- a/src/mission/581-BaoMo-Cam91011/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv" "halcon" "handdleAI") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - ${PROJECT_ROOT_PATH}/src/core - ${PROJECT_ROOT_PATH}/src/core/handleAi - ${PROJECT_ROOT_PATH}/src/core/service - ${PROJECT_ROOT_PATH}/src/core/sql - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) -add_compile_options(/utf-8) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) diff --git a/src/mission/581-Dgh-CB-1/CMakeLists.txt b/src/mission/581-Dgh-CB-1/CMakeLists.txt deleted file mode 100644 index 26de14b..0000000 --- a/src/mission/581-Dgh-CB-1/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv" "halcon" "handdleAI") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - ${PROJECT_ROOT_PATH}/src/core - ${PROJECT_ROOT_PATH}/src/core/handleAi - ${PROJECT_ROOT_PATH}/src/core/service - ${PROJECT_ROOT_PATH}/src/core/sql - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) -add_compile_options(/utf-8) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h - ${PROJECT_ROOT_PATH}/include/yhGlobal.h - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) diff --git a/src/mission/581-Dgh-CB-2/CMakeLists.txt b/src/mission/581-Dgh-CB-2/CMakeLists.txt deleted file mode 100644 index 26de14b..0000000 --- a/src/mission/581-Dgh-CB-2/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv" "halcon" "handdleAI") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - ${PROJECT_ROOT_PATH}/src/core - ${PROJECT_ROOT_PATH}/src/core/handleAi - ${PROJECT_ROOT_PATH}/src/core/service - ${PROJECT_ROOT_PATH}/src/core/sql - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) -add_compile_options(/utf-8) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h - ${PROJECT_ROOT_PATH}/include/yhGlobal.h - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) diff --git a/src/mission/581-Dgh-DB-1/CMakeLists.txt b/src/mission/581-Dgh-DB-1/CMakeLists.txt deleted file mode 100644 index 26de14b..0000000 --- a/src/mission/581-Dgh-DB-1/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv" "halcon" "handdleAI") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - ${PROJECT_ROOT_PATH}/src/core - ${PROJECT_ROOT_PATH}/src/core/handleAi - ${PROJECT_ROOT_PATH}/src/core/service - ${PROJECT_ROOT_PATH}/src/core/sql - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) -add_compile_options(/utf-8) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h - ${PROJECT_ROOT_PATH}/include/yhGlobal.h - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) diff --git a/src/mission/581-Dgh-DB-2/CMakeLists.txt b/src/mission/581-Dgh-DB-2/CMakeLists.txt deleted file mode 100644 index 26de14b..0000000 --- a/src/mission/581-Dgh-DB-2/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv" "halcon" "handdleAI") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - ${PROJECT_ROOT_PATH}/src/core - ${PROJECT_ROOT_PATH}/src/core/handleAi - ${PROJECT_ROOT_PATH}/src/core/service - ${PROJECT_ROOT_PATH}/src/core/sql - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) -add_compile_options(/utf-8) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h - ${PROJECT_ROOT_PATH}/include/yhGlobal.h - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) diff --git a/src/mission/581-Mfd_djy_sd/CMakeLists.txt b/src/mission/581-Mfd_djy_sd/CMakeLists.txt index d94ce25..76e9200 100644 --- a/src/mission/581-Mfd_djy_sd/CMakeLists.txt +++ b/src/mission/581-Mfd_djy_sd/CMakeLists.txt @@ -31,7 +31,7 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "*.h" ) @@ -40,14 +40,14 @@ FILE(GLOB UI_FILES "./*.ui") #find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) add_library(${CURRENT_FOLDER} SHARED ${HEAD_FILES} ${SRC_FILES} ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h + ${PROJECT_ROOT_PATH}/include/interface.h ) @@ -64,7 +64,6 @@ target_link_libraries(${CURRENT_FOLDER} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql ) diff --git a/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h b/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h index 86c611e..e6aa369 100644 --- a/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h +++ b/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h @@ -1,4 +1,4 @@ -#include +#include #include class mfd_detParams { public: @@ -25,6 +25,7 @@ void exceptionResume(std::shared_ptr data, mfd_detParams* _detParams, y using namespace HDevEngineCpp; static bool ManHan(std::shared_ptr data, mfd_detParams* _detParams, yh_581_address address){ try { + data->service->_triggerManager->writeFloat("D100_1,2,3,4,5,6,7,8,9,9"); std::map sqlMapData; sqlMapData["项目"] = "满焊"; sqlMapData["相机"] = "相机" + address.triggerAddr; @@ -167,6 +168,7 @@ static bool ManHan(std::shared_ptr data, mfd_detParams* _detParams, yh static bool YuHan(std::shared_ptr data, mfd_detParams* _detParams, yh_581_address address){ try { data->service->_missionResultHandle->toBarChart("", true, {"测试"}); + //data->service->_paramSyncManager->get(data->service->_paramSyncManager->getGroup(1), "123", 123); std::map sqlMapData; sqlMapData["项目"] = "预焊"; sqlMapData["相机"] = "相机" + address.triggerAddr; @@ -175,7 +177,6 @@ static bool YuHan(std::shared_ptr data, mfd_detParams* _detParams, yh_ qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); return false; } - cv::Mat Paint; cv::Mat src1 = data->oriImgs[0]; //src1 = cv::imread("D://ceshi/15H/1/333.bmp",-1); diff --git a/src/mission/581-Mfd_yh_mh_hh/CMakeLists.txt b/src/mission/581-Mfd_yh_mh_hh/CMakeLists.txt index d94ce25..76e9200 100644 --- a/src/mission/581-Mfd_yh_mh_hh/CMakeLists.txt +++ b/src/mission/581-Mfd_yh_mh_hh/CMakeLists.txt @@ -31,7 +31,7 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "*.h" ) @@ -40,14 +40,14 @@ FILE(GLOB UI_FILES "./*.ui") #find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) add_library(${CURRENT_FOLDER} SHARED ${HEAD_FILES} ${SRC_FILES} ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h + ${PROJECT_ROOT_PATH}/include/interface.h ) @@ -64,7 +64,6 @@ target_link_libraries(${CURRENT_FOLDER} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql ) diff --git a/src/mission/581-Ruke/581-Ruke.h b/src/mission/581-Ruke/581-Ruke.h index 5395361..2a6b620 100644 --- a/src/mission/581-Ruke/581-Ruke.h +++ b/src/mission/581-Ruke/581-Ruke.h @@ -22,10 +22,10 @@ public: } bool initCustom() { #pragma region 注册触发器回调 - ruke_cam1_3.init("Camera1","入壳相机1下",18000, 2, 3, &_params,_serviceManager, bridge, generalAlgoTest); - ruke_cam2_1.init("Camera2", "入壳相机2左",18200 , 2, 1,& _params, _serviceManager, bridge, generalAlgoTest); - ruke_cam3_3.init("Camera3", "入壳相机3上",18400, 2, 3, &_params, _serviceManager, bridge, generalAlgoTest); - ruke_cam4_1.init("Camera4", "入壳相机4右",18600, 2, 1, &_params, _serviceManager, bridge, generalAlgoTest); + ruke_cam1_3.init("Camera1", "入壳相机1下", 18000, 2, 3, &_params, _serviceManager, bridge, generalAlgoTest); + ruke_cam2_1.init("Camera2", "入壳相机2左", 18200, 2, 1,& _params, _serviceManager, bridge, generalAlgoTest); + ruke_cam3_3.init("Camera3", "入壳相机3上", 18400, 2, 3, &_params, _serviceManager, bridge, generalAlgoTest); + ruke_cam4_1.init("Camera4", "入壳相机4右", 18600, 2, 1, &_params, _serviceManager, bridge, generalAlgoTest); #pragma endregion return true; } diff --git a/src/mission/581-Ruke/CMakeLists.txt b/src/mission/581-Ruke/CMakeLists.txt index 26347b4..76e9200 100644 --- a/src/mission/581-Ruke/CMakeLists.txt +++ b/src/mission/581-Ruke/CMakeLists.txt @@ -31,7 +31,7 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "*.h" ) @@ -47,7 +47,7 @@ add_library(${CURRENT_FOLDER} SHARED ${HEAD_FILES} ${SRC_FILES} ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h + ${PROJECT_ROOT_PATH}/include/interface.h ) diff --git a/src/mission/581_YiCiZhuYe_canye/CMakeLists.txt b/src/mission/581_YiCiZhuYe_canye/CMakeLists.txt index 26347b4..76e9200 100644 --- a/src/mission/581_YiCiZhuYe_canye/CMakeLists.txt +++ b/src/mission/581_YiCiZhuYe_canye/CMakeLists.txt @@ -31,7 +31,7 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "*.h" ) @@ -47,7 +47,7 @@ add_library(${CURRENT_FOLDER} SHARED ${HEAD_FILES} ${SRC_FILES} ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h + ${PROJECT_ROOT_PATH}/include/interface.h ) diff --git a/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.h b/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.h deleted file mode 100644 index 558aeb1..0000000 --- a/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.h +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#pragma region 算法 -#include -#include -#include -using namespace HDevEngineCpp; -#pragma endregion -class yuHanHanHouParams { -public: - handdleAI::pSegmentation* segHanYinZhuaQu = nullptr; - handdleAI::pSegmentation* segYuHanDingWei = nullptr; - handdleAI::pSegmentation* segHanHou = nullptr; - handdleAI::pClassification* clsHanHou = nullptr; - bool isTong = true; -}; -struct halconResult { - bool result = true; - double jiErWidth = -1; - double jiErHeight = -1; - double hanYin1 = -1; -}; -void handleAiProcess(cv::Mat& src, cv::Mat& segRes, cv::Mat& Paint, - bool& silieResult, bool& fanZheResult, - cv::Point offset, handdleAI::pClassification* clsPtr, std::vector& clsImgs); -halconResult halconAlgoProcess(cv::Mat& img, cv::Mat& Paint, handdleAI::pSegmentation* seg_hanYinZhuaQu, cv::Mat& segResult); -bool hanHouCeLiang(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address); -bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address); - -namespace hanhou45{ - -} -class _581_YuHan_hanhou : public mission { -public: - _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_top90_1; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_down90_2; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_top90_3; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_down90_4; - - _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_top45_5; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_down45_6; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_top45_7; - _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_down45_8; - std::vector < yuHanHanHouParams> tongDetParams = std::vector < yuHanHanHouParams>(4); - std::vector < yuHanHanHouParams> lvDetParams = std::vector < yuHanHanHouParams>(4); - bool initOnce = false; - void onConfigReloaded() { - HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_602.hdpl"); - - if (initOnce == false) { - for (auto& params : tongDetParams) { - params.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-T.BHD", 64, 0); - params.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanDingWei-T.BHD", 64, 0); - params.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanhanHou-T.BHD", 64, 0); - params.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/cls-yuHanhanHou-T.BHD", 0, 1); - } - - for (auto& params : lvDetParams) { - params.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-L.BHD", 64, 1); - params.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanDingWei-L.BHD", 64, 1); - params.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanhanHou-L.BHD", 64, 1); - params.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/cls-yuHanhanHou-L.BHD", 1, 1); - } - initOnce = true; - } - } - bool initCustom() { -#pragma region 注册触发器回调 - if (_serviceManager->_paramSyncManager->get("hanhou","OUT") == "OUT") { - lv_top90_1.init("Camera1", "极耳尺寸-外-铝-相机1(顶部90°)", { { 522, 1,{540},"523","530",820} }, 1, &lvDetParams[0], _serviceManager, bridge, hanHouCeLiang); - lv_down90_2.init("Camera2", "极耳尺寸-外-铝-相机2(底部90°)", { { 524, 1,{540},"525","532",-1} }, 1, &lvDetParams[1], _serviceManager, bridge, hanHouDown); - tong_top90_3.init("Camera3", "极耳尺寸-外-铜-相机3(顶部90°)", { { 526,1,{540},"527","534",800} }, 1, &tongDetParams[0], _serviceManager, bridge, hanHouCeLiang); - tong_down90_4.init("Camera4", "极耳尺寸-外-铜-相机4(底部90°)", { { 528, 1,{540},"529","536",-1} }, 1, &tongDetParams[1], _serviceManager, bridge, hanHouDown); - - lv_top45_5.init("Camera5", "底部撕裂-外-铝-相机5(顶部45°)", { { 562,1,{540},"563","570",-1} }, 1, &lvDetParams[2], _serviceManager, bridge, hanHouDown); - lv_down45_6.init("Camera6", "底部撕裂-外-铝-相机6(底部45°)", { { 564, 1,{540},"565","572",-1} }, 1, &lvDetParams[3], _serviceManager, bridge, hanHouDown); - tong_top45_7.init("Camera7", "底部撕裂-外-铜-相机7(顶部45°)", { { 566, 1,{540},"567","574",-1} }, 1, &tongDetParams[2], _serviceManager, bridge, hanHouDown); - tong_down45_8.init("Camera8", "底部撕裂-外-铜-相机8(底部45°)", { { 568, 1,{540},"569","576",-1} }, 1, &tongDetParams[3], _serviceManager, bridge, hanHouDown); - } - else { - lv_top90_1.init("Camera1", "极耳尺寸-内-铝-相机1(顶部90°)", { { 602, 1,{580},"603","610",860} }, 1, &lvDetParams[0], _serviceManager, bridge, hanHouCeLiang); - lv_down90_2.init("Camera2", "极耳尺寸-内-铝-相机2(底部90°)", { { 604, 1,{580},"605","612",-1} }, 1, &lvDetParams[1], _serviceManager, bridge, hanHouDown); - tong_top90_3.init("Camera3", "极耳尺寸-内-铜-相机3(顶部90°)", { { 606,1,{580},"607","614",840} }, 1, &tongDetParams[0], _serviceManager, bridge, hanHouCeLiang); - tong_down90_4.init("Camera4", "极耳尺寸-内-铜-相机4(底部90°)", { { 608, 1,{580},"609","616",-1} }, 1, &tongDetParams[1], _serviceManager, bridge, hanHouDown); - - lv_top45_5.init("Camera5", "底部撕裂-内-铝-相机5(顶部45°)", { { 642,1,{580},"643","650",-1} }, 1, &lvDetParams[2], _serviceManager, bridge, hanHouDown); - lv_down45_6.init("Camera6", "底部撕裂-内-铝-相机6(底部45°)", { { 644, 1,{580},"645","652",-1} }, 1, &lvDetParams[3], _serviceManager, bridge, hanHouDown); - tong_top45_7.init("Camera7", "底部撕裂-内-铜-相机7(顶部45°)", { { 646, 1,{580},"647","654",-1} }, 1, &tongDetParams[2], _serviceManager, bridge, hanHouDown); - tong_down45_8.init("Camera8", "底部撕裂-内-铜-相机8(底部45°)", { { 648, 1,{580},"649","656",-1} }, 1, &tongDetParams[3], _serviceManager, bridge, hanHouDown); - } -#pragma endregion - return true; - } -}; - - - - - -#pragma once \ No newline at end of file diff --git a/src/mission/581_ZhongHan_hanhou/CMakeLists.txt b/src/mission/581_ZhongHan_hanhou/CMakeLists.txt deleted file mode 100644 index d94ce25..0000000 --- a/src/mission/581_ZhongHan_hanhou/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv" "halcon" "handdleAI") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - ${PROJECT_ROOT_PATH}/src/core - ${PROJECT_ROOT_PATH}/src/core/handleAi - ${PROJECT_ROOT_PATH}/src/core/service - ${PROJECT_ROOT_PATH}/src/core/sql - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) -add_compile_options(/utf-8) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) diff --git a/src/mission/581_ZhongHan_hanqian/CMakeLists.txt b/src/mission/581_ZhongHan_hanqian/CMakeLists.txt deleted file mode 100644 index d94ce25..0000000 --- a/src/mission/581_ZhongHan_hanqian/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv" "halcon" "handdleAI") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - ${PROJECT_ROOT_PATH}/src/core - ${PROJECT_ROOT_PATH}/src/core/handleAi - ${PROJECT_ROOT_PATH}/src/core/service - ${PROJECT_ROOT_PATH}/src/core/sql - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) -add_compile_options(/utf-8) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) diff --git a/src/mission/581_ZhongHan_silie_jixing/CMakeLists.txt b/src/mission/581_ZhongHan_silie_jixing/CMakeLists.txt deleted file mode 100644 index d94ce25..0000000 --- a/src/mission/581_ZhongHan_silie_jixing/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv" "halcon" "handdleAI") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - ${PROJECT_ROOT_PATH}/src/core - ${PROJECT_ROOT_PATH}/src/core/handleAi - ${PROJECT_ROOT_PATH}/src/core/service - ${PROJECT_ROOT_PATH}/src/core/sql - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) -add_compile_options(/utf-8) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) diff --git a/src/mission/581_ZhongHan_tiejiao_dingbu/CMakeLists.txt b/src/mission/581_ZhongHan_tiejiao_dingbu/CMakeLists.txt deleted file mode 100644 index d94ce25..0000000 --- a/src/mission/581_ZhongHan_tiejiao_dingbu/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv" "halcon" "handdleAI") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - ${PROJECT_ROOT_PATH}/src/core - ${PROJECT_ROOT_PATH}/src/core/handleAi - ${PROJECT_ROOT_PATH}/src/core/service - ${PROJECT_ROOT_PATH}/src/core/sql - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) -add_compile_options(/utf-8) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Gui - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) diff --git a/src/mission/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.cpp b/src/mission/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.cpp new file mode 100644 index 0000000..bc56747 --- /dev/null +++ b/src/mission/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.cpp @@ -0,0 +1,9 @@ +#include <602_RuanLianJie_dinggai.h> + +mission* createMission() { + return new _581_YuHan_hanqian(); +} + +void destroyMission(mission* _mission) { + delete _mission; +} \ No newline at end of file diff --git a/src/mission/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.h b/src/mission/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.h new file mode 100644 index 0000000..1282e7f --- /dev/null +++ b/src/mission/602_RuanLianJie_dinggai/602_RuanLianJie_dinggai.h @@ -0,0 +1,394 @@ +#include +#include +#pragma region 算法 +#include +#include +#include +using namespace HDevEngineCpp; +#pragma endregion +class RuanLianJie_dinnggai { +public: + handdleAI::pSegmentation* segDingwei1 = nullptr; + handdleAI::pSegmentation* seg = nullptr; + handdleAI::pClassification* cls = nullptr; + cv::Mat TP1IMG, TP2Paint; +}; +QByteArray keMaResult = "0"; +QByteArray okNgSaveText = "OK"; +cv::Rect getImageLocateRect(cv::Mat& src, handdleAI::pSegmentation* seg, double bounus = 0.1) { + cv::Mat tmpImg; + cv::resize(src, tmpImg, cv::Size(), bounus, bounus); + cv::Mat ouput = ~seg->Evaluate(tmpImg); + cv::Rect rect = findMaxAreaContour(ouput); + rect.x /= bounus; rect.y /= bounus; + rect.width /= bounus; rect.height /= bounus; + return rect; +} + +bool dinggaijiance(std::shared_ptr data, RuanLianJie_dinnggai* _detParams, sx_581_address address) { + try { +#if 0 + /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ + cv::Mat resultImage = img2D.clone(); + if (resultImage.channels() == 1) { + cv::cvtColor(resultImage, resultImage, cv::COLOR_GRAY2BGR); + } + QString okng_tag = "OK"; + cv::Mat seg_detectImage; + cv::resize(img2D, seg_detectImage, cv::Size(), 1, 1); + plcResult = "1"; + bool isNG = false; + if (DOGLIVE) { + std::vector>clsImgs; + bool isNG = handleAiProcess(seg_detectImage, resultImage, seg_jierFanZhe, cls_jierFanZhe, clsImgs); + for (int i = 0; i < clsImgs.size(); i++) { + addImgToSaveStruct(clsImgs[i].second, "0", getClsSaveFormat(SN, okng_tag, i, clsImgs[i].first)); + } + } + if (isNG == false)//OK + { + putTextHusky(resultImage, utf8_to_gbk("OK").c_str(), cv::Point(50, 50), cv::Scalar(0, 255, 0), 200); + okng_tag = "OK"; + } + else + { + putTextHusky(resultImage, utf8_to_gbk("NG").c_str(), cv::Point(50, 50), cv::Scalar(0, 0, 255), 200); + plcResult = "2"; + } + cv::resize(resultImage, resultImage, cv::Size(), 0.5, 0.5); + resMat.push_back(resultImage); + if (resMat.size() > 0) + { + addImgToSaveStruct(seg_detectImage, "0", getSegSaveFormat(SN, okng_tag));//存seg图 + addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, okng_tag));//存结果图 + } + addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, okng_tag));//存原图图 + + return true; + /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ +#else + if(address.triggerValue == 1) + data->oriImgs[0] = cv::imread("D://40CQ8B622000J0BF0B0050N5F_Camera2_0_01-24-31.bmp", - 1); + if (address.triggerValue == 2) + data->oriImgs[0] = cv::imread("D://40CQ8B622000J0BF0B0050N5F_Camera2_0_01-24-32.bmp", -1); + if (address.triggerValue == 3) + data->oriImgs[0] = cv::imread("D://40CQ8B622000J0BF0B0050N5F_Camera2_0_01-24-31.bmp", -1); + //存图数据加保存队列,加锁,避免数据访问冲突 + QByteArray plcResult = "2"; + double Resolution = 0.01424; + cv::Mat sourceImg; + data->oriImgs[0].copyTo(sourceImg); + cv::Mat Paint; + sourceImg.copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + if (address.triggerValue == 2) + { + HDevEngineCpp::HDevProcedure proc("_3_Cal_FBF_Distance");; + HDevEngineCpp::HDevProcedureCall procedureCall(proc); + sourceImg.copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, 8); + HObject in_Image = MatToHObject(sourceImg); + HalconCpp::HTuple in_Resolution(Resolution), in_FilePath("./halconFiles/"); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); + procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); + procedureCall.Execute();//执行halcon程序 + HalconCpp::HTuple out_LinePoint, out_Circle, out_Flag, out_Distance,out_NgTails; + out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量 + out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");//获取输出控制类变量 + out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 + out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//获取输出控制类变量 + out_NgTails = procedureCall.GetOutputCtrlParamTuple("out_NgTails");//获取输出控制类变量 + keMaResult = "1"; + if (out_Flag.D() == 1) + { + int crossLineLength = 50; + TextRendererZH textPainter(Paint.cols, Paint.rows, 140); + for (int i = 0; i < out_LinePoint.Length() / 4; i++) + { + cv::line(Paint, cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4].D()), + cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()), + cv::Scalar(0, 255, 0), 10); + } + double distance = out_Distance[0].D(); + distance -= out_Circle[2].D() * Resolution;//CHEAT!!! + circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 5); + { + //data1 = QByteArray::number(distance); + std::string text = "二维码与防爆阀相对位置:" + std::to_string(distance); + text = text.substr(0, text.find(".") + 4) + "mm"; + + textPainter.putText(Paint, + (text).c_str(), + cv::Point(100, 500), cv::Scalar(0, 255, 0)); + } + double distance2 = out_Distance[1].D();//二维码的宽度值 + { + QByteArray::number(distance2); + std::string text = "二维码与防爆阀间距:" + std::to_string(distance2); + text = text.substr(0, text.find(".") + 4) + "mm"; + textPainter.putText(Paint, + (text).c_str(), + cv::Point(100, 650), cv::Scalar(0, 255, 0)); + } + double distance3 = out_Distance[2].D();//二维码下方字符串的宽度值 + { + std::string text = "二维码的宽度值:" + std::to_string(distance3); + text = text.substr(0, text.find(".") + 4) + "mm"; + textPainter.putText(Paint, + (text).c_str(), + cv::Point(100, 800), cv::Scalar(0, 255, 0)); + } + //double distance4 = out_Distance[3].D();//二维码左侧字符串的高度值 + //{ + // std::string text = "二维码左字符水平宽度:" + std::to_string(distance4); + // text = text.substr(0, text.find(".") + 4) + "mm"; + // putTextHusky(Paint, + // utf8_to_gbk(text).c_str(), + // cv::Point(100, 950), cv::Scalar(0, 255, 0), 140); + //} + //double distance5 = out_Distance[4].D();//二维码右侧到电芯右侧边缘距离 + //{ + // data2 = QByteArray::number(distance2); + // std::string text = "右间距:" + std::to_string(distance5); + // text = text.substr(0, text.find(".") + 4) + "mm"; + // putTextHusky(Paint, + // utf8_to_gbk(text).c_str(), + // cv::Point(50, 350), cv::Scalar(0, 255, 0), 280); + //} + if (distance > 11.9 || distance < 5.9) + { + std::string text = "上间距NG"; + TextRendererZH textPainter1(Paint.cols, Paint.rows, 280); + textPainter1.putText(Paint, + (text).c_str(), + cv::Point(50, 50), cv::Scalar(0, 0, 255)); + keMaResult = "2"; + okNgSaveText = "NG"; + } + /* if (distance5 > 33.2 || distance5 < 27.2) + { + std::string text = "右间距NG"; + putTextHusky(Paint, + utf8_to_gbk(text).c_str(), + cv::Point(2500, 350), cv::Scalar(0, 0, 255), 280); + keMaResult = "2"; + okNgSaveText = "NG"; + }*/ + + } + else + { + qDebug() << __FUNCTION__ << "line:" << __LINE__ << "二维码error"; + TextRendererZH textPainter2(Paint.cols, Paint.rows, 500); + auto ngDetail = gbkToUtf8(out_NgTails.ToString().Text()); + textPainter2.putText(Paint, ngDetail, cv::Point(0, 50), cv::Scalar(0, 0, 255)); + keMaResult = "2"; + okNgSaveText = "NG"; + } + //#endif + Paint.copyTo(_detParams->TP2Paint); + } + + else if (address.triggerValue == 1) + { + okNgSaveText = "OK"; + keMaResult = "1"; + sourceImg.copyTo(_detParams->TP1IMG); + } + + else if (address.triggerValue == 3) + { + Paint = cv::Mat(_detParams->TP1IMG.rows, _detParams->TP1IMG.cols * 3, CV_8UC1); + _detParams->TP1IMG.copyTo(Paint(cv::Rect(0, 0, _detParams->TP1IMG.cols, _detParams->TP1IMG.rows))); + sourceImg.copyTo(Paint(cv::Rect(_detParams->TP1IMG.cols, 0, _detParams->TP1IMG.cols, _detParams->TP1IMG.rows))); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, 8); + _detParams->TP2Paint.copyTo(Paint(cv::Rect(_detParams->TP1IMG.cols * 2, 0, _detParams->TP1IMG.cols, _detParams->TP1IMG.rows))); + cv::Mat PaintPart2 = Paint(cv::Rect(_detParams->TP1IMG.cols, 0, _detParams->TP1IMG.cols, _detParams->TP1IMG.rows)); + HDevEngineCpp::HDevProcedure proc("_3_Cal_JZ_Distance");; + HDevEngineCpp::HDevProcedureCall procedureCall(proc); + HObject in_Image1, in_Image2; + in_Image1 = MatToHObject(_detParams->TP1IMG); + in_Image2 = MatToHObject(sourceImg); + HalconCpp::HTuple in_FilePath(" "), in_Resolution(Resolution); + procedureCall.SetInputIconicParamObject("in_Image1", in_Image1); + procedureCall.SetInputIconicParamObject("in_Image2", in_Image2); + procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution); + procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); + procedureCall.Execute();//执行halcon程序 + HalconCpp::HTuple out_Edgedistance, out_Distance, out_LinePoint, out_Flag; + out_Edgedistance = procedureCall.GetOutputCtrlParamTuple("out_Edgedistance");//获取输出控制类变量 + out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//获取输出控制类变量 + out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量 + out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 + if (out_Flag.D() == 1) + { + for (int i = 0; i < 4; i++) + { + cv::line(Paint, cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4].D()), + cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()), + cv::Scalar(0, 255, 0), 15); + } + for (int i = 4; i < 8; i++) + { + cv::line(PaintPart2, cv::Point(out_LinePoint[i * 4 + 1].D(), out_LinePoint[i * 4].D()), + cv::Point(out_LinePoint[i * 4 + 3].D(), out_LinePoint[i * 4 + 2].D()), + cv::Scalar(0, 255, 0), 15); + } + double Distance = out_Distance.D(); + TextRendererZH textPainter(Paint.cols, Paint.rows, 280); + //Paint + { + std::string text = "垂直间距:" + std::to_string(out_Edgedistance[0].D()); + //data3 = QByteArray::number(out_Edgedistance[0].D()); + text = text.substr(0, text.find(".") + 4) + "mm"; + textPainter.putText(Paint, + (text).c_str(), + cv::Point(50, 50), cv::Scalar(0, 255, 0)); + } + { + //data4 = QByteArray::number(out_Edgedistance[1].D()); + std::string text = "水平间距:" + std::to_string(out_Edgedistance[1].D()); + text = text.substr(0, text.find(".") + 4) + "mm"; + textPainter.putText(Paint, + (text).c_str(), + cv::Point(50, 300), cv::Scalar(0, 255, 0)); + } + { + //data5 = QByteArray::number(out_Edgedistance[2].D()); + std::string text = "垂直间距:" + std::to_string(out_Edgedistance[2].D()); + text = text.substr(0, text.find(".") + 4) + "mm"; + textPainter.putText(PaintPart2, + (text).c_str(), + cv::Point(50, 50), cv::Scalar(0, 255, 0)); + } + { + //data6 = QByteArray::number(out_Edgedistance[3].D()); + std::string text = "水平间距:" + std::to_string(out_Edgedistance[3].D()); + text = text.substr(0, text.find(".") + 4) + "mm"; + textPainter.putText(PaintPart2, + (text).c_str(), + cv::Point(50, 300), cv::Scalar(0, 255, 0)); + } + /*{ + std::string text = "极柱间距:" + std::to_string(Distance); + text = text.substr(0, text.find(".") + 4) + "mm"; + putTextHusky(Paint, + utf8_to_gbk(text).c_str(), + cv::Point(50, 550), cv::Scalar(0, 0, 255), 280); + putTextHusky(PaintPart2, + utf8_to_gbk(text).c_str(), + cv::Point(50, 550), cv::Scalar(0, 0, 255), 280); + }*/ + + } + else + { + TextRendererZH textPainter1(Paint.cols, Paint.rows, 500); + textPainter1.putText(Paint, "NG,vv", cv::Point(0, 50), cv::Scalar(0, 0, 255)); + okNgSaveText = "NG"; + } + plcResult = keMaResult; + plcResult = "1";//强制OK + data->resultImgs.push_back(Paint); + return true; + } + sourceImg.release(); + plcResult = "1"; + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + return true; +#endif + } + CATCH_EXCEPTIONS + + qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + textPainter.putText(Paint, "NG", cv::Point(0, 0), cv::Scalar(0, 255, 0)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->resultImgs.push_back(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + return true; +} +bool majiarerong(std::shared_ptr data, RuanLianJie_dinnggai * _detParams, sx_581_address address) { + try { +#if 0 + +#else + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + textPainter.putText(Paint, "NG", cv::Point(0, 0), cv::Scalar(0, 255, 0)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->resultImgs.push_back(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr) + "_1");//铜热熔面积 + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_1");//铜热熔点数 + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 4)+ "_1");//铝热熔面积 + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_1");//铝热熔点数 + return true; +#endif + } + CATCH_EXCEPTIONS + + qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + textPainter.putText(Paint, "NG", cv::Point(0, 0), cv::Scalar(0, 255, 0)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->resultImgs.push_back(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr) + "_1");//铜热熔面积 + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_1");//铜热熔点数 + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_1");//铝热熔面积 + data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_1");//铝热熔点数 + return true; +} + +class _581_YuHan_hanqian : public mission { +public: + _581_SX_Single_triggerTemplate< RuanLianJie_dinnggai> dibu_1; + _581_SX_Single_triggerTemplate< RuanLianJie_dinnggai> dibu_2; + _581_SX_Single_triggerTemplate< RuanLianJie_dinnggai> dibu_3; + _581_SX_Single_triggerTemplate< RuanLianJie_dinnggai> dibu_4; + + + + RuanLianJie_dinnggai DetParams1; + RuanLianJie_dinnggai DetParams2; + RuanLianJie_dinnggai DetParams3; + RuanLianJie_dinnggai DetParams4; + + + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); + + } + bool initCustom() { +#pragma region 注册触发器回调 + dibu_1.init("Camera1", "顶盖检测刻码后-相机1", { { 5000, 1,{5010},"5002","5004",-1},{ 5000, 2,{5010},"5002","5004",-1},{ 5000, 3,{5010},"5002","5004",5030} }, 1, &DetParams1, _serviceManager, bridge, dinggaijiance, "防爆阀CCD"); + dibu_2.init("Camera2", "顶盖检测刻码后-相机2", { { 5100, 1,{5110},"5102","5104",-1},{ 5100, 2,{5110},"5102","5104",-1},{ 5100, 3,{5110},"5102","5104",5130} }, 1, &DetParams2, _serviceManager, bridge, dinggaijiance, "防爆阀CCD"); + dibu_3.init("Camera3", "马甲热熔检测-相机1", { { 5200, 1,{5210},"5202","5204",5230 }}, 1, &DetParams3, _serviceManager, bridge, majiarerong, "马甲热熔CCD"); + dibu_4.init("Camera4", "马甲热熔检测-相机2", { { 5300, 1,{5310},"5302","5304",5330} }, 1, &DetParams4, _serviceManager, bridge, majiarerong, "马甲热熔CCD"); +#pragma endregion + return true; + } +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/581-BaoMo-Cam1234/CMakeLists.txt b/src/mission/602_RuanLianJie_dinggai/CMakeLists.txt similarity index 97% rename from src/mission/581-BaoMo-Cam1234/CMakeLists.txt rename to src/mission/602_RuanLianJie_dinggai/CMakeLists.txt index d94ce25..29a2ad1 100644 --- a/src/mission/581-BaoMo-Cam1234/CMakeLists.txt +++ b/src/mission/602_RuanLianJie_dinggai/CMakeLists.txt @@ -47,7 +47,7 @@ add_library(${CURRENT_FOLDER} SHARED ${HEAD_FILES} ${SRC_FILES} ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h + ${PROJECT_ROOT_PATH}/include/interface.h ) diff --git a/src/mission/581-BaoMo-Cam1213/581-BaoMo.cpp b/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D.cpp similarity index 61% rename from src/mission/581-BaoMo-Cam1213/581-BaoMo.cpp rename to src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D.cpp index 0ee499e..3308a80 100644 --- a/src/mission/581-BaoMo-Cam1213/581-BaoMo.cpp +++ b/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D.cpp @@ -1,7 +1,7 @@ -#include <581-BaoMo.h> +#include <952_15_Q_2D3D.h> mission* createMission() { - return new _581_BaoMo(); + return new _952_15_Q_2D3D(); } void destroyMission(mission* _mission) { delete _mission; diff --git a/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D.h b/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D.h new file mode 100644 index 0000000..df223f1 --- /dev/null +++ b/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D.h @@ -0,0 +1,355 @@ +#include +#include +#include +#include +#include +#include +#include + +struct _952_15_Q_2D3D_1_summaryData +{ + QString _2D_P_Result = "-1"; + QString _2D_N_Result = "-1"; + QString _3D_1_Result = "-1"; +}; +class _952_address { +public: + int triggerAddr = -1; + int triggerValue = -1; + std::vector snAddr; + QByteArray completeAddr; + QByteArray resultAddr = "-1"; + int valueOffsetAddr = -1; +}; + +class _2dP_detParams { +public: + handdleAI::pSegmentation* SEG_2D_HuaShang_P; + handdleAI::pSegmentation* SEG_2D_ZangWu_P; + handdleAI::pClassification* CLS_2D_HuaShang_P; + handdleAI::pClassification* CLS_2D_ZangWu_P; +}; +class _2dN_detParams { +public: +}; +class _3d_detParams { +public: + +}; +#pragma region 算法 + +#include +#include +#include +#include + +static bool _952_15_Q_2D_P_ALGO_HuaShangAI(std::shared_ptr data, QMutex* mutex, cv::Mat& img, _2dP_detParams* _handleAiModelManager, cv::Mat& Paint, QMutex& paintMutex) { + cv::Mat segImg = ~_handleAiModelManager->SEG_2D_HuaShang_P->Evaluate(img); + std::vector> contours; + cv::findContours(segImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); + bool isNg = false; + + for (int i = 0; i < contours.size(); i++) { + cv::Rect rect = cv::boundingRect(contours[i]); + if (rect.width < 50 || rect.height < 50) continue; // 过滤掉小轮廓 + auto clsImgs = cutImg2ClsVec(rect, img); + bool clsIsNg = false; + for (auto& clsImg : clsImgs) { + QMutexLocker locker(mutex); + data->clsOriginImgs.push_back(std::make_pair("划伤", clsImg)); + int clsResult = _handleAiModelManager->CLS_2D_HuaShang_P->Evaluate(clsImg); + if (clsResult == 1) { // 假设1表示NG + clsIsNg = true; + break; + } + } + cv::Scalar color = cv::Scalar(0, 255, 0); + if (clsIsNg == true) { + color = cv::Scalar(0, 0, 255); + isNg = true; + QMutexLocker locker(&paintMutex); + cv::drawContours(Paint, contours, i, color, 2); + } + else { + QMutexLocker locker(&paintMutex); + cv::rectangle(Paint, rect, color, 3); + } + putTextZH(Paint, "划伤", cv::Point(rect.x + 10, rect.y - 20), 25, color); + } + return isNg; +} +static bool _952_15_Q_2D_P_ALGO_ZangWuAI(std::shared_ptr data, QMutex* mutex, cv::Mat& img, _2dP_detParams* _handleAiModelManager, cv::Mat& Paint, QMutex& paintMutex) { + cv::Mat segImg = ~_handleAiModelManager->SEG_2D_ZangWu_P->Evaluate(img); + std::vector> contours; + cv::findContours(segImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); + bool isNg = false; + + for (int i = 0; i < contours.size(); i++) { + cv::Rect rect = cv::boundingRect(contours[i]); + if (rect.width < 50 || rect.height < 50) continue; // 过滤掉小轮廓 + auto clsImgs = cutImg2ClsVec(rect, img); + bool clsIsNg = false; + for (auto& clsImg : clsImgs) { + { + QMutexLocker locker(mutex); + data->clsOriginImgs.push_back(std::make_pair("脏污", clsImg)); + } + int clsResult = _handleAiModelManager->CLS_2D_ZangWu_P->Evaluate(clsImg); + if (clsResult == 1) { // 假设1表示NG + clsIsNg = true; + break; + } + } + cv::Scalar color = cv::Scalar(0, 255, 0); + if (clsIsNg == true) { + color = cv::Scalar(0, 0, 255); + isNg = true; + QMutexLocker locker(&paintMutex); + cv::drawContours(Paint, contours, i, color, 2); + } + else { + QMutexLocker locker(&paintMutex); + cv::rectangle(Paint, rect, color, 3); + } + putTextZH(Paint, "脏污", cv::Point(rect.x + 10, rect.y - 20), 25, color); + + } + return isNg; +} + +static bool _952_15_Q_2D_P_ALGO(std::shared_ptr data, _2dP_detParams* _handleAiModelManager, _952_address address) { + //获取模型 + + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 3) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + cv::Mat Paintx; + if (data->oriImgs[0].channels() == 1) + cv::cvtColor(data->oriImgs[0], Paintx, cv::COLOR_GRAY2BGR); + else + data->oriImgs[0].copyTo(Paintx); + TextRendererZH textPainter(Paintx.cols, Paintx.rows, 300); + textPainter.putText(Paintx, "OK", cv::Point(10, 10), cv::Scalar(0, 255, 0)); + data->resultImgs.push_back(Paintx); + return true; + + cv::Mat Paint; + cv::cvtColor(data->oriImgs[2], Paint, cv::COLOR_GRAY2BGR); + QMutex paintMutex; + QMutex mutex; + std::future futureHuaShang = std::async(std::launch::async, _952_15_Q_2D_P_ALGO_HuaShangAI, data, &mutex, data->oriImgs[1], _handleAiModelManager, std::ref(Paint), std::ref(paintMutex)); + std::future futureZangWu = std::async(std::launch::async, _952_15_Q_2D_P_ALGO_ZangWuAI, data, &mutex, data->oriImgs[2], _handleAiModelManager, std::ref(Paint), std::ref(paintMutex)); + + bool huaShangResult = futureHuaShang.get(); + if (huaShangResult) { + putTextZH(Paint, "划伤检测结果: NG", cv::Point(100, 100), 150, cv::Scalar(0, 0, 255)); + } + else { + putTextZH(Paint, "划伤检测结果: OK", cv::Point(100, 100), 150, cv::Scalar(0, 255, 0)); + } + + bool zangWuResult = futureZangWu.get(); + if (zangWuResult) { + putTextZH(Paint, "脏污检测结果: NG", cv::Point(100, 200), 150, cv::Scalar(0, 0, 255)); + } + else { + putTextZH(Paint, "脏污检测结果: OK", cv::Point(100, 200), 150, cv::Scalar(0, 255, 0)); + } + data->resultImgs.push_back(Paint); + data->aiDetOK = huaShangResult || zangWuResult; // 如果任一检测结果为NG,则整体结果为NG + return true; +} +static bool _952_15_Q_2D_N_ALGO(std::shared_ptr data, _2dN_detParams* _handleAiModelManager, _952_address address) { + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + cv::Mat Paint; + if (data->oriImgs[0].channels() == 1) + cv::cvtColor(data->oriImgs[0], Paint, cv::COLOR_GRAY2BGR); + else + data->oriImgs[0].copyTo(Paint); + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + textPainter.putText(Paint, "OK", cv::Point(10, 10), cv::Scalar(0, 255, 0)); + data->resultImgs.push_back(Paint); + return true; +} +static bool _952_15_Q_3D_ALGO(std::shared_ptr data, _3d_detParams* _handleAiModelManager, _952_address address) { + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 2) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + cv::Mat Paint; + if (data->oriImgs[0].channels() == 1) + cv::cvtColor(data->oriImgs[0], Paint, cv::COLOR_GRAY2BGR); + else + data->oriImgs[0].copyTo(Paint); + putTextZH(Paint, "OK", cv::Point(100, 100), 150, cv::Scalar(0, 255, 0)); + data->resultImgs.push_back(Paint); + return true; +} +#pragma endregion + +class _952_15_Q_2D3D : public mission { +public: + _2dP_detParams __2dP_detParams; + _2dN_detParams __2dN_detParams; + _3d_detParams __3d_detParams; + detCallbackChain<_2dP_detParams, _952_address >* algo_2D_P; + detCallbackChain<_2dN_detParams, _952_address >* algo_2D_N; + detCallbackChain<_3d_detParams, _952_address >* algo_3D; + summaryData<_952_15_Q_2D3D_1_summaryData> _summaryData; + //8010 1 + bool Qian_2D_P_SecondTime = false; + void Qian_2D_P(QByteArray& byteArray) { + int snPos = _2dP_address.snAddr[0]; + _serviceManager->_triggerManager->writeShort(_2dP_address.triggerAddr + "_0");//清0 + std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); + std::shared_ptr data = + _serviceManager->_detDataManager->createDetData("Qian_2D_P", sn, 3, _2DCamera_P->config.oriSaveFormat); + _2DCamera_P->captureImage(data); + algo_2D_P->ansyncProcess(data, _2dP_address, ("D" + _2dP_address.completeAddr + "_1,1")); //处理算法 + data->resultImgShowSet.push_back(showImgPack("通道1-2D正极" + QString::number(Qian_2D_P_SecondTime + 1), "结果图")); + Qian_2D_P_SecondTime = !Qian_2D_P_SecondTime; + } + //8020 1 + bool Qian_2D_N_SecondTime = false; + void Qian_2D_N(QByteArray& byteArray) { + int snPos = _2dN_address.snAddr[0]; + _serviceManager->_triggerManager->writeShort(_2dN_address.triggerAddr + "_0");//清0 + std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); + std::shared_ptr data = + _serviceManager->_detDataManager->createDetData( + "Qian_2D_N", sn, 1, _2DCamera_N->config.oriSaveFormat); + _2DCamera_N->captureImage(data); + algo_2D_N->ansyncProcess(data, _2dN_address, ("D" + _2dN_address.completeAddr + "_1,1")); //处理算法 + data->resultImgShowSet.push_back(showImgPack("通道1-2D负极" + QString::number(Qian_2D_N_SecondTime + 1), "结果图")); + Qian_2D_N_SecondTime = !Qian_2D_N_SecondTime; + } + + //8030 1 + bool Qian_3D_1_SecondTime = false; + void Qian_3D_1(QByteArray& byteArray) { + int snPos = _3d_address.snAddr[0]; + _serviceManager->_triggerManager->writeShort(_3d_address.triggerAddr + "_0");//清0 + std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); + std::shared_ptr data = + _serviceManager->_detDataManager->createDetData( + "Qian_3D", sn, 2, _3DCamera_1->config.oriSaveFormat); + _3DCamera_1->captureImage(data); + algo_3D->ansyncProcess(data, _3d_address, ("D" + _3d_address.completeAddr + "_1,1")); //处理算法 + data->resultImgShowSet.push_back(showImgPack("通道1-3D" + QString::number(Qian_3D_1_SecondTime + 1), "结果图")); + Qian_3D_1_SecondTime = !Qian_3D_1_SecondTime; + + } + + //8040 1 Summary1 + void sumRequest1(int triggerPos ,QByteArray& byteArray) { + if (triggerPos == 8090) { + _serviceManager->_triggerManager->writeShort({ "D8040_0" ,"D8042_1","D8045_1","D8046_1","D8047_1","D8048_1" }); + std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, 8500, false, false, -1); + _952_15_Q_2D3D_1_summaryData* dataPtr = _summaryData.get(sn); + _serviceManager->_triggerManager->writeShort({ + "D6020_1", "D6021_1", "D6022_1", "D6023_1", "D6024_1", + "D6025_1", "D6026_1", "D6027_1", "D6028_1", "D6029_1", + "D6030_1", "D6031_1", "D6032_1", "D6033_1", "D6034_1", + "D6035_1", "D6036_1", "D6037_1", "D6038_1", "D6039_1" + }); + _summaryData.remove(sn); + } + else{ + _serviceManager->_triggerManager->writeShort({ "D8090_0" ,"D8092_1","D8095_1","D8096_1","D8097_1","D8098_1" }); + std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, 9000, false, false, -1); + _952_15_Q_2D3D_1_summaryData* dataPtr = _summaryData.get(sn); + _serviceManager->_triggerManager->writeShort({ + "D6120_1", "D6121_1", "D6122_1", "D6123_1", "D6124_1", + "D6125_1", "D6126_1", "D6127_1", "D6128_1", "D6129_1", + "D6130_1", "D6131_1", "D6132_1", "D6133_1", "D6134_1", + "D6135_1", "D6136_1", "D6137_1", "D6138_1", "D6139_1" + }); + _summaryData.remove(sn); + } + } + + bool initOnce = false; + void onConfigReloaded() { + if (initOnce == false) { + /*__2dP_detParams.SEG_2D_ZangWu_P = handdleAI::CreateSegObj("./handleaiModels/seg_zangWu_P_0708.BHD", 1, 0); + __2dP_detParams.SEG_2D_HuaShang_P = handdleAI::CreateSegObj("./handleaiModels/seg_huaShang_P_0708.BHD", 1, 0); + __2dP_detParams.CLS_2D_ZangWu_P = handdleAI::CreateClsObjV3("./handleaiModels/cls_zangWu_P_0708.BHD", 0, 1); + __2dP_detParams.CLS_2D_HuaShang_P = handdleAI::CreateClsObjV3("./handleaiModels/cls_huaShang_P_0708.BHD", 0, 1);*/ + initOnce = true; + } + } + + bool initCustom() { +#pragma region 注册触发器回调 + /*if (_serviceManager->_paramSyncManager->get(_serviceManager->_paramSyncManager->getGroup(1), "way", "IN").toString() == "IN") { + _2dP_address = { 8010 ,1,{8200} ,"8011" ,"-1", - 1}; + _2dN_address = { 8020 ,1,{8300} ,"8021" ,"-1", -1 }; + _3d_address = { 8030 ,1,{8400} ,"8031" ,"-1", -1 }; + summary_triggerPos = 8040; + } + else { + _2dP_address = { 8060 ,1,{8700} ,"8061" ,"-1", -1 }; + _2dN_address = { 8070 ,1,{8800} ,"8071" ,"-1", -1 }; + _3d_address = { 8080 ,1,{8900} ,"8081" ,"-1", -1 }; + summary_triggerPos = 8090; + }*/ + _serviceManager->_triggerManager->registerCallback(_2dP_address.triggerAddr, 1, [this](int triggerPos, int triggerValue, QByteArray& byteArray) {Qian_2D_P(byteArray); }, "2D_1拍照触发"); + _serviceManager->_triggerManager->registerCallback(_2dN_address.triggerAddr, 1, [this](int triggerPos, int triggerValue, QByteArray& byteArray) {Qian_2D_N(byteArray); }, "2D_2拍照触发"); + _serviceManager->_triggerManager->registerCallback(_3d_address.triggerAddr, 1, [this](int triggerPos, int triggerValue, QByteArray& byteArray) {Qian_3D_1(byteArray); }, "3D拍照触发"); + + _serviceManager->_triggerManager->registerCallback(summary_triggerPos, 1, [this](int triggerPos, int triggerValue, QByteArray& byteArray) {sumRequest1(triggerPos,byteArray); }, "结果获取触发"); +#pragma endregion +#pragma region 处理算法回调链 + algo_2D_P = new detCallbackChain<_2dP_detParams, _952_address>(_serviceManager, &__2dP_detParams, bridge); + algo_2D_P->registerProcessAlgoCallback(_952_15_Q_2D_P_ALGO); + + algo_2D_N = new detCallbackChain<_2dN_detParams, _952_address>(_serviceManager, &__2dN_detParams, bridge); + algo_2D_N->registerProcessAlgoCallback(_952_15_Q_2D_N_ALGO); + + algo_3D = new detCallbackChain<_3d_detParams, _952_address>(_serviceManager, &__3d_detParams, bridge); + algo_3D->registerProcessAlgoCallback(_952_15_Q_3D_ALGO); +#pragma endregion + _2DCamera_P = _serviceManager->_cameraManager->getCamera("Camera1");//获取相机 + _2DCamera_N = _serviceManager->_cameraManager->getCamera("Camera2");//获取相机 + _3DCamera_1 = _serviceManager->_cameraManager->getCamera("Camera3");//获取相机 + _serviceManager->_triggerManager->registerPlcValueViewer("通道1-2D正极", + { {"触发",_2dP_address.triggerAddr }, + {"反馈1", _2dP_address.completeAddr.toInt()}, + {"反馈2",_2dP_address.completeAddr.toInt()+1}}); + _serviceManager->_triggerManager->registerPlcValueViewer("通道1-2D负极", + { {"触发",_2dN_address.triggerAddr }, + {"反馈1", _2dN_address.completeAddr.toInt()}, + {"反馈2",_2dN_address.completeAddr.toInt() + 1} }); + _serviceManager->_triggerManager->registerPlcValueViewer("通道1-3D", + { {"触发",_3d_address.triggerAddr }, + {"反馈1", _3d_address.completeAddr.toInt()}, + {"反馈2",_3d_address.completeAddr.toInt() + 1} }); + return true; + } +private: + int summary_triggerPos = 8040; + _952_address _2dP_address, _2dN_address, _3d_address; + camera* _2DCamera_P = nullptr, * _2DCamera_N = nullptr, * _3DCamera_1 = nullptr; +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/581-BaoMo-Cam1234/581-BaoMo.cpp b/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D/952_15_Q_2D3D.cpp similarity index 59% rename from src/mission/581-BaoMo-Cam1234/581-BaoMo.cpp rename to src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D/952_15_Q_2D3D.cpp index a765ef4..3d4b053 100644 --- a/src/mission/581-BaoMo-Cam1234/581-BaoMo.cpp +++ b/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D/952_15_Q_2D3D.cpp @@ -1,6 +1,7 @@ -#include <581-BaoMo.h> +#include <952_15_Q_2D3D.h> + mission* createMission() { - return new _581_BaoMo(); + return new _952_15_Q_2D3D_1(); } void destroyMission(mission* _mission) { delete _mission; diff --git a/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D/952_15_Q_2D3D.h b/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D/952_15_Q_2D3D.h new file mode 100644 index 0000000..70c8441 --- /dev/null +++ b/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D/952_15_Q_2D3D.h @@ -0,0 +1,491 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct _952_15_Q_2D3D_1_summaryData +{ + QString _2D_P_Result = "-1"; + QString _2D_N_Result = "-1"; + QString _3D_1_Result = "-1"; +}; +class handleAIModels { +public: + handleAiModelSeg* SEG_2D_HuaShang_P; + handleAiModelSeg* SEG_2D_ZangWu_P; + handleAiModelCls* CLS_2D_HuaShang_P; + handleAiModelCls* CLS_2D_ZangWu_P; +}; +#pragma region 算法 + +#include +#include +#include +#include + +static bool _952_15_Q_2D_P_ALGO_HuaShangAI(cv::Mat& img, handleAIModels* _handleAiModelManager, cv::Mat& Paint, QMutex& paintMutex) { + cv::Mat segImg = ~_handleAiModelManager->SEG_2D_HuaShang_P->Evaluate(img); + std::vector> contours; + cv::findContours(segImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); + bool isNg = false; + + for (int i = 0; i < contours.size(); i++) { + cv::Rect rect = cv::boundingRect(contours[i]); + if (rect.width < 50 || rect.height < 50) continue; // 过滤掉小轮廓 + auto clsImgs = cutImg2ClsVec(rect, img); + bool clsIsNg = false; + for (auto& clsImg : clsImgs) { + int clsResult = _handleAiModelManager->CLS_2D_HuaShang_P->Evaluate(clsImg); + if (clsResult == 1) { // 假设1表示NG + clsIsNg = true; + break; + } + } + cv::Scalar color = cv::Scalar(0, 255, 0); + if (clsIsNg == true) { + color = cv::Scalar(0, 0, 255); + isNg = true; + QMutexLocker locker(&paintMutex); + cv::drawContours(Paint, contours, i, color, 2); + } + else { + QMutexLocker locker(&paintMutex); + cv::rectangle(Paint, rect, color, 3); + } + putTextZH(Paint, "划伤", cv::Point(rect.x + 10, rect.y - 20), 25, color); + } + return isNg; +} +static bool _952_15_Q_2D_P_ALGO_ZangWuAI(cv::Mat& img, handleAIModels* _handleAiModelManager, cv::Mat& Paint, QMutex& paintMutex) { + cv::Mat segImg = ~_handleAiModelManager->SEG_2D_ZangWu_P->Evaluate(img); + std::vector> contours; + cv::findContours(segImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); + bool isNg = false; + + for (int i = 0; i < contours.size(); i++) { + cv::Rect rect = cv::boundingRect(contours[i]); + if (rect.width < 50 || rect.height < 50) continue; // 过滤掉小轮廓 + auto clsImgs = cutImg2ClsVec(rect, img); + bool clsIsNg = false; + for (auto& clsImg : clsImgs) { + int clsResult = _handleAiModelManager->CLS_2D_ZangWu_P->Evaluate(clsImg); + if (clsResult == 1) { // 假设1表示NG + clsIsNg = true; + break; + } + } + cv::Scalar color = cv::Scalar(0, 255, 0); + if (clsIsNg == true) { + color = cv::Scalar(0, 0, 255); + isNg = true; + QMutexLocker locker(&paintMutex); + cv::drawContours(Paint, contours, i, color, 2); + } + else { + QMutexLocker locker(&paintMutex); + cv::rectangle(Paint, rect, color, 3); + } + putTextZH(Paint, "脏污", cv::Point(rect.x + 10, rect.y - 20), 25, color); + + } + return isNg; +} + +static bool _952_15_Q_2D_P_ALGO(std::shared_ptr data, handleAIModels* _handleAiModelManager) { + //获取模型 + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 3) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + + cv::Mat Paint; + cv::cvtColor(data->oriImgs[2], Paint, cv::COLOR_GRAY2BGR); + data->resultImgs.push_back(Paint); + return true; + + QMutex paintMutex; + std::future futureHuaShang = std::async(std::launch::async, _952_15_Q_2D_P_ALGO_HuaShangAI, data->oriImgs[1], _handleAiModelManager, std::ref(Paint), std::ref(paintMutex)); + std::future futureZangWu = std::async(std::launch::async, _952_15_Q_2D_P_ALGO_ZangWuAI, data->oriImgs[2], _handleAiModelManager, std::ref(Paint), std::ref(paintMutex)); + + bool huaShangResult = futureHuaShang.get(); + if (huaShangResult) { + putTextZH(Paint, "划伤检测结果: NG", cv::Point(100, 100), 150, cv::Scalar(0, 0, 255)); + } + else { + putTextZH(Paint, "划伤检测结果: OK", cv::Point(100, 100), 150, cv::Scalar(0, 255, 0)); + } + + bool zangWuResult = futureZangWu.get(); + if (zangWuResult) { + putTextZH(Paint, "脏污检测结果: NG", cv::Point(100, 200), 150, cv::Scalar(0, 0, 255)); + } + else { + putTextZH(Paint, "脏污检测结果: OK", cv::Point(100, 200), 150, cv::Scalar(0, 255, 0)); + } + data->resultImgs.push_back(Paint); + data->aiDetOK = huaShangResult || zangWuResult; // 如果任一检测结果为NG,则整体结果为NG + return true; +} +static bool _952_15_Q_2D_N_ALGO(std::shared_ptr data, handleAIModels* _handleAiModelManager) { + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + cv::Mat Paint; + cv::cvtColor(data->oriImgs[0], Paint, cv::COLOR_GRAY2BGR); + putTextZH(Paint, "OK", cv::Point(100, 100), 150, cv::Scalar(0, 255, 0)); + data->resultImgs.push_back(Paint); + return true; +} +static bool _952_15_Q_3D_ALGO(std::shared_ptr data, handleAIModels* _handleAiModelManager) { + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 2) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + cv::Mat Paint; + if (data->oriImgs[0].channels() == 1) + cv::cvtColor(data->oriImgs[0], Paint, cv::COLOR_GRAY2BGR); + else + data->oriImgs[0].copyTo(Paint); + putTextZH(Paint, "OK", cv::Point(100, 100), 150, cv::Scalar(0, 255, 0)); + data->resultImgs.push_back(Paint); + return true; +} +#pragma endregion + +class _952_15_Q_2D3D_1 : public mission { +public: +#pragma region 由外部输入的参数 + std::string _2D_P_Camera_Name; + std::string _2D_N_Camera_Name; + std::string _3D_1_Camera_Name; + + int _2D_P_triggerPos; + std::vector _2D_P_triggerReply; + int _2D_P_snPos; + QString _2D_P_viewName; + + int _2D_N_triggerPos; + std::vector _2D_N_triggerReply; + int _2D_N_snPos; + QString _2D_N_viewName; + + int _3D_triggerPos; + std::vector _3D_triggerReply; + int _3D_snPos; + QString _3D_P_viewName; + + int summary_triggerPos; +#pragma endregion + handleAIModels _handleAIModels; + std::shared_ptr< detCallbackChain> algo_2D_P; + std::shared_ptr< detCallbackChain> algo_2D_N; + std::shared_ptr< detCallbackChain> algo_3D; + summaryData<_952_15_Q_2D3D_1_summaryData> _summaryData; + bool init(ServiceManager* _serviceManagerIN, + nlohmann::json& _missionJson, + SQLiteDB* _SQLiteDB, qtFuncBridge* bridgeIn) { + bridge = bridgeIn; + _serviceManager = _serviceManagerIN; + prasingJson(_missionJson); +#pragma region 相机获取 + _2DCamera_P = _serviceManager->_cameraManager->getCamera(_2D_P_Camera_Name); + if (_2DCamera_P == nullptr) { + std::cout << "camera ->> " << _2D_P_Camera_Name << " not found" << std::endl; + return false; + } + + _2DCamera_N = _serviceManager->_cameraManager->getCamera(_2D_N_Camera_Name); + if (_2DCamera_N == nullptr) { + std::cout << "camera ->> " << _2D_N_Camera_Name << " not found" << std::endl; + return false; + } + + _3DCamera_1 = _serviceManager->_cameraManager->getCamera(_3D_1_Camera_Name); + if (_3DCamera_1 == nullptr) { + std::cout << "camera ->> " << _3D_1_Camera_Name << " not found" << std::endl; + return false; + } +#pragma endregion +#pragma region 注册触发器回调 + + _serviceManager->_triggerManager->registerCallback(_2D_P_triggerPos, 1, [this](QByteArray& byteArray) {Qian_2D_P(byteArray); }, "2D_1拍照触发"); + _serviceManager->_triggerManager->registerCallback(_2D_N_triggerPos, 1, [this](QByteArray& byteArray) {Qian_2D_N(byteArray); }, "2D_2拍照触发"); + _serviceManager->_triggerManager->registerCallback(_3D_triggerPos, 1, [this](QByteArray& byteArray) {Qian_3D_1(byteArray); }, "3D拍照触发"); + + _serviceManager->_triggerManager->registerCallback(summary_triggerPos, 1, [this](QByteArray& byteArray) {sumRequest1(byteArray); }, "结果获取触发"); +#pragma endregion +#pragma region 处理算法回调链 + algo_2D_P = std::make_shared>(_serviceManager->_imgSaveThreadManager, &_handleAIModels); + algo_2D_P->registerProcessAlgoCallback(_952_15_Q_2D_P_ALGO); + algo_2D_P->registerResultHandleCallback(([this](std::shared_ptr data) { + Qian_2D_P_ResultHandle(data); + })); + + algo_2D_N = std::make_shared>(_serviceManager->_imgSaveThreadManager, &_handleAIModels); + algo_2D_N->registerProcessAlgoCallback(_952_15_Q_2D_N_ALGO); + algo_2D_N->registerResultHandleCallback(([this](std::shared_ptr data) { + Qian_2D_P_ResultHandle(data); + })); + + algo_3D = std::make_shared>(_serviceManager->_imgSaveThreadManager, &_handleAIModels); + algo_3D->registerProcessAlgoCallback(_952_15_Q_3D_ALGO); + algo_3D->registerResultHandleCallback(([this](std::shared_ptr data) { + Qian_2D_P_ResultHandle(data); + })); +#pragma endregion + + _handleAIModels.SEG_2D_HuaShang_P = _serviceManagerIN->_handleAiModelManager->getSegModel("SEG_2D_HuaShang_P"); + _handleAIModels.SEG_2D_ZangWu_P = _serviceManagerIN->_handleAiModelManager->getSegModel("SEG_2D_ZangWu_P"); + _handleAIModels.CLS_2D_HuaShang_P = _serviceManagerIN->_handleAiModelManager->getClsModel("CLS_2D_HuaShang_P"); + _handleAIModels.CLS_2D_ZangWu_P = _serviceManagerIN->_handleAiModelManager->getClsModel("CLS_2D_ZangWu_P"); + //HDevEngineCpp::HDevEngine myEngine; + //myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_952.hdpl"); + return true; + } + void prasingJson(nlohmann::json& _missionJson) { + try { + _2D_P_Camera_Name = _missionJson["_2D_P_Camera_Name"].get(); + _2D_N_Camera_Name = _missionJson["_2D_N_Camera_Name"].get(); + _3D_1_Camera_Name = _missionJson["_3D_1_Camera_Name"].get(); + _2D_P_triggerPos = _missionJson["_2D_P_triggerPos"].get(); + _2D_P_triggerReply = _missionJson["_2D_P_triggerReply"].get>(); + _2D_P_snPos = _missionJson["_2D_P_snPos"].get(); + _2D_P_viewName = QString::fromStdString(_missionJson["_2D_P_viewName"].get()); + _2D_N_triggerPos = _missionJson["_2D_N_triggerPos"].get(); + _2D_N_triggerReply = _missionJson["_2D_N_triggerReply"].get>(); + _2D_N_snPos = _missionJson["_2D_N_snPos"].get(); + _2D_N_viewName = QString::fromStdString(_missionJson["_2D_N_viewName"].get()); + _3D_triggerPos = _missionJson["_3D_triggerPos"].get(); + _3D_triggerReply = _missionJson["_3D_triggerReply"].get>(); + _3D_snPos = _missionJson["_3D_snPos"].get(); + _3D_P_viewName = QString::fromStdString(_missionJson["_3D_P_viewName"].get()); + summary_triggerPos = _missionJson["summary_triggerPos"].get(); + } + catch (const nlohmann::json::out_of_range& e) { + std::cerr << "JSON out-of-range error: " << e.what() << std::endl; + } + catch (const nlohmann::json::type_error& e) { + std::cerr << "JSON type error: " << e.what() << std::endl; + } + catch (const nlohmann::json::exception& e) { + std::cerr << "JSON general exception: " << e.what() << std::endl; + } + + + } + //8010 1 + bool Qian_2D_P_SecondTime = false; + void Qian_2D_P(QByteArray& byteArray) { + int snPos = _2D_P_snPos; + _serviceManager->_triggerManager->writeShort(_2D_P_triggerReply); + std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); + std::shared_ptr data = + _serviceManager->_detDataManager->createDetData("Qian_2D_P", sn, 3, _2DCamera_P->config.oriSaveFormat); + _2DCamera_P->captureImage(data); + algo_2D_P->ansyncProcess(data); //处理算法 + /*data->oriImgs.push_back(cv::imread("I:\\952Code\\CODES\\7.07\\7.07\\zj\\zw\\A2250707-100400132132177\\A2250707-100400132132177Qian_2D_P_10-02-06-93_Count0.bmp", -1)); + data->oriImgs.push_back(cv::imread("I:\\952Code\\CODES\\7.07\\7.07\\zj\\zw\\A2250707-100400132132177\\A2250707-100400132132177Qian_2D_P_10-02-06-94_Count1.bmp", -1)); + data->oriImgs.push_back(cv::imread("I:\\952Code\\CODES\\7.07\\7.07\\zj\\zw\\A2250707-100400132132177\\A2250707-100400132132177Qian_2D_P_10-02-06-94_Count2.bmp", -1));*/ + + qDebug() << "[ Station 10 ] " << QString::fromUtf8("_2DCamera_P 检测开始 uuid :") << data->uuid << "SN" << QString::fromStdString(sn);; + std::cout << "通道1 SN:" << sn << "检测开始" << std::endl; + data->resultImgShowSet.push_back(new showImgPack(_2D_P_viewName + QString::number(Qian_2D_P_SecondTime + 1), "结果图")); + Qian_2D_P_SecondTime = !Qian_2D_P_SecondTime; + } + void Qian_2D_P_ResultHandle(std::shared_ptr data) { + //发送图片 + if (data->resultImgs.size() > 0) { + for (int i = 0; i < data->resultImgs.size() && i < data->resultImgShowSet.size(); i++) { + showImgPack* pack = data->resultImgShowSet[min(i, (int)data->resultImgShowSet.size() - 1)]; + QPixmap pixmap = cvMatToQPixMap(data->resultImgs[i]); + pack->img = pixmap; + emit bridge->displayWidget_sendImg(pack); + pixmap = QPixmap(); + } + } + //结果数据保存 + if (data->resultData.size() > 0) { + std::string sn = data->SNcode; + try { + _952_15_Q_2D3D_1_summaryData* dataPtr = _summaryData.get(sn); + // dataPtr->LT_Distance = data->resultData["LT_Distance"].toString(); + //dataPtr->RT_Distance = data->resultData["RT_Distance"].toString(); + // dataPtr->LD_Distance = data->resultData["LD_Distance"].toString(); + // dataPtr->RD_Distance = data->resultData["RD_Distance"].toString(); + // dataPtr->L_Duiqidu = data->resultData["L_Duiqidu"].toString(); + // dataPtr->R_Duiqidu = data->resultData["R_Duiqidu"].toString(); + + // if (data->cameraKeyName == "2.5D-H-1") { + // emit bridge->summaryData_addData("后段1-左上留白", data->resultData["LT_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段1-右上留白", data->resultData["RT_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段1-左下留白", data->resultData["LD_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段1-右下留白", data->resultData["RD_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段1-左对齐度", data->resultData["L_Duiqidu"].toDouble()); + // emit bridge->summaryData_addData("后段1-右对齐度", data->resultData["R_Duiqidu"].toDouble()); + // } + // else{ + // emit bridge->summaryData_addData("后段2-左上留白", data->resultData["LT_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段2-右上留白", data->resultData["RT_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段2-左下留白", data->resultData["LD_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段2-右下留白", data->resultData["RD_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段2-左对齐度", data->resultData["L_Duiqidu"].toDouble()); + // emit bridge->summaryData_addData("后段2-右对齐度", data->resultData["R_Duiqidu"].toDouble()); + // + // } + + } + catch (...) { + qDebug() << "[ Station 10 ] " << QString::fromUtf8("后段检测结果数据异常 SN:") << QString::fromStdString(data->SNcode); + } + } + else { + qDebug() << "[ Station 10 ] " << QString::fromUtf8("后段检测结果数据为空 SN:") << QString::fromStdString(data->SNcode); + } + std::cout << "SN:" << data->SNcode << "检测结束 结果获取完成" << std::endl; + } + //8020 1 + bool Qian_2D_N_SecondTime = false; + void Qian_2D_N(QByteArray& byteArray) { + int snPos = _2D_N_snPos; + _serviceManager->_triggerManager->writeShort(_2D_N_triggerReply); + std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); + std::shared_ptr data = + _serviceManager->_detDataManager->createDetData( + "Qian_2D_N", sn, 1, _2DCamera_N->config.oriSaveFormat); + _2DCamera_N->captureImage(data); + algo_2D_N->ansyncProcess(data); //处理算法 + qDebug() << "[ Station 10 ] " << QString::fromUtf8("_2DCamera_P 检测开始 uuid :") << data->uuid << "SN" << QString::fromStdString(sn);; + std::cout << "通道1 SN:" << sn << "检测开始" << std::endl; + data->resultImgShowSet.push_back(new showImgPack(_2D_N_viewName + QString::number(Qian_2D_N_SecondTime + 1), "结果图")); + Qian_2D_N_SecondTime = !Qian_2D_N_SecondTime; + } + + //8030 1 + bool Qian_3D_1_SecondTime = false; + void Qian_3D_1(QByteArray& byteArray) { + int snPos = _3D_snPos; + _serviceManager->_triggerManager->writeShort(_3D_triggerReply); + std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); + std::shared_ptr data = + _serviceManager->_detDataManager->createDetData( + "Qian_3D", sn, 2, _3DCamera_1->config.oriSaveFormat); + _3DCamera_1->captureImage(data); + algo_3D->ansyncProcess(data); //处理算法 + qDebug() << "[ Station 10 ] " << QString::fromUtf8("_2DCamera_P 检测开始 uuid :") << data->uuid << "SN" << QString::fromStdString(sn);; + std::cout << "通道1 SN:" << sn << "检测开始" << std::endl; + data->resultImgShowSet.push_back(new showImgPack(_3D_P_viewName + QString::number(Qian_3D_1_SecondTime + 1), "结果图")); + Qian_3D_1_SecondTime = !Qian_3D_1_SecondTime; + + } + + void HouDuan12ResultHandle(std::shared_ptr data) { + //发送图片 + if (data->resultImgs.size() > 0) { + for (int i = 0; i < data->resultImgs.size() && i < data->resultImgShowSet.size(); i++) { + showImgPack* pack = data->resultImgShowSet[min(i, (int)data->resultImgShowSet.size() - 1)]; + QPixmap pixmap = cvMatToQPixMap(data->resultImgs[i]); + pack->img = pixmap; + emit bridge->displayWidget_sendImg(pack); + pixmap = QPixmap(); + } + } + //结果数据保存 + if (data->resultData.size() > 0) { + std::string sn = data->SNcode; + try { + _952_15_Q_2D3D_1_summaryData* dataPtr = _summaryData.get(sn); + // dataPtr->LT_Distance = data->resultData["LT_Distance"].toString(); + //dataPtr->RT_Distance = data->resultData["RT_Distance"].toString(); + // dataPtr->LD_Distance = data->resultData["LD_Distance"].toString(); + // dataPtr->RD_Distance = data->resultData["RD_Distance"].toString(); + // dataPtr->L_Duiqidu = data->resultData["L_Duiqidu"].toString(); + // dataPtr->R_Duiqidu = data->resultData["R_Duiqidu"].toString(); + + // if (data->cameraKeyName == "2.5D-H-1") { + // emit bridge->summaryData_addData("后段1-左上留白", data->resultData["LT_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段1-右上留白", data->resultData["RT_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段1-左下留白", data->resultData["LD_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段1-右下留白", data->resultData["RD_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段1-左对齐度", data->resultData["L_Duiqidu"].toDouble()); + // emit bridge->summaryData_addData("后段1-右对齐度", data->resultData["R_Duiqidu"].toDouble()); + // } + // else{ + // emit bridge->summaryData_addData("后段2-左上留白", data->resultData["LT_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段2-右上留白", data->resultData["RT_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段2-左下留白", data->resultData["LD_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段2-右下留白", data->resultData["RD_Distance"].toDouble()); + // emit bridge->summaryData_addData("后段2-左对齐度", data->resultData["L_Duiqidu"].toDouble()); + // emit bridge->summaryData_addData("后段2-右对齐度", data->resultData["R_Duiqidu"].toDouble()); + // + // } + + } + catch (...) { + qDebug() << "[ Station 10 ] " << QString::fromUtf8("后段检测结果数据异常 SN:") << QString::fromStdString(data->SNcode); + } + } + else { + qDebug() << "[ Station 10 ] " << QString::fromUtf8("后段检测结果数据为空 SN:") << QString::fromStdString(data->SNcode); + } + std::cout << "SN:" << data->SNcode << "检测结束 结果获取完成" << std::endl; + } + + //8040 1 Summary1 + void sumRequest1(QByteArray& byteArray) { + _serviceManager->_triggerManager->writeShort({ "D8040_0" ,"D9402_1","D9404_1" }); + int snPos = summary_triggerPos; + std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); + _952_15_Q_2D3D_1_summaryData* dataPtr = _summaryData.get(sn); + _serviceManager->_triggerManager->writeShort({ + "D6020_1", "D6021_1", "D6022_1", "D6023_1", "D6024_1", + "D6025_1", "D6026_1", "D6027_1", "D6028_1", "D6029_1", + "D6030_1", "D6031_1", "D6032_1", "D6033_1", "D6034_1", + "D6035_1", "D6036_1", "D6037_1", "D6038_1", "D6039_1" + }); + + _serviceManager->_triggerManager->sendFinsMsg("write_float_D8046_" + dataPtr->_2D_P_Result);//右上留白 + _serviceManager->_triggerManager->sendFinsMsg("write_float_D8047_" + dataPtr->_2D_N_Result);//右下留白 + _serviceManager->_triggerManager->sendFinsMsg("write_float_D8048_" + dataPtr->_3D_1_Result);//右对其度 + + std::cout << "通道1 SN:" << sn << " 发送结果" << std::endl;//:\n左留白->" << dataPtr->leftLiuBai.toStdString() << "\n右留白->" << dataPtr->rightLiuBai.toStdString() << "\n对其度->" << dataPtr->duiqidu.toStdString()< data, handleAiModelManager* _handleAiModelManager) { + cv::Mat testImg; + if (data->oriImgs[0].channels() == 1) + cv::cvtColor(data->oriImgs[0], testImg, cv::COLOR_GRAY2BGR); + cv::putText(testImg, "result test", cv::Point(200, 200), + 1, 10, cv::Scalar(0, 255, 0), 4); + data->resultImgs.push_back(testImg); + return false; + } + +private: + + camera* _2DCamera_P = nullptr, * _2DCamera_N = nullptr, * _3DCamera_1 = nullptr; + qtFuncBridge* bridge; + ServiceManager* _serviceManager = nullptr; +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/581_YuHan_hanhou/CMakeLists.txt b/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D/CMakeLists.txt similarity index 97% rename from src/mission/581_YuHan_hanhou/CMakeLists.txt rename to src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D/CMakeLists.txt index 26347b4..76bbff3 100644 --- a/src/mission/581_YuHan_hanhou/CMakeLists.txt +++ b/src/mission/952/952_15_Q_2D3D/952_15_Q_2D3D/CMakeLists.txt @@ -15,7 +15,7 @@ message(" ENV_TARGET : " ${ENV_TARGET} ) include_directories( ${PROJECT_ROOT_PATH}/src/core ${PROJECT_ROOT_PATH}/src/core/handleAi - ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/back ${PROJECT_ROOT_PATH}/src/core/sql ${ENV_INCLUDE} ) diff --git a/src/mission/581_ZhongHan_dibutiejiao/CMakeLists.txt b/src/mission/952/952_15_Q_2D3D/CMakeLists.txt similarity index 97% rename from src/mission/581_ZhongHan_dibutiejiao/CMakeLists.txt rename to src/mission/952/952_15_Q_2D3D/CMakeLists.txt index d94ce25..29a2ad1 100644 --- a/src/mission/581_ZhongHan_dibutiejiao/CMakeLists.txt +++ b/src/mission/952/952_15_Q_2D3D/CMakeLists.txt @@ -47,7 +47,7 @@ add_library(${CURRENT_FOLDER} SHARED ${HEAD_FILES} ${SRC_FILES} ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h + ${PROJECT_ROOT_PATH}/include/interface.h ) diff --git a/src/mission/952/952_15_Q_2D3D/backend.json b/src/mission/952/952_15_Q_2D3D/backend.json new file mode 100644 index 0000000..3a3b330 --- /dev/null +++ b/src/mission/952/952_15_Q_2D3D/backend.json @@ -0,0 +1,49 @@ +{ + "missionDllPath": "952_15_Q_2D3D_1", + "imgSavePath": "D://CCD", + "Triggers": { + "key": "finstcp", + "initStr": "init_192.168.1.50_9600_128_6_0", + "sleepTime": 20, + "readNum": 400, + "writeType": "ushort", + "heartBeatCmd": "writeHeart_short_D9204_1", + "readAllCmd": "read_byte_D8000_800", + "moduleName": "Hd_SocketModule_FinsTcp" + }, + "CameraSetting": [ + { + "key": "2D-P-1 (24488341)", + "connectionName": "2D-P-1 (24488341)", + "serialNum": "", + "triggerMode": "software_trigger", + "moduleName": "Hd_CameraModule_Basler_hard", + "imageShow": [ + "通道1-2D正极#曝光1", + "通道1-2D正极#曝光2", + "通道1-2D正极#曝光3" + ] + }, + { + "key": "2D-N-1 (24488402)", + "connectionName": "2D-N-1 (24488402)", + "serialNum": "", + "triggerMode": "software_trigger", + "moduleName": "Hd_CameraModule_Basler_hard-2", + "imageShow": [ + "通道1-2D负极#曝光1" + ] + }, + { + "key": "162762", + "connectionName": "162762", + "serialNum": "", + "triggerMode": "software_trigger", + "moduleName": "Hd_3DCameraLMI_module_PointCloud", + "imageShow": [ + "通道1-3D#高度图", + "通道1-3D#亮度图" + ] + } + ] +} \ No newline at end of file diff --git a/src/mission/952/952_15_Q_2D3D/externalData.json b/src/mission/952/952_15_Q_2D3D/externalData.json new file mode 100644 index 0000000..be4130e --- /dev/null +++ b/src/mission/952/952_15_Q_2D3D/externalData.json @@ -0,0 +1,6 @@ +{ + "952BiaoDing_3d_threshold": 0.5, + "952BiaoDing_in_InnerOffset": 3.0, + "952BiaoDing_in_OutOffset": 23.0, + "952BiaoDing_mode": 0 +} \ No newline at end of file diff --git a/src/mission/952/952_15_Q_2D3D/setting.json b/src/mission/952/952_15_Q_2D3D/setting.json new file mode 100644 index 0000000..8136a14 --- /dev/null +++ b/src/mission/952/952_15_Q_2D3D/setting.json @@ -0,0 +1,623 @@ +{ + "952-15-2D3D-1": { + "ImageView": { + "通道1-2D正极1": { + "viewer": [ + "结果图", + "曝光1", + "曝光2", + "曝光3" + ], + "xPos": 0, + "yPos": 0 + }, + "通道1-2D正极2": { + "viewer": [ + "结果图", + "曝光1", + "曝光2", + "曝光3" + ], + "xPos": 0, + "yPos": 1 + }, + "通道1-2D负极1": { + "viewer": [ + "结果图", + "曝光1" + ], + "xPos": 1, + "yPos": 0 + }, + "通道1-2D负极2": { + "viewer": [ + "结果图", + "曝光1" + ], + "xPos": 1, + "yPos": 1 + }, + "通道1-3D1": { + "viewer": [ + "结果图", + "高度图", + "亮度图" + ], + "xPos": 2, + "yPos": 0 + }, + "通道1-3D2": { + "viewer": [ + "结果图", + "高度图", + "亮度图" + ], + "xPos": 2, + "yPos": 1 + } + }, + "backend": { + "CameraSetting": [ + { + "connectionName": "2D-P-1 (24488341)", + "dllPath": "Hd_CameraModule_Basler_hard", + "imageShow": [ + "通道1-2D正极1#曝光1", + "通道1-2D正极1#曝光2", + "通道1-2D正极1#曝光3", + "通道1-2D正极2#曝光1", + "通道1-2D正极2#曝光2", + "通道1-2D正极2#曝光3" + ], + "key": "2D-P-1 (24488341)", + "oriSaveFormat": [] + }, + { + "connectionName": "2D-N-1 (24488402)", + "dllPath": "Hd_CameraModule_Basler_hard", + "imageShow": [ + "通道1-2D负极1#曝光1", + "通道1-2D负极2#曝光1" + ], + "key": "2D-N-1 (24488402)", + "oriSaveFormat": [] + }, + { + "connectionName": "162762", + "dllPath": "Hd_3DCameraLMI_module_PointCloud", + "imageShow": [ + "通道1-3D1#高度图", + "通道1-3D1#亮度图", + "通道1-3D2#高度图", + "通道1-3D2#亮度图" + ], + "key": "162762", + "oriSaveFormat": [ + "tiff", + "bmp" + ] + } + ], + "Triggers": { + "heartBeatCmd": "writeHeart_short_D8014_1", + "initStr": "init_192.168.1.50_9600_128_6_0", + "moduleName": "Hd_SocketModule_FinsTcp", + "readAllCmd": "read_byte_D8000_800", + "readNum": 400 + }, + "handleAi": { + "modelPath": "./HandleAiModels" + }, + "handleAiModel": { + "cls": { + "CLS_2D_HuaShang_P": { + "gpuIndex": 0, + "modelPath": "./handleaiModels/cls_huaShang_P_0708.BHD" + }, + "CLS_2D_ZangWu_P": { + "gpuIndex": 0, + "modelPath": "./handleaiModels/cls_zangWu_P_0708.BHD" + } + }, + "det": {}, + "seg": { + "SEG_2D_HuaShang_P": { + "gpuIndex": 1, + "modelPath": "./handleaiModels/seg_huaShang_P_0708.BHD" + }, + "SEG_2D_ZangWu_P": { + "gpuIndex": 1, + "modelPath": "./handleaiModels/seg_zangWu_P_0708.BHD" + } + } + }, + "imgSaveBasePath": "D://CCD", + "missionDllPath": "952_15_Q_2D3D", + "missionSettings": { + "_2D_N_Camera_Name": "2D-N-1 (24488402)", + "_2D_N_snPos": 8300, + "_2D_N_triggerPos": 8020, + "_2D_N_triggerReply": [ + "D8020_0", + "D8021_1", + "D8022_1" + ], + "_2D_N_viewName": "通道1-2D负极", + "_2D_P_Camera_Name": "2D-P-1 (24488341)", + "_2D_P_snPos": 8200, + "_2D_P_triggerPos": 8010, + "_2D_P_triggerReply": [ + "D8010_0", + "D8011_1", + "D8012_1" + ], + "_2D_P_viewName": "通道1-2D正极", + "_3D_1_Camera_Name": "162762", + "_3D_P_viewName": "通道1-3D", + "_3D_snPos": 8400, + "_3D_triggerPos": 8030, + "_3D_triggerReply": [ + "D8030_0", + "D8031_1", + "D8032_1" + ], + "summary_triggerPos": 8040 + } + }, + "softwareTile": "952-15前段端面1", + "sublUiSetting": {} + }, + "952-15-2D3D-2": { + "ImageView": { + "通道2-2D正极1": { + "viewer": [ + "结果图", + "曝光1", + "曝光2", + "曝光3" + ], + "xPos": 0, + "yPos": 0 + }, + "通道2-2D正极2": { + "viewer": [ + "结果图", + "曝光1", + "曝光2", + "曝光3" + ], + "xPos": 0, + "yPos": 1 + }, + "通道2-2D负极1": { + "viewer": [ + "结果图", + "曝光1" + ], + "xPos": 1, + "yPos": 0 + }, + "通道2-2D负极2": { + "viewer": [ + "结果图", + "曝光1" + ], + "xPos": 1, + "yPos": 1 + }, + "通道2-3D1": { + "viewer": [ + "结果图", + "高度图", + "亮度图" + ], + "xPos": 2, + "yPos": 0 + }, + "通道2-3D2": { + "viewer": [ + "结果图", + "高度图", + "亮度图" + ], + "xPos": 2, + "yPos": 1 + } + }, + "backend": { + "CameraSetting": [ + { + "connectionName": "2D-P-2 (24488342)", + "dllPath": "Hd_VirualCamera", + "imageShow": [ + "通道2-2D正极1#曝光1", + "通道2-2D正极1#曝光2", + "通道2-2D正极1#曝光3", + "通道2-2D正极2#曝光1", + "通道2-2D正极2#曝光2", + "通道2-2D正极2#曝光3" + ], + "key": "2D-P-2 (24488342)", + "oriSaveFormat": [] + }, + { + "connectionName": "2D-N-2 (24488458)", + "dllPath": "Hd_VirualCamera", + "imageShow": [ + "通道2-2D负极1#曝光1", + "通道2-2D负极2#曝光1" + ], + "key": "2D-N-2 (24488458)", + "oriSaveFormat": [] + }, + { + "connectionName": "156112", + "dllPath": "Hd_VirualCamera", + "imageShow": [ + "通道2-3D1#高度图", + "通道2-3D1#亮度图", + "通道2-3D2#高度图", + "通道2-3D2#亮度图" + ], + "key": "156112", + "oriSaveFormat": [ + "tiff", + "bmp" + ] + } + ], + "Triggers": { + "heartBeatCmd": "writeHeart_short_D9204_1", + "initStr": "init_127.0.0.1_9600_128_6_0", + "moduleName": "Hd_SocketModule_FinsTcp", + "readAllCmd": "read_byte_D8000_800", + "readNum": 400 + }, + "handleAi": { + "modelPath": "./HandleAiModels" + }, + "imgSaveBasePath": "D://CCD", + "missionDllPath": "952_15_Q_2D3D", + "missionSettings": { + "_2D_N_Camera_Name": "2D-N-2 (24488458)", + "_2D_N_snPos": 8800, + "_2D_N_triggerPos": 8070, + "_2D_N_triggerReply": [ + "D8070_0", + "D8071_1", + "D8072_1" + ], + "_2D_N_viewName": "通道2-2D负极", + "_2D_P_Camera_Name": "2D-P-2 (24488342)", + "_2D_P_snPos": 8700, + "_2D_P_triggerPos": 8060, + "_2D_P_triggerReply": [ + "D8060_0", + "D8061_1", + "D8062_1" + ], + "_2D_P_viewName": "通道2-2D正极", + "_3D_1_Camera_Name": "156112", + "_3D_P_viewName": "通道2-3D", + "_3D_snPos": 8900, + "_3D_triggerPos": 8080, + "_3D_triggerReply": [ + "D8080_0", + "D8081_1", + "D8082_1" + ], + "summary_triggerPos": 8090 + } + }, + "softwareTile": "952-15前段端面2", + "sublUiSetting": {} + }, + "952-15-H": { + "ImageView": { + "后段1-1": { + "viewer": [ + "结果图", + "正反射图像", + "形状图像1", + "标准图像" + ], + "xPos": 0, + "yPos": 0 + }, + "后段1-2": { + "viewer": [ + "结果图", + "正反射图像", + "形状图像1", + "标准图像" + ], + "xPos": 0, + "yPos": 1 + }, + "后段2-1": { + "viewer": [ + "结果图", + "正反射图像", + "形状图像1", + "标准图像" + ], + "xPos": 1, + "yPos": 0 + }, + "后段2-2": { + "viewer": [ + "结果图", + "正反射图像", + "形状图像1", + "标准图像" + ], + "xPos": 1, + "yPos": 1 + } + }, + "backend": { + "CameraSetting": [ + { + "connectionName": "25D-1", + "dllPath": "Hd_25DCameraVJ_module-ch1", + "imageShow": [ + "后段1-1#正反射图像", + "后段1-1#形状图像1", + "后段1-1#标准图像", + "后段1-2#正反射图像", + "后段1-2#形状图像1", + "后段1-2#标准图像" + ], + "key": "25D-1", + "oriSaveFormat": [] + }, + { + "connectionName": "25D-2", + "dllPath": "Hd_25DCameraVJ_module-ch2", + "imageShow": [ + "后段2-1#正反射图像", + "后段2-1#形状图像1", + "后段2-1#标准图像", + "后段2-2#正反射图像", + "后段2-2#形状图像1", + "后段2-2#标准图像" + ], + "key": "25D-2", + "oriSaveFormat": [] + } + ], + "Triggers": { + "heartBeatCmd": "writeHeart_short_D9204_1", + "initStr": "init_192.168.1.51_9600_128_6_0", + "key": "finstcp", + "moduleName": "Hd_SocketModule_FinsTcp", + "readAllCmd": "read_byte_D9200_800", + "readNum": 400, + "sleepTime": 20, + "writeType": "ushort" + }, + "imgSaveBasePath": "D://CCD", + "missionDllPath": "952_15_H_25D.dll" + }, + "missionSettings": {}, + "softwareTile": "952-15后段", + "sublUiSetting": [ + { + "height": 0, + "key": "后段1-左上留白", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 0, + "y": 0 + }, + { + "height": 0, + "key": "后段1-右上留白", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 1, + "y": 0 + }, + { + "height": 0, + "key": "后段1-左下留白", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 0, + "y": 1 + }, + { + "height": 0, + "key": "后段1-右下留白", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 1, + "y": 1 + }, + { + "height": 0, + "key": "后段1-左对齐度", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 0, + "y": 2 + }, + { + "height": 0, + "key": "后段1-右对齐度", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 1, + "y": 2 + }, + { + "height": 0, + "key": "后段2-左上留白", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 2, + "y": 0 + }, + { + "height": 0, + "key": "后段2-右上留白", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 3, + "y": 0 + }, + { + "height": 0, + "key": "后段2-左下留白", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 2, + "y": 1 + }, + { + "height": 0, + "key": "后段2-右下留白", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 3, + "y": 1 + }, + { + "height": 0, + "key": "后段2-左对齐度", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 2, + "y": 2 + }, + { + "height": 0, + "key": "后段2-右对齐度", + "limitHigh": 1.5, + "limitLow": -0.5, + "widgetType": "WaveFormWidget", + "width": 0, + "x": 3, + "y": 2 + } + ] + }, + "952-15-Q": { + "ImageView": { + "前段1-1": { + "viewer": [ + "结果图", + "正反射图像", + "形状图像1", + "标准图像" + ], + "xPos": 0, + "yPos": 0 + }, + "前段1-2": { + "viewer": [ + "结果图", + "正反射图像", + "形状图像1", + "标准图像" + ], + "xPos": 0, + "yPos": 1 + }, + "前段2-1": { + "viewer": [ + "结果图", + "正反射图像", + "形状图像1", + "标准图像" + ], + "xPos": 1, + "yPos": 0 + }, + "前段2-2": { + "viewer": [ + "结果图", + "正反射图像", + "形状图像1", + "标准图像" + ], + "xPos": 1, + "yPos": 1 + } + }, + "backend": { + "CameraSetting": [ + { + "connectionName": "25D-1", + "dllPath": "Hd_25DCameraVJ_module-ch1", + "imageShow": [ + "后段1-1#正反射图像", + "后段1-1#形状图像1", + "后段1-1#标准图像", + "后段1-2#正反射图像", + "后段1-2#形状图像1", + "后段1-2#标准图像" + ], + "key": "25D-1", + "oriSaveFormat": [] + }, + { + "connectionName": "25D-2", + "dllPath": "Hd_25DCameraVJ_module-ch2", + "imageShow": [ + "后段2-1#正反射图像", + "后段2-1#形状图像1", + "后段2-1#标准图像", + "后段2-2#正反射图像", + "后段2-2#形状图像1", + "后段2-2#标准图像" + ], + "key": "25D-2", + "oriSaveFormat": [] + } + ], + "Triggers": { + "heartBeatCmd": "writeHeart_short_D9204_1", + "initStr": "init_127.0.0.1_9600_128_6_0", + "key": "finstcp", + "moduleName": "Hd_SocketModule_FinsTcp", + "readAllCmd": "read_byte_D9200_800", + "readNum": 400, + "sleepTime": 20, + "writeType": "ushort" + }, + "imgSaveBasePath": "D://CCD", + "missionDllPath": "952_15_Q_25D.dll" + }, + "missionSettings": {}, + "softwareTile": "952-15前段主体", + "sublUiSetting": {} + }, + "main": { + "jsonVersion": "1.0.1", + "loginPassWord": "", + "objectSelect": "952-15-2D3D-1" + } +} \ No newline at end of file diff --git a/src/plugin/CMakeLists.txt b/src/mission/952/CMakeLists.txt similarity index 100% rename from src/plugin/CMakeLists.txt rename to src/mission/952/CMakeLists.txt diff --git a/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp b/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp new file mode 100644 index 0000000..0db6fde --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp @@ -0,0 +1,231 @@ +#include <581-BaoMo-Cam1213.h> + +struct halconResult { + double resultX = -99; + double resultY = -99; +}; +halconResult dituo(std::shared_ptr data,cv::Mat& src, cv::Mat& Paint,bool isLeft) { + halconResult result; + try { + cv::Mat srcHalf; + cv::resize(src, srcHalf, cv::Size(0, 0), 0.5, 0.5); + if (srcHalf.channels() != 3) + cv::cvtColor(srcHalf, Paint, cv::COLOR_GRAY2BGR); + else + srcHalf.copyTo(Paint); + TextRendererZH textPainter(Paint.cols, Paint.rows, 50); + + HalconCpp::HObject in_Image = MatToHObject(src); + HDevEngineCpp::HDevProcedure proc("_4_TD_BlueCover_Inspection"); + HDevProcedureCall procedureCall(proc); + + //vs+halcon联调debug + /*HDevEngineCpp::HDevEngine myEngine; + myEngine.StartDebugServer(); + procedureCall.SetWaitForDebugConnection(true);*/ + + HTuple in_Par, in_FilePath("./halconFiles/"); + in_Par[0] = data->service->_paramSyncManager->get("底托检测", "宽度阈值(mm)", 150).toInt(); + in_Par[1] = data->service->_paramSyncManager->get("底托检测", "高度阈值(mm)", 150).toInt(); + in_Par[2] = data->service->_paramSyncManager->get("底托检测", "面积阈值(mm)", 300).toInt(); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_Par", in_Par); + procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); + procedureCall.Execute(); + HTuple out_X = procedureCall.GetOutputCtrlParamTuple("out_X"); + HTuple out_Y = procedureCall.GetOutputCtrlParamTuple("out_Y"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + HTuple out_NgDetails = procedureCall.GetOutputCtrlParamTuple("out_NgDetails"); + int outFlag = out_Flag.D(); + //handleAiFuture.wait(); + //_result = handleAiFuture.get(); + if (outFlag == 1) { + textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + } + else { + data->halconOK = false; + for (int i = 0; i < out_Y.Length() / 2 - 1; i++) { + cv::circle(Paint, cv::Point(out_X[i * 2 + 1].D(), out_Y[i * 2].D()) / 2, 1, + cv::Scalar(0, 0, 255), 1); + } + std::string ngDetails = out_NgDetails.ToString().Text(); + result.resultX = out_X.D(); + result.resultY = out_Y.D(); + if (isLeft == true) { + textPainter.putText(Paint, "缺陷长度:" + std::to_string(result.resultX) + "mm", cv::Point(700, 800), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "缺陷宽度:" + std::to_string(result.resultY) + "mm", cv::Point(700, 850), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, ngDetails.substr(1, ngDetails.length() - 2), cv::Point(700, 900), cv::Scalar(0, 0, 255)); + } + else { + textPainter.putText(Paint, "缺陷长度:" + std::to_string(result.resultX) + "mm", cv::Point(50, 800), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "缺陷宽度:" + std::to_string(result.resultY) + "mm", cv::Point(50, 850), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, ngDetails.substr(1, ngDetails.length() - 2), cv::Point(50, 900), cv::Scalar(0, 0, 255)); + } + } + } + CATCH_EXCEPTIONS + return result; +} +bool ALGO_BaoMoHouDiBu_test(std::shared_ptr data, baoMoHouDiBuDetParams* _detParams, yh_581_address address) { + try { + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + std::vector < std::string> defects; + + //data->oriImgs.clear(); + //data->oriImgs.push_back(cv::imread("D://testImage/dituo_1.bmp", -1)); + //data->oriImgs.push_back(cv::imread("D://testImage/dituo_2.bmp", -1)); + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() < 2) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + data->resultImgs.push_back(Paint); + return false; + } + if (data->oriImgs[0].rows == 100) { + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); + data->resultImgs.push_back(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + return false; + } + + cv::Mat Paint,Paint1,Paint2; + bool leftFirst = address.triggerAddr == 20200; + auto feature1 = std::async(std::launch::async,dituo, data, std::ref(data->oriImgs[0]), std::ref(Paint1),leftFirst); + auto feature2 = std::async(std::launch::async, dituo, data, std::ref(data->oriImgs[1]), std::ref(Paint2),~leftFirst); + feature1.wait(); + halconResult hResult1 = feature1.get(); + + feature2.wait(); + halconResult hResult2 = feature2.get(); + cv::hconcat(Paint1, Paint2, Paint); + + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(hResult1.resultX));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(hResult1.resultY));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(hResult2.resultX));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_" + QByteArray::number(hResult2.resultY));//发送结果 + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1,0,1");//发送结果 + data->service->_missionResultHandle->toBarChart(data->SNcode, !defects.size() > 0, defects); + data->resultImgs.push_back(Paint); + } + CATCH_EXCEPTIONS + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1,0,1");//发送结果 + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + data->resultImgs.push_back(Paint); + return true; +} +bool ALGO_BaoMoHouDiBu(std::shared_ptr data, baoMoHouDiBuDetParams* _detParams, yh_581_address address) { + try { + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + std::vector < std::string> defects; + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() < 2) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + data->resultImgs.push_back(Paint); + return false; + } + if (data->oriImgs[0].rows == 100) { + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); + data->resultImgs.push_back(Paint); + return false; + } + + cv::Mat Paint; + clock_t start, finish; + start = clock(); + + cv::Mat src1 = data->oriImgs[0]; + cv::Mat srcHalf; + cv::resize(src1, srcHalf, cv::Size(0, 0), 0.5, 0.5); + if (srcHalf.channels() != 3) + cv::cvtColor(srcHalf, Paint, cv::COLOR_GRAY2BGR); + else + srcHalf.copyTo(Paint); + TextRendererZH textPainter(Paint.cols, Paint.rows, 50); + HalconCpp::HObject in_Image = MatToHObject(src1); + //vs+halcon联调debug + HDevEngineCpp::HDevProcedure proc("_4_TD_BlueCover_Inspection"); + HDevProcedureCall procedureCall(proc); + + /*HDevEngineCpp::HDevEngine myEngine; + myEngine.StartDebugServer(); + procedureCall.SetWaitForDebugConnection(true);*/ + + HTuple in_Par, in_FilePath("./halconFiles/"); + in_Par[0] = data->service->_paramSyncManager->get("底托检测","宽度阈值(mm)", 150).toInt(); + in_Par[1] = data->service->_paramSyncManager->get("底托检测", "高度阈值(mm)", 150).toInt(); + in_Par[2] = data->service->_paramSyncManager->get("底托检测", "面积阈值(mm)", 300).toInt(); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_Par", in_Par); + procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath); + procedureCall.Execute(); + HTuple out_X = procedureCall.GetOutputCtrlParamTuple("out_X"); + HTuple out_Y = procedureCall.GetOutputCtrlParamTuple("out_Y"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + HTuple out_NgDetails = procedureCall.GetOutputCtrlParamTuple("out_NgDetails"); + int outFlag = out_Flag.D(); + //handleAiFuture.wait(); + //_result = handleAiFuture.get(); + double resultX = -99, resultY = -99; + if (outFlag == 1) { + textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + } + else { + data->halconOK = false; + for (int i = 0; i < out_Y.Length() / 2 - 1; i++) { + cv::circle(Paint, cv::Point(out_X[i * 2 + 1].D(), out_Y[i * 2].D()) / 2, 1, + cv::Scalar(0, 0, 255), 1); + } + std::string ngDetails = out_NgDetails.ToString().Text(); + resultX = out_X.D(); + resultY = out_Y.D(); + if (address.triggerAddr == 20200 || address.triggerAddr == 20402) { + textPainter.putText(Paint, "缺陷长度:" + std::to_string(resultX) + "mm", cv::Point(700, 800), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "缺陷宽度:" + std::to_string(resultY) + "mm", cv::Point(700, 850), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, ngDetails.substr(1, ngDetails.length() - 2), cv::Point(700, 900), cv::Scalar(0, 0, 255)); + } + else { + textPainter.putText(Paint, "缺陷长度:" + std::to_string(resultX) + "mm", cv::Point(50, 800), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "缺陷宽度:" + std::to_string(resultY) + "mm", cv::Point(50, 850), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, ngDetails.substr(1, ngDetails.length() - 2), cv::Point(50, 900), cv::Scalar(0, 0, 255)); + } + } + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1,0,1");//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(resultX));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(resultY));//发送结果 + data->service->_missionResultHandle->toBarChart(data->SNcode, !defects.size() > 0, defects); + data->resultImgs.push_back(Paint); + } + CATCH_EXCEPTIONS + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_" + QByteArray::number(-99));//发送结果 + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1,0,1");//发送结果 + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + data->resultImgs.push_back(Paint); + return true; +} + +mission* createMission() { + return new _581_BaoMo(); +} +void destroyMission(mission* _mission) { + delete _mission; +} \ No newline at end of file diff --git a/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h b/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h new file mode 100644 index 0000000..ada0fbc --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +using namespace HDevEngineCpp; + +class baoMoHouDiBuDetParams { +public: + +}; +static bool ALGO_BaoMoHouDiBu_test(std::shared_ptr data, baoMoHouDiBuDetParams* _detParams, yh_581_address address); +static bool ALGO_BaoMoHouDiBu(std::shared_ptr data, baoMoHouDiBuDetParams* _detParams, yh_581_address address); + + +class _581_BaoMo : public mission { +public: + using baoMoHouDiBuTrigger = _581_Single_triggerTemplate; + baoMoHouDiBuTrigger _station_1; + baoMoHouDiBuTrigger _station_2; + + baoMoHouDiBuDetParams _baoMoHouDiBuDetParams; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); + } + bool initCustom() { +#pragma region 注册触发器回调 + + _station_1.init("Camera1","包膜后底托位置度检测-左-相机12",20200,1,2, &_baoMoHouDiBuDetParams,_serviceManager,bridge, ALGO_BaoMoHouDiBu_test); + _station_2.init("Camera2", "包膜后底托位置度检测-右-相机13",20400,1,2,&_baoMoHouDiBuDetParams, _serviceManager, bridge, ALGO_BaoMoHouDiBu_test); +#pragma endregion + return true; + } + + + //9600 +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/581-BaoMo-Cam1213/CMakeLists.txt b/src/mission/BaoMo/581-BaoMo-Cam1213/CMakeLists.txt similarity index 96% rename from src/mission/581-BaoMo-Cam1213/CMakeLists.txt rename to src/mission/BaoMo/581-BaoMo-Cam1213/CMakeLists.txt index 26347b4..76e9200 100644 --- a/src/mission/581-BaoMo-Cam1213/CMakeLists.txt +++ b/src/mission/BaoMo/581-BaoMo-Cam1213/CMakeLists.txt @@ -31,7 +31,7 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "*.h" ) @@ -47,7 +47,7 @@ add_library(${CURRENT_FOLDER} SHARED ${HEAD_FILES} ${SRC_FILES} ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h + ${PROJECT_ROOT_PATH}/include/interface.h ) diff --git a/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.cpp b/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.cpp new file mode 100644 index 0000000..4b84b21 --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.cpp @@ -0,0 +1,160 @@ +#include <581-BaoMo-Cam1234.h> + +cv::Rect extractRegion(cv::Mat& src,int binary_threshold = 50) { + cv::Mat binary; + threshold(src, binary, binary_threshold, 255, cv::THRESH_BINARY); + cv::dilate(binary, binary, cv::getStructuringElement(cv::MORPH_RECT,cv::Size(5,5))); + std::vector> contours; + findContours(binary, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + + double maxArea = 0; + int maxAreaIdx = -1; + for (size_t i = 0; i < contours.size(); i++) { + double area = contourArea(contours[i]); + if (area > maxArea) { + maxArea = area; + maxAreaIdx = i; + } + } + cv::Rect boundingRect = cv::boundingRect(contours[maxAreaIdx]); + return boundingRect; +} +int index = 0; +bool BaoMoQianShangDaMian(std::shared_ptr data, baoMoQianDaMianDetParams* _detParams, yh_581_address address) { + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + try { + //cv::Mat segImg; + //cv::resize(data->oriImgs[0], segImg, cv::Size(), 0.5, 0.5); + //cv::Rect ROI = extractRegion(segImg); + //segImg(ROI).copyTo(segImg); + cv::Mat Paint; + if (data->oriImgs[0].channels() == 1) + cv::cvtColor(data->oriImgs[0], Paint, cv::COLOR_GRAY2RGB); + else + data->oriImgs[0].copyTo(Paint); + //TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + //textPainter.putText(Paint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); + //segImg = ~_detParams->seg_baomodamian->Evaluate(segImg); + //std::vector>contours; + //cv::findContours(segImg, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + //int clsIndex = 0; + //bool isNG = false; + //for (auto& contour : contours) { + // cv::Rect rect = cv::boundingRect(contour); + // if (rect.width < 60 || rect.height < 60) + // continue; + // cv::Mat clsImg = cutImg2Cls(rect, data->oriImgs[0]); + // data->clsOriginImgs.push_back({ std::to_string(clsIndex),clsImg}); + // int clsResult = _detParams->cls_baomodamian->Evaluate(clsImg); + // if (clsResult == 1 || clsResult == 2) { + // cv::drawContours(Paint, contours, clsIndex, cv::Scalar(0, 0, 255), 3); + // //isNG = true; + // } + // clsIndex++; + //} + TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + //if (isNG == true) { + // textPainter.putText(Paint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); + // if (data->service->_paramSyncManager->get("强制OK", false).toBool()) + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2"); + // else + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + //} + //else { + // textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + //} + //data->segOriginImgs.push_back(segImg); + data->resultImgs.push_back(Paint); + textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + return true; + } + CATCH_EXCEPTIONS + generalExceptionResume(data, address, "检测异常"); + return true; + +} + +bool BaoMoQianXiaDaMian(std::shared_ptr data, baoMoQianDaMianDetParams* _detParams, yh_581_address address) { + + QString date = QDateTime::currentDateTime().toString("yyyy_MM_dd_HH_mm_ss_").toUtf8() + QString::number(index); + //data->service->_triggerManager->writeShort("D" + QByteArray::number(address.snAddr) + "_" + convertStringForFins(date)); + data->SNcode = date.toStdString(); + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + index++; + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + if (data->oriImgs[0].rows == 200) { + generalExceptionResume(data, address, "检测异常"); + return false; + } + try { + cv::Mat segImg; + cv::resize(data->oriImgs[0], segImg, cv::Size(), 0.5, 0.5); + cv::Rect ROI = extractRegion(segImg); + segImg(ROI).copyTo(segImg); + cv::Mat Paint; + if (data->oriImgs[0].channels() == 1) + cv::cvtColor(data->oriImgs[0], Paint, cv::COLOR_GRAY2RGB); + else + data->oriImgs[0].copyTo(Paint); + //TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + //textPainter.putText(Paint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); + segImg = ~_detParams->seg_baomodamian->Evaluate(segImg); + std::vector>contours; + cv::findContours(segImg, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + int clsIndex = 0; + bool isNG = false; + for (auto& contour : contours) { + cv::Rect rect = cv::boundingRect(contour); + if (rect.width < 60 || rect.height < 60) + continue; + cv::Mat clsImg = cutImg2Cls(rect, data->oriImgs[0]); + data->clsOriginImgs.push_back({ std::to_string(clsIndex),clsImg}); + int clsResult = _detParams->cls_baomodamian->Evaluate(clsImg); + if (clsResult == 1 || clsResult == 2) { + cv::drawContours(Paint, contours, clsIndex, cv::Scalar(0, 0, 255), 3); + //isNG = true; + } + clsIndex++; + } + TextRendererZH textPainter(Paint.cols, Paint.rows, 500); + //if (isNG == true) { + // textPainter.putText(Paint, "NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); + // if (data->service->_paramSyncManager->get("强制OK", false).toBool()) + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2"); + // else + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + //} + //else { + // textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + // data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + //} + textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + data->segOriginImgs.push_back(segImg); + data->resultImgs.push_back(Paint); + + + return true; + } + CATCH_EXCEPTIONS + generalExceptionResume(data, address, "检测异常"); + return true; + +} +mission* createMission() { + return new _581_BaoMo_Cam1234(); +} +void destroyMission(mission* _mission) { + delete _mission; +} \ No newline at end of file diff --git a/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.h b/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.h new file mode 100644 index 0000000..f881078 --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam1234/581-BaoMo-Cam1234.h @@ -0,0 +1,64 @@ +#include +#include +#include +#include +using namespace HDevEngineCpp; + +class baoMoQianDaMianDetParams { +public: + handdleAI::pSegmentation* seg_baomodamian = nullptr; + handdleAI::pClassification* cls_baomodamian = nullptr; +}; + + +bool BaoMoQianShangDaMian(std::shared_ptr data, baoMoQianDaMianDetParams* _detParams, yh_581_address address); +bool BaoMoQianXiaDaMian(std::shared_ptr data, baoMoQianDaMianDetParams* _detParams, yh_581_address address); +class _581_BaoMo_Cam1234 : public mission { +public: + using baoMoQianDaMianTrigger = _581_Union_triggerTemplate; + baoMoQianDaMianTrigger _shangdamian_1; + baoMoQianDaMianTrigger _xiadamian_2; + std::vector _baoMoQianDaMianDetParams = std::vector< baoMoQianDaMianDetParams>(2); + + using generalTrigger = _581_Union_triggerTemplate; + generalTrigger _station_3; + generalTrigger _station_4; + detParams _detParams; + bool initOnce = false; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); + + if (initOnce == false) { + + /* _baoMoQianDaMianDetParams[0].seg_baomodamian = handdleAI::CreateSegObjS("./handleAiModels/BaoMoQianDaMian_Seg.BHD", 64, 0); + _baoMoQianDaMianDetParams[0].cls_baomodamian = handdleAI::CreateClsObjV3("./handleAiModels/BaoMoQianDaMian_Cls.BHD", 0, 1); + + _baoMoQianDaMianDetParams[1].seg_baomodamian = handdleAI::CreateSegObjS("./handleAiModels/BaoMoQianDaMian_Seg.BHD", 64, 1); + _baoMoQianDaMianDetParams[1].cls_baomodamian = handdleAI::CreateClsObjV3("./handleAiModels/BaoMoQianDaMian_Cls.BHD", 1, 1);*/ + + initOnce = true; + } + + + } + bool initCustom() { +#pragma region 注册触发器回调 + _shangdamian_1.init("Camera1","包膜前外观检测大面相机1(上大面)", 18000,2, 1, &_baoMoQianDaMianDetParams[0], _serviceManager, bridge, BaoMoQianShangDaMian); + _xiadamian_2.init("Camera2", "包膜前外观检测大面相机2(下大面)", 18200,2, 1, &_baoMoQianDaMianDetParams[1], _serviceManager, bridge, BaoMoQianXiaDaMian); + + _station_3.init("Camera3", "包膜前产品边缘检测大面-外-相机3(下大面顶盖侧)", 18400,2, 2, &_detParams,_serviceManager,bridge, generalAlgoTest); + _station_4.init("Camera4", "包膜前产品边缘检测大面-内-相机4(下大面底部侧)", 18600 ,2, 2, &_detParams, _serviceManager, bridge, generalAlgoTest); +#pragma endregion + return true; + } + void reloadAlgo(QByteArray& byteArray) { + + } + + //9600 +}; + + + +#pragma once \ No newline at end of file diff --git a/src/mission/581_YuHan_hanqian/CMakeLists.txt b/src/mission/BaoMo/581-BaoMo-Cam1234/CMakeLists.txt similarity index 96% rename from src/mission/581_YuHan_hanqian/CMakeLists.txt rename to src/mission/BaoMo/581-BaoMo-Cam1234/CMakeLists.txt index 26347b4..76e9200 100644 --- a/src/mission/581_YuHan_hanqian/CMakeLists.txt +++ b/src/mission/BaoMo/581-BaoMo-Cam1234/CMakeLists.txt @@ -31,7 +31,7 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "*.h" ) @@ -47,7 +47,7 @@ add_library(${CURRENT_FOLDER} SHARED ${HEAD_FILES} ${SRC_FILES} ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h + ${PROJECT_ROOT_PATH}/include/interface.h ) diff --git a/src/mission/581-BaoMo-Cam5678/581-BaoMo.cpp b/src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.cpp similarity index 78% rename from src/mission/581-BaoMo-Cam5678/581-BaoMo.cpp rename to src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.cpp index 0ee499e..a9252aa 100644 --- a/src/mission/581-BaoMo-Cam5678/581-BaoMo.cpp +++ b/src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.cpp @@ -1,4 +1,4 @@ -#include <581-BaoMo.h> +#include <581-BaoMo-Cam5678.h> mission* createMission() { return new _581_BaoMo(); diff --git a/src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.h b/src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.h new file mode 100644 index 0000000..00c5395 --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam5678/581-BaoMo-Cam5678.h @@ -0,0 +1,221 @@ +#include +#include + +struct _581_BaoMoResult +{ + bool result = true; + std::vector < std::string> defects; +}; +class baoMoHouDaMianDetParams { +public: + handdleAI::pSegmentation* dingwei = nullptr; + handdleAI::pSegmentation* seg = nullptr; + handdleAI::pClassification* cls = nullptr; +}; +#pragma region 算法 +#include +#include +#include +using namespace HDevEngineCpp; +#pragma endregion +#pragma region 算法 + +std::vector BaoMoHou_DaMianAi(std::shared_ptr data, cv::Mat src, cv::Mat& Paint, + baoMoHouDaMianDetParams* _detParams) { + if (_detParams->seg == nullptr || _detParams->cls == nullptr) + return {}; + std::vector defects; + TextRendererZH textPainter(Paint.cols, Paint.rows, 150); + bool huaShangNg = false; + cv::Mat segImg = ~_detParams->seg->Evaluate(src); + std::vector> contours; + cv::findContours(segImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); + bool isOK = true; + for (int i = 0; i < contours.size(); i++) { + cv::Rect rect = cv::boundingRect(contours[i]); + if (rect.width < 100 || rect.height < 100) continue; // 过滤掉小轮廓 + auto clsImgs = cutImg2ClsVec(rect, src, cv::Size(128, 128)); + bool clsIsNg = false; + for (auto& clsImg : clsImgs) { + int clsResult = _detParams->cls->Evaluate(clsImg); + if (clsResult == 1) { + clsIsNg = true; + huaShangNg = true; + } + data->clsOriginImgs.push_back({ "CLS",clsImg }); + } + if (clsIsNg == true) { + cv::Scalar color = cv::Scalar(0, 0, 255); + isOK = false; + cv::drawContours(Paint, contours, i, color, 2); + textPainter.putText(Paint, "NG", cv::Point(rect.x + 10, rect.y - 20), color); + } + } + if (huaShangNg == true) + defects.push_back("划伤"); + return defects; +} +static bool BaoMoHou_ShangDaMian(std::shared_ptr data, baoMoHouDaMianDetParams* _detParams, yh_581_address address) +{ + try { + //data->oriImgs[0] = cv::imread("D://testImage//Camera1.bmp", -1); + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + /*if (data->oriImgs[0].rows == 150) { + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); + return false; + }*/ + + cv::Mat Paint; + //QMutex paintMutex; + clock_t start, finish; + start = clock(); + + cv::Mat src1 = data->oriImgs[0]; + cv::Mat srcHalf; + cv::resize(src1, srcHalf, cv::Size(0, 0), 0.5, 0.5); + if (srcHalf.channels() != 3) + cv::cvtColor(srcHalf, Paint, cv::COLOR_GRAY2BGR); + else + srcHalf.copyTo(Paint); + TextRendererZH textPainter(Paint.cols, Paint.rows, 150); + //std::future > handleAiFuture = std::async(std::launch::async, BaoMoHou_DaMianAi, data, srcHalf, Paint, _detParams); + HalconCpp::HObject in_Image = MatToHObject(src1); + HDevEngineCpp::HDevProcedure proc("_4_Cal_Long_Coatingcover_Dist"); + HDevProcedureCall procedureCall(proc); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_xResolution", HTuple(0.0308812)); + procedureCall.SetInputCtrlParamTuple("in_yResolution", HTuple(0.029527)); + procedureCall.Execute(); + HTuple out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance"); + HTuple out_Line = procedureCall.GetOutputCtrlParamTuple("out_Line"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + int outFlag = out_Flag.D(); + // handleAiFuture.wait(); + //auto defects = handleAiFuture.get(); + if (outFlag == 1) { + for (int i = 0; i < out_Line.Length() / 4; i++) { + cv::line(Paint, cv::Point(out_Line[i * 4 + 1].D(), out_Line[i * 4].D()) / 2, + cv::Point(out_Line[i * 4 + 3].D(), out_Line[i * 4 + 2].D()) / 2, + cv::Scalar(0, 255, 0), 5); + } + /*out_Distance[0]: 上端盖到膜的距离< / c> + * out_Distance[1] : 中端盖到膜的距离< / c> + * out_Distance[2] : 下端盖到膜的距离< / c> + * out_Distance[3] : 电芯宽度 < / c> + * out_Distance[4] : 电芯高度< / c>*/ + textPainter.putText(Paint, "上端盖到膜的距离:" + std::to_string(out_Distance[0].D()) + "mm", cv::Point(50, 150), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "中端盖到膜的距离:" + std::to_string(out_Distance[1].D()) + "mm", cv::Point(50, 350), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "下端盖到膜的距离:" + std::to_string(out_Distance[2].D()) + "mm", cv::Point(50, 550), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "电芯宽度:" + std::to_string(out_Distance[3].D()) + "mm", cv::Point(50, 750), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "电芯高度:" + std::to_string(out_Distance[4].D()) + "mm", cv::Point(50, 950), cv::Scalar(0, 255, 0)); + } + else { + data->halconOK = false; + textPainter.putText(Paint, "OK", cv::Point(50, 300), cv::Scalar(0, 255, 0)); + } + + data->resultImgs.push_back(Paint); + //data->service->_missionResultHandle->toBarChart(data->SNcode, !defects.size() > 0, defects); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123"); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123"); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + return true; + } + CATCH_EXCEPTIONS + generalExceptionResume(data, address, "NG"); +} + +static bool BaoMoHou_XiaDaMian(std::shared_ptr data, baoMoHouDaMianDetParams* _detParams, yh_581_address address) +{ + try { + //data->oriImgs[0] = cv::imread("D://testImage//Camera2.bmp", -1); + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + /*if (data->oriImgs[0].rows == 150) { + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); + return false; + }*/ + + cv::Mat Paint; + //QMutex paintMutex; + clock_t start, finish; + start = clock(); + + cv::Mat src1 = data->oriImgs[0]; + cv::Mat srcHalf; + cv::resize(src1, srcHalf, cv::Size(0, 0), 0.5, 0.5); + if (srcHalf.channels() != 3) + cv::cvtColor(srcHalf, Paint, cv::COLOR_GRAY2BGR); + else + srcHalf.copyTo(Paint); + //切图 + //cv::Mat segResult = _detParams->dingwei->Evaluate(srcHalf); + + //auto _result = BaoMoHou_DaMianAi(data, srcHalf, Paint, _detParams); + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + textPainter.putText(Paint, "OK", cv::Point(500, 50), cv::Scalar(0, 255, 0)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->resultImgs.push_back(Paint); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123"); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123"); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1"); + return true; + } + CATCH_EXCEPTIONS + generalExceptionResume(data, address, "OK"); +} + +#pragma endregion + +class _581_BaoMo : public mission { +public: + using baoMoHouShangDaMianTrigger = _581_Single_triggerTemplate; + baoMoHouShangDaMianTrigger _station_1;//shangdamian + baoMoHouShangDaMianTrigger _station_3;//shangdamian + + using baoMoHouXiaDaMianTrigger = _581_Single_triggerTemplate; + baoMoHouXiaDaMianTrigger _station_2;//xiadamian + baoMoHouXiaDaMianTrigger _station_4;//xiadamian + + std::vector _baoMoHouDaMianDetParams = std::vector< baoMoHouDaMianDetParams>(4); + detParams _detParams; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); + } + bool initCustom() { + +#pragma region 注册触发器回调 + + _station_1.init("Camera1", "包膜后大面外观检测-左上-相机5(上大面1)",18800,1,1, &_baoMoHouDaMianDetParams[0], _serviceManager, bridge, BaoMoHou_ShangDaMian); + _station_3.init("Camera3", "包膜后大面外观检测-右上-相机7(上大面2)", 19200, 1, 1, &_baoMoHouDaMianDetParams[1], _serviceManager, bridge, BaoMoHou_ShangDaMian); + + _station_2.init("Camera2", "包膜后大面外观检测-左下-相机6(下大面四角1)", 19000, 1, 1, &_baoMoHouDaMianDetParams[2], _serviceManager, bridge, BaoMoHou_XiaDaMian); + _station_4.init("Camera4", "包膜后大面外观检测-右下-相机8(下大面四角2)",19400, 1,1, &_baoMoHouDaMianDetParams[3], _serviceManager, bridge, BaoMoHou_XiaDaMian); +#pragma endregion + return true; + } +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/581-BaoMo-Cam5678/CMakeLists.txt b/src/mission/BaoMo/581-BaoMo-Cam5678/CMakeLists.txt similarity index 96% rename from src/mission/581-BaoMo-Cam5678/CMakeLists.txt rename to src/mission/BaoMo/581-BaoMo-Cam5678/CMakeLists.txt index 26347b4..76e9200 100644 --- a/src/mission/581-BaoMo-Cam5678/CMakeLists.txt +++ b/src/mission/BaoMo/581-BaoMo-Cam5678/CMakeLists.txt @@ -31,7 +31,7 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "*.h" ) @@ -47,7 +47,7 @@ add_library(${CURRENT_FOLDER} SHARED ${HEAD_FILES} ${SRC_FILES} ${UI_FILES} - ${PROJECT_ROOT_PATH}/include/qtBridge.h + ${PROJECT_ROOT_PATH}/include/interface.h ) diff --git a/src/mission/581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp b/src/mission/BaoMo/581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp similarity index 91% rename from src/mission/581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp rename to src/mission/BaoMo/581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp index 43980a2..2977872 100644 --- a/src/mission/581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp +++ b/src/mission/BaoMo/581-BaoMo-Cam91011/581-BaoMo-Cam91011.cpp @@ -80,8 +80,8 @@ bool halconAlgo1_BaoMoHouCeMian_HouDu(std::shared_ptr data, yh_581_add int outFlag = out_Flag.D(); TextRendererZH textPainter(Paint.cols, Paint.rows, 300); - double limitHigh = data->service->_paramSyncManager->get("最大宽度阈值(MAX)", 200).toFloat(); - double limitLow = data->service->_paramSyncManager->get("最小宽度阈值(MIN)", 0).toFloat(); + double limitHigh = data->service->_paramSyncManager->get(data->service->_paramSyncManager->getGroup(1), "最大宽度阈值(MAX)", 200).toFloat(); + double limitLow = data->service->_paramSyncManager->get(data->service->_paramSyncManager->getGroup(1), "最小宽度阈值(MIN)", 0).toFloat(); if (outFlag == 1) { QMutexLocker locker(mutex); @@ -120,10 +120,10 @@ bool halconAlgo1_BaoMoHouCeMian_PoSun(std::shared_ptr data, yh_581_add cv::Mat img = HObject2Mat(test); cv::resize(img, img, cv::Size(), 0.5, 0.5); HTuple in_Parameters; - in_Parameters[0] = data->service->_paramSyncManager->get("灰度管控阈值", 230).toInt(); - in_Parameters[1] = data->service->_paramSyncManager->get("缺陷像素数量管控阈值(pix)", 300000).toInt(); - in_Parameters[2] = data->service->_paramSyncManager->get("缺陷的宽度管控阈值(pix)", 600).toInt(); - in_Parameters[3] = data->service->_paramSyncManager->get("缺陷的高度管控阈值(pix)", 60).toInt(); + in_Parameters[0] = data->service->_paramSyncManager->get(data->service->_paramSyncManager->getGroup(1), "灰度管控阈值", 230).toInt(); + in_Parameters[1] = data->service->_paramSyncManager->get(data->service->_paramSyncManager->getGroup(1), "缺陷像素数量管控阈值(pix)", 300000).toInt(); + in_Parameters[2] = data->service->_paramSyncManager->get(data->service->_paramSyncManager->getGroup(1), "缺陷的宽度管控阈值(pix)", 600).toInt(); + in_Parameters[3] = data->service->_paramSyncManager->get(data->service->_paramSyncManager->getGroup(1), "缺陷的高度管控阈值(pix)", 60).toInt(); HDevEngineCpp::HDevProcedure proc("_4_TR_TL_BlueCover_Inspection"); HDevProcedureCall procedureCall(proc); @@ -173,7 +173,7 @@ bool ALGO_BaoMoHouCeMian(std::shared_ptr data, baoMoHouDaMianDetParams clock_t start, finish; start = clock(); - data->oriImgs[0] = cv::imread("D:/04QCB82602000JFB5000019N_Camera2_0.bmp", -1); + //data->oriImgs[0] = cv::imread("D:/04QCB82602000JFB5000019N_Camera2_0.bmp", -1); // cv::Mat src = data->oriImgs[0]; diff --git a/src/mission/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h b/src/mission/BaoMo/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h similarity index 70% rename from src/mission/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h rename to src/mission/BaoMo/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h index 255e2c5..d5b8006 100644 --- a/src/mission/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h +++ b/src/mission/BaoMo/581-BaoMo-Cam91011/581-BaoMo-Cam91011.h @@ -18,12 +18,10 @@ static bool ALGO_BaoMoHouCeMian(std::shared_ptr data, baoMoHouDaMianDe class _581_BaoMo : public mission { public: - using baoMoHouDaMianTrigger = _581_Union_triggerTemplate; - baoMoHouDaMianTrigger _station_1; - baoMoHouDaMianTrigger _station_2; + _581_Union_triggerTemplate _station_1; + _581_Union_triggerTemplate _station_2; - using generalTrigger = _581_Union_triggerTemplate; - generalTrigger _station_3; + _581_Union_triggerTemplate _station_3; std::vector < baoMoHouDaMianDetParams> _baoMoHouDaMianDetParams = std::vector < baoMoHouDaMianDetParams>(2); detParams _detParams; @@ -43,17 +41,10 @@ public: bool initCustom() { #pragma region 注册触发器回调 - //baoMoHouDaMianTrigger::resultHandleCallback resultCallback_BaoMoHouCeMian = - // ([=](yh_581_address address, _581_BaoMoResult, std::shared_ptr ) { - // _serviceManager->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - // }); + _station_1.init("Camera1","包膜后侧面贴胶错位检测-外-相机9",19600,2,1,&_baoMoHouDaMianDetParams[0], _serviceManager, bridge, ALGO_BaoMoHouCeMian); _station_2.init("Camera2", "包膜后侧面贴胶错位检测-内-相机10",19800,2,1, &_baoMoHouDaMianDetParams[1], _serviceManager, bridge, ALGO_BaoMoHouCeMian); - //generalTrigger::resultHandleCallback resultCallback_general = - // ([=](yh_581_address address, _581_Result, std::shared_ptr ) { - // _serviceManager->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - // }); _station_3.init("Camera3", "包膜后外观检测大面相机11(下大面)",20000,2,1, &_detParams, _serviceManager, bridge, generalAlgoTest); #pragma endregion return true; diff --git a/src/mission/BaoMo/581-BaoMo-Cam91011/CMakeLists.txt b/src/mission/BaoMo/581-BaoMo-Cam91011/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/BaoMo/581-BaoMo-Cam91011/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/BaoMo/CMakeLists.txt b/src/mission/BaoMo/CMakeLists.txt new file mode 100644 index 0000000..f9a95fd --- /dev/null +++ b/src/mission/BaoMo/CMakeLists.txt @@ -0,0 +1,11 @@ +# CMakeList.txt: 遍历文件夹 添加子项目 + +set(OUR_LIBS "") +SUBDIRENAMES(OUR_LIBS ${CMAKE_CURRENT_SOURCE_DIR} "" OFF) +message("OUR_LIBS :" ${OUR_LIBS}) + + +# 遍历子库 +foreach(dll ${OUR_LIBS}) + add_subdirectory(${dll}) +endforeach(dll ${}) diff --git a/src/mission/581-Dgh-CB-1/581-Dgh-CB-1.cpp b/src/mission/DGH/581-Dgh-CB-1/581-Dgh-CB-1.cpp similarity index 100% rename from src/mission/581-Dgh-CB-1/581-Dgh-CB-1.cpp rename to src/mission/DGH/581-Dgh-CB-1/581-Dgh-CB-1.cpp diff --git a/src/mission/581-Dgh-CB-1/581-Dgh-CB-1.h b/src/mission/DGH/581-Dgh-CB-1/581-Dgh-CB-1.h similarity index 100% rename from src/mission/581-Dgh-CB-1/581-Dgh-CB-1.h rename to src/mission/DGH/581-Dgh-CB-1/581-Dgh-CB-1.h diff --git a/src/mission/DGH/581-Dgh-CB-1/CMakeLists.txt b/src/mission/DGH/581-Dgh-CB-1/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/DGH/581-Dgh-CB-1/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/581-Dgh-CB-2/581-Dgh-CB-2.cpp b/src/mission/DGH/581-Dgh-CB-2/581-Dgh-CB-2.cpp similarity index 100% rename from src/mission/581-Dgh-CB-2/581-Dgh-CB-2.cpp rename to src/mission/DGH/581-Dgh-CB-2/581-Dgh-CB-2.cpp diff --git a/src/mission/581-Dgh-CB-2/581-Dgh-CB-2.h b/src/mission/DGH/581-Dgh-CB-2/581-Dgh-CB-2.h similarity index 100% rename from src/mission/581-Dgh-CB-2/581-Dgh-CB-2.h rename to src/mission/DGH/581-Dgh-CB-2/581-Dgh-CB-2.h diff --git a/src/mission/DGH/581-Dgh-CB-2/CMakeLists.txt b/src/mission/DGH/581-Dgh-CB-2/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/DGH/581-Dgh-CB-2/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/581-Dgh-DB-1/581-Dgh-DB-1.cpp b/src/mission/DGH/581-Dgh-DB-1/581-Dgh-DB-1.cpp similarity index 100% rename from src/mission/581-Dgh-DB-1/581-Dgh-DB-1.cpp rename to src/mission/DGH/581-Dgh-DB-1/581-Dgh-DB-1.cpp diff --git a/src/mission/581-Dgh-DB-1/581-Dgh-DB-1.h b/src/mission/DGH/581-Dgh-DB-1/581-Dgh-DB-1.h similarity index 100% rename from src/mission/581-Dgh-DB-1/581-Dgh-DB-1.h rename to src/mission/DGH/581-Dgh-DB-1/581-Dgh-DB-1.h diff --git a/src/mission/DGH/581-Dgh-DB-1/CMakeLists.txt b/src/mission/DGH/581-Dgh-DB-1/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/DGH/581-Dgh-DB-1/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/581-Dgh-DB-2/581-Dgh-DB-2.cpp b/src/mission/DGH/581-Dgh-DB-2/581-Dgh-DB-2.cpp similarity index 100% rename from src/mission/581-Dgh-DB-2/581-Dgh-DB-2.cpp rename to src/mission/DGH/581-Dgh-DB-2/581-Dgh-DB-2.cpp diff --git a/src/mission/581-Dgh-DB-2/581-Dgh-DB-2.h b/src/mission/DGH/581-Dgh-DB-2/581-Dgh-DB-2.h similarity index 99% rename from src/mission/581-Dgh-DB-2/581-Dgh-DB-2.h rename to src/mission/DGH/581-Dgh-DB-2/581-Dgh-DB-2.h index 94fa59e..3e3567a 100644 --- a/src/mission/581-Dgh-DB-2/581-Dgh-DB-2.h +++ b/src/mission/DGH/581-Dgh-DB-2/581-Dgh-DB-2.h @@ -121,7 +121,7 @@ cv::Mat LocalCutImg_DET(handdleAI::pDetection* pDet, cv::Mat src, float zoom, in static std::vectordingGaiHanClsCut(cv::Rect boundingBox, cv::Mat imgInput, cv::Size targetSize = cv::Size(128, 128)) { std::vector result; - int splitCount = getMax(boundingBox.width, boundingBox.height) / getMax(boundingBox.width, boundingBox.height); + int splitCount = std::max(boundingBox.width, boundingBox.height) / std::max(boundingBox.width, boundingBox.height); //std::cout << "splitCount" << splitCount; if (splitCount > 2) {//大于2分段裁 if (boundingBox.width > boundingBox.height) {//宽大于高,横着裁 diff --git a/src/mission/DGH/581-Dgh-DB-2/CMakeLists.txt b/src/mission/DGH/581-Dgh-DB-2/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/DGH/581-Dgh-DB-2/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/DGH/CMakeLists.txt b/src/mission/DGH/CMakeLists.txt new file mode 100644 index 0000000..f9a95fd --- /dev/null +++ b/src/mission/DGH/CMakeLists.txt @@ -0,0 +1,11 @@ +# CMakeList.txt: 遍历文件夹 添加子项目 + +set(OUR_LIBS "") +SUBDIRENAMES(OUR_LIBS ${CMAKE_CURRENT_SOURCE_DIR} "" OFF) +message("OUR_LIBS :" ${OUR_LIBS}) + + +# 遍历子库 +foreach(dll ${OUR_LIBS}) + add_subdirectory(${dll}) +endforeach(dll ${}) diff --git a/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.cpp b/src/mission/YuHan/581_YuHan_hanhou/581_YuHan_hanhou.cpp similarity index 57% rename from src/mission/581_YuHan_hanhou/581_YuHan_hanhou.cpp rename to src/mission/YuHan/581_YuHan_hanhou/581_YuHan_hanhou.cpp index 181ab1c..73cb514 100644 --- a/src/mission/581_YuHan_hanhou/581_YuHan_hanhou.cpp +++ b/src/mission/YuHan/581_YuHan_hanhou/581_YuHan_hanhou.cpp @@ -1,5 +1,11 @@ #include <581_YuHan_hanhou.h> +std::string controlAccuracy(float num, int length) { + std::string resultString = std::to_string(num); + resultString = resultString.substr(0, resultString.find(".") + length + 1); + return resultString; +} + void handleAiProcess(cv::Mat& src, cv::Mat& segRes, cv::Mat& Paint, bool& silieResult, bool& fanZheResult, cv::Point offset, handdleAI::pClassification* clsPtr, std::vector& clsImgs){ @@ -13,7 +19,7 @@ void handleAiProcess(cv::Mat& src, cv::Mat& segRes, cv::Mat& Paint, rect.x += offset.x; rect.y += offset.y; - if (originRect.width < 50 || originRect.height < 50) + if (originRect.width < 200 || originRect.height < 200) continue; std::vector clsImgVec = cutImg2ClsVec(rect, src); std::vector clsRes;//true ok @@ -69,7 +75,7 @@ halconResult halconAlgoProcess(cv::Mat& img, cv::Mat& Paint, handdleAI::pSegment out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量 out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//获取输出控制类变量 out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 - if (out_Flag.D() == 1) + if (out_Flag.D() == 0) { for (auto i = 0; i < out_LinePoint.Length(); i += 4) { @@ -79,13 +85,23 @@ halconResult halconAlgoProcess(cv::Mat& img, cv::Mat& Paint, handdleAI::pSegment cv::Scalar(0, 255, 0), 5); } - double value1 = out_Distance[0].D(); - double value2 = out_Distance[1].D(); - double value3 = out_Distance[2].D(); + if(out_Distance.Length() > 6) { + double hanYin_Width = out_Distance[0].D();//焊印的宽度 + double hanYin_Height = out_Distance[1].D();//焊印的高度 + double hanYIn_Area = out_Distance[2].D() * 0.013682 * 0.013682;//焊印的面积 + double jiEr_Width = out_Distance[3].D();//极耳的宽度 + double jiEr_Height = out_Distance[4].D();//极耳的高度 + double hanYin_Distance_Up = out_Distance[5].D();//焊印上边缘到极耳上边缘的距离 + double hanYin_Distance_Down = out_Distance[6].D();//焊印下边缘到极耳下边缘的距离 - result.jiErWidth = value1; - result.jiErHeight = value2; - result.hanYin1 = value3; + result.jiErWidth = jiEr_Width; + result.jiErHeight = jiEr_Height; + result.hanYin_Width = hanYin_Width; + result.hanYin_Height = hanYin_Height; + result.hanYin_Area = hanYIn_Area; + result.hanYin_Distance_Up = hanYin_Distance_Up; + result.hanYin_Distance_Down = hanYin_Distance_Down; + } } else { @@ -98,35 +114,19 @@ halconResult halconAlgoProcess(cv::Mat& img, cv::Mat& Paint, handdleAI::pSegment return result; } bool hanHouCeLiang(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address) { - QByteArray plcResult = "2"; + QByteArray plcResult = "1"; try { -#if 0 - /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ - QString resultTag = "OK"; - Mat srcImage; - srcImage = img2D.clone(); - cv::Mat dstImage; - srcImage.copyTo(dstImage); - cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5); - putTextHusky(dstImage, utf8_to_gbk("AI_OK").c_str(), cv::Point(1800, 50), cv::Scalar(0, 255, 0), 200); - putTextHusky(dstImage, utf8_to_gbk("ALGO_OK").c_str(), cv::Point(1800, 250), cv::Scalar(0, 255, 0), 200); - cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5); - resMat.push_back(dstImage); - addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, resultTag)); - addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, resultTag)); - return true; - /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ -#else + //data->oriImgs[0] = cv::imread("D:/testImage/L.bmp", -1); cv::Mat sourceImg = data->oriImgs[0]; + cv::Mat Paint; - data->oriImgs[0].copyTo(Paint); - + sourceImg.copyTo(Paint); if (Paint.channels() == 1) cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); //HALCON异步处理 cv::Mat hySegResult; - auto futrue = std::async(std::launch::async, halconAlgoProcess, sourceImg, Paint, _detParams->segHanYinZhuaQu, std::ref(hySegResult));//异步执行 + auto futrue = std::async(std::launch::async, halconAlgoProcess,sourceImg, Paint, _detParams->segHanYinZhuaQu, std::ref(hySegResult));//异步执行 //handleAI主线程处理 定位极耳 float resizeRate = 5.0; @@ -147,10 +147,11 @@ bool hanHouCeLiang(std::shared_ptr data, yuHanHanHouParams* _detParams cv::Mat SegRes = ~_detParams->segHanHou->Evaluate(matDet); bool silieOk = true, fanZheOk = true; std::vector clsImgs; - handleAiProcess(sourceImg, SegRes, Paint, silieOk, fanZheOk, cv::Point(rect.x * resizeRate, rect.y * resizeRate), _detParams->clsHanHou, clsImgs); + //handleAiProcess(sourceImg, SegRes, Paint, silieOk, fanZheOk, cv::Point(rectCutJier.x, rectCutJier.y, _detParams->clsHanHou, clsImgs); //等待halcon算法完成 futrue.wait(); + data->oriImgs.push_back(hySegResult); halconResult halconResult = futrue.get(); //结果处理 QString okNgSaveText = "OK"; @@ -158,39 +159,85 @@ bool hanHouCeLiang(std::shared_ptr data, yuHanHanHouParams* _detParams QByteArray fanzheResultText = fanZheOk == true ? "1" : "2"; TextRendererZH textPainter(Paint.cols, Paint.rows, 300); if (silieOk == true && fanZheOk == true) {//OK - textPainter.putText(Paint, "缺陷检测OK", cv::Point(4000, 50), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "缺陷检测OK", cv::Point(4200, 50), cv::Scalar(0, 255, 0)); } else { - textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(4000, 50), cv::Scalar(0, 255, 0)); - plcResult = "2"; + textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(4200, 50), cv::Scalar(0, 0, 255)); + //plcResult = "2"; data->aiDetOK = false; } - if (halconResult.result == true) { - textPainter.putText(Paint, "算法OK", cv::Point(4000, 350), cv::Scalar(0, 255, 0)); + + silieResultText = "1"; fanzheResultText = "1"; +#pragma region 判断结果以及储存结果 + double hanyinChangLimitHigh = data->service->_paramSyncManager->get("焊印长","焊印长(上限)", 30.5).toDouble(); + double hanyinChangLimitLow = data->service->_paramSyncManager->get("焊印长", "焊印长(下限)", 29.5).toDouble(); + bool hanyinChangEnable = data->service->_paramSyncManager->get("焊印长", "焊印长判定启用", false).toBool(); + + double hanyinKuanLimitHigh = data->service->_paramSyncManager->get("焊印宽", "焊印宽(上限)", 10.5).toDouble(); + double hanyinKuanLimitLow = data->service->_paramSyncManager->get("焊印宽", "焊印宽(下限)", 9.5).toDouble(); + bool hanyinKuanEnable = data->service->_paramSyncManager->get("焊印宽", "焊印宽判定启用", false).toBool(); + + double jierChangLimitHigh = data->service->_paramSyncManager->get("极耳长度", "极耳长度(上限)", 21).toDouble(); + double jierChangLimitLow = data->service->_paramSyncManager->get("极耳长度", "极耳长度(下限)", 19).toDouble(); + bool jierChangEnable = data->service->_paramSyncManager->get("极耳长度", "极耳长度判定启用", false).toBool(); + + if (halconResult.hanYin_Width > hanyinChangLimitHigh || halconResult.hanYin_Width < hanyinChangLimitLow) { + textPainter.putText(Paint, "焊印长度" + controlAccuracy(halconResult.hanYin_Width, 4) + "mm", cv::Point(100, 300), cv::Scalar(0, 0, 255));//焊印宽度 + if (hanyinChangEnable == true) + plcResult = "2"; } else { - textPainter.putText(Paint, "算法NG", cv::Point(4000, 350), cv::Scalar(0, 255, 0)); - plcResult = "2"; - data->halconOK = false; + textPainter.putText(Paint, "焊印长度" + controlAccuracy(halconResult.hanYin_Width, 4) + "mm", cv::Point(100, 300), cv::Scalar(0, 255, 0));//焊印宽度 + } + + if (halconResult.hanYin_Height > hanyinKuanLimitHigh || halconResult.hanYin_Height < hanyinKuanLimitLow) { + textPainter.putText(Paint, "焊印宽度" + controlAccuracy(halconResult.hanYin_Height, 4) + "mm", cv::Point(100, 550), cv::Scalar(0, 0, 255));//焊印高度 + if (hanyinKuanEnable == true) + plcResult = "2"; + } + else { + textPainter.putText(Paint, "焊印宽度" + controlAccuracy(halconResult.hanYin_Height, 4) + "mm", cv::Point(100, 550), cv::Scalar(0, 255, 0));//焊印高度 } - plcResult = "1"; silieResultText = "1"; fanzheResultText = "1"; + if (halconResult.jiErHeight > jierChangLimitHigh || halconResult.jiErHeight < jierChangLimitLow) { + textPainter.putText(Paint, "极耳裁切长度" + controlAccuracy(halconResult.jiErHeight, 4) + "mm", cv::Point(100, 50), cv::Scalar(0, 0, 255));//极耳高度 + if (hanyinKuanEnable == true) + plcResult = "2"; + } + else { + textPainter.putText(Paint, "极耳裁切长度" + controlAccuracy(halconResult.jiErHeight, 4) + "mm", cv::Point(100, 50), cv::Scalar(0, 255, 0));//极耳高度 + } + if (plcResult == "2" || halconResult.result == false) { + textPainter.putText(Paint, "算法NG", cv::Point(4200, 350), cv::Scalar(0, 0, 255)); + data->halconOK = false; + } + if(data->service->_paramSyncManager->get("通用设置","强制OK", false).toBool() == true) + plcResult = "1"; + + data->sqlVec.insert({ {"焊印长度",halconResult.hanYin_Width }, { "焊印宽度",halconResult.hanYin_Height }, { "极耳裁切长度",halconResult.jiErHeight } }); +#pragma endregion + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr) + "_" + silieResultText);//发送数据-撕裂OKNG data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 1) + "_" + fanzheResultText);//发送数据-翻折OKNG data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(halconResult.jiErWidth));//发送数据-极耳宽 data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(halconResult.jiErHeight));//发送数据-极耳高 data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_1");//发送数据-焊印位置判定结果 - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 8) + "_" + QByteArray::number(halconResult.hanYin1));//发送数据-芯包顶部到焊印的距离 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 8) + "_" + QByteArray::number(halconResult.hanYin_Distance_Down));//发送数据-芯包顶部到焊印的距离 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 10) + "_" + QByteArray::number(halconResult.hanYin_Width));//发送数据-极耳宽 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 12) + "_" + QByteArray::number(halconResult.hanYin_Height));//发送数据-极耳高 - textPainter.putText(Paint, "极耳宽度" + std::to_string(halconResult.jiErWidth), cv::Point(100, 50), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "极耳高度" + std::to_string(halconResult.jiErHeight), cv::Point(100, 300), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "焊印上边缘到极耳上边缘高度" + std::to_string(halconResult.hanYin1), cv::Point(100, 550), cv::Scalar(0, 255, 0)); + //textPainter.putText(Paint, "极耳裁切宽度" + std::to_string(halconResult.jiErWidth), cv::Point(100, 50), cv::Scalar(0, 255, 0));//极耳宽度,暂时不显示 + + + + textPainter.putText(Paint, "焊印面积" + controlAccuracy(halconResult.hanYin_Area, 4) + "mm²", cv::Point(100, 800), cv::Scalar(0, 255, 0));//焊印面积 + textPainter.putText(Paint, "焊印上边缘到极耳上边缘高度" + controlAccuracy(halconResult.hanYin_Distance_Up, 4) + "mm", cv::Point(100, 1050), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "焊印下边缘到极耳下边缘高度" + controlAccuracy(halconResult.hanYin_Distance_Down, 4) + "mm", cv::Point(100, 1300), cv::Scalar(0, 255, 0)); cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); data->resultImgs.push_back(Paint); return true; -#endif } CATCH_EXCEPTIONS @@ -200,38 +247,23 @@ bool hanHouCeLiang(std::shared_ptr data, yuHanHanHouParams* _detParams if (Paint.channels() == 1) cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); TextRendererZH textPainter(Paint.cols, Paint.rows, 300); - textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 0, 255)); cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); data->resultImgs.push_back(Paint); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + if (data->service->_paramSyncManager->get("通用设置","强制OK", false).toBool() == true) + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + else + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//结果反馈 return true; } bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address) { QByteArray plcResult = "2"; - try{ -#if 0 - /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ - QString resultTag = "OK"; - Mat srcImage; - srcImage = img2D.clone(); - cv::Mat dstImage; - srcImage.copyTo(dstImage); - cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5); - putTextHusky(dstImage, utf8_to_gbk("AI_OK").c_str(), cv::Point(1800, 50), cv::Scalar(0, 255, 0), 200); - cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5); - resMat.push_back(dstImage); - addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, resultTag)); - addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, resultTag)); - return true; - /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ - -#else - //存图数据加保存队列,加锁,避免数据访问冲突 + try { cv::Mat sourceImg = data->oriImgs[0]; + //sourceImg = cv::imread("./testImages/"+ std::to_string(_detParams->cameraIndex) +".bmp"); cv::Mat Paint; sourceImg.copyTo(Paint); - if (Paint.channels() == 1) cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); @@ -252,19 +284,24 @@ bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, s //SEG缺陷检测 cv::Mat SegRes = ~_detParams->segHanHou->Evaluate(matDet); + data->segOriginImgs.push_back(matDet); bool silieOk = true, fanZheOk = true; std::vector clsImgs; - handleAiProcess(sourceImg, SegRes, Paint, silieOk, fanZheOk, cv::Point(rect.x * resizeRate, rect.y * resizeRate), _detParams->clsHanHou, clsImgs); + if (_detParams->cameraIndex > 4) { + handleAiProcess(sourceImg, SegRes, Paint, silieOk, fanZheOk, cv::Point(rectCutJier.x, rectCutJier.y), _detParams->clsHanHou, clsImgs); + } QString okNgSaveText = "OK"; QByteArray silieResultText = silieOk == true ? "1" : "2"; QByteArray fanzheResultText = fanZheOk == true ? "1" : "2"; plcResult = "1"; + cv::Rect cutPaintRect = cv::Rect(rectCutJier.x - 100, rectCutJier.y - 100, rectCutJier.width + 200, rectCutJier.height + 200) & cv::Rect(0, 0, sourceImg.cols, sourceImg.rows); + Paint = Paint(cutPaintRect).clone();//裁切结果图,确保界面只显示一个极耳 TextRendererZH textPainter(Paint.cols, Paint.rows, 200); if (silieOk == true && fanZheOk == true) {//OK - textPainter.putText(Paint, "OK", cv::Point(3000, 50), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "OK", cv::Point(50, 50), cv::Scalar(0, 255, 0)); } else { - textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(3000, 50), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(50, 50), cv::Scalar(0, 0, 255)); plcResult = "2"; data->aiDetOK = false; } @@ -274,7 +311,6 @@ bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, s cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); data->resultImgs.push_back(Paint); return true; -#endif } CATCH_EXCEPTIONS @@ -284,7 +320,7 @@ bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, s if (Paint.channels() == 1) cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); TextRendererZH textPainter(Paint.cols, Paint.rows, 300); - textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 0, 255)); cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); data->resultImgs.push_back(Paint); data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 @@ -292,8 +328,11 @@ bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, s } + + + mission* createMission() { - return new _581_YuHan_hanhou(); + return new _581_YuHan_hanqian(); } void destroyMission(mission* _mission) { delete _mission; diff --git a/src/mission/YuHan/581_YuHan_hanhou/581_YuHan_hanhou.h b/src/mission/YuHan/581_YuHan_hanhou/581_YuHan_hanhou.h new file mode 100644 index 0000000..5504f1c --- /dev/null +++ b/src/mission/YuHan/581_YuHan_hanhou/581_YuHan_hanhou.h @@ -0,0 +1,156 @@ +#include +#include +#pragma region 算法 +#include +#include +#include +using namespace HDevEngineCpp; +#pragma endregion +class yuHanHanHouParams { +public: + handdleAI::pSegmentation* segHanYinZhuaQu = nullptr; + handdleAI::pSegmentation* segYuHanDingWei = nullptr; + handdleAI::pSegmentation* segHanHou = nullptr; + handdleAI::pClassification* clsHanHou = nullptr; + int cameraIndex = 1; + bool isTong = true; +}; +struct halconResult { + bool result = true; + double hanYin_Width = -1;//焊印宽度 + double hanYin_Height = -1;//焊印高度 + double hanYin_Area = -1;//焊印面积 + double jiErWidth = -1;//极耳的宽度 + double jiErHeight = -1;//极耳的高度 + double hanYin_Distance_Up = -1;//焊印上边缘到极耳上边缘的距离 + double hanYin_Distance_Down = -1;//焊印下边缘到极耳下边缘的距离 +}; +void handleAiProcess(cv::Mat& src, cv::Mat& segRes, cv::Mat& Paint, + bool& silieResult, bool& fanZheResult, + cv::Point offset, handdleAI::pClassification* clsPtr, std::vector& clsImgs,int sgin); +halconResult halconAlgoProcess(cv::Mat& img, cv::Mat& Paint, handdleAI::pSegmentation* seg_hanYinZhuaQu, cv::Mat& segResult); +bool hanHouCeLiang(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address); +bool hanHouDown(std::shared_ptr data, yuHanHanHouParams* _detParams, sx_581_address address); +class _581_YuHan_hanqian : public mission { +public: + _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_top90_1; + _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_down90_2; + _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_top90_3; + _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_down90_4; + + _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_top45_5; + _581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_down45_6; + _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_top45_7; + _581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_down45_8; + + //std::vector < yuHanHanHouParams> tongDetParams; + //std::vector < yuHanHanHouParams> lvDetParams; + + std::vector < yuHanHanHouParams> tong_90_DetParams; + std::vector < yuHanHanHouParams> lv_90_DetParams; + + std::vector < yuHanHanHouParams> dibu_45_tong_DetParams; + std::vector < yuHanHanHouParams> dingbu_45_tong_DetParams; + + std::vector < yuHanHanHouParams> dibu_45_lv_DetParams; + std::vector < yuHanHanHouParams> dingbu_45_lv_DetParams; + bool initOnce = false; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_602.hdpl"); + if (initOnce == false) { + for (int i = 0; i < 2; i++) + { + yuHanHanHouParams tong_90; + /*tong_90.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuHanDingWei-90-T-seg.BHD", 64, 0); + tong_90.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-T.BHD", 64, 0); + tong_90.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanhanHou-T.BHD", 64, 0); + tong_90.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/cls-yuHanhanHou-T.BHD", 0, 1);*/ + tong_90_DetParams.push_back(tong_90); + + yuHanHanHouParams lv_90; + /*lv_90.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuHanDingWei-90-L-seg.BHD", 64, 1); + lv_90.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-L.BHD", 64, 1); + lv_90.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanhanHou-L.BHD", 64, 1); + lv_90.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/cls-yuHanhanHou-L.BHD", 1, 1);*/ + lv_90_DetParams.push_back(lv_90); + + } + + yuHanHanHouParams dibu_45_lv; + //dibu_45_lv.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuHanDingWei-45-L-seg.BHD", 64, 1); + //dibu_45_lv.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-L.BHD", 64, 1); + //dibu_45_lv.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuHanhanHou-dibu-45-L-seg.BHD", 64, 1); + //dibu_45_lv.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/yuHanhanHou-dibu-45-L-cls.BHD", 1, 1); + dibu_45_lv_DetParams.push_back(dibu_45_lv); + + yuHanHanHouParams dibu_45_tong; + //dibu_45_tong.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuHanDingWei-45-T-seg.BHD", 64, 0); + //dibu_45_tong.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-T.BHD", 64, 0); + //dibu_45_tong.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuHanhanHou-dibu-45-T-seg.BHD", 64, 0); + //dibu_45_tong.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/yuHanhanHou-dibu-45-T-cls.BHD", 0, 1); + dibu_45_tong_DetParams.push_back(dibu_45_tong); + + yuHanHanHouParams dingbu_45_lv; + //dingbu_45_lv.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuHanDingWei-45-L-seg.BHD", 64, 1); + //dingbu_45_lv.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-L.BHD", 64, 1); + //dingbu_45_lv.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuHanhanHou-dingbu-45-L-seg.BHD", 64, 1); + //dingbu_45_lv.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/yuHanhanHou-45-L-cls.BHD", 1, 1);//未更新 + dingbu_45_lv_DetParams.push_back(dingbu_45_lv); + + yuHanHanHouParams dingbu_45_tong; + //dingbu_45_tong.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuHanDingWei-45-T-seg.BHD", 64, 0); + //dingbu_45_tong.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-T.BHD", 64, 0); + //dingbu_45_tong.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/yuHanhanHou-dingbu-45-T-seg.BHD", 64, 0); + //dingbu_45_tong.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/yuHanhanHou-dingbu-45-T-cls.BHD", 0, 1); + dingbu_45_tong_DetParams.push_back(dingbu_45_tong); + + initOnce = true; + } + + + lv_90_DetParams[0].cameraIndex = 1; + lv_90_DetParams[1].cameraIndex = 2; + tong_90_DetParams[0].cameraIndex = 3; + tong_90_DetParams[1].cameraIndex = 4; + + dingbu_45_lv_DetParams[0].cameraIndex = 5; + dibu_45_lv_DetParams[0].cameraIndex = 6; + dingbu_45_tong_DetParams[0].cameraIndex = 7; + dibu_45_tong_DetParams[0].cameraIndex = 8; + + } + bool initCustom() { +#pragma region 注册触发器回调 + if (_serviceManager->_paramSyncManager->get("内外侧判断", "hanhou", "OUT") == "OUT") { + lv_top90_1.init("Camera1", "极耳尺寸-外-铝-相机1(顶部90°)", { { 522, 1,{540},"523","530",820} }, 1, &lv_90_DetParams[0], _serviceManager, bridge, hanHouCeLiang); + lv_down90_2.init("Camera2", "极耳尺寸-外-铝-相机2(底部90°)", { { 524, 1,{540},"525","532",-1} }, 1, &lv_90_DetParams[1], _serviceManager, bridge, hanHouDown); + tong_top90_3.init("Camera3", "极耳尺寸-外-铜-相机3(顶部90°)", { { 526,1,{540},"527","534",800} }, 1, &tong_90_DetParams[0], _serviceManager, bridge, hanHouCeLiang); + tong_down90_4.init("Camera4", "极耳尺寸-外-铜-相机4(底部90°)", { { 528, 1,{540},"529","536",-1} }, 1, &tong_90_DetParams[1], _serviceManager, bridge, hanHouDown); + + lv_top45_5.init("Camera5", "底部撕裂-外-铝-相机5(顶部45°)", { { 562,1,{540},"563","570",-1} }, 1, &dingbu_45_lv_DetParams[0], _serviceManager, bridge, hanHouDown); + lv_down45_6.init("Camera6", "底部撕裂-外-铝-相机6(底部45°)", { { 564, 1,{540},"565","572",-1} }, 1, &dibu_45_lv_DetParams[0], _serviceManager, bridge, hanHouDown); + tong_top45_7.init("Camera7", "底部撕裂-外-铜-相机7(顶部45°)", { { 566, 1,{540},"567","574",-1} }, 1, &dingbu_45_tong_DetParams[0], _serviceManager, bridge, hanHouDown); + tong_down45_8.init("Camera8", "底部撕裂-外-铜-相机8(底部45°)", { { 568, 1,{540},"569","576",-1} }, 1, &dibu_45_tong_DetParams[0], _serviceManager, bridge, hanHouDown); + } + else { + lv_top90_1.init("Camera1", "极耳尺寸-内-铝-相机1(顶部90°)", { { 602, 1,{580},"603","610",860} }, 1, &lv_90_DetParams[0], _serviceManager, bridge, hanHouCeLiang); + lv_down90_2.init("Camera2", "极耳尺寸-内-铝-相机2(底部90°)", { { 604, 1,{580},"605","612",-1} }, 1, &lv_90_DetParams[1], _serviceManager, bridge, hanHouDown); + tong_top90_3.init("Camera3", "极耳尺寸-内-铜-相机3(顶部90°)", { { 606,1,{580},"607","614",840} }, 1, &tong_90_DetParams[0], _serviceManager, bridge, hanHouCeLiang); + tong_down90_4.init("Camera4", "极耳尺寸-内-铜-相机4(底部90°)", { { 608, 1,{580},"609","616",-1} }, 1, &tong_90_DetParams[1], _serviceManager, bridge, hanHouDown); + + lv_top45_5.init("Camera5", "底部撕裂-内-铝-相机5(顶部45°)", { { 642,1,{580},"643","650",-1} }, 1, &dingbu_45_lv_DetParams[0], _serviceManager, bridge, hanHouDown); + lv_down45_6.init("Camera6", "底部撕裂-内-铝-相机6(底部45°)", { { 644, 1,{580},"645","652",-1} }, 1, &dibu_45_lv_DetParams[0], _serviceManager, bridge, hanHouDown); + tong_top45_7.init("Camera7", "底部撕裂-内-铜-相机7(顶部45°)", { { 646, 1,{580},"647","654",-1} }, 1, &dingbu_45_tong_DetParams[0], _serviceManager, bridge, hanHouDown); + tong_down45_8.init("Camera8", "底部撕裂-内-铜-相机8(底部45°)", { { 648, 1,{580},"649","656",-1} }, 1, &dibu_45_tong_DetParams[0], _serviceManager, bridge, hanHouDown); + } +#pragma endregion + return true; + } +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/YuHan/581_YuHan_hanhou/CMakeLists.txt b/src/mission/YuHan/581_YuHan_hanhou/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/YuHan/581_YuHan_hanhou/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/581_YuHan_hanqian/581_YuHan_hanqian.cpp b/src/mission/YuHan/581_YuHan_hanqian/581_YuHan_hanqian.cpp similarity index 100% rename from src/mission/581_YuHan_hanqian/581_YuHan_hanqian.cpp rename to src/mission/YuHan/581_YuHan_hanqian/581_YuHan_hanqian.cpp diff --git a/src/mission/581_YuHan_hanqian/581_YuHan_hanqian.h b/src/mission/YuHan/581_YuHan_hanqian/581_YuHan_hanqian.h similarity index 92% rename from src/mission/581_YuHan_hanqian/581_YuHan_hanqian.h rename to src/mission/YuHan/581_YuHan_hanqian/581_YuHan_hanqian.h index d0bf975..5d13766 100644 --- a/src/mission/581_YuHan_hanqian/581_YuHan_hanqian.h +++ b/src/mission/YuHan/581_YuHan_hanqian/581_YuHan_hanqian.h @@ -68,7 +68,7 @@ bool handleAiProcess(cv::Mat& seg_detImg, cv::Mat& seg_Paint, for (int i = 0; i < contours.size(); i++) { cv::Rect cls_rect = cv::boundingRect(contours[i]); - if (cls_rect.width < 50 || cls_rect.height < 50) + if (cls_rect.width < 200 || cls_rect.height < 200) continue; #if 1 std::vector clsImgVec = cutImg2ClsVec(cls_rect, seg_detImg); @@ -148,11 +148,12 @@ bool jiErFanZhe(std::shared_ptr data, yuHanHanQianParams* _detParams, } addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, okng_tag));//存原图图 - return true; + return true; /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ #else + bool detEnable = data->service->_paramSyncManager->get("极耳翻折","极耳翻折判定启用", true).toBool(); //存图数据加保存队列,加锁,避免数据访问冲突 - QByteArray plcResult = "2"; + QByteArray plcResult = "1"; cv::Mat sourceImg; data->oriImgs[0].copyTo(sourceImg); cv::Mat Paint; @@ -164,11 +165,12 @@ bool jiErFanZhe(std::shared_ptr data, yuHanHanQianParams* _detParams, auto rect = getImageLocateRect(sourceImg, _detParams->segDingWei, 1.0 / resizeRate);//定位 rect = rect & (cv::Rect(0, 0, sourceImg.cols, sourceImg.rows));//防止越界 bool isNG = false; - cv::Mat seg_saveImg; + cv::Mat seg_CutImg,seg_LocateImg; + sourceImg(rect).copyTo(seg_CutImg); + cv::resize(sourceImg, seg_LocateImg, cv::Size(), 0.2, 0.2); if (rect.width > 500 || rect.height > 500) { isNG = handleAiProcess(sourceImg(rect), Paint(rect), _detParams->segJiErFanZhe, _detParams->clsJiErFanZhe, data->clsOriginImgs); cv::rectangle(Paint, rect, cv::Scalar(0, 255, 255), 3); - cv::resize(sourceImg(rect), seg_saveImg, cv::Size(), 0.5, 0.5); } else { isNG = true; @@ -182,14 +184,17 @@ bool jiErFanZhe(std::shared_ptr data, yuHanHanQianParams* _detParams, } else { - textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 0, 255)); data->aiDetOK = false; - plcResult = "2"; + if(data->service->_paramSyncManager->get("通用设置","极耳翻折判定启用", true).toBool() == true) + plcResult = "2"; } - plcResult = "1";//强制OK - data->resultImgs.push_back(Paint); - sourceImg.release(); + if(data->service->_paramSyncManager->get("通用设置","强制OK", false).toBool() == true) + plcResult = "1";//强制OK data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + data->segOriginImgs.push_back(seg_CutImg); + data->segOriginImgs.push_back(seg_LocateImg); + data->resultImgs.push_back(Paint); return true; #endif } @@ -228,13 +233,13 @@ public: if (initOnce == false) { for (auto& params : tongDetParams) { params.segDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/60_2_hanqian_dingwei_seg.BHD", 64, 0); - params.segJiErFanZhe = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/60_2_hanqian_segT.BHD", 64, 0); - params.clsJiErFanZhe = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanqian/60_2_hanqian_clsT.BHD", 0, 1); + params.segJiErFanZhe = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/hanqian_T-seg.BHD", 64, 0); + params.clsJiErFanZhe = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanqian/hanqian_T-cls.BHD", 0, 1); } for (auto& params : lvDetParams) { params.segDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/60_2_hanqian_dingwei_seg.BHD", 64, 1); - params.segJiErFanZhe = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/60_2_hanqian_segL.BHD", 64, 1); - params.clsJiErFanZhe = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanqian/60_2_hanqian_clsL.BHD", 1, 1); + params.segJiErFanZhe = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/hanqian_L-seg.BHD", 64, 1); + params.clsJiErFanZhe = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanqian/hanqian_L-cls.BHD", 1, 1); params.isTong = false; } initOnce = true; diff --git a/src/mission/YuHan/581_YuHan_hanqian/CMakeLists.txt b/src/mission/YuHan/581_YuHan_hanqian/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/YuHan/581_YuHan_hanqian/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/YuHan/581_YuHan_jixing/581_YuHan_jixing.cpp b/src/mission/YuHan/581_YuHan_jixing/581_YuHan_jixing.cpp new file mode 100644 index 0000000..7760162 --- /dev/null +++ b/src/mission/YuHan/581_YuHan_jixing/581_YuHan_jixing.cpp @@ -0,0 +1,8 @@ +#include <581_YuHan_jixing.h> + +mission* createMission() { + return new _581_YuHan_hanqian(); +} +void destroyMission(mission* _mission) { + delete _mission; +} \ No newline at end of file diff --git a/src/mission/YuHan/581_YuHan_jixing/581_YuHan_jixing.h b/src/mission/YuHan/581_YuHan_jixing/581_YuHan_jixing.h new file mode 100644 index 0000000..d67e066 --- /dev/null +++ b/src/mission/YuHan/581_YuHan_jixing/581_YuHan_jixing.h @@ -0,0 +1,177 @@ +#include +#include +#pragma region 算法 +#include +#include +#include +using namespace HDevEngineCpp; +#pragma endregion +class yuHanParams { +public: + + bool isTong = true; +}; +bool halconProcess(cv::Mat& sourceImg, cv::Mat& Paint) { + try { + HDevEngineCpp::HDevProcedure proc("YH_Color_Inspection"); + HDevEngineCpp::HDevProcedureCall procedureCall(proc); + HObject in_Image = MatToHObject(sourceImg); + procedureCall.SetInputIconicParamObject("in_Image", in_Image);//设置输入图像类变量 + procedureCall.Execute();//执行halcon程序 + HTuple out_ColorType; + HTuple out_Flag; + out_ColorType = procedureCall.GetOutputCtrlParamTuple("out_ColorType");//获取输出图像类变量 + out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 + //相机2 OK为铜 NG为铝 + if (out_Flag.D() == 1) + { + if (out_ColorType.D() == 1)//铜 + { + //cv::putText(Paint, "OK", cv::Point(0, 550), 2, 10, cv::Scalar(0, 255, 0), 10); + return true; + } + else//铝 + { + //cv::putText(Paint, "NG", cv::Point(0, 550), 2, 10, cv::Scalar(0, 0, 255), 10); + return false; + } + } + else + { + //cv::putText(Paint, "NG", cv::Point(0, 550), 2, 10, cv::Scalar(0, 0, 255), 10); + return false; + } + } + catch (HDevEngineCpp::HDevEngineException& ex) { + + std::cout << "HDevEngineException: " << ex.Message() << std::endl; \ + qDebug() << "HDevEngineException: " << ex.Message(); \ + } + catch (HalconCpp::HException& ex) { + + std::cout << "Halcon Exception Caught!" << std::endl; \ + std::cout << "Error Code: " << ex.ErrorCode() << std::endl; \ + std::cout << "Error Message: " << ex.ErrorMessage() << std::endl; \ + qDebug() << "Halcon Exception Caught!"; \ + qDebug() << "Error Code: " << ex.ErrorCode(); \ + qDebug() << "Error Message: " << ex.ErrorMessage(); \ + } +} +bool jixingjiance(std::shared_ptr data, yuHanParams* detParams, sx_581_address address) { + try{ +#if 0 + /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ + cv::Mat resultImage = img2D.clone(); + if (resultImage.channels() == 1) { + cv::cvtColor(resultImage, resultImage, cv::COLOR_GRAY2BGR); + } + QString okng_tag = "OK"; + cv::Mat seg_detectImage; + cv::resize(img2D, seg_detectImage, cv::Size(), 1, 1); + plcResult = "1"; + bool isNG = false; + if (DOGLIVE) { + std::vector>clsImgs; + bool isNG = handleAiProcess(seg_detectImage, resultImage, seg_jierFanZhe, cls_jierFanZhe, clsImgs); + for (int i = 0; i < clsImgs.size(); i++) { + addImgToSaveStruct(clsImgs[i].second, "0", getClsSaveFormat(SN, okng_tag, i, clsImgs[i].first)); + } + } + if (isNG == false)//OK + { + putTextHusky(resultImage, utf8_to_gbk("OK").c_str(), cv::Point(50, 50), cv::Scalar(0, 255, 0), 200); + okng_tag = "OK"; + } + else + { + putTextHusky(resultImage, utf8_to_gbk("NG").c_str(), cv::Point(50, 50), cv::Scalar(0, 0, 255), 200); + plcResult = "2"; + } + cv::resize(resultImage, resultImage, cv::Size(), 0.5, 0.5); + resMat.push_back(resultImage); + if (resMat.size() > 0) + { + addImgToSaveStruct(seg_detectImage, "0", getSegSaveFormat(SN, okng_tag));//存seg图 + addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, okng_tag));//存结果图 + } + addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, okng_tag));//存原图图 + + return true; + /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/ +#else + //存图数据加保存队列,加锁,避免数据访问冲突 + bool jiXingEnable = data->service->_paramSyncManager->get("极性","极性判定启用", true).toBool(); + QByteArray plcResult = "1"; + cv::Mat sourceImg; + data->oriImgs[0].copyTo(sourceImg); + cv::Mat Paint; + sourceImg.copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + bool isNG = halconProcess(sourceImg, Paint); + + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + if (isNG)//OK + { + textPainter.putText(Paint, "OK", cv::Point(100, 50), cv::Scalar(0, 255, 0)); + } + else + { + textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 0, 255)); + data->halconOK = false; + if(jiXingEnable == true) + plcResult = "2"; + } + if (jiXingEnable == false) + plcResult = "1";//强制OK + data->resultImgs.push_back(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + return true; +#endif + } + CATCH_EXCEPTIONS + + qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + cv::Mat Paint; + data->oriImgs[0].copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + TextRendererZH textPainter(Paint.cols, Paint.rows, 15); + textPainter.putText(Paint, "NG", cv::Point(1000, 50), cv::Scalar(0, 255, 0)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->resultImgs.push_back(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + return true; +} +class _581_YuHan_hanqian : public mission { +public: + _581_SX_Single_triggerTemplate< yuHanParams> in_lv_top_1; + _581_SX_Single_triggerTemplate< yuHanParams> in_lv_down_2; + _581_SX_Single_triggerTemplate< yuHanParams> in_tong_top_3; + _581_SX_Single_triggerTemplate< yuHanParams> in_tong_down_4; + + yuHanParams tongDetParams; + yuHanParams lvDetParams; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); + + lvDetParams.isTong = false; + } + bool initCustom() { +#pragma region 注册触发器回调 + in_lv_top_1.init("Camera1", "极性检测-相机1", { { 400, 1,{410},"401","402",-1} }, 1, &lvDetParams, _serviceManager, bridge, jixingjiance); + in_lv_down_2.init("Camera2", "极性检测-相机2", { { 430, 1,{440},"431","432",-1 }}, 1, & lvDetParams, _serviceManager, bridge, jixingjiance); + in_tong_top_3.init("Camera3", "极性检测-相机3", { { 460,1,{470},"461","462",-1} }, 1, &tongDetParams, _serviceManager, bridge, jixingjiance); + in_tong_down_4.init("Camera4", "极性检测-相机4", { { 490, 1,{500},"491","492",-1 }}, 1, & tongDetParams, _serviceManager, bridge, jixingjiance); + +#pragma endregion + return true; + } +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/YuHan/581_YuHan_jixing/CMakeLists.txt b/src/mission/YuHan/581_YuHan_jixing/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/YuHan/581_YuHan_jixing/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/YuHan/CMakeLists.txt b/src/mission/YuHan/CMakeLists.txt new file mode 100644 index 0000000..f9a95fd --- /dev/null +++ b/src/mission/YuHan/CMakeLists.txt @@ -0,0 +1,11 @@ +# CMakeList.txt: 遍历文件夹 添加子项目 + +set(OUR_LIBS "") +SUBDIRENAMES(OUR_LIBS ${CMAKE_CURRENT_SOURCE_DIR} "" OFF) +message("OUR_LIBS :" ${OUR_LIBS}) + + +# 遍历子库 +foreach(dll ${OUR_LIBS}) + add_subdirectory(${dll}) +endforeach(dll ${}) diff --git a/src/mission/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.cpp b/src/mission/ZhongHan/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.cpp similarity index 100% rename from src/mission/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.cpp rename to src/mission/ZhongHan/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.cpp diff --git a/src/mission/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.h b/src/mission/ZhongHan/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.h similarity index 100% rename from src/mission/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.h rename to src/mission/ZhongHan/581_ZhongHan_dibutiejiao/581_ZhongHan_dibutiejiao.h diff --git a/src/mission/ZhongHan/581_ZhongHan_dibutiejiao/CMakeLists.txt b/src/mission/ZhongHan/581_ZhongHan_dibutiejiao/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/ZhongHan/581_ZhongHan_dibutiejiao/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp b/src/mission/ZhongHan/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp similarity index 97% rename from src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp rename to src/mission/ZhongHan/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp index 39cd41c..58e705e 100644 --- a/src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp +++ b/src/mission/ZhongHan/581_ZhongHan_hanhou/581_ZhongHan_hanhou.cpp @@ -128,7 +128,9 @@ bool zhongHan_hanHouCeLiang(std::shared_ptr data, zhongHan2dCeLiangPar textPainter.putText(Paint, "上焊印长:" + QString::number(out_HYValues1[0].D(),'f', 3).toStdString() + "mm", cv::Point(50, 360), cv::Scalar(0, 255, 0)); textPainter.putText(Paint, "上焊印宽:" + QString::number(out_HYValues1[1].D(),'f', 3).toStdString() + "mm", cv::Point(50, 480), cv::Scalar(0, 255, 0)); textPainter.putText(Paint, "上焊印面积:" + QString::number(out_HYValues1[2].D(), 'f', 3).toStdString() + "mm²", cv::Point(50, 600), cv::Scalar(0, 255, 0)); - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(out_Distance1[1].D())); + + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(out_Distance1[2].D())); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(out_Distance1[2].D())); } //2 { @@ -143,8 +145,12 @@ bool zhongHan_hanHouCeLiang(std::shared_ptr data, zhongHan2dCeLiangPar else { textPainter.putText(Paint, "下焊印右边缘到连接片圆心竖直间距:" + QString::number(out_Distance2[1].D(), 'f', 3).toStdString() + "mm", cv::Point(50, cutImage.rows - 170), cv::Scalar(0, 255, 0)); } + xingBaoDingBuDaoHanYinJianJu = (out_Distance1[2].D() + out_Distance2[2].D())/2; + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 8) + "_" + QByteArray::number(out_Distance2[2].D())); + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 10) + "_" + QByteArray::number(out_Distance2[2].D())); + if (data->cameraKeyName == "Camera1") data->service->_triggerManager->writeFloat("D5820_" + QByteArray::number(xingBaoDingBuDaoHanYinJianJu)); else diff --git a/src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.h b/src/mission/ZhongHan/581_ZhongHan_hanhou/581_ZhongHan_hanhou.h similarity index 100% rename from src/mission/581_ZhongHan_hanhou/581_ZhongHan_hanhou.h rename to src/mission/ZhongHan/581_ZhongHan_hanhou/581_ZhongHan_hanhou.h diff --git a/src/mission/ZhongHan/581_ZhongHan_hanhou/CMakeLists.txt b/src/mission/ZhongHan/581_ZhongHan_hanhou/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/ZhongHan/581_ZhongHan_hanhou/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.cpp b/src/mission/ZhongHan/581_ZhongHan_hanqian/581_ZhongHan_hanqian.cpp similarity index 100% rename from src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.cpp rename to src/mission/ZhongHan/581_ZhongHan_hanqian/581_ZhongHan_hanqian.cpp diff --git a/src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h b/src/mission/ZhongHan/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h similarity index 98% rename from src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h rename to src/mission/ZhongHan/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h index 7b3ba38..888720f 100644 --- a/src/mission/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h +++ b/src/mission/ZhongHan/581_ZhongHan_hanqian/581_ZhongHan_hanqian.h @@ -174,11 +174,6 @@ bool hanQianCeLiang_Main(std::shared_ptr data, zhongHanHanQianParams* cv::drawMarker(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), cv::Scalar(0, 255, 0), cv::MARKER_CROSS, 200, 5); cv::circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 5); } - cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); - plcResult = "1";//强制OK - data->resultImgs.push_back(Paint); - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 - return true; } else{ std::string errTails = out_NGTails.S().Text(); @@ -192,6 +187,7 @@ bool hanQianCeLiang_Main(std::shared_ptr data, zhongHanHanQianParams* plcResult = "1";//强制OK data->resultImgs.push_back(Paint); data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 return true; } CATCH_EXCEPTIONS diff --git a/src/mission/ZhongHan/581_ZhongHan_hanqian/CMakeLists.txt b/src/mission/ZhongHan/581_ZhongHan_hanqian/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/ZhongHan/581_ZhongHan_hanqian/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.cpp b/src/mission/ZhongHan/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.cpp similarity index 100% rename from src/mission/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.cpp rename to src/mission/ZhongHan/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.cpp diff --git a/src/mission/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.h b/src/mission/ZhongHan/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.h similarity index 100% rename from src/mission/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.h rename to src/mission/ZhongHan/581_ZhongHan_silie_jixing/581_ZhongHan_silie_jixing.h diff --git a/src/mission/ZhongHan/581_ZhongHan_silie_jixing/CMakeLists.txt b/src/mission/ZhongHan/581_ZhongHan_silie_jixing/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/ZhongHan/581_ZhongHan_silie_jixing/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.cpp b/src/mission/ZhongHan/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.cpp similarity index 100% rename from src/mission/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.cpp rename to src/mission/ZhongHan/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.cpp diff --git a/src/mission/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.h b/src/mission/ZhongHan/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.h similarity index 100% rename from src/mission/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.h rename to src/mission/ZhongHan/581_ZhongHan_tiejiao_dingbu/581_ZhongHan_tiejiao_dingbu.h diff --git a/src/mission/ZhongHan/581_ZhongHan_tiejiao_dingbu/CMakeLists.txt b/src/mission/ZhongHan/581_ZhongHan_tiejiao_dingbu/CMakeLists.txt new file mode 100644 index 0000000..76e9200 --- /dev/null +++ b/src/mission/ZhongHan/581_ZhongHan_tiejiao_dingbu/CMakeLists.txt @@ -0,0 +1,77 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES}) diff --git a/src/mission/ZhongHan/CMakeLists.txt b/src/mission/ZhongHan/CMakeLists.txt new file mode 100644 index 0000000..f9a95fd --- /dev/null +++ b/src/mission/ZhongHan/CMakeLists.txt @@ -0,0 +1,11 @@ +# CMakeList.txt: 遍历文件夹 添加子项目 + +set(OUR_LIBS "") +SUBDIRENAMES(OUR_LIBS ${CMAKE_CURRENT_SOURCE_DIR} "" OFF) +message("OUR_LIBS :" ${OUR_LIBS}) + + +# 遍历子库 +foreach(dll ${OUR_LIBS}) + add_subdirectory(${dll}) +endforeach(dll ${}) diff --git a/src/plugin/autoDelete/CMakeLists.txt b/src/plugin/autoDelete/CMakeLists.txt deleted file mode 100644 index a4b4bed..0000000 --- a/src/plugin/autoDelete/CMakeLists.txt +++ /dev/null @@ -1,71 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) - - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES LINKER_LANGUAGE C - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) diff --git a/src/plugin/autoDelete/autoDelete.cpp b/src/plugin/autoDelete/autoDelete.cpp deleted file mode 100644 index ee011fd..0000000 --- a/src/plugin/autoDelete/autoDelete.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include -IPlugin* createPlugin() { - return new autoDeletePlugin(); -} -void destroyPlxugin(IPlugin* plugin) { - delete plugin; -} \ No newline at end of file diff --git a/src/plugin/autoDelete/autoDelete.h b/src/plugin/autoDelete/autoDelete.h deleted file mode 100644 index 38b4fbd..0000000 --- a/src/plugin/autoDelete/autoDelete.h +++ /dev/null @@ -1,238 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/// -/// 自动删除文件夹,支持按日期删除,按磁盘剩余容量删除,或者两者都是,请在主线程声明qtimer -/// -class autoDelete : public QThread -{ - Q_OBJECT -public: - enum clearMode - { - dayBefore, - sizeOver, - sizeOverOrDayBefore, - }; - /// - /// 构造函数 - /// - /// 文件夹路径 - /// 删除几天前的,磁盘剩余容量小于多少,两者都是 - /// 检测间隔如果只检测日期建议设大一点,如果只检测磁盘容量建议设小一点,默认十分钟 - autoDelete(std::vector pathVec, clearMode mode, int Interval) - { - for (auto& path : pathVec) - detPathVec.push_back(QString::fromStdString(path)); - detMode = mode; - threadInterval = Interval; - this->start(); - } - ~autoDelete() - { - runFlag = false; - } - void run() override - { - while (runFlag) - { - exacute(); - QThread::sleep(threadInterval); - } - } - void exacute() - { - for (auto& detPath : detPathVec) - { - switch (detMode) - { - case dayBefore://删除几天前的 - deleteDirBeforeDays(detPath, daySet); - break; - case sizeOver://磁盘剩余容量小于多少 - if (getDriveFreeSpaceAsGb(detPath) < sizeSet) - deleteOldestSonDir(detPath);//删除最老的文件夹 - break; - case sizeOverOrDayBefore://两者都是 - if (getDriveFreeSpaceAsGb(detPath) < sizeSet)//磁盘剩余容量小于多少 - deleteOldestDir(detPath);//删除最老的文件夹 - deleteDirBeforeDays(detPath, daySet);//同时删除几天前的 - break; - default: - qDebug() << "none mode det"; - break; - } - } - } - void setDay(int day) - { - daySet = day; - } - void setSize(int size) - { - sizeSet = size; - } -private: - bool deleteOldestSonDir(const QString& folderPath) - { - QString oldestDir = getOldestDir(folderPath); - if (oldestDir.isEmpty()) - return false; - oldestDir = folderPath + "//" + oldestDir; - deleteOldestDir(oldestDir); - if (getAllDirs(oldestDir).size() == 0)//删除后文件夹为空,删除父文件夹 - { - QDir dir(oldestDir); - dir.removeRecursively(); - } - return true; - } - bool deleteDirBeforeDays(const QString& folderPath, int day) - { - std::vector dirs = getAllDirs(folderPath); - for (auto& dir : dirs) - { - QFileInfo fileInfo(QString::fromStdString(dir)); - QDateTime fileTime = fileInfo.created(); - QDateTime nowTime = QDateTime::currentDateTime(); - std::string result = fileTime.toString("yyyy-MM-dd").toStdString(); - int dayBefore = fileTime.daysTo(nowTime); - if (dayBefore > day) - { - QDir dir(QString::fromStdString(dir)); - dir.removeRecursively(); - } - } - return true; - } - /// - /// 检查磁盘剩余空间,以GB为单位返回 - /// - /// example"E://""E://111/222"支持文件夹或者磁盘路径 - /// - int getDriveFreeSpaceAsGb(const QString& folderPath) { - QStorageInfo storageInfo(folderPath); - - if (storageInfo.isValid() && storageInfo.isReady()) { - return storageInfo.bytesAvailable() / 1073741824; - } - - return -1; // Indicate failure to retrieve disk space - } - /// - /// 检查磁盘剩余空间,以Mb为单位返回 - /// - /// example"E://""E://111/222"支持文件夹或者磁盘路径 - /// - int getDriveFreeSpaceAsMb(const QString& folderPath) { - QStorageInfo storageInfo(folderPath); - - if (storageInfo.isValid() && storageInfo.isReady()) { - return storageInfo.bytesAvailable() / 1048576; - } - - return -1; // Indicate failure to retrieve disk space - } - /// - /// 返回最老创建时间文件夹名 - /// - /// - /// - QString getOldestDir(const QString& folderPath) - { - std::string oldestDir; - QDateTime oldestTime; - std::vector files = getAllDirs(folderPath); - for (auto file : files) - { - QFileInfo fileInfo(QString::fromStdString(folderPath.toStdString() + "//" + file)); - QDateTime fileTime = fileInfo.created(); - QString str = fileInfo.created().toString(); - std::cout << "Current date and time: " << str.toStdString() << std::endl; - if (oldestTime.isNull() || fileTime < oldestTime) - { - oldestTime = fileTime; - oldestDir = file; - } - } - return QString::fromStdString(oldestDir); - } - /// - /// 删除最老创建时间文件夹 - /// - /// - /// - bool deleteOldestDir(const QString& folderPath) - { - QString oldestDir = getOldestDir(folderPath); - if (oldestDir.isEmpty()) - return false; - oldestDir = folderPath + "//" + oldestDir; - QDir dir(oldestDir); - dir.removeRecursively(); - return true; - } - std::vector getAllDirs(const QString& folderPath) - { - std::vector foldersVec; - QDir folderDir(folderPath); - if (!folderDir.exists()) { - return foldersVec; - } - - QStringList folders = folderDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - - for (const QString& folder : folders) { - foldersVec.push_back(folderPath.toStdString() + "//" + folder.toStdString()); - } - return foldersVec; - } - std::vector detPathVec; - clearMode detMode; - int daySet = 30;//天 - int sizeSet = 100;//GB - int threadInterval = 0;//sec - bool runFlag = true; -}; - - -class autoDeletePlugin :public IPlugin -{ -public: - autoDelete _autoDelete; - autoDeletePlugin(): - _autoDelete({ "D://CCD" }, autoDelete::dayBefore, 3600) { - name = "hwMonitor"; - } - bool start() - { - _autoDelete.start(); - return true; - } - bool stop() - { - _autoDelete.terminate(); - _autoDelete.quit(); - return true; - } - pluginState getState() - { - return _autoDelete.isRunning() ? pluginState::running : pluginState::stop; - } -}; - -extern "C" -{ - __declspec(dllexport) IPlugin* createPlugin(); - __declspec(dllexport) void destroyPlxugin(IPlugin* plugin); -} - -#pragma once \ No newline at end of file diff --git a/src/plugin/hwMonitor/CMakeLists.txt b/src/plugin/hwMonitor/CMakeLists.txt deleted file mode 100644 index a4b4bed..0000000 --- a/src/plugin/hwMonitor/CMakeLists.txt +++ /dev/null @@ -1,71 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) - - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES LINKER_LANGUAGE C - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) -message( " header files "${HEAD_FILES}) diff --git a/src/plugin/hwMonitor/hardwareMonitor.cpp b/src/plugin/hwMonitor/hardwareMonitor.cpp deleted file mode 100644 index 08b7a82..0000000 --- a/src/plugin/hwMonitor/hardwareMonitor.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include -IPlugin* createPlugin() { - return new hardwareMonitorPlugin(); -} -void destroyPlugin(IPlugin* plugin) { - delete plugin; -} \ No newline at end of file diff --git a/src/plugin/hwMonitor/hardwareMonitor.h b/src/plugin/hwMonitor/hardwareMonitor.h deleted file mode 100644 index b09c937..0000000 --- a/src/plugin/hwMonitor/hardwareMonitor.h +++ /dev/null @@ -1,217 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class hardwareMonitor :public QThread -{ -public: - int outputCnt = 10; - struct CPUUsage { - DWORD_PTR coreId; - double usage; - }; - struct oneTimeData - { - QString time; - std::vectorcpuState; - std::vectormemState; - }; - std::vector getCPUUsagePerCore() { - std::vector coreUsages; - int numCores = sysInfo.dwNumberOfProcessors; - std::vector idleTimes(numCores), kernelTimes(numCores), userTimes(numCores); - std::vector prevIdleTimes(numCores), prevKernelTimes(numCores), prevUserTimes(numCores); - - // 初始获取 - GetSystemTimes(&prevIdleTimes[0], &prevKernelTimes[0], &prevUserTimes[0]); - - Sleep(100); - - // 获取再次的 CPU 时间 - GetSystemTimes(&idleTimes[0], &kernelTimes[0], &userTimes[0]); - - for (int i = 0; i < numCores; ++i) { - ULARGE_INTEGER idleTime, kernelTime, userTime; - ULARGE_INTEGER prevIdleTime, prevKernelTime, prevUserTime; - - idleTime.LowPart = idleTimes[i].dwLowDateTime; - idleTime.HighPart = idleTimes[i].dwHighDateTime; - kernelTime.LowPart = kernelTimes[i].dwLowDateTime; - kernelTime.HighPart = kernelTimes[i].dwHighDateTime; - userTime.LowPart = userTimes[i].dwLowDateTime; - userTime.HighPart = userTimes[i].dwHighDateTime; - - prevIdleTime.LowPart = prevIdleTimes[i].dwLowDateTime; - prevIdleTime.HighPart = prevIdleTimes[i].dwHighDateTime; - prevKernelTime.LowPart = prevKernelTimes[i].dwLowDateTime; - prevKernelTime.HighPart = prevKernelTimes[i].dwHighDateTime; - prevUserTime.LowPart = prevUserTimes[i].dwLowDateTime; - prevUserTime.HighPart = prevUserTimes[i].dwHighDateTime; - - ULONGLONG totalIdle = idleTime.QuadPart - prevIdleTime.QuadPart; - ULONGLONG totalKernel = kernelTime.QuadPart - prevKernelTime.QuadPart; - ULONGLONG totalUser = userTime.QuadPart - prevUserTime.QuadPart; - - ULONGLONG total = totalKernel + totalUser; - - CPUUsage usage; - usage.coreId = i; - usage.usage = (total > 0) ? (static_cast(total - totalIdle) / total) * 100.0 : 0.0; - coreUsages.push_back(usage); - } - - return coreUsages; - } - std::vector getMemState() - { - MEMORYSTATUSEX memInfo; - memInfo.dwLength = sizeof(MEMORYSTATUSEX); - if (GlobalMemoryStatusEx(&memInfo)) { - // 获取总物理内存和已用内存 - DWORDLONG totalPhysical = memInfo.ullTotalPhys; - DWORDLONG usedPhysical = memInfo.ullTotalPhys - memInfo.ullAvailPhys; - - // 获取总虚拟内存和已用虚拟内存 - DWORDLONG totalVirtual = memInfo.ullTotalVirtual; - DWORDLONG usedVirtual = memInfo.ullTotalVirtual - memInfo.ullAvailVirtual; - - // 计算内存占用率 - double physicalMemoryUsage = (static_cast(usedPhysical) / totalPhysical) * 100.0; - double virtualMemoryUsage = (static_cast(usedVirtual) / totalVirtual) * 100.0; - return { physicalMemoryUsage,virtualMemoryUsage }; - } - else - return { 0,0 }; - } - ~hardwareMonitor() - { - runFlag = false; - } - static void createDirectoryIfNotExists(const std::string& path) { - // 检查路径是否存在 - if (!std::filesystem::exists(path)) { - // 创建路径 - - std::filesystem::create_directories(path); - //std::cout << "已创建文件夹: " << path << std::endl; - } - else {/* - std::cout << "文件夹已存在: " << path << std::endl;*/ - } - } - void writeCsv(std::vector& State) { - if (State.size() == 0) - { - //std::cerr << "hw数据为空! " << std::endl; - return; - } - createDirectoryIfNotExists("./Log"); - QString fileName("./Log/" + QDate::currentDate().toString("yyyy-MM-dd") + "hwMonitor.csv"); - QFile file(fileName); - bool isEmpty = !file.exists() || file.size() == 0; - // 打开文件进行写入 - if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) { - //std::cerr << "无法打开文件进行写入: " << file.errorString().toStdString() << std::endl; - return; - } - - QTextStream out(&file); - - // 表头 - if (isEmpty == true) - { - QStringList headers; - headers.append("getTime"); - for (int i = 0; i < State[0].cpuState.size(); i++) - headers.append("CORE" + QString::number(i)); - headers.append("pMem,vMem"); - out << headers.join(",") << "\n"; - } - - // 循环写入数据 - for (auto& data : State) - { - QStringList csvData; - csvData.append(data.time); - for (auto& cpuData : data.cpuState) - csvData.append(QString::number(cpuData.usage)); - for (auto& memuData : data.memState) - csvData.append(QString::number(memuData)); - out << csvData.join(",") << "\n"; - } - - // 关闭文件 - file.close(); - State.clear();//成功写入后清除 - } - void run() - { - //初始化 - runFlag = true; - GetSystemInfo(&sysInfo); - //循环读取 - std::vector< oneTimeData> datas; - while (runFlag) - { - oneTimeData _oneTimeData; - //CPU占用 - _oneTimeData.cpuState = getCPUUsagePerCore(); - //内存占用 - _oneTimeData.memState = getMemState(); - //记录时间 - _oneTimeData.time = QTime::currentTime().toString("HH:mm:ss"); - - QThread::msleep(10); - datas.push_back(_oneTimeData); - if (datas.size() > outputCnt) - { - writeCsv(datas); - } - - } - } - void stop() - { - runFlag = false; - } -private: - SYSTEM_INFO sysInfo; - bool runFlag = true; -}; -class hardwareMonitorPlugin :public IPlugin -{ -public: - hardwareMonitor _hardwareMonitor; - hardwareMonitorPlugin() { - name = "hwMonitor"; - } - bool start() - { - _hardwareMonitor.start(); - return true; - } - bool stop() - { - _hardwareMonitor.stop(); - return true; - } - pluginState getState() - { - return _hardwareMonitor.isRunning() ? pluginState::running : pluginState::stop; - } -}; - -extern "C" -{ - __declspec(dllexport) IPlugin* createPlugin(); - __declspec(dllexport) void destroyPlugin(IPlugin* plugin); -} - - -#pragma once \ No newline at end of file diff --git a/subModule/Hd_CameraModule_HIK_hard_PCIE/CMakeLists.txt b/subModule/Hd_25DCameraVJ_module/CMakeLists.txt similarity index 92% rename from subModule/Hd_CameraModule_HIK_hard_PCIE/CMakeLists.txt rename to subModule/Hd_25DCameraVJ_module/CMakeLists.txt index e86c65b..47da335 100644 --- a/subModule/Hd_CameraModule_HIK_hard_PCIE/CMakeLists.txt +++ b/subModule/Hd_25DCameraVJ_module/CMakeLists.txt @@ -3,7 +3,7 @@ get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) string(TIMESTAMP RUN_TIME) message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) -set(DLL_NAMES "mvs" "opencv") +set(DLL_NAMES "opencv" "keyence2_5D" "2_5Ddll") foreach(child ${DLL_NAMES}) LIST(APPEND ENV_INCLUDE ${${child}_include}) LIST(APPEND ENV_LIB ${${child}_lib}) @@ -12,6 +12,7 @@ endforeach() message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) message(" ENV_LIB : " ${ENV_LIB} ) message(" ENV_TARGET : " ${ENV_TARGET} ) + include_directories( ${ENV_INCLUDE} @@ -19,7 +20,6 @@ include_directories( link_directories ( ${ENV_LIB} - ) @@ -56,15 +56,14 @@ set_target_properties(${CURRENT_FOLDER} PROPERTIES LINKER_LANGUAGE C target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} + ${qt_target_link} + ${opencv_target_link} + ${keyence2_5D_target_link} Qt${QT_VERSION_MAJOR}::Core ) # target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - string(TIMESTAMP RUN_TIME) message( " model end : " ${CURRENT_FOLDER}:${RUN_TIME}) diff --git a/subModule/Hd_25DCameraVJ_module/Hd_25DCameraVJ_module.cpp b/subModule/Hd_25DCameraVJ_module/Hd_25DCameraVJ_module.cpp new file mode 100644 index 0000000..581008f --- /dev/null +++ b/subModule/Hd_25DCameraVJ_module/Hd_25DCameraVJ_module.cpp @@ -0,0 +1,1013 @@ +#include "Hd_25DCameraVJ_module.h" +#include + +#include "KglDevice.h" +#include "KglStream.h" +#include "KglSystem.h" +#include "KglBuffer.h" +#include "KglDefine.h" +#include "KglResult.h" +using namespace Keyence; +#include + +KglDevice* kglDevice; +KglStream* kglStream; +KglGenParameterArray* kgllFeatureNodes; +KglBuffer* kglBuffer; +std::string sModelName; +// Camera type +#define CameraTypeArea 1 +#define CameraTypeLine 2 +#define CameraTypeXT 3 +#define CameraTypeRB 4 +int iCameraType; +int getImageTimeOut = 3000; +QString lastError; +QQueue> queuePic; +QMutex* n_mutex = new QMutex(); +std::vector sImageType; +static int imgNum = 1; +std::string serialNum; +#pragma region Device control +void Connect(int index) +{ + KglSystem kglSystem; + const KglDeviceInfo* deviceInfo; + std::string inputkey; + if (KGL_SUCCESS != kglSystem.find()) { + qDebug() << "Failed to find camera device."; + return; + } + + uint32_t count = kglSystem.getDeviceCount(); + if (count == 0) + { + qDebug() << ("No camera device can be found.\n"); + return; + } + + if ((index < 0) || (count <= index)) + { + qDebug() << ("The entry is invalid.\n"); + return; + } + + kglDevice = new KglDevice(); + kglStream = new KglStream(); + + for (int i = 0; i < count; i++) + { + deviceInfo = kglSystem.getDeviceInfo(index + i); + cout << deviceInfo->getIPAddress() << endl; + cout << deviceInfo->getSerialNumber() << endl; + std::string abc = deviceInfo->getSerialNumber(); + if (abc == serialNum) + { + break; + } + } + sModelName = deviceInfo->getModelName(); + if ((sModelName == ("CA-HL02MX")) || + (sModelName == ("CA-HL04MX")) || + (sModelName == ("CA-HL08MX"))) + { + iCameraType = CameraTypeLine; + } + else if ((sModelName == ("XT-024")) || + (sModelName == ("XT-060"))) + { + iCameraType = CameraTypeXT; + } + else if ((sModelName == ("RB-500")) || + (sModelName == ("RB-800")) || + (sModelName == ("RB-1200"))) + { + iCameraType = CameraTypeRB; + } + else { + iCameraType = CameraTypeArea; + } + cout << deviceInfo->getIPAddress() << endl; + int cnt = 0; + while (KGL_SUCCESS != kglDevice->connect(deviceInfo->getIPAddress())) { + cnt++; + Sleep(1000); + if (cnt > 3) + { + qDebug() << ("Cannot connect to the camera device.\n"); + return; + } + } + + if (KGL_SUCCESS != kglStream->open(*kglDevice)) { + qDebug() << ("Cannot connect to the stream.\n"); + return; + } + + // Get FeatureNode of camera device + kgllFeatureNodes = kglDevice->getDeviceParameters(); +} + +void Disconnect() +{ + if ((kglStream != NULL) && (kglStream->isOpen())) + { + KglResult result = kglStream->close(*kglDevice); + if (KGL_SUCCESS != result) { + qDebug() << ("Cannot disconnect from the stream.\n"); + return; + } + } + + if ((kglDevice != NULL) && (kglDevice->isConnected())) + { + if (KGL_SUCCESS != kglDevice->disconnect()) { + qDebug() << ("Cannot disconnect from the camera device.\n"); + return; + } + } +} +#pragma endregion + +#pragma region Feature access +void setIntegerValue(const std::string sFeatureName, const int64_t value) +{ + KglResult result; + KglString sConfigurationLastFailureCause; + + result = kgllFeatureNodes->setIntegerValue(sFeatureName.c_str(), value); + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : setParam\n"); + return; + } +} + +void setFloatValue(const std::string sFeatureName, const double value) +{ + KglResult result; + KglString sConfigurationLastFailureCause; + + result = kgllFeatureNodes->setFloatValue(sFeatureName.c_str(), value); + if (KGL_SUCCESS != result) + { + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : setParam\n"); + return; + } + } +} + +void setBooleanValue(const std::string sFeatureName, const bool value) +{ + KglResult result; + KglString sConfigurationLastFailureCause; + + result = kgllFeatureNodes->setBooleanValue(sFeatureName.c_str(), value); + if (KGL_SUCCESS != result) + { + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : setParam\n"); + return; + } + } +} + +void setEnumValue(const std::string sFeatureName, std::string value) +{ + KglResult result; + KglString sConfigurationLastFailureCause; + + result = kgllFeatureNodes->setEnumValue(sFeatureName.c_str(), value.c_str()); + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : setParam\n"); + return; + } +} + +void setStringValue(const std::string sFeatureName, const std::string value) +{ + KglResult result; + KglString sConfigurationLastFailureCause; + + result = kgllFeatureNodes->setStringValue(sFeatureName.c_str(), value.c_str()); + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : setParam\n"); + return; + } +} + +void executeCommand(const std::string sFeatureName) +{ + KglResult result; + + result = kgllFeatureNodes->executeCommand(sFeatureName.c_str()); + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : execCommand\n"); + return; + } +} + +void getIntegerValue(const std::string sFeatureName, int64_t& value) +{ + KglResult result; + + result = kgllFeatureNodes->getIntegerValue(sFeatureName.c_str(), value); + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : getParam\n"); + return; + } +} + +void getFloatValue(const std::string sFeatureName, double& value) +{ + KglResult result; + + result = kgllFeatureNodes->getFloatValue(sFeatureName.c_str(), value); + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : getParam\n"); + return; + } +} + +void getBooleanValue(const std::string sFeatureName, bool& value) +{ + KglResult result; + + result = kgllFeatureNodes->getBooleanValue(sFeatureName.c_str(), value); + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : getParam\n"); + return; + } +} + +void getEnumValue(const std::string sFeatureName, std::string& value) +{ + KglResult result; + KglString featurevalue; + + result = kgllFeatureNodes->getEnumValue(sFeatureName.c_str(), featurevalue); + value = featurevalue; + + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : getParam\n"); + return; + } +} + +void getStringValue(const std::string sFeatureName, std::string& value) +{ + KglResult result; + KglString featurevalue; + + result = kgllFeatureNodes->getStringValue(sFeatureName.c_str(), featurevalue); + value = featurevalue; + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : getParam\n"); + return; + } +} +#pragma endregion + +#pragma region Import XML +void ImportDeviceParameters(std::string sFilePath) +{ + setEnumValue("OperationMode", "SetupMode"); + + if (!sFilePath.empty()) + { + KglTargetDataSet target = (KglTargetDataSet)(KglTargetData::CameraParameters) + | (KglTargetDataSet)(KglTargetData::ParameterSetOfCameraParameter) + | (KglTargetDataSet)(KglTargetData::ModelImageOfCameraParameter) + | (KglTargetDataSet)(KglTargetData::CameraParametersOfEnvironmentSettings) + | (KglTargetDataSet)(KglTargetData::CommonParametersOfEnvironmentSettings) + | (KglTargetDataSet)(KglTargetData::CommonCameraParameters) + | (KglTargetDataSet)(KglTargetData::CalibrationOfCameraParameter); + KglImportDeviceParamOption option = KglImportDeviceParamOption(); + option.bOverwriteModelImage = true; + option.bOverwriteCalibration = true; + KglString failFeature; + + KglResult ret = kglDevice->importDeviceParameters(sFilePath.c_str(), failFeature, target, option); + if (ret != KGL_SUCCESS) + { + qDebug() << ("Failed to load a Feature List file.\n"); + return; + } + } + + setEnumValue("OperationMode", "RunMode"); +} +#pragma endregion + +#pragma region Optional Functions +std::vector GetEnableImageType(std::string sImageType) +{ + std::vector EnableImageType; + + std::string StdImageTypeTable[1][2] = + { + { "StdNormalImageEnable", "StdNormalImage" } + }; + + std::string LtrxNmlImageTypeTable[15][2] = + { + { "LtrxNormalImageEnable", "LtrxNormalImage" }, + { "LtrxUpperImageEnable", "LtrxUpperImage" }, + { "LtrxUpperRightImageEnable", "LtrxUpperRightImage" }, + { "LtrxRightImageEnable", "LtrxRightImage" }, + { "LtrxLowerRightImageEnable", "LtrxLowerRightImage" }, + { "LtrxLowerImageEnable", "LtrxLowerImage" }, + { "LtrxLowerLeftImageEnable", "LtrxLowerLeftImage" }, + { "LtrxLeftImageEnable", "LtrxLeftImage" }, + { "LtrxUpperLeftImageEnable", "LtrxUpperLeftImage" }, + { "LtrxShapeImage1Enable", "LtrxShapeImage1" }, + { "LtrxShapeImage2Enable", "LtrxShapeImage2" }, + { "LtrxShapeImage3Enable", "LtrxShapeImage3" }, + { "LtrxTextureImageEnable", "LtrxTextureImage" }, + { "LtrxGradientXImageEnable", "LtrxGradientXImage" }, + { "LtrxGradientYImageEnable", "LtrxGradientYImage" }, + }; + + std::string MlspImageTypeTable[11][2] = + { + { "MlspUVImageEnable", "MlspUVImage" }, + { "MlspBlueImageEnable", "MlspBlueImage" }, + { "MlspGreenImageEnable", "MlspGreenImage" }, + { "MlspAmberImageEnable", "MlspAmberImage" }, + { "MlspRedImageEnable", "MlspRedImage" }, + { "MlspFarRedImageEnable", "MlspFarRedImage" }, + { "MlspIRImageEnable", "MlspIRImage" }, + { "MlspWhiteImageEnable", "MlspWhiteImage" }, + { "MlspAverageGrayscaleImageEnable", "MlspAverageGrayscaleImage" }, + { "MlspColorImageEnable", "MlspColorImage" }, + { "MlspColorDifferenceImageEnable", "MlspColorDifferenceImage" } + }; + + std::string SprfImageTypeTable[16][2] = + { + { "SprfX1ImageEnable", "SprfX1Image" }, + { "SprfX2ImageEnable", "SprfX2Image" }, + { "SprfX3ImageEnable", "SprfX3Image" }, + { "SprfX4ImageEnable", "SprfX4Image" }, + { "SprfY1ImageEnable", "SprfY1Image" }, + { "SprfY2ImageEnable", "SprfY2Image" }, + { "SprfY3ImageEnable", "SprfY3Image" }, + { "SprfY4ImageEnable", "SprfY4Image" }, + { "SprfSpecularReflectionImageEnable", "SprfSpecularReflectionImage" }, + { "SprfDiffuseReflectionImageEnable", "SprfDiffuseReflectionImage" }, + { "SprfShapeImage1Enable", "SprfShapeImage1" }, + { "SprfShapeImage2Enable", "SprfShapeImage2" }, + { "SprfPhaseXImageEnable", "SprfPhaseXImage" }, + { "SprfPhaseYImageEnable", "SprfPhaseYImage" }, + { "SprfGlossRatioImageEnable", "SprfGlossRatioImage" }, + { "SprfNormalImageEnable", "SprfNormalImage" } + }; + + std::string Cap3DImageTypeTable[2][2] = + { + { "Cap3DAreascan3DImageEnable", "Areascan3DImage" }, + { "Cap3DAreascan2DImageEnable", "Areascan2DImage" }, + }; + + std::string RBImageTypeTable[2][2] = + { + { "Areascan3DImageEnable", "Areascan3DImage" }, + { "Areascan2DGrayscaleImageEnable", "Areascan2DGrayscaleImage" }, + }; + + std::string XTImageTypeTable[3][2] = + { + { "Areascan3DImageEnable", "Areascan3DImage" }, + { "Areascan2DColorImageEnable", "Areascan2DColorImage" }, + { "Areascan2DGrayscaleImageEnable", "Areascan2DGrayscaleImage" } + }; + + std::string FilteredImageTable[8][2] = + { + { "FilteredImageEnable", "FilteredImage1" }, + { "FilteredImageEnable", "FilteredImage2" }, + { "FilteredImageEnable", "FilteredImage3" }, + { "FilteredImageEnable", "FilteredImage4" }, + { "FilteredImageEnable", "FilteredImage5" }, + { "FilteredImageEnable", "FilteredImage6" }, + { "FilteredImageEnable", "FilteredImage7" }, + { "FilteredImageEnable", "FilteredImage8" } + }; + + int64_t sTargetParameterSet; + getIntegerValue("TargetParameterSet", sTargetParameterSet); + setIntegerValue("ParameterSetSelector", sTargetParameterSet); + + if (iCameraType == CameraTypeLine) + { + std::string sCaptureMode; + getEnumValue("CaptureMode", sCaptureMode); + if (sCaptureMode == "Fixed_MultipleImages") + { + bool sEnable; + getBooleanValue("IndividualFilterPerFixedCaptureNoEnable", sEnable); + if (sEnable) + { + int64_t sTargetCaptureCount; + getIntegerValue("TargetFixedCaptureNo", sTargetCaptureCount); + setIntegerValue("FixedCaptureNoSelector", sTargetCaptureCount); + } + } + } + + bool sEnable; + if (iCameraType == CameraTypeRB) + { + for (UINT i = 0; i < 2; i++) + { + std::string sFeatureName = RBImageTypeTable[i][0]; + std::string sImageName = RBImageTypeTable[i][1]; + getBooleanValue(sFeatureName, sEnable); + if (sEnable) + { + EnableImageType.push_back(sImageName); + } + } + } + else if (iCameraType == CameraTypeXT) + { + for (UINT i = 0; i < 3; i++) + { + std::string sFeatureName = XTImageTypeTable[i][0]; + std::string sImageName = XTImageTypeTable[i][1]; + getBooleanValue(sFeatureName, sEnable); + if (sEnable) + { + EnableImageType.push_back(sImageName); + } + } + } + else + { + std::string sLightingMode = ""; + getEnumValue("ImagingMode", sLightingMode); + + if (sLightingMode == "StandardLighting") + { + for (UINT i = 0; i < 1; i++) + { + std::string sFeatureName = StdImageTypeTable[i][0]; + std::string sImageName = StdImageTypeTable[i][1]; + getBooleanValue(sFeatureName, sEnable); + if (sEnable) + { + EnableImageType.push_back(sImageName); + } + } + } + else if (sLightingMode == "LumiTrax") + { + for (UINT i = 0; i < 15; i++) + { + std::string sFeatureName = LtrxNmlImageTypeTable[i][0]; + std::string sImageName = LtrxNmlImageTypeTable[i][1]; + getBooleanValue(sFeatureName, sEnable); + if (sEnable) + { + EnableImageType.push_back(sImageName); + } + } + } + else if (sLightingMode == "MultiSpectrum") + { + for (UINT i = 0; i < 11; i++) + { + std::string sFeatureName = MlspImageTypeTable[i][0]; + std::string sImageName = MlspImageTypeTable[i][1]; + getBooleanValue(sFeatureName, sEnable); + if (sEnable) + { + EnableImageType.push_back(sImageName); + } + } + } + else if (sLightingMode == "LumiTraxSpecularReflection") + { + for (UINT i = 0; i < 16; i++) + { + std::string sFeatureName = SprfImageTypeTable[i][0]; + std::string sImageName = SprfImageTypeTable[i][1]; + getBooleanValue(sFeatureName, sEnable); + if (sEnable) + { + EnableImageType.push_back(sImageName); + } + } + } + else if (sLightingMode == "Capture3D") + { + for (UINT i = 0; i < 2; i++) + { + std::string sFeatureName = Cap3DImageTypeTable[i][0]; + std::string sImageName = Cap3DImageTypeTable[i][1]; + getBooleanValue(sFeatureName, sEnable); + if (sEnable) + { + EnableImageType.push_back(sImageName); + } + } + } + } + + for (UINT i = 0; i < 8; i++) + { + setIntegerValue("FilteredImageSelector", (i + 1)); + + std::string sFeatureName = FilteredImageTable[i][0]; + std::string sImageName = FilteredImageTable[i][1]; + getBooleanValue(sFeatureName, sEnable); + if (sEnable) + { + EnableImageType.push_back(sImageName); + } + } + + UINT ImageTypeSize = (UINT)EnableImageType.size(); + if (ImageTypeSize < 5) + { + for (int i = ImageTypeSize; i < 5; i++) + { + EnableImageType.push_back(""); + } + } + + qDebug() << ("Select an image type.\n\n"); + + for (UINT i = 0; i < ImageTypeSize; ++i) + { + qDebug() << ((std::to_string(i + 1) + " :" + EnableImageType[i] + "\n").c_str()); + } + + uint32_t iSelected = atoi(sImageType.c_str()); + if ((iSelected == 0) || (iSelected > ImageTypeSize)) + { + qDebug() << ("The entry is invalid.\n"); + return EnableImageType; + } + return EnableImageType; +} + +void ConvertRGBA8toBGRA8(void* buffer, int pixelSize) +{ + std::byte dataR; + std::byte dataB; + + for (int i = 0; i < pixelSize; i++) + { + dataR = *((std::byte*)(buffer)+(i * 4)); + dataB = *((std::byte*)(buffer)+(i * 4) + 2); + + *((std::byte*)(buffer)+(i * 4)) = dataB; + *((std::byte*)(buffer)+(i * 4) + 2) = dataR; + } +} +#pragma endregion + +#pragma region Acquisition control + +bool AcquisitionStart() +{ + KglResult result; + + result = kglStream->startAcquisition(*kglDevice); + if (KGL_SUCCESS != result) { + qDebug() << ("Error : acquisitionStart\n error:")<< result; + return false; + } + + return true; +} + +void AcquisitionStop() +{ + KglResult result; + + result = kglStream->stopAcquisition(*kglDevice); + if (KGL_SUCCESS != result) { + qDebug() << ("Error : acquisitionStop\n"); + return; + } +} + +bool QueueBuffer() +{ + KglResult result; + KglResult operationResult; + + uint32_t payloadsize = kglDevice->getPayloadSize(); + if (payloadsize == 0) + { + qDebug() << ("Error : getPayloadSize\n"); + return false; + } + + kglBuffer = new KglBuffer(); + result = kglBuffer->allocate(payloadsize); + if (KGL_SUCCESS != result) + { + qDebug() << ("Error : allocate\n"); + return false; + } + + result = kglStream->queueBuffer(kglBuffer); + if ((KGL_SUCCESS != result) && (KGL_PENDING != result)) + { + qDebug() << ("Error : queueBuffer\n"); + return false; + } +} + +cv::Mat RetrieveBuffer() +{ + KglResult result; + KglResult operationResult; + + result = kglStream->retrieveBuffer(&kglBuffer, operationResult); + if ((KGL_SUCCESS != result) || (KGL_SUCCESS != operationResult)) + { + if (kglBuffer != NULL) + { + kglBuffer->free(); + delete(kglBuffer); + kglBuffer = NULL; + } + qDebug() << ("Error : retrieveBuffer\n error:")<< kglStream; + return Mat(); + } + + UINT bmpSize = kglBuffer->getAcquiredSize(); + char* data = (char*)malloc(bmpSize); + + CopyMemory((void*)data, kglBuffer->getDataPointer(), bmpSize); + + cv::Mat mat; + int64_t width; + int64_t height; + std::string sPixelFormat; + getIntegerValue("Width", width); + getIntegerValue("Height", height); + getEnumValue("PixelFormat", sPixelFormat); + + if (sPixelFormat == "Mono8") + { + mat = cv::Mat(height, width, CV_8UC1, data); + } + + else if (sPixelFormat == "Mono16") + { + mat = cv::Mat(height, width, CV_16UC1, data); + } + + else if (sPixelFormat == "BGR8Packed") + { + mat = cv::Mat(height, width, CV_8UC3, data); + } + + else if (sPixelFormat == "RGB8Packed") + { + mat = cv::Mat(height, width, CV_8UC3, data); + cv::cvtColor(mat, mat, COLOR_BGR2RGB); + + } + else if (sPixelFormat == "BGRA8Packed") + { + mat = cv::Mat(height, width, CV_8UC4, data); + } + + else if (sPixelFormat == "RGBA8Packed") + { + mat = cv::Mat(height, width, CV_8UC3, data); + cv::cvtColor(mat, mat, COLOR_BGRA2RGBA); + } + + if (kglBuffer != NULL) + { + kglBuffer->free(); + delete(kglBuffer); + kglBuffer = NULL; + } + + cv::Mat bmpMat; + mat.copyTo(bmpMat); + if (data) + { + free(data); + } + //imwrite("C:\\pic\\Img" + to_string(imgNum) + ".bmp", bmpMat); + //imgNum++; + return bmpMat; +} + +void SaveBMP(cv::Mat bmp) +{ + std::string inputkey; + std::string sFilePath; + + qDebug() << ("Do you want to save the image as a BMP file?\n\n"); + qDebug() << ("1 :Yes\n"); + qDebug() << ("2 : No\n"); + std::cin >> inputkey; + qDebug() << ("------------------------------\n"); + switch (atoi(inputkey.c_str())) + { + case 1: + qDebug() << ("Enter the full path of the BMP file.\n\n"); + std::cin >> sFilePath; + qDebug() << ("------------------------------\n"); + break; + case 2: + return; + break; + default: + qDebug() << ("The entry is invalid.\n"); + return; + break; + } + try + { + /*System::String^ FilePath = gcnew System::String(sFilePath.c_str()); + FileStream^ stream = gcnew FileStream(FilePath, FileMode::Create, FileAccess::Write); + TiffBitmapEncoder^ encoder = gcnew TiffBitmapEncoder(); + encoder->Compression = TiffCompressOption::None; + encoder->Frames->Add(BitmapFrame::Create(bmp)); + encoder->Save(stream);*/ + //cv::imwrite(sFilePath, bmp); + } + catch (char) + { + qDebug() << ("Failed to save the BMP file.\n"); + qDebug() << ("------------------------------"); + } +} + +void TriggerSoftware() +{ + Sleep(5000); + kgllFeatureNodes->executeCommand("TriggerSoftware"); +} + + +bool AcquisitionStartEx_SingleFrame(bool bMultiCaptureUpdateImage, std::string sMultiCaptureImageType, std::vector& matVec) +{ + + std::string sPixelFormat; + + setBooleanValue("MultiCaptureUpdateImage", bMultiCaptureUpdateImage); + setEnumValue("MultiCaptureImageType", sMultiCaptureImageType); + + //cv::Mat bmp; + + //bmp = QueueBuffer(); + cv::Mat bmp; + + if (!QueueBuffer()) + return false; + + AcquisitionStart(); + bmp = RetrieveBuffer(); + if (!bmp.empty()) + { + matVec.push_back(bmp); + AcquisitionStop(); + bmp.release(); + return true; + } + else + { + AcquisitionStop(); + bmp.release(); + return false; + } + + + //if (sPixelFormat == "RGBA8Packed") + //{ + // ConvertRGBA8toBGRA8(BitmapImage->BackBuffer.ToPointer(), (BitmapImage->PixelWidth * BitmapImage->PixelHeight)); + //} + + //SaveBMP(bmp); + +} + +#pragma endregion + + +void MyThread::run() +{ + while (m_runFlag) + { + std::vector matVecs; + if (AcquisitionStartEx_SingleFrame(TRUE, sImageType[0], matVecs) == true) {//为true的话就是重新获取一组图片中的一张sImageType类型的图片 false就是在同一组图片获取sImageType类型的图片 + for (int i = 1; i < 3; i++) + AcquisitionStartEx_SingleFrame(FALSE, sImageType[i], matVecs);//为true的话就是重新获取一组图片中的一张sImageType类型的图片 false就是在同一组图片获取sImageType类型的图片 + if (matVecs.size() > 0) + { + n_mutex->lock(); + queuePic.append(matVecs); + qDebug() << "Acquisition sucess size" << queuePic.size(); + m_flag = true; + n_mutex->unlock(); + + } + } + else + matVecs.clear(); + + //QThread::msleep(5); + } +} + +Hd_25DCameraVJ_module* create() +{ + qDebug() << "[info]" << __FUNCTION__ << "line:" << __LINE__ << "Hd_MvCamera_module create success!"; + return new Hd_25DCameraVJ_module; +} + +void destory(Hd_25DCameraVJ_module* ptr) +{ + if (ptr) + { + delete ptr; + ptr = nullptr; + } + qDebug() << "[info] " << __FUNCTION__ << " line:" << __LINE__ << "Hd_MvCamera_module destory success!"; +} + +Hd_25DCameraVJ_module::Hd_25DCameraVJ_module() +{ + //m_thread = new MyThread; + //m_mutex = new QMutex(); + workThread = new MyThread(); +} + +Hd_25DCameraVJ_module::~Hd_25DCameraVJ_module() +{ + if (workThread) + { + workThread->setFlag(false); + workThread->wait(); + workThread->quit(); + workThread->deleteLater(); + workThread = nullptr; + } + + Disconnect(); + + if (n_mutex) + { + delete n_mutex; + n_mutex = nullptr; + } + + qDebug() << "[info]" << __FUNCTION__ << "line:" << __LINE__ << " delete success!"; +} + +bool Hd_25DCameraVJ_module::readData(std::vector&mat , QByteArray& data) +{ + Q_UNUSED(data) + + if (data == "getStatus") { + data = lastError.toUtf8(); + return true; + } + + if (queuePic.isEmpty()) + { + return false; + } + QMutexLocker locker(n_mutex); + vector dstMat = queuePic.dequeue(); + //for (int i=0;i& mat , QByteArray&data) +{ + Q_UNUSED(mat) + + cameraIndex = data.toInt(); + return true; +} + +bool Hd_25DCameraVJ_module::initParas(QByteArray& initData) +{ +#if 1 + QByteArrayList valueList = initData.split('#'); + if (valueList.size() < 3) { + qDebug() << "[Error] Hd_25DCameraVJ_module initParas fail--params error!参数数量不满足"; + lastError = "参数数量不满足"; + return false; + } + serialNum = valueList[0]; + std::string path = valueList[1].toStdString(); + getImageTimeOut = valueList[2].toInt(); + + KglResult initRes = KglSystem::initialize(); + Connect(0); + setBooleanValue("GevGVCPPendingAck", TRUE); + + //ImportDeviceParameters("C://EVE2.5dConfig//CA-HL08MX_hardTrigger.XML"); + ImportDeviceParameters(path.c_str()); + //setEnumValue("AcquisitionMode", "SingleFrame"); + bool bBGEnable; + getBooleanValue("ImageCaptureBufferEnable", bBGEnable); + if (bBGEnable) + { + executeCommand("ImageCaptureBufferClear"); + executeCommand("BufferCaptureAcquisitionStart"); + } + std::string sImageType1 = "1"; + sImageType = GetEnableImageType(sImageType1); //获取图像类别 6张 + + std::string sTriggerMode; + getEnumValue("TriggerMode", sTriggerMode); + sTriggerSource = ""; + if (sTriggerMode == "On") + { + getEnumValue("TriggerSource", sTriggerSource); + //if (sTriggerSource.compare("Software")) + // workThread->start(); + qDebug() << __FUNCTION__ << __LINE__ << "sTriggerSource:" << QString::fromStdString(sTriggerSource); + } + else + { + //workThread->start(); + qDebug() << __FUNCTION__ << __LINE__ << "hardTrigger"; + } + std::vector matVecs; + workThread->start(); + //workThread->run(); + + //KglResult res = kgllFeatureNodes->executeCommand("TriggerSoftware"); +#endif + return true; +} + +bool Hd_25DCameraVJ_module::run()//软触发 +{ + //qDebug() << "[info]" << __FUNCTION__ << " line:" << __LINE__ << " run start" < 0) + { + n_mutex->lock(); + result = true; + n_mutex->unlock(); + softwareTriggerStatus = 0; + return true; + } + if (!sTriggerSource.compare("Software") && softwareTriggerStatus == 0) + { + KglResult res = kgllFeatureNodes->executeCommand("TriggerSoftware");//软触发 + softwareTriggerStatus = 1; + return false; + } +#endif + { + QMutexLocker locker(n_mutex); + queuePic.clear(); + } + int sleepMs = 10; + int cnt = 0; + int timeoutCnt = getImageTimeOut / sleepMs; + while (true) + { + QMutexLocker locker(n_mutex); + if (queuePic.size() > 0)return true; + if (cnt++ > timeoutCnt) { + queuePic.push_back(cv::Mat(200, 200, CV_8UC1, cv::Scalar(0))); //返回空图 + qDebug() << QString::fromStdString(serialNum) << "timeout"; + return true; + } + QThread::msleep(sleepMs); + } + return true; + } + catch (QString ev) + { + qDebug() << "[info] FUNCTION:" << __FUNCTION__ << " line:" << __LINE__ << " ev:" << ev; + } + //qDebug() << "[info]"<< __FUNCTION__ << " line:" << __LINE__ << " run end" ; + return true; +} \ No newline at end of file diff --git a/subModule/Hd_25DCameraVJ_module/Hd_25DCameraVJ_module.h b/subModule/Hd_25DCameraVJ_module/Hd_25DCameraVJ_module.h new file mode 100644 index 0000000..868df2a --- /dev/null +++ b/subModule/Hd_25DCameraVJ_module/Hd_25DCameraVJ_module.h @@ -0,0 +1,56 @@ +#ifndef Hd_25DCameraVJ_module_H +#define Hd_25DCameraVJ_module_H +#include +#include +#include +#include +#include +#include + +#include + +using namespace cv; +using namespace std; +#pragma execution_character_set("utf-8") +static bool m_flag = true; +class MyThread : public QThread +{ + Q_OBJECT +public: + explicit MyThread(QObject* parent = nullptr) :m_obj(parent) {} + void run(); + void setFlag(bool r) { m_runFlag = r; }; +private: + bool m_runFlag = true; + QObject* m_obj; +signals: + +}; + + +class Hd_25DCameraVJ_module :public dsModuleBase +{ +public: + Hd_25DCameraVJ_module(); + virtual ~Hd_25DCameraVJ_module(); + bool readData(std::vector&, QByteArray&); + bool writeData(std::vector&, QByteArray&); + bool initParas(QByteArray&); + bool run(); + + std::string sTriggerSource; +private: + bool softwareTriggerStatus = 0; + int cameraIndex = 0; + MyThread* workThread = nullptr; + +}; + +extern "C" +{ +Q_DECL_EXPORT Hd_25DCameraVJ_module * create(); +Q_DECL_EXPORT void destory(Hd_25DCameraVJ_module * ptr); +} + +#endif // Hd_25DCameraVJ_module_H +//Hd_25DCameraVJ_module diff --git a/subModule/Hd_25DCameraVJ_module/readme.txt b/subModule/Hd_25DCameraVJ_module/readme.txt new file mode 100644 index 0000000..52d011d --- /dev/null +++ b/subModule/Hd_25DCameraVJ_module/readme.txt @@ -0,0 +1,3 @@ +基恩士2.5D相机 +初始化格式 序列号#路径#超时时间 +SAMPLE: xxxxxxxxx#C://EVE2.5dConfig//CA-HL08MX_hardTrigger.XML#1000 \ No newline at end of file diff --git a/subModule/Hd_CameraModule_3DKeyence/CMakeLists.txt b/subModule/Hd_CameraModule_3DKeyence/CMakeLists.txt index cb49af5..8533141 100644 --- a/subModule/Hd_CameraModule_3DKeyence/CMakeLists.txt +++ b/subModule/Hd_CameraModule_3DKeyence/CMakeLists.txt @@ -29,7 +29,7 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "./*.h" ) diff --git a/subModule/Hd_CameraModule_3DKeyence/Hd_CameraModule_3DKeyence.cpp b/subModule/Hd_CameraModule_3DKeyence/Hd_CameraModule_3DKeyence.cpp index 12900e1..2e1d3fc 100644 --- a/subModule/Hd_CameraModule_3DKeyence/Hd_CameraModule_3DKeyence.cpp +++ b/subModule/Hd_CameraModule_3DKeyence/Hd_CameraModule_3DKeyence.cpp @@ -16,6 +16,8 @@ int G_yImageSize = 0; // Number of Y lines. //int _lastImageSizeHeight[MAX_LJXA_DEVICENUM]; int imgTakeNum = 0, imgTarget = 1; int imgIndex = 0; +int getImageTimeOut = 3000; +QString lastError; QMutex* m_mutex = nullptr; std::mutex bufferMutex; QQueue< cv::Mat> heightMatS;//高度图 @@ -330,86 +332,35 @@ bool Hd_CameraModule_3DKeyence::writeData(std::vector &mat,QByteArray & //传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1... bool Hd_CameraModule_3DKeyence::initParas(QByteArray& initData) { + QByteArrayList valueList = initData.split('#'); + if (valueList.size() < 6) { + qDebug() << "[Error] " << " Hd_CameraModule_HIK initParas fail--params error!参数数量不满足"; + lastError = "参数数量不满足"; + return false; + } EthernetConfig.wPortNo = 24691; - QByteArrayList valueList = initData.split('+'); - camera_name = valueList[0]; - //deviceId = valueList[0].toInt(); //相机头序号 - if (valueList.size() > 1) - for (int i = 0; i < valueList.size(); i++) - { - QString valuei = byteArrayToUnicode(valueList[i]); - if (valuei.contains("ip")) - { - //ip#192.168.0.1 - QStringList valueL = valuei.split("#"); - if (valueL.size() == 2) - { - QStringList valueL1 = valueL[1].split("."); - if (valueL1.size() == 4) - { - EthernetConfig.abyIpAddress[0] = valueL1.at(0).toInt(); - EthernetConfig.abyIpAddress[1] = valueL1.at(1).toInt(); - EthernetConfig.abyIpAddress[2] = valueL1.at(2).toInt(); - EthernetConfig.abyIpAddress[3] = valueL1.at(3).toInt(); - } - } - } - if (valuei.contains("deviceId")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() == 2) - { - deviceId = valueL[1].toInt(); - } - } - if (valuei.contains("port")) - { - //port#24691 - QStringList valueL = valuei.split('#'); - if (valueL.size() == 2) - { - EthernetConfig.wPortNo = valueL[1].toInt(); - } - } - if (valuei.contains("xImageSize")) - { - //xImageSize#1600 - QStringList valueL = valuei.split('#'); - if (valueL.size() == 2) - { - xImageSize = valueL[1].toInt(); - G_xImageSize = valueL[1].toInt(); - } - } - if (valuei.contains("yImageSize")) - { - //yImageSize#2000 - QStringList valueL = valuei.split('#'); - if (valueL.size() == 2) - { - yImageSize = valueL[1].toInt(); - G_yImageSize = valueL[1].toInt(); - } - } - if (valuei.contains("y_pitch_um")) - { - //y_pitch_um#40 - QStringList valueL = valuei.split('#'); - if (valueL.size() == 2) - { - y_pitch_um = valueL[1].toDouble(); - } - } - if (valuei.contains("imgTarget")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() == 2) - { - imgTarget = valueL[1].toInt(); - } - } - } + camera_name = valueList[0]; + auto valueL1 = valueList[0].split('.'); + if (valueL1.size() == 4) + { + EthernetConfig.abyIpAddress[0] = valueL1.at(0).toInt(); + EthernetConfig.abyIpAddress[1] = valueL1.at(1).toInt(); + EthernetConfig.abyIpAddress[2] = valueL1.at(2).toInt(); + EthernetConfig.abyIpAddress[3] = valueL1.at(3).toInt(); + } + + deviceId = valueList[1].toInt(); + + xImageSize = valueList[2].toInt(); + G_xImageSize = valueList[2].toInt(); + + yImageSize = valueList[3].toInt(); + G_yImageSize = valueList[3].toInt(); + + imgTarget = valueList[4].toInt(); + + getImageTimeOut = valueList[5].toInt(); yCounts = yImageSize; qDebug() << __FUNCTION__ << " line:" << __LINE__ << " camera_name:" << camera_name << " paras init is success!"; @@ -527,20 +478,22 @@ bool Hd_CameraModule_3DKeyence::run() { while (imgTakeNum != imgTarget) { - int timeOutCnt = 0; - while (_imageAvailable[deviceId] != 1 && timeOutCnt < 120) + int sleepMs = 10; + int cnt = 0; + int timeoutCnt = getImageTimeOut / sleepMs; + while (_imageAvailable[deviceId] != 1 ) { - timeOutCnt++; QThread::msleep(10); + if (cnt++ >= timeoutCnt) + { + heightMatS.push_back(cv::Mat(G_yImageSize, G_xImageSize, CV_8UC1, cv::Scalar(0, 0, 0))); + luminanceMatS.push_back(cv::Mat(G_yImageSize, G_xImageSize, CV_8UC1, cv::Scalar(0, 0, 0))); + imgTakeNum++; + qDebug() << "imgGetERROR insert blank img cameraID:" << camera_name; + continue; + } } - if (timeOutCnt >= 120) - { - heightMatS.push_back(cv::Mat(G_yImageSize, G_xImageSize, CV_8UC1, cv::Scalar(0, 0, 0))); - luminanceMatS.push_back(cv::Mat(G_yImageSize, G_xImageSize, CV_8UC1, cv::Scalar(0, 0, 0))); - imgTakeNum++; - qDebug() << "imgGetERROR insert blank img cameraID:" << camera_name; - continue; - } + std::lock_guard lock(bufferMutex); _getParam[deviceId].luminance_enabled = profileInfo_ptr->byLuminanceOutput; @@ -603,7 +556,7 @@ bool Hd_CameraModule_3DKeyence::run() _lastImageSizeHeight[deviceId] = 0; imgTakeNum++; } - qDebug() << "take2 Finish"; + qDebug() << camera_name <<"Finish"; return true; } catch (QString ev) diff --git a/subModule/Hd_CameraModule_3DKeyence/readme.txt b/subModule/Hd_CameraModule_3DKeyence/readme.txt new file mode 100644 index 0000000..7a69391 --- /dev/null +++ b/subModule/Hd_CameraModule_3DKeyence/readme.txt @@ -0,0 +1,3 @@ +基恩士3D相机 +初始化格式 IP#DEVICE-ID(手动按照初始化的顺序从0开始递增)#图像宽(X)#图像高(Y)#取图次数#超时时间 +192.168.31.1#0#3200#850#1#1000 \ No newline at end of file diff --git a/subModule/Hd_CameraModule_HIK_soft_GIGE/CMakeLists.txt b/subModule/Hd_CameraModule_HIK_General/CMakeLists.txt similarity index 98% rename from subModule/Hd_CameraModule_HIK_soft_GIGE/CMakeLists.txt rename to subModule/Hd_CameraModule_HIK_General/CMakeLists.txt index e86c65b..8412669 100644 --- a/subModule/Hd_CameraModule_HIK_soft_GIGE/CMakeLists.txt +++ b/subModule/Hd_CameraModule_HIK_General/CMakeLists.txt @@ -28,7 +28,7 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "./*.h" ) diff --git a/subModule/Hd_CameraModule_HIK_General/Hd_CameraModule_HIK_General.cpp b/subModule/Hd_CameraModule_HIK_General/Hd_CameraModule_HIK_General.cpp new file mode 100644 index 0000000..aff70fc --- /dev/null +++ b/subModule/Hd_CameraModule_HIK_General/Hd_CameraModule_HIK_General.cpp @@ -0,0 +1,375 @@ +#include "Hd_CameraModule_HIK_General.h" +using namespace std; +#include +#include +#include +#include +#include +enum statusEnum { + CONNECTED, + RECONNECTING, + DISCONNECTED +}; +enum triggerModeEnum { + SOFTWARE, + HARDWARE, + EMPTY +}; +statusEnum cameraStatus = DISCONNECTED; +triggerModeEnum triggerMode = HARDWARE; +int getImageTimeOut = 3000; +bool runFlag = true; +//总取图数 +int imgIndex = 0; +MV_CC_DEVICE_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量,用来存储设备列表 +string Username = ""; +int cameraIndex = -1; +QString lastError; +QQueue queuepic; +QMutex* n_mutex = new QMutex(); + +void* handle = NULL; +void CloseDevice(); + +//0106 断线重连 +void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser); +void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0); +//搜索所有设备 +int SearchDevice(){ + + if (m_stDevList.nDeviceNum == 0) { + memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); + // ch:枚举子网内所有设备 | en:Enumerate all devices within subnet + int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList); + if (MV_OK != nRet) + { + return -1; + } + } + for (int i = 0; i < m_stDevList.nDeviceNum; i++) + { + //SN + unsigned char* name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chSerialNumber; + string userName = static_cast((LPCSTR)name); + if (Username == userName) + { + return i; + break; + } + + name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stUsb3VInfo.chSerialNumber; + userName = static_cast((LPCSTR)name); + if (Username == userName) + { + return i; + break; + } + } + return -1; +} + +bool connectDevice() +{ + int cameraIndex = SearchDevice(); + if (cameraIndex == -1){ + //未匹配到相机 + qDebug() << "[Waring] " << "Hd_CameraModule_HIK not match --CameraName:" << QString::fromStdString(Username); + lastError = "找不到相机" + QString::fromStdString(Username); + return false; + } + if (handle != NULL) + { + MV_CC_StopGrabbing(handle); + MV_CC_CloseDevice(handle); + MV_CC_DestroyHandle(handle); + } + + //打开相机 + MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[cameraIndex]); + int nRet = MV_CC_OpenDevice(handle); + ////触发模式 + if(triggerMode == SOFTWARE) + { + MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON); + MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE); + } + else if(triggerMode == HARDWARE) + { + MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON); + MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0); + } + + // //加载用户集,相机设置应当UserSet1 + nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1"); + if (MV_OK != nRet)qDebug() << "Set UserSetSelector fail! nRet " << nRet; + // ch:注册抓图回调 | en:Register image callback + MV_CC_SetIntValueEx(handle, "GevHeartbeatTimeout", 3000);//心跳日志 + + nRet = MV_CC_RegisterImageCallBackEx(handle, ImageCallBackEx, handle);//注册回调 + if (MV_OK != nRet)return false; + nRet = MV_CC_RegisterExceptionCallBack(handle, ReconnectDevice, NULL);//断线重连 + if (MV_OK != nRet)return false; + + MV_CC_StartGrabbing(handle); + cameraStatus = CONNECTED; + return true; +} +void SetExposureTime(float exposureValue) +{ + qDebug() << "[INFO] " << "exposureValue:" << exposureValue; + MV_CC_SetEnumValue(handle, "ExposureAuto", MV_EXPOSURE_AUTO_MODE_OFF); + MV_CC_SetFloatValue(handle, "ExposureTime", exposureValue); +} + +void SetGain(float GainValue) +{ + qDebug() << "[INFO] " << "GainValue:" << GainValue; + MV_CC_SetEnumValue(handle, "GainAuto", 0); + MV_CC_SetFloatValue(handle, "Gain", GainValue); +} + +//断线重连 +void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser){ + + qDebug() << "[Error] " << " MV camera disconnects!"; + + if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT && cameraStatus == CONNECTED){ + + cameraStatus = RECONNECTING; + // 启动后台线程负责重连,避免在回调线程中长时间阻塞 + std::thread([]() { + qDebug() << "[Info] start reconnect thread"; + + // 确保设备资源关闭 + CloseDevice(); + int times = 0; + while (runFlag) + { + qDebug() << "[Info] reconnect times:" << times++; + if (connectDevice()) + { + qWarning() << "[Hd_CameraModule_HIK] reconnect success!"; + cameraStatus = CONNECTED; + return; + } + + } + }).detach(); + } +} + +//回调函数; +//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题 +void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0) +{ + Q_UNUSED(pUser0) + int frameNum = 0; + double time_Start = (double)clock(); + QMutexLocker locker(n_mutex); + cv::Mat srcImage = cv::Mat(); + //qDebug() << "[info]" << __FUNCTION__ << " line:" << __LINE__ << "--- start"; + if (pFrameInfo0) + { + //获取的是单通道灰度图 + if (pFrameInfo0->enPixelType == PixelType_Gvsp_Mono8)//获取当前采集到的图像格式 + { + srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC1, pData0); + } + //获取的是RGB8图 + else if (pFrameInfo0->enPixelType == PixelType_Gvsp_BGR8_Packed) + { + srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0); + + //cvtColor(srcImage, srcImage, COLOR_RGB2BGR);//导致异色 + } + else if (IsColor(pFrameInfo0->enPixelType)) //其它格式彩色图 + { + MvGvspPixelType enDstPixelType = PixelType_Gvsp_Undefined; + enDstPixelType = PixelType_Gvsp_BGR8_Packed; + unsigned char* pConvertData = NULL; + pConvertData = (unsigned char*)malloc(pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3); + if (NULL == pConvertData) + { + printf("malloc pConvertData fail!\n"); + } + else + { + unsigned int nConvertDataSize = 0; + nConvertDataSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3; + + // ch:像素格式转换 | en:Convert pixel format + MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 }; + + frameNum = pFrameInfo0->nFrameNum; //ch:帧号 | en:frame number + stConvertParam.nWidth = pFrameInfo0->nWidth; //ch:图像宽 | en:image width + stConvertParam.nHeight = pFrameInfo0->nHeight; //ch:图像高 | en:image height + stConvertParam.pSrcData = pData0; //ch:输入数据缓存 | en:input data buffer + stConvertParam.nSrcDataLen = pFrameInfo0->nFrameLen; //ch:输入数据大小 | en:input data size + stConvertParam.enSrcPixelType = pFrameInfo0->enPixelType; //ch:输入像素格式 | en:input pixel format + stConvertParam.enDstPixelType = enDstPixelType; //ch:输出像素格式 | en:output pixel format + stConvertParam.pDstBuffer = pConvertData; //ch:输出数据缓存 | en:output data buffer + stConvertParam.nDstBufferSize = nConvertDataSize; //ch:输出缓存大小 | en:output buffer size + int nRet = MV_CC_ConvertPixelType(handle, &stConvertParam); + + Mat mysrcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, stConvertParam.pDstBuffer); + mysrcImage.copyTo(srcImage); + + free(pConvertData); + pConvertData = NULL; + stConvertParam = { 0 }; + } + } + } + if (srcImage.empty()) + { + srcImage = cv::Mat(5, 5, CV_8UC1).setTo(0); + } + queuepic.push_back(srcImage); + pData0 = { 0 }; + double time_End = (double)clock(); + qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" + << "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgIndex << "nFrameNum : " << frameNum; +} + +//关闭设备 +void CloseDevice() +{ + + // 如果 handle 已经为空,直接返回 + if (handle == nullptr) + return; + + // 使用 SDK 正确的停止/关闭/销毁流程,避免使用 CloseHandle 等不匹配的 API + MV_CC_StopGrabbing(handle); + MV_CC_CloseDevice(handle); + MV_CC_DestroyHandle(handle); + handle = nullptr; +} + +Hd_CameraModule_HIK_General::~Hd_CameraModule_HIK_General() +{ + runFlag = false; + CloseDevice(); + if (n_mutex) + { + delete n_mutex; + n_mutex = nullptr; + } + + qDebug() << "[INFO] " << " delete success!"; +} +//从类中读数据到实例对象 +bool Hd_CameraModule_HIK_General::readData(std::vector& mat, QByteArray& data) +{ + if(data == "getStatus"){ + data = lastError.toUtf8(); + return true; + } + + if (queuepic.isEmpty()) + { + return false; + } + QMutexLocker locker(n_mutex); + cv::Mat img = queuepic.dequeue(); + mat.push_back(img); + + qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex; + return true; +} + +//实例对象把数据写入到类;加载模型后会运行此函数 +bool Hd_CameraModule_HIK_General::writeData(std::vector& mat, QByteArray& data) +{ + Q_UNUSED(mat); + if (data.contains("deviceList")) { + auto result = QByteArrayToMV_CC_DeviceInfoList(data.mid(10)); + if (result.nDeviceNum != 0) { + m_stDevList = result; + return true; + } + } + return true; +} +//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1... +bool Hd_CameraModule_HIK_General::initParas(QByteArray& initData) +{ + QByteArrayList valueList = initData.split('#'); + if (valueList.size() < 3) { + qDebug() << "[Error] " << " Hd_CameraModule_HIK initParas fail--params error!参数数量不满足"; + lastError = "参数数量不满足"; + return false; + } + Username = valueList[0]; + + auto triggerModeStr = valueList[1]; + if (triggerModeStr == "HARDWARE") + triggerMode = HARDWARE; + else if (triggerModeStr == "SOFTWARE") + triggerMode = SOFTWARE; + else if (triggerModeStr == "EMPTY") + triggerMode = EMPTY; + else { + qDebug() << "[Error] " << " Hd_CameraModule_HIK initParas fail--params error!触发模式参数错误"; + lastError = "触发模式参数错误"; + return false; + } + + getImageTimeOut = valueList[2].toInt(); + + imgIndex = 0; + return connectDevice(); +} + +bool Hd_CameraModule_HIK_General::run() +{ + qDebug() << "[INFO] " << " run start" << QString::fromStdString(Username); + if (triggerMode == SOFTWARE) + MV_CC_SetCommandValue(handle, "TriggerSoftware"); + try + { + int sleepMs = 10; + int cnt = 0; + int timeoutCnt = getImageTimeOut / sleepMs; + while (true) + { + QMutexLocker locker(n_mutex); + if (queuepic.size() > 0)return true; + if (cnt++ > timeoutCnt) { + queuepic.push_back(cv::Mat(200, 200, CV_8UC1, cv::Scalar(0))); //返回空图 + qDebug() << QString::fromStdString(Username) << "timeout" ; + return true; + } + QThread::msleep(sleepMs); + } + } + catch (QString ev) + { + qDebug() << "[Error] " << " ev:" << ev; + } + return true; +} + +//相机连接状态:正常连接或断开 +bool Hd_CameraModule_HIK_General::checkStatus() +{ + //status = moduleStatus; + return status; +} + + +Hd_CameraModule_HIK_General* create() +{ + qDebug() << "[INFO] " << "Hd_CameraModule_HIK create success!"; + return new Hd_CameraModule_HIK_General; +} + +void destory(Hd_CameraModule_HIK_General* ptr) +{ + if (ptr) + { + delete ptr; + ptr = nullptr; + } + qDebug() << "[INFO] " << "Hd_CameraModule_HIK destory success!"; +} \ No newline at end of file diff --git a/subModule/Hd_CameraModule_HIK_General/Hd_CameraModule_HIK_General.h b/subModule/Hd_CameraModule_HIK_General/Hd_CameraModule_HIK_General.h new file mode 100644 index 0000000..2483799 --- /dev/null +++ b/subModule/Hd_CameraModule_HIK_General/Hd_CameraModule_HIK_General.h @@ -0,0 +1,84 @@ +#ifndef Hd_CameraModule_HIK_General_H +#define Hd_CameraModule_HIK_General_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace cv; +#pragma execution_character_set("utf-8") + +static MV_CC_DEVICE_INFO_LIST QByteArrayToMV_CC_DeviceInfoList(const QByteArray& byteArray) { + MV_CC_DEVICE_INFO_LIST deviceInfoList; + if (byteArray.size() == sizeof(MV_CC_DEVICE_INFO_LIST)) { + memcpy(&deviceInfoList, byteArray.constData(), sizeof(MV_CC_DEVICE_INFO_LIST)); + } + else { + qDebug() << "Invalid size of QByteArray for MV_CC_DEVICE_INFO_LIST!"; + } + return deviceInfoList; +} +bool IsColor(MvGvspPixelType enType) +{ + switch (enType) + { + case PixelType_Gvsp_RGB8_Packed: + case PixelType_Gvsp_YUV422_Packed: + case PixelType_Gvsp_YUV422_YUYV_Packed: + case PixelType_Gvsp_BayerGR8: + case PixelType_Gvsp_BayerRG8: + case PixelType_Gvsp_BayerGB8: + case PixelType_Gvsp_BayerBG8: + case PixelType_Gvsp_BayerGB10: + case PixelType_Gvsp_BayerGB10_Packed: + case PixelType_Gvsp_BayerBG10: + case PixelType_Gvsp_BayerBG10_Packed: + case PixelType_Gvsp_BayerRG10: + case PixelType_Gvsp_BayerRG10_Packed: + case PixelType_Gvsp_BayerGR10: + case PixelType_Gvsp_BayerGR10_Packed: + case PixelType_Gvsp_BayerGB12: + case PixelType_Gvsp_BayerGB12_Packed: + case PixelType_Gvsp_BayerBG12: + case PixelType_Gvsp_BayerBG12_Packed: + case PixelType_Gvsp_BayerRG12: + case PixelType_Gvsp_BayerRG12_Packed: + case PixelType_Gvsp_BayerGR12: + case PixelType_Gvsp_BayerGR12_Packed: + return true; + default: + return false; + } +} +class Hd_CameraModule_HIK_General :public dsModuleBase +{ +public: + Hd_CameraModule_HIK_General() {}; + virtual ~Hd_CameraModule_HIK_General(); + //从类中读数据到实例对象 + bool readData(std::vector& mat, QByteArray& data); + //实例对象把数据写入到类 + bool writeData(std::vector& mat, QByteArray& data); + bool initParas(QByteArray& initData); + bool run(); + bool checkStatus(); +private: + + //MyThread *m_thread = nullptr; + //QMutex* m_mutex; +}; + +extern "C" +{ +Q_DECL_EXPORT Hd_CameraModule_HIK_General * create(); +Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_General * ptr); +} + +#endif // Hd_CameraModule_HIK_hard_H +//Hd_CameraModule_HIK_General diff --git a/subModule/Hd_CameraModule_HIK_General/readme.txt b/subModule/Hd_CameraModule_HIK_General/readme.txt new file mode 100644 index 0000000..ccb05c9 --- /dev/null +++ b/subModule/Hd_CameraModule_HIK_General/readme.txt @@ -0,0 +1,3 @@ +֧³ÖUSBÉ豸ºÍÍø¿ÚÉ豸£¬²»֧³ֲɼ¯¿¨É豸 +³õʼ»¯¸ñʽ "Ïà»úÐòÁкÅ#HARDWARE/SOFTWARE/EMPTY#ȡͼ³¬ʱʱ¼ä" +SAMPLE: Vir76210850#SOFTWARE#2000 \ No newline at end of file diff --git a/subModule/Hd_CameraModule_HIK_hard_GIGE/CMakeLists.txt b/subModule/Hd_CameraModule_HIK_PCIE/CMakeLists.txt similarity index 98% rename from subModule/Hd_CameraModule_HIK_hard_GIGE/CMakeLists.txt rename to subModule/Hd_CameraModule_HIK_PCIE/CMakeLists.txt index e86c65b..8412669 100644 --- a/subModule/Hd_CameraModule_HIK_hard_GIGE/CMakeLists.txt +++ b/subModule/Hd_CameraModule_HIK_PCIE/CMakeLists.txt @@ -28,7 +28,7 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "./*.h" ) diff --git a/subModule/Hd_CameraModule_HIK_PCIE/Hd_CameraModule_HIK_PCIE.cpp b/subModule/Hd_CameraModule_HIK_PCIE/Hd_CameraModule_HIK_PCIE.cpp new file mode 100644 index 0000000..677e85d --- /dev/null +++ b/subModule/Hd_CameraModule_HIK_PCIE/Hd_CameraModule_HIK_PCIE.cpp @@ -0,0 +1,380 @@ +#include "Hd_CameraModule_HIK_PCIE.h" +using namespace std; +#include +#include +#include +#include +#include +enum statusEnum { + CONNECTED, + RECONNECTING, + DISCONNECTED +}; +enum triggerModeEnum { + SOFTWARE, + HARDWARE, + EMPTY +}; +statusEnum cameraStatus = DISCONNECTED; +triggerModeEnum triggerMode = HARDWARE; +int getImageTimeOut = 3000; +bool runFlag = true; +//总取图数 +int imgIndex = 0; +MV_GENTL_DEV_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量,用来存储设备列表 +MV_GENTL_IF_INFO_LIST m_stIFList; +string Username = ""; +int cameraIndex = -1; +QString lastError; +QQueue queuepic; +QMutex* n_mutex = new QMutex(); + +void* handle = NULL; +void CloseDevice(); + +//0106 断线重连 +void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser); +void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0); +//搜索所有设备 +int SearchDevice(){ + + if (m_stIFList.nInterfaceNum != 0) { + const char* chCtiPath = "MvFGProducerXoF.cti";//.cti文件路径 + int nRet = 0; + nRet = MV_CC_EnumInterfacesByGenTL(&m_stIFList, chCtiPath); + if (nRet != MV_OK) + { + qDebug() << "EnumInterfacsByGenTL fail"; + return -1; + } + + } + if (m_stIFList.nInterfaceNum == 0) + { + qDebug() << "No Device"; + return -1; + } + int nRet = 0; + // ch:枚举子网内所有设备 | en:Enumerate all devices within subnet + for (int p = 0; p < m_stIFList.nInterfaceNum; p++) + { + memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); + nRet = MV_CC_EnumDevicesByGenTL(m_stIFList.pIFInfo[p], &m_stDevList); + for (int i = 0; i < m_stDevList.nDeviceNum; i++) + { + //SN + unsigned char* name = m_stDevList.pDeviceInfo[i]->chSerialNumber; + string userName = static_cast((LPCSTR)name); + if (Username == userName) + { + return i; + } + } + } + if (MV_OK != nRet) + { + return -1; + } + return -1; +} + +bool connectDevice() +{ + int cameraIndex = SearchDevice(); + if (cameraIndex == -1) { + //未匹配到相机 + qDebug() << "[Waring] " << "Hd_CameraModule_HIK not match --CameraName:" << QString::fromStdString(Username); + lastError = "找不到相机" + QString::fromStdString(Username); + return false; + } + if (handle != NULL) + { + MV_CC_StopGrabbing(handle); + MV_CC_CloseDevice(handle); + MV_CC_DestroyHandle(handle); + } + + //打开相机 + MV_CC_CreateHandleByGenTL(&handle, m_stDevList.pDeviceInfo[cameraIndex]); + int nRet = MV_CC_OpenDevice(handle); + // //加载用户集,相机设置应当UserSet1 + nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1"); + if (MV_OK != nRet) + { + qDebug() << "Set UserSetSelector fail! nRet " << nRet; + } + // ch:注册抓图回调 | en:Register image callback + MV_CC_SetIntValueEx(handle, "GevHeartbeatTimeout", 3000);//心跳日志 + + nRet = MV_CC_RegisterImageCallBackEx(handle, ImageCallBackEx, handle);//注册回调 + if (MV_OK != nRet) + return false; + nRet = MV_CC_RegisterExceptionCallBack(handle, ReconnectDevice, NULL);//断线重连 + if (MV_OK != nRet) + return false; + MV_CC_StartGrabbing(handle); + return true; +} +void SetExposureTime(float exposureValue) +{ + qDebug() << "[INFO] " << "exposureValue:" << exposureValue; + MV_CC_SetEnumValue(handle, "ExposureAuto", MV_EXPOSURE_AUTO_MODE_OFF); + MV_CC_SetFloatValue(handle, "ExposureTime", exposureValue); +} + +void SetGain(float GainValue) +{ + qDebug() << "[INFO] " << "GainValue:" << GainValue; + MV_CC_SetEnumValue(handle, "GainAuto", 0); + MV_CC_SetFloatValue(handle, "Gain", GainValue); +} + +void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser) { + + qDebug() << "[Error] " << " MV camera disconnects!"; + + if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT && cameraStatus == CONNECTED) { + + cameraStatus = RECONNECTING; + // 启动后台线程负责重连,避免在回调线程中长时间阻塞 + std::thread([]() { + qDebug() << "[Info] start reconnect thread"; + + // 确保设备资源关闭 + CloseDevice(); + int times = 0; + while (runFlag) + { + qDebug() << "[Info] reconnect times:" << times++; + if (connectDevice()) + { + qWarning() << "[Hd_CameraModule_HIK] reconnect success!"; + cameraStatus = CONNECTED; + return; + } + + } + }).detach(); + } +} + + + +//回调函数; +//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题 +void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0) +{ + Q_UNUSED(pUser0) + int frameNum = 0; + double time_Start = (double)clock(); + QMutexLocker locker(n_mutex); + cv::Mat srcImage = cv::Mat(); + //qDebug() << "[info]" << __FUNCTION__ << " line:" << __LINE__ << "--- start"; + if (pFrameInfo0) + { + //获取的是单通道灰度图 + if (pFrameInfo0->enPixelType == PixelType_Gvsp_Mono8)//获取当前采集到的图像格式 + { + srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC1, pData0); + } + //获取的是RGB8图 + else if (pFrameInfo0->enPixelType == PixelType_Gvsp_BGR8_Packed) + { + srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0); + + //cvtColor(srcImage, srcImage, COLOR_RGB2BGR);//导致异色 + } + else if (IsColor(pFrameInfo0->enPixelType)) //其它格式彩色图 + { + MvGvspPixelType enDstPixelType = PixelType_Gvsp_Undefined; + enDstPixelType = PixelType_Gvsp_BGR8_Packed; + unsigned char* pConvertData = NULL; + pConvertData = (unsigned char*)malloc(pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3); + if (NULL == pConvertData) + { + printf("malloc pConvertData fail!\n"); + } + else + { + unsigned int nConvertDataSize = 0; + nConvertDataSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3; + + // ch:像素格式转换 | en:Convert pixel format + MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 }; + + frameNum = pFrameInfo0->nFrameNum; //ch:帧号 | en:frame number + stConvertParam.nWidth = pFrameInfo0->nWidth; //ch:图像宽 | en:image width + stConvertParam.nHeight = pFrameInfo0->nHeight; //ch:图像高 | en:image height + stConvertParam.pSrcData = pData0; //ch:输入数据缓存 | en:input data buffer + stConvertParam.nSrcDataLen = pFrameInfo0->nFrameLen; //ch:输入数据大小 | en:input data size + stConvertParam.enSrcPixelType = pFrameInfo0->enPixelType; //ch:输入像素格式 | en:input pixel format + stConvertParam.enDstPixelType = enDstPixelType; //ch:输出像素格式 | en:output pixel format + stConvertParam.pDstBuffer = pConvertData; //ch:输出数据缓存 | en:output data buffer + stConvertParam.nDstBufferSize = nConvertDataSize; //ch:输出缓存大小 | en:output buffer size + int nRet = MV_CC_ConvertPixelType(handle, &stConvertParam); + + Mat mysrcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, stConvertParam.pDstBuffer); + mysrcImage.copyTo(srcImage); + + free(pConvertData); + pConvertData = NULL; + stConvertParam = { 0 }; + } + } + } + if (srcImage.empty()) + { + srcImage = cv::Mat(5, 5, CV_8UC1).setTo(0); + } + + queuepic.push_back(srcImage); + pData0 = { 0 }; + double time_End = (double)clock(); + qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" + << "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgIndex << "nFrameNum : " << frameNum; +} + +Hd_CameraModule_HIK_hard_PCIE::Hd_CameraModule_HIK_hard_PCIE() +{ + //m_thread = new MyThread; + //m_mutex = new QMutex(); +} +//关闭设备 +void CloseDevice() +{ + if (handle == nullptr) + return; + unsigned int nRet = MV_CC_StopGrabbing(handle); + if (nRet == 0) { + //MV_CC_CloseDevice(handle); + //MV_CC_DestroyHandle(handle); + } + //nRet = MV_CC_CloseDevice(handle); + //nRet = MV_CC_DestroyHandle(handle); +} +Hd_CameraModule_HIK_hard_PCIE::~Hd_CameraModule_HIK_hard_PCIE() +{ + CloseDevice(); + if (n_mutex) + { + delete n_mutex; + n_mutex = nullptr; + } + + qDebug() << "[INFO] " << " delete success!"; +} +//从类中读数据到实例对象 +bool Hd_CameraModule_HIK_hard_PCIE::readData(std::vector& mat, QByteArray& data) +{ + if (data == "getStatus") { + data = lastError.toUtf8(); + return true; + } + + if (queuepic.isEmpty()) + { + return false; + } + QMutexLocker locker(n_mutex); + cv::Mat img = queuepic.dequeue(); + mat.push_back(img); + + qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex; + return true; +} + +//实例对象把数据写入到类;加载模型后会运行此函数 +bool Hd_CameraModule_HIK_hard_PCIE::writeData(std::vector& mat, QByteArray& data) +{ + Q_UNUSED(mat); + if (data.contains("deviceList")) { + auto result = QByteArrayToMV_GENTL_IF_INFO_LIST(data.mid(10)); + if (result.nInterfaceNum != 0) { + m_stIFList = result; + return true; + } + } + return true; +} + +bool Hd_CameraModule_HIK_hard_PCIE::initParas(QByteArray& initData) +{ + QByteArrayList valueList = initData.split('#'); + if (valueList.size() < 3) { + qDebug() << "[Error] " << " Hd_CameraModule_HIK initParas fail--params error!参数数量不满足"; + lastError = "参数数量不满足"; + return false; + } + Username = valueList[0]; + + auto triggerModeStr = valueList[1]; + if (triggerModeStr == "HARDWARE") + triggerMode = HARDWARE; + else if (triggerModeStr == "SOFTWARE") + triggerMode = SOFTWARE; + else if (triggerModeStr == "EMPTY") + triggerMode = EMPTY; + else { + qDebug() << "[Error] " << " Hd_CameraModule_HIK initParas fail--params error!触发模式参数错误"; + lastError = "触发模式参数错误"; + return false; + } + + getImageTimeOut = valueList[2].toInt(); + + imgIndex = 0; + return connectDevice(); +} + +bool Hd_CameraModule_HIK_hard_PCIE::run() +{ + qDebug() << "[INFO] " << " run start" << QString::fromStdString(Username); + if (triggerMode == SOFTWARE) + MV_CC_SetCommandValue(handle, "TriggerSoftware"); + try + { + int sleepMs = 10; + int cnt = 0; + int timeoutCnt = getImageTimeOut / sleepMs; + while (true) + { + QMutexLocker locker(n_mutex); + if (queuepic.size() > 0)return true; + if (cnt++ > timeoutCnt) { + queuepic.push_back(cv::Mat(200, 200, CV_8UC1, cv::Scalar(0))); //返回空图 + qDebug() << QString::fromStdString(Username) << "timeout"; + return true; + } + QThread::msleep(sleepMs); + } + } + catch (QString ev) + { + qDebug() << "[Error] " << " ev:" << ev; + } + return true; +} + + +//相机连接状态:正常连接或断开 +bool Hd_CameraModule_HIK_hard_PCIE::checkStatus() +{ + //status = moduleStatus; + return status; +} + +Hd_CameraModule_HIK_hard_PCIE* create() +{ + qDebug() << "[INFO] " << "Hd_CameraModule_HIK create success!"; + return new Hd_CameraModule_HIK_hard_PCIE; +} + +void destory(Hd_CameraModule_HIK_hard_PCIE* ptr) +{ + if (ptr) + { + delete ptr; + ptr = nullptr; + } + qDebug() << "[INFO] " << "Hd_CameraModule_HIK destory success!"; +} \ No newline at end of file diff --git a/subModule/Hd_CameraModule_HIK_PCIE/Hd_CameraModule_HIK_PCIE.h b/subModule/Hd_CameraModule_HIK_PCIE/Hd_CameraModule_HIK_PCIE.h new file mode 100644 index 0000000..9dae2e6 --- /dev/null +++ b/subModule/Hd_CameraModule_HIK_PCIE/Hd_CameraModule_HIK_PCIE.h @@ -0,0 +1,84 @@ +#ifndef Hd_CameraModule_HIK_hard_PCIE_H +#define Hd_CameraModule_HIK_hard_PCIE_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace cv; +#pragma execution_character_set("utf-8") +static MV_GENTL_IF_INFO_LIST QByteArrayToMV_GENTL_IF_INFO_LIST(const QByteArray& byteArray) { + MV_GENTL_IF_INFO_LIST deviceInfoList; + if (byteArray.size() == sizeof(MV_GENTL_IF_INFO_LIST)) { + memcpy(&deviceInfoList, byteArray.constData(), sizeof(MV_GENTL_IF_INFO_LIST)); + } + else { + qDebug() << "Invalid size of QByteArray for MV_GENTL_IF_INFO_LIST!"; + } + return deviceInfoList; +} +bool IsColor(MvGvspPixelType enType) +{ + switch (enType) + { + case PixelType_Gvsp_RGB8_Packed: + case PixelType_Gvsp_YUV422_Packed: + case PixelType_Gvsp_YUV422_YUYV_Packed: + case PixelType_Gvsp_BayerGR8: + case PixelType_Gvsp_BayerRG8: + case PixelType_Gvsp_BayerGB8: + case PixelType_Gvsp_BayerBG8: + case PixelType_Gvsp_BayerGB10: + case PixelType_Gvsp_BayerGB10_Packed: + case PixelType_Gvsp_BayerBG10: + case PixelType_Gvsp_BayerBG10_Packed: + case PixelType_Gvsp_BayerRG10: + case PixelType_Gvsp_BayerRG10_Packed: + case PixelType_Gvsp_BayerGR10: + case PixelType_Gvsp_BayerGR10_Packed: + case PixelType_Gvsp_BayerGB12: + case PixelType_Gvsp_BayerGB12_Packed: + case PixelType_Gvsp_BayerBG12: + case PixelType_Gvsp_BayerBG12_Packed: + case PixelType_Gvsp_BayerRG12: + case PixelType_Gvsp_BayerRG12_Packed: + case PixelType_Gvsp_BayerGR12: + case PixelType_Gvsp_BayerGR12_Packed: + return true; + default: + return false; + } +} +class Hd_CameraModule_HIK_hard_PCIE :public dsModuleBase +{ +public: + Hd_CameraModule_HIK_hard_PCIE(); + virtual ~Hd_CameraModule_HIK_hard_PCIE(); + //从类中读数据到实例对象 + bool readData(std::vector& mat, QByteArray& data); + //实例对象把数据写入到类 + bool writeData(std::vector& mat, QByteArray& data); + bool initParas(QByteArray& initData); + bool run(); + bool checkStatus(); +private: + std::vector imgShouldGetVec; + int imgShouldGetIndex = 0; + //MyThread *m_thread = nullptr; + //QMutex* m_mutex; +}; + +extern "C" +{ +Q_DECL_EXPORT Hd_CameraModule_HIK_hard_PCIE * create(); +Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_hard_PCIE * ptr); +} + +#endif // Hd_CameraModule_HIK_hard_H +//Hd_CameraModule_HIK_hard_PCIE diff --git a/subModule/Hd_CameraModule_HIK_PCIE/readme.txt b/subModule/Hd_CameraModule_HIK_PCIE/readme.txt new file mode 100644 index 0000000..11cf21a --- /dev/null +++ b/subModule/Hd_CameraModule_HIK_PCIE/readme.txt @@ -0,0 +1,3 @@ +֧³ֲɼ¯¿¨Ïà»ú +³õʼ»¯¸ñʽ "Ïà»úÐòÁкÅ#HARDWARE/SOFTWARE/EMPTY#ȡͼ³¬ʱʱ¼ä" +SAMPLE: Vir76210850#SOFTWARE#2000 \ No newline at end of file diff --git a/subModule/Hd_CameraModule_HIK_hard_GIGE/Hd_CameraModule_HIK_hard_GIGE.cpp b/subModule/Hd_CameraModule_HIK_hard_GIGE/Hd_CameraModule_HIK_hard_GIGE.cpp deleted file mode 100644 index 3789fba..0000000 --- a/subModule/Hd_CameraModule_HIK_hard_GIGE/Hd_CameraModule_HIK_hard_GIGE.cpp +++ /dev/null @@ -1,593 +0,0 @@ -#include "Hd_CameraModule_HIK_hard_GIGE.h" -#include -using namespace std; -#include -#include -#include -#include -#include - -static std::atomic g_reconnecting(false); -static std::mutex g_reconnect_mutex; - -QByteArray mv_Status = "connected";//0106 新增相机断联报警 -long long index = 0; //相机序号 -void* handle; -string Username = ""; -bool m_flag = false; -//MV_CC_DEVICE_INFO_LIST m_stDevList;//相机设备 -bool moduleStatus = true; -QQueue queuepic; -//data == "rest_newProductIn"时要结束run;机台报警,取图超时,复位后重新拍的情况。 -bool ifBreak = false; -//ifRunning减少ifBreak的判断;"rest_newProductIn"时,Logic_camera_thread框架会结束未处理完的相相机取图 -bool ifRunning = false; - -MV_CC_DEVICE_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量,用来存储设备列表 -//MV_GENTL_IF_INFO_LIST m_stIFList; -void CloseDevice(); -static MV_CC_DEVICE_INFO_LIST QByteArrayToMV_CC_DeviceInfoList(const QByteArray& byteArray) { - MV_CC_DEVICE_INFO_LIST deviceInfoList; - if (byteArray.size() == sizeof(MV_CC_DEVICE_INFO_LIST)) { - memcpy(&deviceInfoList, byteArray.constData(), sizeof(MV_CC_DEVICE_INFO_LIST)); - } - else { - qDebug() << "Invalid size of QByteArray for MV_CC_DEVICE_INFO_LIST!"; - } - return deviceInfoList; -} -QString byteArrayToUnicode(const QByteArray array) { - - // state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功 - // 如果转换成功,则值为0,如果值大于0,则说明转换失败 - QTextCodec::ConverterState state; - // 先尝试使用utf-8的方式把QByteArray转换成QString - QString text = QTextCodec::codecForName("UTF-8")->toUnicode(array.constData(), array.size(), &state); - // 如果转换时无效字符数量大于0,说明编码格式不对 - if (state.invalidChars > 0) - { - // 再尝试使用GBK的方式进行转换,一般就能转换正确(当然也可能是其它格式,但比较少见了) - text = QTextCodec::codecForName("GBK")->toUnicode(array); - } - return text; -} -QMutex* n_mutex = new QMutex(); -//cv::Mat srcImage; -//是否为标准通信流程: -//标准通信流程,run函数设置曝光/增益;非标准通信流程(简单通信流程),回调函数设置曝光/增益 -int imgCnt = 0; -bool ifStandard = false; -//相机取图超时时间 -int getImageTimeOut = 3000; -//总取图数 -int imgIndex = 0; -//曝光值列表 -QQueue expourseTimeList; -//增益列表 -QQueue gainList; - -bool IsColor(MvGvspPixelType enType) -{ - switch (enType) - { - case PixelType_Gvsp_RGB8_Packed: - case PixelType_Gvsp_YUV422_Packed: - case PixelType_Gvsp_YUV422_YUYV_Packed: - case PixelType_Gvsp_BayerGR8: - case PixelType_Gvsp_BayerRG8: - case PixelType_Gvsp_BayerGB8: - case PixelType_Gvsp_BayerBG8: - case PixelType_Gvsp_BayerGB10: - case PixelType_Gvsp_BayerGB10_Packed: - case PixelType_Gvsp_BayerBG10: - case PixelType_Gvsp_BayerBG10_Packed: - case PixelType_Gvsp_BayerRG10: - case PixelType_Gvsp_BayerRG10_Packed: - case PixelType_Gvsp_BayerGR10: - case PixelType_Gvsp_BayerGR10_Packed: - case PixelType_Gvsp_BayerGB12: - case PixelType_Gvsp_BayerGB12_Packed: - case PixelType_Gvsp_BayerBG12: - case PixelType_Gvsp_BayerBG12_Packed: - case PixelType_Gvsp_BayerRG12: - case PixelType_Gvsp_BayerRG12_Packed: - case PixelType_Gvsp_BayerGR12: - case PixelType_Gvsp_BayerGR12_Packed: - return true; - default: - return false; - } -} -//0106 断线重连 -void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser); -void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0); -//搜索所有设备 -int SearchDevice() -{ - if (m_stDevList.nDeviceNum == 0) { - memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); - // ch:枚举子网内所有设备 | en:Enumerate all devices within subnet - int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList); - if (MV_OK != nRet) - { - return 0; - } - } - for (int i = 0; i < m_stDevList.nDeviceNum; i++) - { - //SN - unsigned char* name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chSerialNumber; - //userID - //unsigned char* name=m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chUserDefinedName; - string userName = static_cast((LPCSTR)name); - if (Username == userName) - { - index = i; - break; - } - } - return -1; -} - -bool connectDevice() -{ - //MV_CC_Initialize(); - index = -1; - SearchDevice(); - if (index == -1) - { - //未匹配到相机 - //qDebug() << "[Waring] " << "Hd_CameraModule_HIK not match --CameraName:" << QString::fromStdString(Username); - return false; - } - unsigned char* name = m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.chUserDefinedName; - string userName = static_cast((LPCSTR)name); - qDebug() << "[INFO] " << " start" << "--UserName:" << QString::fromStdString(userName); - if (handle != NULL) - { - MV_CC_StopGrabbing(handle); - MV_CC_CloseDevice(handle); - MV_CC_DestroyHandle(handle); - } - - //打开相机 - MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[index]); - int nRet = MV_CC_OpenDevice(handle); - ////触发模式 - MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0); - MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON); - // //加载用户集,相机设置应当UserSet1 - nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1"); - if (MV_OK != nRet) - { - qDebug() << "Set UserSetSelector fail! nRet " << nRet; - } - // ch:注册抓图回调 | en:Register image callback - MV_CC_SetIntValueEx(handle, "GevHeartbeatTimeout", 3000);//心跳日志 - - nRet = MV_CC_RegisterImageCallBackEx(handle, ImageCallBackEx, handle);//注册回调 - if (MV_OK != nRet) - return false; - nRet = MV_CC_RegisterExceptionCallBack(handle, ReconnectDevice, NULL);//断线重连 - if (MV_OK != nRet) - return false; - MV_CC_StartGrabbing(handle); - return true; -} -void SetExposureTime(float exposureValue) -{ - qDebug() << "[INFO] " << "exposureValue:" << exposureValue; - MV_CC_SetEnumValue(handle, "ExposureAuto", MV_EXPOSURE_AUTO_MODE_OFF); - MV_CC_SetFloatValue(handle, "ExposureTime", exposureValue); -} - -void SetGain(float GainValue) -{ - qDebug() << "[INFO] " << "GainValue:" << GainValue; - MV_CC_SetEnumValue(handle, "GainAuto", 0); - MV_CC_SetFloatValue(handle, "Gain", GainValue); -} - -//0518 断线重连 -void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser) -{ - mv_Status = "disconnect"; - qDebug() << "[Error] " << " MV camera disconnects!"; - moduleStatus = false; - - if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT) - { - // 如果已有重连线程在运行,则直接返回 - bool expected = false; - if (!g_reconnecting.compare_exchange_strong(expected, true)) - { - qDebug() << "[Info] reconnect already in progress"; - return; - } - - // 启动后台线程负责重连,避免在回调线程中长时间阻塞 - std::thread([]() { - qDebug() << "[Info] start reconnect thread"; - - // 确保设备资源关闭 - CloseDevice(); - - int attempt = 0; - int delay_ms = 500; // 初始延迟 - while (true) - { - attempt++; - qDebug() << "[Info] reconnect attempt:" << attempt; - if (connectDevice()) - { - qWarning() << "[Hd_CameraModule_HIK] reconnect success!"; - moduleStatus = true; - mv_Status = "connected"; - g_reconnecting = false; - break; - } - - // 指数退避,最大 5000ms - std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms)); - delay_ms = delay_ms * 2; - if (delay_ms > 5000) delay_ms = 5000; - - // 在某些场景可能希望退出重连(例如程序关闭),如果未来需要可增加退出条件 - } - }).detach(); - } -} - -//0106 断连提示 -void _stdcall ExceptionCB(unsigned int nMesgType, void* pUser) { - mv_Status = "disconnect"; - qDebug() << "[Error] " << " MvCameraTL disconnects!"; -} - - -Hd_CameraModule_HIK_hard_PCIE* create() -{ - qDebug() << "[INFO] " << "Hd_CameraModule_HIK create success!"; - return new Hd_CameraModule_HIK_hard_PCIE; -} - -void destory(Hd_CameraModule_HIK_hard_PCIE* ptr) -{ - if (ptr) - { - delete ptr; - ptr = nullptr; - } - qDebug() << "[INFO] " << "Hd_CameraModule_HIK destory success!"; -} - -//回调函数; -//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题 -void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0) -{ - Q_UNUSED(pUser0) - int frameNum = 0; - double time_Start = (double)clock(); - n_mutex->lock(); - cv::Mat srcImage = cv::Mat(); - //qDebug() << "[info]" << __FUNCTION__ << " line:" << __LINE__ << "--- start"; - if (pFrameInfo0) - { - //获取的是单通道灰度图 - if (pFrameInfo0->enPixelType == PixelType_Gvsp_Mono8)//获取当前采集到的图像格式 - { - srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC1, pData0); - } - //获取的是RGB8图 - else if (pFrameInfo0->enPixelType == PixelType_Gvsp_BGR8_Packed) - { - srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0); - - //cvtColor(srcImage, srcImage, COLOR_RGB2BGR);//导致异色 - } - else if (IsColor(pFrameInfo0->enPixelType)) //其它格式彩色图 - { - MvGvspPixelType enDstPixelType = PixelType_Gvsp_Undefined; - enDstPixelType = PixelType_Gvsp_BGR8_Packed; - unsigned char* pConvertData = NULL; - pConvertData = (unsigned char*)malloc(pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3); - if (NULL == pConvertData) - { - printf("malloc pConvertData fail!\n"); - } - else - { - unsigned int nConvertDataSize = 0; - nConvertDataSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3; - - // ch:像素格式转换 | en:Convert pixel format - MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 }; - - frameNum = pFrameInfo0->nFrameNum; //ch:帧号 | en:frame number - stConvertParam.nWidth = pFrameInfo0->nWidth; //ch:图像宽 | en:image width - stConvertParam.nHeight = pFrameInfo0->nHeight; //ch:图像高 | en:image height - stConvertParam.pSrcData = pData0; //ch:输入数据缓存 | en:input data buffer - stConvertParam.nSrcDataLen = pFrameInfo0->nFrameLen; //ch:输入数据大小 | en:input data size - stConvertParam.enSrcPixelType = pFrameInfo0->enPixelType; //ch:输入像素格式 | en:input pixel format - stConvertParam.enDstPixelType = enDstPixelType; //ch:输出像素格式 | en:output pixel format - stConvertParam.pDstBuffer = pConvertData; //ch:输出数据缓存 | en:output data buffer - stConvertParam.nDstBufferSize = nConvertDataSize; //ch:输出缓存大小 | en:output buffer size - int nRet = MV_CC_ConvertPixelType(handle, &stConvertParam); - - Mat mysrcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, stConvertParam.pDstBuffer); - mysrcImage.copyTo(srcImage); - - free(pConvertData); - pConvertData = NULL; - stConvertParam = { 0 }; - } - } - } - if (srcImage.empty()) - { - srcImage = cv::Mat(5, 5, CV_8UC1).setTo(0); - } - if (ifStandard == false) - { - imgIndex++; - if (expourseTimeList.size() > 1 && expourseTimeList[imgIndex % expourseTimeList.size()] != expourseTimeList[(imgIndex - 1) % expourseTimeList.size()]) - SetExposureTime(expourseTimeList[imgIndex % expourseTimeList.size()]); - if (gainList.size() > 1 && gainList[imgIndex % gainList.size()] != gainList[(imgIndex - 1) % gainList.size()]) - SetGain(gainList[imgIndex % gainList.size()]); - } - queuepic.push_back(srcImage); - m_flag = true; - n_mutex->unlock(); - pData0 = { 0 }; - imgCnt++; - double time_End = (double)clock(); - std::cout << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" - << "--CameraName:" << Username << " imgIndex:" << imgCnt << "nFrameNum : " << frameNum << std::endl; - qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" - << "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgCnt << "nFrameNum : " << frameNum; -} - -Hd_CameraModule_HIK_hard_PCIE::Hd_CameraModule_HIK_hard_PCIE() -{ - //m_thread = new MyThread; - //m_mutex = new QMutex(); -} -//关闭设备 -void CloseDevice() -{ - - // 如果 handle 已经为空,直接返回 - if (handle == nullptr) - return; - - // 使用 SDK 正确的停止/关闭/销毁流程,避免使用 CloseHandle 等不匹配的 API - MV_CC_StopGrabbing(handle); - MV_CC_CloseDevice(handle); - MV_CC_DestroyHandle(handle); - handle = nullptr; -} - -Hd_CameraModule_HIK_hard_PCIE::~Hd_CameraModule_HIK_hard_PCIE() -{ - CloseDevice(); - if (n_mutex) - { - delete n_mutex; - n_mutex = nullptr; - } - - qDebug() << "[INFO] " << " delete success!"; -} -//从类中读数据到实例对象 -bool Hd_CameraModule_HIK_hard_PCIE::readData(std::vector& mat, QByteArray& data) -{ - if (queuepic.isEmpty()) - { - //qCritical() << __FUNCTION__ << " line:" <<__LINE__ << " srcImage is null"; - return false; - } - n_mutex->lock(); - cv::Mat img = queuepic.dequeue(); - mat.push_back(img); - n_mutex->unlock(); - - qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex; - return true; -} - -//实例对象把数据写入到类;加载模型后会运行此函数 -bool Hd_CameraModule_HIK_hard_PCIE::writeData(std::vector& mat, QByteArray& data) -{ - Q_UNUSED(mat); - if (data.contains("deviceList")) { - auto result = QByteArrayToMV_CC_DeviceInfoList(data.mid(10)); - if (result.nDeviceNum != 0) { - m_stDevList = result; - return true; - } - } - QStringList dataList = QString::fromUtf8(data).split("_"); - //2024.02.18更新,相机对应的读SN信号时,表示新产品进入,设置初始值 - if (data == "rest_newProductIn") - { - //根据实际项目,设置初始值:曝光、增益,ROI区域等 - { - if (expourseTimeList.size() > 0) - SetExposureTime(expourseTimeList[0]); - if (gainList.size() > 0) - SetGain(gainList[0]); - } - if (queuepic.size() > 0) - { - n_mutex->lock(); - //queuepic.clear(); - n_mutex->unlock(); - std::cout << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << Username << std::endl; - qWarning() << __FUNCTION__ << " line: " << __LINE__ << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << QString::fromStdString(Username); - } - if (ifRunning == true) - { - ifBreak = true; - Sleep(10); - } - imgIndex = 0; - return true; - } - else if (dataList.size() > 1) { - if (dataList[0] == "cameraTriggerSignal") { - imgShouldGetVec.clear(); - imgShouldGetIndex = 0; - for (int i = 1; i < dataList.size(); i++) - imgShouldGetVec.push_back(dataList[i].toInt()); - } - } - else - { - m_flag = false; - expourseTimeList.clear(); - gainList.clear(); - } - //Username= data.toStdString(); - return true; -} -//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1... -bool Hd_CameraModule_HIK_hard_PCIE::initParas(QByteArray& initData) -{ - QByteArrayList valueList = initData.split('+'); - Username = valueList[0]; - imgIndex = 0; - expourseTimeList.clear(); - gainList.clear(); - if (valueList.size() > 1) - for (int i = 1; i < valueList.size(); i++) - { - QString valuei = byteArrayToUnicode(valueList[i]); - //valuei.prepend(valueList[i]); - if (valuei.contains("expourseTime")) - { - QStringList expourseTimeL = valuei.split('#'); - if (expourseTimeL.size() > 1) - for (int j = 1; j < expourseTimeL.size(); j++) - expourseTimeList.enqueue(expourseTimeL[j].toFloat()); - } - if (valuei.contains("gain")) - { - QStringList gainL = valuei.split('#'); - if (gainL.size() > 1) - for (int j = 1; j < gainL.size(); j++) - gainList.enqueue(gainL[j].toFloat()); - } - - if (valuei.contains("是否为标准通信流程")) - { - if (valuei.contains("true")) - ifStandard = true; - } - if (valuei.contains("取图超时")) - { - QStringList gainL = valuei.split('#'); - if (gainL.size() > 1) - getImageTimeOut = gainL[1].toInt(); - if (getImageTimeOut < 50) - getImageTimeOut = 1000; - } - if (valuei.contains("OffsetX")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "OffsetX", valueL[1].toInt()); - } - if (valuei.contains("OffsetY")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "OffsetY", valueL[1].toInt()); - } - if (valuei.contains("Width")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "Width", valueL[1].toInt()); - } - if (valuei.contains("Height")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "Height", valueL[1].toInt()); - } - } - - bool ifOk = connectDevice(); - if (ifOk == true) - { - if (expourseTimeList.size() > 0) - SetExposureTime(expourseTimeList[0]); - if (gainList.size() > 0) - SetGain(gainList[0]); - } - imgIndex = 0; - return ifOk; -} - -bool Hd_CameraModule_HIK_hard_PCIE::run() -{ - //queuepic.clear(); - qDebug() << "[INFO] " << " run start" << QString::fromStdString(Username); - bool result = false; - ifRunning = true; - ifBreak = false; - //MV_CC_SetCommandValue(handle, "TriggerSoftware"); - try - { - m_flag = false; - int mytime = 0; - int cnt = 0; - while (true) - { - n_mutex->lock(); - cnt++; - if (queuepic.size() > 0) - { - n_mutex->unlock(); - result = true; - break; - } - if (cnt > 120) { - queuepic.push_back(cv::Mat(200, 200, CV_8UC1, cv::Scalar(0))); //返回空图 - std::cout << "timeout" << std::endl; - n_mutex->unlock(); - return true; - } - n_mutex->unlock(); - QThread::msleep(10); - } - //考虑到误触发、漏触发的图,在这里进行设置。 - //需要设置曝光时 - if (ifStandard == true) - { - imgIndex++; - if (expourseTimeList.size() > 1 && expourseTimeList[imgIndex % expourseTimeList.size()] != expourseTimeList[(imgIndex - 1) % expourseTimeList.size()]) - SetExposureTime(expourseTimeList[imgIndex % expourseTimeList.size()]); - if (gainList.size() > 1 && gainList[imgIndex % gainList.size()] != gainList[(imgIndex - 1) % gainList.size()]) - SetGain(gainList[imgIndex % gainList.size()]); - } - } - catch (QString ev) - { - qDebug() << "[Error] " << " ev:" << ev; - } - qDebug() << "[INFO] " << __LINE__ << " run end"; - return result; -} - -//相机连接状态:正常连接或断开 -bool Hd_CameraModule_HIK_hard_PCIE::checkStatus() -{ - //status = moduleStatus; - return moduleStatus; -} - diff --git a/subModule/Hd_CameraModule_HIK_hard_GIGE/Hd_CameraModule_HIK_hard_GIGE.h b/subModule/Hd_CameraModule_HIK_hard_GIGE/Hd_CameraModule_HIK_hard_GIGE.h deleted file mode 100644 index 5bf23b2..0000000 --- a/subModule/Hd_CameraModule_HIK_hard_GIGE/Hd_CameraModule_HIK_hard_GIGE.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef Hd_CameraModule_HIK_hard_PCIE_H -#define Hd_CameraModule_HIK_hard_PCIE_H -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace cv; -#pragma execution_character_set("utf-8") - -class Hd_CameraModule_HIK_hard_PCIE :public dsModuleBase -{ -public: - Hd_CameraModule_HIK_hard_PCIE(); - virtual ~Hd_CameraModule_HIK_hard_PCIE(); - //从类中读数据到实例对象 - bool readData(std::vector& mat, QByteArray& data); - //实例对象把数据写入到类 - bool writeData(std::vector& mat, QByteArray& data); - bool initParas(QByteArray& initData); - bool run(); - bool checkStatus(); -private: - std::vector imgShouldGetVec; - int imgShouldGetIndex = 0; - //MyThread *m_thread = nullptr; - //QMutex* m_mutex; -}; - -extern "C" -{ -Q_DECL_EXPORT Hd_CameraModule_HIK_hard_PCIE * create(); -Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_hard_PCIE * ptr); -} - -#endif // Hd_CameraModule_HIK_hard_H -//Hd_CameraModule_HIK_hard_PCIE diff --git a/subModule/Hd_CameraModule_HIK_hard_PCIE/Hd_CameraModule_HIK_hard_PCIE.cpp b/subModule/Hd_CameraModule_HIK_hard_PCIE/Hd_CameraModule_HIK_hard_PCIE.cpp deleted file mode 100644 index 1abe4b2..0000000 --- a/subModule/Hd_CameraModule_HIK_hard_PCIE/Hd_CameraModule_HIK_hard_PCIE.cpp +++ /dev/null @@ -1,571 +0,0 @@ -#include "Hd_CameraModule_HIK_hard_PCIE.h" -#include -using namespace std; -#include -QByteArray mv_Status = "connected";//0106 新增相机断联报警 -long long index = 0; //相机序号 -void* handle; -string Username = ""; -bool m_flag = false; -//MV_CC_DEVICE_INFO_LIST m_stDevList;//相机设备 -bool moduleStatus = true; -QQueue queuepic; -//data == "rest_newProductIn"时要结束run;机台报警,取图超时,复位后重新拍的情况。 -bool ifBreak = false; -//ifRunning减少ifBreak的判断;"rest_newProductIn"时,Logic_camera_thread框架会结束未处理完的相相机取图 -bool ifRunning = false; - -MV_GENTL_DEV_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量,用来存储设备列表 -MV_GENTL_IF_INFO_LIST m_stIFList; -void CloseDevice(); -QString byteArrayToUnicode(const QByteArray array) { - - // state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功 - // 如果转换成功,则值为0,如果值大于0,则说明转换失败 - QTextCodec::ConverterState state; - // 先尝试使用utf-8的方式把QByteArray转换成QString - QString text = QTextCodec::codecForName("UTF-8")->toUnicode(array.constData(), array.size(), &state); - // 如果转换时无效字符数量大于0,说明编码格式不对 - if (state.invalidChars > 0) - { - // 再尝试使用GBK的方式进行转换,一般就能转换正确(当然也可能是其它格式,但比较少见了) - text = QTextCodec::codecForName("GBK")->toUnicode(array); - } - return text; -} -QMutex* n_mutex = new QMutex(); -//cv::Mat srcImage; -//是否为标准通信流程: -//标准通信流程,run函数设置曝光/增益;非标准通信流程(简单通信流程),回调函数设置曝光/增益 -int imgCnt = 0; -bool ifStandard = false; -//相机取图超时时间 -int getImageTimeOut = 3000; -//总取图数 -int imgIndex = 0; -//曝光值列表 -QQueue expourseTimeList; -//增益列表 -QQueue gainList; - -bool IsColor(MvGvspPixelType enType) -{ - switch (enType) - { - case PixelType_Gvsp_RGB8_Packed: - case PixelType_Gvsp_YUV422_Packed: - case PixelType_Gvsp_YUV422_YUYV_Packed: - case PixelType_Gvsp_BayerGR8: - case PixelType_Gvsp_BayerRG8: - case PixelType_Gvsp_BayerGB8: - case PixelType_Gvsp_BayerBG8: - case PixelType_Gvsp_BayerGB10: - case PixelType_Gvsp_BayerGB10_Packed: - case PixelType_Gvsp_BayerBG10: - case PixelType_Gvsp_BayerBG10_Packed: - case PixelType_Gvsp_BayerRG10: - case PixelType_Gvsp_BayerRG10_Packed: - case PixelType_Gvsp_BayerGR10: - case PixelType_Gvsp_BayerGR10_Packed: - case PixelType_Gvsp_BayerGB12: - case PixelType_Gvsp_BayerGB12_Packed: - case PixelType_Gvsp_BayerBG12: - case PixelType_Gvsp_BayerBG12_Packed: - case PixelType_Gvsp_BayerRG12: - case PixelType_Gvsp_BayerRG12_Packed: - case PixelType_Gvsp_BayerGR12: - case PixelType_Gvsp_BayerGR12_Packed: - return true; - default: - return false; - } -} -//0106 断线重连 -void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser); -void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0); -//搜索所有设备 -int SearchDevice() -{ - //MV_CC_Initialize(); - /* MV_CC_DEVICE_INFO_LIST stDeviceList; - memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); - unsigned int nnRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE | MV_GENTL_CXP_DEVICE | MV_GENTL_XOF_DEVICE, &stDeviceList); - return 1;*/ - const char* chCtiPath = "MvFGProducerXoF.cti";//.cti文件路径 - int nRet = 0; - nRet = MV_CC_EnumInterfacesByGenTL(&m_stIFList, chCtiPath); - if (nRet != MV_OK) - { - qDebug() << "EnumInterfacsByGenTL fail"; - return 0; - } - - if (m_stIFList.nInterfaceNum == 0) - { - qDebug() << "No Device"; - return 0; - } - - // ch:枚举子网内所有设备 | en:Enumerate all devices within subnet - for (int p = 0; p < m_stIFList.nInterfaceNum; p++) - { - memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); - nRet = MV_CC_EnumDevicesByGenTL(m_stIFList.pIFInfo[p], &m_stDevList); - bool ifHas = false; - for (int i = 0; i < m_stDevList.nDeviceNum; i++) - { - //SN - unsigned char* name = m_stDevList.pDeviceInfo[i]->chSerialNumber; - string userName = static_cast((LPCSTR)name); - if (Username == userName) - { - index = i; - ifHas = true; - break; - } - } - if (ifHas)break; - } - if (MV_OK != nRet) - { - return 0; - } - return -1; -} - -bool connectDevice() -{ - //MV_CC_Initialize(); - index = -1; - SearchDevice(); - if (index == -1) - { - //未匹配到相机 - //qDebug() << "[Waring] " << "Hd_CameraModule_HIK not match --CameraName:" << QString::fromStdString(Username); - return false; - } - unsigned char* name = m_stDevList.pDeviceInfo[index]->chSerialNumber; - string userName = static_cast((LPCSTR)name); - qDebug() << "[INFO] " << " start" << "--UserName:" << QString::fromStdString(userName); - if (handle != NULL) - { - MV_CC_StopGrabbing(handle); - MV_CC_CloseDevice(handle); - MV_CC_DestroyHandle(handle); - } - - //打开相机 - MV_CC_CreateHandleByGenTL(&handle, m_stDevList.pDeviceInfo[index]); - int nRet = MV_CC_OpenDevice(handle); - ////触发模式 - //MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0); - //MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON); - // //加载用户集,相机设置应当UserSet1 - nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1"); - if (MV_OK != nRet) - { - qDebug() << "Set UserSetSelector fail! nRet " << nRet; - } - // ch:注册抓图回调 | en:Register image callback - MV_CC_SetIntValueEx(handle, "GevHeartbeatTimeout", 3000);//心跳日志 - - nRet = MV_CC_RegisterImageCallBackEx(handle, ImageCallBackEx, handle);//注册回调 - if (MV_OK != nRet) - return false; - nRet = MV_CC_RegisterExceptionCallBack(handle, ReconnectDevice, NULL);//断线重连 - if (MV_OK != nRet) - return false; - MV_CC_StartGrabbing(handle); - return true; -} -void SetExposureTime(float exposureValue) -{ - qDebug() << "[INFO] " << "exposureValue:" << exposureValue; - MV_CC_SetEnumValue(handle, "ExposureAuto", MV_EXPOSURE_AUTO_MODE_OFF); - MV_CC_SetFloatValue(handle, "ExposureTime", exposureValue); -} - -void SetGain(float GainValue) -{ - qDebug() << "[INFO] " << "GainValue:" << GainValue; - MV_CC_SetEnumValue(handle, "GainAuto", 0); - MV_CC_SetFloatValue(handle, "Gain", GainValue); -} - -//0518 断线重连 -void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser) -{ - mv_Status = "disconnect"; - std::cout << "相机重连中..." << std::endl; - qDebug() << "[Error] " << " MV camera disconnects!"; - moduleStatus = false; - if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT) - { - //断开连接 - CloseDevice(); - handle = nullptr; - BOOL bConnected = FALSE; - while (1) - { - Sleep(100); - if (connectDevice() == true) - { - qWarning() << "[Hd_CameraModule_HIK] " << " Hd_CameraModule_HIK create success again! "; - moduleStatus = true; - break; - } - - } - } -} - -//0106 断连提示 -void _stdcall ExceptionCB(unsigned int nMesgType, void* pUser) { - mv_Status = "disconnect"; - qDebug() << "[Error] " << " MvCameraTL disconnects!"; -} - - -Hd_CameraModule_HIK_hard_PCIE* create() -{ - qDebug() << "[INFO] " << "Hd_CameraModule_HIK create success!"; - return new Hd_CameraModule_HIK_hard_PCIE; -} - -void destory(Hd_CameraModule_HIK_hard_PCIE* ptr) -{ - if (ptr) - { - delete ptr; - ptr = nullptr; - } - qDebug() << "[INFO] " << "Hd_CameraModule_HIK destory success!"; -} - -//回调函数; -//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题 -void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0) -{ - Q_UNUSED(pUser0) - int frameNum = 0; - double time_Start = (double)clock(); - n_mutex->lock(); - cv::Mat srcImage = cv::Mat(); - //qDebug() << "[info]" << __FUNCTION__ << " line:" << __LINE__ << "--- start"; - if (pFrameInfo0) - { - //获取的是单通道灰度图 - if (pFrameInfo0->enPixelType == PixelType_Gvsp_Mono8)//获取当前采集到的图像格式 - { - srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC1, pData0); - } - //获取的是RGB8图 - else if (pFrameInfo0->enPixelType == PixelType_Gvsp_BGR8_Packed) - { - srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0); - - //cvtColor(srcImage, srcImage, COLOR_RGB2BGR);//导致异色 - } - else if (IsColor(pFrameInfo0->enPixelType)) //其它格式彩色图 - { - MvGvspPixelType enDstPixelType = PixelType_Gvsp_Undefined; - enDstPixelType = PixelType_Gvsp_BGR8_Packed; - unsigned char* pConvertData = NULL; - pConvertData = (unsigned char*)malloc(pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3); - if (NULL == pConvertData) - { - printf("malloc pConvertData fail!\n"); - } - else - { - unsigned int nConvertDataSize = 0; - nConvertDataSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3; - - // ch:像素格式转换 | en:Convert pixel format - MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 }; - - frameNum = pFrameInfo0->nFrameNum; //ch:帧号 | en:frame number - stConvertParam.nWidth = pFrameInfo0->nWidth; //ch:图像宽 | en:image width - stConvertParam.nHeight = pFrameInfo0->nHeight; //ch:图像高 | en:image height - stConvertParam.pSrcData = pData0; //ch:输入数据缓存 | en:input data buffer - stConvertParam.nSrcDataLen = pFrameInfo0->nFrameLen; //ch:输入数据大小 | en:input data size - stConvertParam.enSrcPixelType = pFrameInfo0->enPixelType; //ch:输入像素格式 | en:input pixel format - stConvertParam.enDstPixelType = enDstPixelType; //ch:输出像素格式 | en:output pixel format - stConvertParam.pDstBuffer = pConvertData; //ch:输出数据缓存 | en:output data buffer - stConvertParam.nDstBufferSize = nConvertDataSize; //ch:输出缓存大小 | en:output buffer size - int nRet = MV_CC_ConvertPixelType(handle, &stConvertParam); - - Mat mysrcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, stConvertParam.pDstBuffer); - mysrcImage.copyTo(srcImage); - - free(pConvertData); - pConvertData = NULL; - stConvertParam = { 0 }; - } - } - } - if (srcImage.empty()) - { - srcImage = cv::Mat(5, 5, CV_8UC1).setTo(0); - } - if (ifStandard == false) - { - imgIndex++; - if (expourseTimeList.size() > 1 && expourseTimeList[imgIndex % expourseTimeList.size()] != expourseTimeList[(imgIndex - 1) % expourseTimeList.size()]) - SetExposureTime(expourseTimeList[imgIndex % expourseTimeList.size()]); - if (gainList.size() > 1 && gainList[imgIndex % gainList.size()] != gainList[(imgIndex - 1) % gainList.size()]) - SetGain(gainList[imgIndex % gainList.size()]); - } - queuepic.push_back(srcImage); - m_flag = true; - n_mutex->unlock(); - pData0 = { 0 }; - imgCnt++; - double time_End = (double)clock(); - std::cout << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" - << "--CameraName:" << Username << " imgIndex:" << imgCnt << "nFrameNum : " << frameNum << std::endl; - qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" - << "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgCnt << "nFrameNum : " << frameNum; -} - -Hd_CameraModule_HIK_hard_PCIE::Hd_CameraModule_HIK_hard_PCIE() -{ - //m_thread = new MyThread; - //m_mutex = new QMutex(); -} -//关闭设备 -void CloseDevice() -{ - if (handle == nullptr) - return; - unsigned int nRet = MV_CC_StopGrabbing(handle); - if (nRet == 0) { - //MV_CC_CloseDevice(handle); - //MV_CC_DestroyHandle(handle); - } - //nRet = MV_CC_CloseDevice(handle); - //nRet = MV_CC_DestroyHandle(handle); -} -Hd_CameraModule_HIK_hard_PCIE::~Hd_CameraModule_HIK_hard_PCIE() -{ - CloseDevice(); - if (n_mutex) - { - delete n_mutex; - n_mutex = nullptr; - } - - qDebug() << "[INFO] " << " delete success!"; -} -//从类中读数据到实例对象 -bool Hd_CameraModule_HIK_hard_PCIE::readData(std::vector& mat, QByteArray& data) -{ - if (queuepic.isEmpty()) - { - //qCritical() << __FUNCTION__ << " line:" <<__LINE__ << " srcImage is null"; - return false; - } - n_mutex->lock(); - cv::Mat img = queuepic.dequeue(); - mat.push_back(img); - queuepic.clear(); - n_mutex->unlock(); - - qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex; - return true; -} - -//实例对象把数据写入到类;加载模型后会运行此函数 -bool Hd_CameraModule_HIK_hard_PCIE::writeData(std::vector& mat, QByteArray& data) -{ - Q_UNUSED(mat); - QStringList dataList = QString::fromUtf8(data).split("_"); - //2024.02.18更新,相机对应的读SN信号时,表示新产品进入,设置初始值 - if (data == "rest_newProductIn") - { - //根据实际项目,设置初始值:曝光、增益,ROI区域等 - { - if (expourseTimeList.size() > 0) - SetExposureTime(expourseTimeList[0]); - if (gainList.size() > 0) - SetGain(gainList[0]); - } - if (queuepic.size() > 0) - { - n_mutex->lock(); - queuepic.clear(); - n_mutex->unlock(); - std::cout << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << Username << std::endl; - qWarning() << __FUNCTION__ << " line: " << __LINE__ << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << QString::fromStdString(Username); - } - if (ifRunning == true) - { - ifBreak = true; - Sleep(10); - } - imgIndex = 0; - return true; - } - else if (dataList.size() > 1) { - if (dataList[0] == "cameraTriggerSignal") { - imgShouldGetVec.clear(); - imgShouldGetIndex = 0; - for (int i = 1; i < dataList.size(); i++) - imgShouldGetVec.push_back(dataList[i].toInt()); - } - } - else - { - m_flag = false; - expourseTimeList.clear(); - gainList.clear(); - } - //Username= data.toStdString(); - return true; -} -//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1... -bool Hd_CameraModule_HIK_hard_PCIE::initParas(QByteArray& initData) -{ - QByteArrayList valueList = initData.split('+'); - Username = valueList[0]; - imgIndex = 0; - expourseTimeList.clear(); - gainList.clear(); - if (valueList.size() > 1) - for (int i = 1; i < valueList.size(); i++) - { - QString valuei = byteArrayToUnicode(valueList[i]); - //valuei.prepend(valueList[i]); - if (valuei.contains("expourseTime")) - { - QStringList expourseTimeL = valuei.split('#'); - if (expourseTimeL.size() > 1) - for (int j = 1; j < expourseTimeL.size(); j++) - expourseTimeList.enqueue(expourseTimeL[j].toFloat()); - } - if (valuei.contains("gain")) - { - QStringList gainL = valuei.split('#'); - if (gainL.size() > 1) - for (int j = 1; j < gainL.size(); j++) - gainList.enqueue(gainL[j].toFloat()); - } - - if (valuei.contains("是否为标准通信流程")) - { - if (valuei.contains("true")) - ifStandard = true; - } - if (valuei.contains("取图超时")) - { - QStringList gainL = valuei.split('#'); - if (gainL.size() > 1) - getImageTimeOut = gainL[1].toInt(); - if (getImageTimeOut < 50) - getImageTimeOut = 1000; - } - if (valuei.contains("OffsetX")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "OffsetX", valueL[1].toInt()); - } - if (valuei.contains("OffsetY")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "OffsetY", valueL[1].toInt()); - } - if (valuei.contains("Width")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "Width", valueL[1].toInt()); - } - if (valuei.contains("Height")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "Height", valueL[1].toInt()); - } - } - - bool ifOk = connectDevice(); - if (ifOk == true) - { - if (expourseTimeList.size() > 0) - SetExposureTime(expourseTimeList[0]); - if (gainList.size() > 0) - SetGain(gainList[0]); - } - imgIndex = 0; - return ifOk; -} - -bool Hd_CameraModule_HIK_hard_PCIE::run() -{ - - qDebug() << "[INFO] " << " run start" << QString::fromStdString(Username); - bool result = false; - ifRunning = true; - ifBreak = false; - try - { - m_flag = false; - int mytime = 0; - int cnt = 0; - while (true) - { - /* if (moduleStatus == false || mytime++ > getImageTimeOut || ifBreak == true) - { - result = false; - break; - }*/ - - cnt++; - if (queuepic.size() > 0) - { - result = true; - std::cout << "\n gotImg" << std::endl; - break; - } - if (cnt > 150) { - n_mutex->lock(); - //queuepic.push_back(cv::imread("D://Image_20250809202445856.bmp", -1)); - queuepic.push_back(cv::Mat(200, 200, CV_8UC1, cv::Scalar(0))); //返回空图 - std::cout << "timeout" << std::endl; - n_mutex->unlock(); - return true; - } - QThread::msleep(10); - } - //考虑到误触发、漏触发的图,在这里进行设置。 - //需要设置曝光时 - if (ifStandard == true) - { - imgIndex++; - if (expourseTimeList.size() > 1 && expourseTimeList[imgIndex % expourseTimeList.size()] != expourseTimeList[(imgIndex - 1) % expourseTimeList.size()]) - SetExposureTime(expourseTimeList[imgIndex % expourseTimeList.size()]); - if (gainList.size() > 1 && gainList[imgIndex % gainList.size()] != gainList[(imgIndex - 1) % gainList.size()]) - SetGain(gainList[imgIndex % gainList.size()]); - } - } - catch (QString ev) - { - qDebug() << "[Error] " << " ev:" << ev; - } - qDebug() << "[INFO] " << __LINE__ << " run end"; - return result; -} - -//相机连接状态:正常连接或断开 -bool Hd_CameraModule_HIK_hard_PCIE::checkStatus() -{ - //status = moduleStatus; - return moduleStatus; -} - diff --git a/subModule/Hd_CameraModule_HIK_hard_PCIE/Hd_CameraModule_HIK_hard_PCIE.h b/subModule/Hd_CameraModule_HIK_hard_PCIE/Hd_CameraModule_HIK_hard_PCIE.h deleted file mode 100644 index 5bf23b2..0000000 --- a/subModule/Hd_CameraModule_HIK_hard_PCIE/Hd_CameraModule_HIK_hard_PCIE.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef Hd_CameraModule_HIK_hard_PCIE_H -#define Hd_CameraModule_HIK_hard_PCIE_H -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace cv; -#pragma execution_character_set("utf-8") - -class Hd_CameraModule_HIK_hard_PCIE :public dsModuleBase -{ -public: - Hd_CameraModule_HIK_hard_PCIE(); - virtual ~Hd_CameraModule_HIK_hard_PCIE(); - //从类中读数据到实例对象 - bool readData(std::vector& mat, QByteArray& data); - //实例对象把数据写入到类 - bool writeData(std::vector& mat, QByteArray& data); - bool initParas(QByteArray& initData); - bool run(); - bool checkStatus(); -private: - std::vector imgShouldGetVec; - int imgShouldGetIndex = 0; - //MyThread *m_thread = nullptr; - //QMutex* m_mutex; -}; - -extern "C" -{ -Q_DECL_EXPORT Hd_CameraModule_HIK_hard_PCIE * create(); -Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_hard_PCIE * ptr); -} - -#endif // Hd_CameraModule_HIK_hard_H -//Hd_CameraModule_HIK_hard_PCIE diff --git a/subModule/Hd_CameraModule_HIK_hard_USB/CMakeLists.txt b/subModule/Hd_CameraModule_HIK_hard_USB/CMakeLists.txt deleted file mode 100644 index 3f4ea58..0000000 --- a/subModule/Hd_CameraModule_HIK_hard_USB/CMakeLists.txt +++ /dev/null @@ -1,70 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "mvs" "opencv") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - - ${ENV_INCLUDE} - ) - -link_directories ( - ${ENV_LIB} - - ) - - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "./*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ) - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES LINKER_LANGUAGE C - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} - ) - - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - ${ENV_TARGET} - Qt${QT_VERSION_MAJOR}::Core - ) - - -# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) - - - - -string(TIMESTAMP RUN_TIME) -message( " model end : " ${CURRENT_FOLDER}:${RUN_TIME}) diff --git a/subModule/Hd_CameraModule_HIK_hard_USB/Hd_CameraModule_HIK_hard_USB.cpp b/subModule/Hd_CameraModule_HIK_hard_USB/Hd_CameraModule_HIK_hard_USB.cpp deleted file mode 100644 index 1559841..0000000 --- a/subModule/Hd_CameraModule_HIK_hard_USB/Hd_CameraModule_HIK_hard_USB.cpp +++ /dev/null @@ -1,739 +0,0 @@ -#include "Hd_CameraModule_HIK_hard_USB.h" -using namespace std; -#include -#include -#include -#include -QByteArray mv_Status = "connected";//0106 新增相机断联报警 -//cv::Mat srcImage; -int index = -1; //相机序号 -void* handle; //相机指针 -string Username = ""; -bool m_flag = false; -MV_CC_DEVICE_INFO_LIST m_stDevList;//相机设备 -bool moduleStatus = true; -QQueue queuepic; -cv::Mat matList[1000] = { cv::Mat() }; -//data == "rest_newProductIn"时要结束run;机台报警,取图超时,复位后重新拍的情况。 -bool ifBreak = false; -//ifRunning减少ifBreak的判断;"rest_newProductIn"时,Logic_camera_thread框架会结束未处理完的相相机取图 -bool ifRunning = false; -bool ifChangeExpourseAndGain = true; - - -QString byteArrayToUnicode(const QByteArray array) { - - // state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功 - // 如果转换成功,则值为0,如果值大于0,则说明转换失败 - QTextCodec::ConverterState state; - // 先尝试使用utf-8的方式把QByteArray转换成QString - QString text = QTextCodec::codecForName("UTF-8")->toUnicode(array.constData(), array.size(), &state); - // 如果转换时无效字符数量大于0,说明编码格式不对 - if (state.invalidChars > 0) - { - // 再尝试使用GBK的方式进行转换,一般就能转换正确(当然也可能是其它格式,但比较少见了) - text = QTextCodec::codecForName("GBK")->toUnicode(array); - } - return text; -} -static MV_CC_DEVICE_INFO_LIST QByteArrayToMV_CC_DeviceInfoList(const QByteArray& byteArray) { - MV_CC_DEVICE_INFO_LIST deviceInfoList; - if (byteArray.size() == sizeof(MV_CC_DEVICE_INFO_LIST)) { - memcpy(&deviceInfoList, byteArray.constData(), sizeof(MV_CC_DEVICE_INFO_LIST)); - } - else { - qDebug() << "Invalid size of QByteArray for MV_CC_DEVICE_INFO_LIST!"; - } - return deviceInfoList; -} -#pragma execution_character_set("utf-8") - -QMutex* n_mutex;// = new QMutex(); -//是否为标准通信流程: -//标准通信流程,run函数设置曝光/增益;非标准通信流程(简单通信流程),回调函数设置曝光/增益 -bool ifStandard = false; -//相机取图超时时间 -int getImageTimeOut = 1000; -//总取图数 -int imgIndex = 0; -//曝光值列表 -QQueue expourseTimeList; -//增益列表 -QQueue gainList; - -//0106 断线重连 -void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser); -void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0); - - -bool IsColor(MvGvspPixelType enType) -{ - switch (enType) - { - case PixelType_Gvsp_RGB8_Packed: - case PixelType_Gvsp_YUV422_Packed: - case PixelType_Gvsp_YUV422_YUYV_Packed: - case PixelType_Gvsp_BayerGR8: - case PixelType_Gvsp_BayerRG8: - case PixelType_Gvsp_BayerGB8: - case PixelType_Gvsp_BayerBG8: - case PixelType_Gvsp_BayerGB10: - case PixelType_Gvsp_BayerGB10_Packed: - case PixelType_Gvsp_BayerBG10: - case PixelType_Gvsp_BayerBG10_Packed: - case PixelType_Gvsp_BayerRG10: - case PixelType_Gvsp_BayerRG10_Packed: - case PixelType_Gvsp_BayerGR10: - case PixelType_Gvsp_BayerGR10_Packed: - case PixelType_Gvsp_BayerGB12: - case PixelType_Gvsp_BayerGB12_Packed: - case PixelType_Gvsp_BayerBG12: - case PixelType_Gvsp_BayerBG12_Packed: - case PixelType_Gvsp_BayerRG12: - case PixelType_Gvsp_BayerRG12_Packed: - case PixelType_Gvsp_BayerGR12: - case PixelType_Gvsp_BayerGR12_Packed: - return true; - default: - return false; - } -} - -//搜索所有设备 -int SearchDevice() -{ - if (m_stDevList.nDeviceNum == 0) { - memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); - // ch:枚举子网内所有设备 | en:Enumerate all devices within subnet - int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList); - if (MV_OK != nRet) - { - return 0; - } - } - for (int i = 0; i < m_stDevList.nDeviceNum; i++) - { - //SN - unsigned char* name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stUsb3VInfo.chSerialNumber; - //userID - //unsigned char* name=m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chUserDefinedName; - string userName = static_cast((LPCSTR)name); - if (Username == userName) - { - index = i; - break; - } - } - return -1; -} - -bool connectDevice() -{ - index = -1; - SearchDevice(); - if (index == -1) - { - //未匹配到相机 - qDebug() << "[Waring] " << "Hd_CameraModule_HIK_hard_USB not match --CameraName:" << QString::fromStdString(Username); - return false; - } - unsigned char* name = m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.chUserDefinedName; - string userName = static_cast((LPCSTR)name); - qDebug() << "[INFO] " << " start" << "--UserName:" << QString::fromStdString(userName); - if (handle != NULL) - { - MV_CC_StopGrabbing(handle); - MV_CC_CloseDevice(handle); - MV_CC_DestroyHandle(handle); - } - - //打开相机 - MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[index]); - int nRet = MV_CC_OpenDevice(handle); - ////触发模式 - MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0); - MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON); - // //加载用户集,相机设置应当UserSet1 - nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1"); - if (MV_OK != nRet) - { - qDebug() << "Set UserSetSelector fail! nRet " << nRet; - } - // ch:注册抓图回调 | en:Register image callback - MV_CC_SetIntValueEx(handle, "GevHeartbeatTimeout", 3000);//心跳日志 - - nRet = MV_CC_RegisterImageCallBackEx(handle, ImageCallBackEx, handle);//注册回调 - if (MV_OK != nRet) - return false; - nRet = MV_CC_RegisterExceptionCallBack(handle, ReconnectDevice, NULL);//断线重连 - if (MV_OK != nRet) - return false; - MV_CC_StartGrabbing(handle); - return true; -} - -//0106 断线重连 -void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser) -{ - mv_Status = "disconnect"; - qDebug() << "[Error] " << " MV camera disconnects!"; - moduleStatus = false; - if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT) - { - //断开连接 - MV_CC_CloseDevice(handle); - int nRet = MV_CC_DestroyHandle(handle); - handle = nullptr; - BOOL bConnected = FALSE; - while (1) - { - Sleep(100); - if (connectDevice() == true) - { - qWarning() << "[Hd_CameraModule_HIK_hard_USB] " << " Hd_CameraModule_HIK_hard_USB create success again! "; - moduleStatus = true; - break; - } - - } - } -} -void _stdcall ExceptionCB(unsigned int nMesgType, void* pUser) { - mv_Status = "disconnect"; - qDebug() << "[Error] " << " MV camera disconnects!"; - moduleStatus = false; -} - -int RGB2BGR(unsigned char* pRgbData, unsigned int nWidth, unsigned int nHeight) -{ - - if (NULL == pRgbData) - { - return MV_E_PARAMETER; - } - - for (unsigned int j = 0; j < nHeight; j++) - { - for (unsigned int i = 0; i < nWidth; i++) - { - unsigned char red = pRgbData[j * (nWidth * 3) + i * 3]; - pRgbData[j * (nWidth * 3) + i * 3] = pRgbData[j * (nWidth * 3) + i * 3 + 2]; - pRgbData[j * (nWidth * 3) + i * 3 + 2] = red; - } - } - - return MV_OK; - -} - -Hd_CameraModule_HIK_hard_USB* create() -{ - qDebug() << "[INFO] " << "Hd_CameraModule_HIK_hard_USB create success!" ; - return new Hd_CameraModule_HIK_hard_USB; -} - -void destory(Hd_CameraModule_HIK_hard_USB * ptr) -{ - if(ptr) - { - delete ptr; - ptr = nullptr; - } - qDebug() << "[INFO] " << "Hd_CameraModule_HIK_hard_USB destory success!"; -} -//回调函数; -//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题 -void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0) -{ - n_mutex->lock(); - double time_Start = (double)clock(); - int frameNum = 0; - cv::Mat srcImage = cv::Mat(); - if (pFrameInfo0) - { - //获取的是单通道灰度图 - if (pFrameInfo0->enPixelType == PixelType_Gvsp_Mono8)//获取当前采集到的图像格式 - { - srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC1, pData0); - } - //获取的是RGB8图 - else if (pFrameInfo0->enPixelType == PixelType_Gvsp_BGR8_Packed) - { - srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0); - } - - ////获取的是RGB8图 - //else if (pFrameInfo0->enPixelType == PixelType_Gvsp_RGB8_Packed) - //{ - // cv::Mat dst = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0); - // //cv::cvtColor(matimage, matimage, cv::COLOR_RGB2BGR); - // srcImage = cv::Mat::zeros(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3); - // std::vector channels; - // cv::split(dst, channels);//分割matimage的通道 - // std::vector dstchannels; - // for (int i = 2; i >= 0; i--) - // { - // dstchannels.push_back(channels[i]); - // } - // merge(dstchannels, srcImage); - //} - - else if (IsColor(pFrameInfo0->enPixelType)) //其它格式彩色图 - { - MvGvspPixelType enDstPixelType = PixelType_Gvsp_Undefined; - enDstPixelType = PixelType_Gvsp_BGR8_Packed; - unsigned char* pConvertData = NULL; - pConvertData = (unsigned char*)malloc(pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3); - if (NULL == pConvertData) - { - printf("malloc pConvertData fail!\n"); - } - else - { - unsigned int nConvertDataSize = 0; - nConvertDataSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3; - - // ch:像素格式转换 | en:Convert pixel format - MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 }; - - frameNum = pFrameInfo0->nFrameNum; //ch:帧号 | en:frame number - stConvertParam.nWidth = pFrameInfo0->nWidth; //ch:图像宽 | en:image width - stConvertParam.nHeight = pFrameInfo0->nHeight; //ch:图像高 | en:image height - stConvertParam.pSrcData = pData0; //ch:输入数据缓存 | en:input data buffer - stConvertParam.nSrcDataLen = pFrameInfo0->nFrameLen; //ch:输入数据大小 | en:input data size - stConvertParam.enSrcPixelType = pFrameInfo0->enPixelType; //ch:输入像素格式 | en:input pixel format - stConvertParam.enDstPixelType = enDstPixelType; //ch:输出像素格式 | en:output pixel format - stConvertParam.pDstBuffer = pConvertData; //ch:输出数据缓存 | en:output data buffer - stConvertParam.nDstBufferSize = nConvertDataSize; //ch:输出缓存大小 | en:output buffer size - int nRet = MV_CC_ConvertPixelType(handle, &stConvertParam); - - Mat mysrcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, stConvertParam.pDstBuffer); - mysrcImage.copyTo(srcImage); - - free(pConvertData); - pConvertData = NULL; - stConvertParam = { 0 }; - } - } - } - if(srcImage.empty()) - { - srcImage = cv::Mat(5, 5, CV_8UC1).setTo(0); - } - - m_flag = true; - queuepic.push_back(srcImage.clone()); - n_mutex->unlock(); - pData0 = { 0 }; - double time_End = (double)clock(); - std::cout << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" - << "--CameraName:" << Username << " imgIndex:" << imgIndex << "nFrameNum : " << frameNum << std::endl; - - qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" - << "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgIndex << "nFrameNum : " << frameNum; - /*QString savePath = "../runtime/Bin_DEVICE/testImg/camera_" + QString::number(imgIndex + 1)+".png"; - cv::Mat resizeS; - cv::resize(srcImage, resizeS, cv::Size(), 0.1, 0.1); - cv::imwrite(savePath.toStdString(), resizeS);*/ -} - -void SetExposureTime(float exposureValue) -{ - qDebug() << "[INFO] " << "exposureValue:" << exposureValue; - MV_CC_SetEnumValue(handle, "ExposureAuto", MV_EXPOSURE_AUTO_MODE_OFF); - MV_CC_SetFloatValue(handle, "ExposureTime", exposureValue); -} - -void SetGain(float GainValue) -{ - qDebug() << "[INFO] " << "GainValue:" << GainValue; - MV_CC_SetEnumValue(handle, "GainAuto", 0); - MV_CC_SetFloatValue(handle, "Gain", GainValue); -} -Hd_CameraModule_HIK_hard_USB::Hd_CameraModule_HIK_hard_USB() -{ - n_mutex = new QMutex(); - m_thread = new MyThread; -} -//关闭设备 -void CloseDevice() -{ - MV_CC_StopGrabbing(handle); - MV_CC_CloseDevice(handle); - MV_CC_DestroyHandle(handle); - handle = nullptr; //此处注释掉的话,软件断开再连接,回调函数不出图 -} - -Hd_CameraModule_HIK_hard_USB::~Hd_CameraModule_HIK_hard_USB() -{ - m_flag = true; - Sleep(10); - CloseDevice(); - if (n_mutex) - { - delete n_mutex; - n_mutex = nullptr; - } - if(m_thread) - { - m_thread->exit(); - m_thread->wait(1); - delete m_thread; - m_thread = nullptr; - } - - qDebug() << "[INFO] " << " delete success!"; -} -//从类中读数据到实例对象 -bool Hd_CameraModule_HIK_hard_USB::readData(std::vector &mat,QByteArray &data) -{ - if (queuepic.isEmpty()) - { - qCritical() << __FUNCTION__ << " line:" <<__LINE__ << " srcImage is null"; - return false; - } - n_mutex->lock(); - cv::Mat img = cv::Mat(); - queuepic.dequeue().copyTo(img); - mat.push_back(img.clone()); - n_mutex->unlock(); - QString qimgIndex = "imgIndex_" + QString::number(imgIndex-1)+"_中文测试"; - data = qimgIndex.toLocal8Bit(); - qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex-1; - return true; -} -//实例对象把数据写入到类 -bool Hd_CameraModule_HIK_hard_USB::writeData(std::vector &mat,QByteArray &data) -{ - //2024.02.18更新,相机对应的读SN信号时,表示新产品进入,设置初始值 - if (data.contains("deviceList")) { - auto result = QByteArrayToMV_CC_DeviceInfoList(data.mid(10)); - if (result.nDeviceNum != 0) { - m_stDevList = result; - return true; - } - } - if (data == "rest_newProductIn") - { - //根据实际项目,设置初始值:曝光、增益,ROI区域等 - { - if (expourseTimeList.size() > 0) - SetExposureTime(expourseTimeList[0]); - if (gainList.size() > 0) - SetGain(gainList[0]); - } - - if (queuepic.size() > 0) - { - n_mutex->lock(); - //queuepic.clear(); - n_mutex->unlock(); - std::cout << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << Username << std::endl; - qWarning() << __FUNCTION__ << " line: " << __LINE__ << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << QString::fromStdString(Username); - } - if (ifRunning == true) - { - ifBreak = true; - Sleep(10); - } - imgIndex = 0; - return true; - } - else - { - m_flag = false; - //expourseTimeList.clear(); - //gainList.clear(); - } - //if (data == "ifChangeExpourseAndGain_false") - // ifChangeExpourseAndGain = false; - //else - // ifChangeExpourseAndGain = true; - //if (data.contains("SetExposureTime_")) - //{ - // QByteArrayList dataList = data.split('#'); - // for (int i = 0; i < dataList.size(); i++) - // { - // if (dataList[i].contains("SetExposureTime_")) - // { - // int value = byteArrayToUnicode(dataList[i]).split("SetExposureTime_")[1].toInt(); - // SetExposureTime(value); - // } - // if (dataList[i].contains("SetGain_")) - // { - // double value = byteArrayToUnicode(dataList[i]).split("SetGain_")[1].toInt(); - // SetGain(value); - // } - // if (dataList[i].contains("TriggerMode_")) - // { - // QString value = byteArrayToUnicode(dataList[i]).split("TriggerMode_")[1]; - // if (value == "软触发") - // ////触发模式 - // { - // MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE); - // currentTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE; - // } - // else - // { - // MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0); - // currentTriggerSource = MV_TRIGGER_SOURCE_LINE0; - // } - // } - // } - //} - ////调试模式下,data==ifChangeExpourseAndGain_false;非调试模式运行时,data不包含SetExposureTime_ - //else if (data != "ifChangeExpourseAndGain_false" && initTriggerSource != currentTriggerSource) - //{ - // MV_CC_SetEnumValue(handle, "TriggerSource", initTriggerSource); - // currentTriggerSource = initTriggerSource; - //} - - - /*data.append("SetExposureTime_" + ui.spinBox->text() + "#"); - data.append("SetGain_" + ui.doubleSpinBox->text() + "#"); - data.append("TriggerMode_" + ui.comboBox_triggerMode->currentText());*/ - - - qDebug() << "Hd_CameraModule_HIK_hard_USB::writeData::" << data; - - m_flag = false; - //Username = data.toStdString(); - return true; -} - - -//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1... -bool Hd_CameraModule_HIK_hard_USB::initParas(QByteArray& initData) -{ - QByteArrayList valueList = initData.split('+'); - Username = valueList[0]; - imgIndex = 0; - - expourseTimeList.clear(); - gainList.clear(); - - - bool ifOk = true; - if (handle == NULL) - ifOk = connectDevice(); - if (ifOk == false) - return false; - if (valueList.size() > 1) - for (int i = 1; i < valueList.size(); i++) - { - QString valuei = byteArrayToUnicode(valueList[i]); - //valuei.prepend(valueList[i]); - if (valuei.contains("expourseTime")) - { - QStringList expourseTimeL = valuei.split('#'); - if (expourseTimeL.size() > 1) - for (int j = 1; j < expourseTimeL.size(); j++) - expourseTimeList.enqueue(expourseTimeL[j].toFloat()); - } - if (valuei.contains("gain")) - { - QStringList gainL = valuei.split('#'); - if (gainL.size() > 1) - for (int j = 1; j < gainL.size(); j++) - gainList.enqueue(gainL[j].toFloat()); - } - - if (valuei.contains("是否为标准通信流程")) - { - if (valuei.contains("true")) - ifStandard = true; - } - if (valuei.contains("取图超时")) - { - QStringList gainL = valuei.split('#'); - if (gainL.size() > 1) - getImageTimeOut = gainL[1].toInt(); - if (getImageTimeOut < 50) - getImageTimeOut = 1000; - } - if (valuei.contains("OffsetX")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if(valueL[1].toInt()>=0) - MV_CC_SetIntValue(handle, "OffsetX", valueL[1].toInt()); - } - if (valuei.contains("OffsetY")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "OffsetY", valueL[1].toInt()); - } - if (valuei.contains("Width")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "Width", valueL[1].toInt()); - } - if (valuei.contains("Height")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "Height", valueL[1].toInt()); - } - - //if (valuei.contains("触发方式")) - //{ - // QStringList valueL = valuei.split('#'); - // if (valueL.size() > 1) - // if (valueL[1].toInt() >= 0) - // if (valueL[1] == "软触发") - // { - // MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE); - // currentTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE; - // initTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE; - // } - // else - // { - // MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0); - // currentTriggerSource = MV_TRIGGER_SOURCE_LINE0; - // initTriggerSource = MV_TRIGGER_SOURCE_LINE0; - // } - //} - } - - if (ifOk == true) - { - if (expourseTimeList.size() > 0) - SetExposureTime(expourseTimeList[0]); - if (gainList.size() > 0) - SetGain(gainList[0]); - } - imgIndex = 0; - if (ifOk == true) - { - MVCC_FLOATVALUE mf = { 0 }; - MV_CC_GetFloatValue(handle, "ExposureTime", &mf); - std::cout << "ExposureTime::" << mf.fCurValue << std::endl; - mf = { 0 }; - MV_CC_GetFloatValue(handle, "Gain", &mf); - std::cout << "Gain::" << mf.fCurValue << std::endl; - MVCC_INTVALUE mI = { 0 }; - MV_CC_GetIntValue(handle, "OffsetX", &mI); - std::cout << "OffsetX::" << mI.nCurValue << std::endl; - mI = { 0 }; - MV_CC_GetIntValue(handle, "OffsetY", &mI); - std::cout << "OffsetY::" << mI.nCurValue << std::endl; - mI = { 0 }; - MV_CC_GetIntValue(handle, "Width", &mI); - std::cout << "Width::" << mI.nCurValue << std::endl; - mI = { 0 }; - MV_CC_GetIntValue(handle, "Height", &mI); - std::cout << "Height::" << mI.nCurValue << std::endl; - MVCC_ENUMVALUE me = { 0 }; - MV_CC_GetEnumValue(handle,"BalanceWhiteAuto",&me); //自动白平衡 - std::cout << "BalanceWhiteAuto::" << me.nCurValue << std::endl; - - } - - return ifOk; -} -bool Hd_CameraModule_HIK_hard_USB::run() -{ - if (imgIndex == expourseTimeList.size()) - imgIndex = 0; - //Sleep(100); - qDebug() << "[INFO] " << " run start" <lock(); - m_flag = false; - //Sleep(2); - //n_mutex->unlock(); - //m_thread->run(); //start()线程运行,频率高时有低概率无响应; - - //if (currentTriggerSource == MV_TRIGGER_SOURCE_SOFTWARE) - //{ - // MV_CC_SetCommandValue(handle, "TriggerSoftware"); - // qDebug() << "[INFO] " << "TriggerSoftware"; - //} - //else - // qDebug() << "[INFO] " << "TriggerHardware"; - //MV_CC_SetCommandValue(handle, "TriggerSoftware"); - //Sleep(15); - //int mytime = 0; - int cnt = 0; - while (true) - { - /* if (moduleStatus == false || mytime++ > getImageTimeOut || ifBreak == true) - { - result = false; - break; - }*/ - n_mutex->lock(); - cnt++; - if (queuepic.size() > 0) - { - n_mutex->unlock(); - result = true; - std::cout << "\n gotImg" << std::endl; - break; - } - if (cnt > 150) { - queuepic.push_back(cv::Mat(200, 200, CV_8UC1, cv::Scalar(0))); //返回空图 - std::cout << "timeout" << std::endl; - n_mutex->unlock(); - return true; - } - n_mutex->unlock(); - QThread::msleep(10); - } - - //qDebug() << "[INFO] " << " expourseTimeList " << QString::fromStdString(Username); - //软触发,不考虑误触发、漏触发 - if (ifChangeExpourseAndGain == true) - { - imgIndex++; - if (expourseTimeList.size() > 1 && expourseTimeList[imgIndex % expourseTimeList.size()] != expourseTimeList[(imgIndex - 1) % expourseTimeList.size()]) - SetExposureTime(expourseTimeList[imgIndex % expourseTimeList.size()]); - //Sleep(1); - if (gainList.size() > 1 && gainList[imgIndex % gainList.size()] != gainList[(imgIndex - 1) % gainList.size()]) - SetGain(gainList[imgIndex % gainList.size()]); - //Sleep(1); - } - if (result == false) - { - QString currPath = "../runtime/Bin_DEVICE/testImg/testImg_"; - if (ifChangeExpourseAndGain == true) - currPath +=QString::number(imgIndex-1); - else - currPath += QString::number(imgIndex); - currPath += ".jpg"; - cv::Mat readMat = cv::imread(currPath.toStdString()); - queuepic.push_back(readMat); - qDebug() << "取图失败,读取图片:" << currPath; - result = true; - } - - } - catch (QString ev) - { - qDebug() << "[Error] " << " ev:" << ev ; - } - qDebug() << "[INFO] " << __LINE__ << " run end" ; - return result; -} - -//相机连接状态:正常连接或断开 -bool Hd_CameraModule_HIK_hard_USB::checkStatus() -{ - //status = moduleStatus; - return moduleStatus; -} - -void MyThread::run() -{ - MV_CC_SetCommandValue(handle, "TriggerSoftware"); -} diff --git a/subModule/Hd_CameraModule_HIK_hard_USB/Hd_CameraModule_HIK_hard_USB.h b/subModule/Hd_CameraModule_HIK_hard_USB/Hd_CameraModule_HIK_hard_USB.h deleted file mode 100644 index cd42309..0000000 --- a/subModule/Hd_CameraModule_HIK_hard_USB/Hd_CameraModule_HIK_hard_USB.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef Hd_CameraModule_HIK_hard_USB_H -#define Hd_CameraModule_HIK_hard_USB_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include - -using namespace cv; -#pragma execution_character_set("utf-8") - - -class MyThread; -class Hd_CameraModule_HIK_hard_USB :public dsModuleBase -{ -public: - Hd_CameraModule_HIK_hard_USB(); - virtual ~Hd_CameraModule_HIK_hard_USB(); - //从类中读数据到实例对象 - bool readData(std::vector& mat, QByteArray& data); - //实例对象把数据写入到类 - bool writeData(std::vector& mat, QByteArray& data); - bool initParas(QByteArray&); - bool run(); - bool checkStatus(); -private: - MyThread *m_thread = nullptr; -}; - -class MyThread : public QThread -{ - Q_OBJECT -public: - explicit MyThread(QObject *parent = nullptr):m_obj(parent){} - void run(); -private: - QObject *m_obj; -signals: - -}; - -extern "C" -{ -Q_DECL_EXPORT Hd_CameraModule_HIK_hard_USB * create(); -Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_hard_USB * ptr); -} - -#endif // Hd_CameraModule_HIK_hard_USB_H diff --git a/subModule/Hd_CameraModule_HIK_soft_GIGE/Hd_CameraModule_HIK_soft_GIGE.cpp b/subModule/Hd_CameraModule_HIK_soft_GIGE/Hd_CameraModule_HIK_soft_GIGE.cpp deleted file mode 100644 index 9391dbb..0000000 --- a/subModule/Hd_CameraModule_HIK_soft_GIGE/Hd_CameraModule_HIK_soft_GIGE.cpp +++ /dev/null @@ -1,598 +0,0 @@ -#include "Hd_CameraModule_HIK_soft_GIGE.h" -#include -using namespace std; -#include -#include -#include -#include -#include - -QByteArray mv_Status = "connected";//0106 新增相机断联报警 -long long index = 0; //相机序号 -void* handle; -string Username = ""; -bool m_flag = false; -//MV_CC_DEVICE_INFO_LIST m_stDevList;//相机设备 -bool moduleStatus = true; -static std::atomic g_reconnecting(false); -static std::mutex g_reconnect_mutex; -QQueue queuepic; -//data == "rest_newProductIn"时要结束run;机台报警,取图超时,复位后重新拍的情况。 -bool ifBreak = false; -//ifRunning减少ifBreak的判断;"rest_newProductIn"时,Logic_camera_thread框架会结束未处理完的相相机取图 -bool ifRunning = false; - -MV_CC_DEVICE_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量,用来存储设备列表 -//MV_GENTL_IF_INFO_LIST m_stIFList; -void CloseDevice(); -static MV_CC_DEVICE_INFO_LIST QByteArrayToMV_CC_DeviceInfoList(const QByteArray& byteArray) { - MV_CC_DEVICE_INFO_LIST deviceInfoList; - if (byteArray.size() == sizeof(MV_CC_DEVICE_INFO_LIST)) { - memcpy(&deviceInfoList, byteArray.constData(), sizeof(MV_CC_DEVICE_INFO_LIST)); - } - else { - qDebug() << "Invalid size of QByteArray for MV_CC_DEVICE_INFO_LIST!"; - } - return deviceInfoList; -} -QString byteArrayToUnicode(const QByteArray array) { - - // state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功 - // 如果转换成功,则值为0,如果值大于0,则说明转换失败 - QTextCodec::ConverterState state; - // 先尝试使用utf-8的方式把QByteArray转换成QString - QString text = QTextCodec::codecForName("UTF-8")->toUnicode(array.constData(), array.size(), &state); - // 如果转换时无效字符数量大于0,说明编码格式不对 - if (state.invalidChars > 0) - { - // 再尝试使用GBK的方式进行转换,一般就能转换正确(当然也可能是其它格式,但比较少见了) - text = QTextCodec::codecForName("GBK")->toUnicode(array); - } - return text; -} -QMutex* n_mutex = new QMutex(); -//cv::Mat srcImage; -//是否为标准通信流程: -//标准通信流程,run函数设置曝光/增益;非标准通信流程(简单通信流程),回调函数设置曝光/增益 -int imgCnt = 0; -bool ifStandard = false; -//相机取图超时时间 -int getImageTimeOut = 3000; -//总取图数 -int imgIndex = 0; -//曝光值列表 -QQueue expourseTimeList; -//增益列表 -QQueue gainList; - -bool IsColor(MvGvspPixelType enType) -{ - switch (enType) - { - case PixelType_Gvsp_RGB8_Packed: - case PixelType_Gvsp_YUV422_Packed: - case PixelType_Gvsp_YUV422_YUYV_Packed: - case PixelType_Gvsp_BayerGR8: - case PixelType_Gvsp_BayerRG8: - case PixelType_Gvsp_BayerGB8: - case PixelType_Gvsp_BayerBG8: - case PixelType_Gvsp_BayerGB10: - case PixelType_Gvsp_BayerGB10_Packed: - case PixelType_Gvsp_BayerBG10: - case PixelType_Gvsp_BayerBG10_Packed: - case PixelType_Gvsp_BayerRG10: - case PixelType_Gvsp_BayerRG10_Packed: - case PixelType_Gvsp_BayerGR10: - case PixelType_Gvsp_BayerGR10_Packed: - case PixelType_Gvsp_BayerGB12: - case PixelType_Gvsp_BayerGB12_Packed: - case PixelType_Gvsp_BayerBG12: - case PixelType_Gvsp_BayerBG12_Packed: - case PixelType_Gvsp_BayerRG12: - case PixelType_Gvsp_BayerRG12_Packed: - case PixelType_Gvsp_BayerGR12: - case PixelType_Gvsp_BayerGR12_Packed: - return true; - default: - return false; - } -} -//0106 断线重连 -void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser); -void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0); -//搜索所有设备 -int SearchDevice() -{ - if (m_stDevList.nDeviceNum == 0) { - memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); - // ch:枚举子网内所有设备 | en:Enumerate all devices within subnet - int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList); - if (MV_OK != nRet) - { - return 0; - } - } - for (int i = 0; i < m_stDevList.nDeviceNum; i++) - { - //SN - unsigned char* name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chSerialNumber; - //userID - //unsigned char* name=m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chUserDefinedName; - string userName = static_cast((LPCSTR)name); - if (Username == userName) - { - index = i; - break; - } - } - return -1; -} - -bool connectDevice() -{ - //MV_CC_Initialize(); - index = -1; - SearchDevice(); - if (index == -1) - { - //未匹配到相机 - //qDebug() << "[Waring] " << "Hd_CameraModule_HIK not match --CameraName:" << QString::fromStdString(Username); - return false; - } - unsigned char* name = m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.chUserDefinedName; - string userName = static_cast((LPCSTR)name); - qDebug() << "[INFO] " << " start" << "--UserName:" << QString::fromStdString(userName); - if (handle != NULL) - { - MV_CC_StopGrabbing(handle); - MV_CC_CloseDevice(handle); - MV_CC_DestroyHandle(handle); - } - - //打开相机 - MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[index]); - int nRet = MV_CC_OpenDevice(handle); - ////触发模式 - MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON); - MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE); - // //加载用户集,相机设置应当UserSet1 - nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1"); - if (MV_OK != nRet) - { - qDebug() << "Set UserSetSelector fail! nRet " << nRet; - } - // ch:注册抓图回调 | en:Register image callback - MV_CC_SetIntValueEx(handle, "GevHeartbeatTimeout", 3000);//心跳日志 - - nRet = MV_CC_RegisterImageCallBackEx(handle, ImageCallBackEx, handle);//注册回调 - if (MV_OK != nRet) - return false; - nRet = MV_CC_RegisterExceptionCallBack(handle, ReconnectDevice, NULL);//断线重连 - if (MV_OK != nRet) - return false; - MV_CC_StartGrabbing(handle); - return true; -} -void SetExposureTime(float exposureValue) -{ - qDebug() << "[INFO] " << "exposureValue:" << exposureValue; - MV_CC_SetEnumValue(handle, "ExposureAuto", MV_EXPOSURE_AUTO_MODE_OFF); - MV_CC_SetFloatValue(handle, "ExposureTime", exposureValue); -} - -void SetGain(float GainValue) -{ - qDebug() << "[INFO] " << "GainValue:" << GainValue; - MV_CC_SetEnumValue(handle, "GainAuto", 0); - MV_CC_SetFloatValue(handle, "Gain", GainValue); -} - -//关闭设备 -void CloseDevice() -{ - // 如果 handle 已经为空,直接返回 - if (handle == nullptr) - return; - - // 使用 SDK 正确的停止/关闭/销毁流程,避免在回调或其他线程中出错 - MV_CC_StopGrabbing(handle); - MV_CC_CloseDevice(handle); - MV_CC_DestroyHandle(handle); - handle = nullptr; //确保后续可以重新创建 handle -} - -//0518 断线重连 -void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser) -{ - mv_Status = "disconnect"; - qDebug() << "[Error] " << " MV camera disconnects!"; - moduleStatus = false; - - if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT) - { - // 如果已有重连线程在运行,则直接返回 - bool expected = false; - if (!g_reconnecting.compare_exchange_strong(expected, true)) - { - qDebug() << "[Info] reconnect already in progress"; - return; - } - - // 启动后台线程负责重连,避免在回调线程中长时间阻塞 - std::thread([]() { - qDebug() << "[Info] start reconnect thread"; - - // 确保设备资源关闭 - CloseDevice(); - - int attempt = 0; - int delay_ms = 500; // 初始延迟 - while (true) - { - attempt++; - qDebug() << "[Info] reconnect attempt:" << attempt; - if (connectDevice()) - { - qWarning() << "[Hd_CameraModule_HIK] reconnect success!"; - moduleStatus = true; - mv_Status = "connected"; - g_reconnecting = false; - break; - } - - // 指数退避,最大 5000ms - std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms)); - delay_ms = delay_ms * 2; - if (delay_ms > 5000) delay_ms = 5000; - - // 在某些场景可能希望退出重连(例如程序关闭),如果未来需要可增加退出条件 - } - }).detach(); - } -} - -//0106 断连提示 -void _stdcall ExceptionCB(unsigned int nMesgType, void* pUser) { - mv_Status = "disconnect"; - qDebug() << "[Error] " << " MvCameraTL disconnects!"; -} - - -Hd_CameraModule_HIK_soft_GIGE* create() -{ - qDebug() << "[INFO] " << "Hd_CameraModule_HIK create success!"; - return new Hd_CameraModule_HIK_soft_GIGE; -} - -void destory(Hd_CameraModule_HIK_soft_GIGE* ptr) -{ - if (ptr) - { - delete ptr; - ptr = nullptr; - } - qDebug() << "[INFO] " << "Hd_CameraModule_HIK destory success!"; -} - -//回调函数; -//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题 -void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0) -{ - Q_UNUSED(pUser0) - int frameNum = 0; - double time_Start = (double)clock(); - n_mutex->lock(); - cv::Mat srcImage = cv::Mat(); - //qDebug() << "[info]" << __FUNCTION__ << " line:" << __LINE__ << "--- start"; - if (pFrameInfo0) - { - //获取的是单通道灰度图 - if (pFrameInfo0->enPixelType == PixelType_Gvsp_Mono8)//获取当前采集到的图像格式 - { - srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC1, pData0); - } - //获取的是RGB8图 - else if (pFrameInfo0->enPixelType == PixelType_Gvsp_BGR8_Packed) - { - srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0); - - //cvtColor(srcImage, srcImage, COLOR_RGB2BGR);//导致异色 - } - else if (IsColor(pFrameInfo0->enPixelType)) //其它格式彩色图 - { - MvGvspPixelType enDstPixelType = PixelType_Gvsp_Undefined; - enDstPixelType = PixelType_Gvsp_BGR8_Packed; - unsigned char* pConvertData = NULL; - pConvertData = (unsigned char*)malloc(pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3); - if (NULL == pConvertData) - { - printf("malloc pConvertData fail!\n"); - } - else - { - unsigned int nConvertDataSize = 0; - nConvertDataSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3; - - // ch:像素格式转换 | en:Convert pixel format - MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 }; - - frameNum = pFrameInfo0->nFrameNum; //ch:帧号 | en:frame number - stConvertParam.nWidth = pFrameInfo0->nWidth; //ch:图像宽 | en:image width - stConvertParam.nHeight = pFrameInfo0->nHeight; //ch:图像高 | en:image height - stConvertParam.pSrcData = pData0; //ch:输入数据缓存 | en:input data buffer - stConvertParam.nSrcDataLen = pFrameInfo0->nFrameLen; //ch:输入数据大小 | en:input data size - stConvertParam.enSrcPixelType = pFrameInfo0->enPixelType; //ch:输入像素格式 | en:input pixel format - stConvertParam.enDstPixelType = enDstPixelType; //ch:输出像素格式 | en:output pixel format - stConvertParam.pDstBuffer = pConvertData; //ch:输出数据缓存 | en:output data buffer - stConvertParam.nDstBufferSize = nConvertDataSize; //ch:输出缓存大小 | en:output buffer size - int nRet = MV_CC_ConvertPixelType(handle, &stConvertParam); - - Mat mysrcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, stConvertParam.pDstBuffer); - mysrcImage.copyTo(srcImage); - - free(pConvertData); - pConvertData = NULL; - stConvertParam = { 0 }; - } - } - } - if (srcImage.empty()) - { - srcImage = cv::Mat(5, 5, CV_8UC1).setTo(0); - } - if (ifStandard == false) - { - imgIndex++; - if (expourseTimeList.size() > 1 && expourseTimeList[imgIndex % expourseTimeList.size()] != expourseTimeList[(imgIndex - 1) % expourseTimeList.size()]) - SetExposureTime(expourseTimeList[imgIndex % expourseTimeList.size()]); - if (gainList.size() > 1 && gainList[imgIndex % gainList.size()] != gainList[(imgIndex - 1) % gainList.size()]) - SetGain(gainList[imgIndex % gainList.size()]); - } - queuepic.push_back(srcImage); - m_flag = true; - n_mutex->unlock(); - pData0 = { 0 }; - imgCnt++; - double time_End = (double)clock(); - std::cout << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" - << "--CameraName:" << Username << " imgIndex:" << imgCnt << "nFrameNum : " << frameNum << std::endl; - qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms" - << "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgCnt << "nFrameNum : " << frameNum; -} - -Hd_CameraModule_HIK_soft_GIGE::Hd_CameraModule_HIK_soft_GIGE() -{ - //m_thread = new MyThread; - //m_mutex = new QMutex(); -} -Hd_CameraModule_HIK_soft_GIGE::~Hd_CameraModule_HIK_soft_GIGE() -{ - CloseDevice(); - if (n_mutex) - { - delete n_mutex; - n_mutex = nullptr; - } - - qDebug() << "[INFO] " << " delete success!"; -} -//从类中读数据到实例对象 -bool Hd_CameraModule_HIK_soft_GIGE::readData(std::vector& mat, QByteArray& data) -{ - if (queuepic.isEmpty()) - { - //qCritical() << __FUNCTION__ << " line:" <<__LINE__ << " srcImage is null"; - return false; - } - n_mutex->lock(); - cv::Mat img = queuepic.dequeue(); - mat.push_back(img); - n_mutex->unlock(); - - qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex; - return true; -} - -//实例对象把数据写入到类;加载模型后会运行此函数 -bool Hd_CameraModule_HIK_soft_GIGE::writeData(std::vector& mat, QByteArray& data) -{ - Q_UNUSED(mat); - if (data.contains("deviceList")) { - auto result = QByteArrayToMV_CC_DeviceInfoList(data.mid(10)); - if (result.nDeviceNum != 0) { - m_stDevList = result; - return true; - } - } - QStringList dataList = QString::fromUtf8(data).split("_"); - //2024.02.18更新,相机对应的读SN信号时,表示新产品进入,设置初始值 - if (data == "rest_newProductIn") - { - //根据实际项目,设置初始值:曝光、增益,ROI区域等 - { - if (expourseTimeList.size() > 0) - SetExposureTime(expourseTimeList[0]); - if (gainList.size() > 0) - SetGain(gainList[0]); - } - if (queuepic.size() > 0) - { - n_mutex->lock(); - //queuepic.clear(); - n_mutex->unlock(); - std::cout << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << Username << std::endl; - qWarning() << __FUNCTION__ << " line: " << __LINE__ << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << QString::fromStdString(Username); - } - if (ifRunning == true) - { - ifBreak = true; - Sleep(10); - } - imgIndex = 0; - return true; - } - else if (dataList.size() > 1) { - if (dataList[0] == "cameraTriggerSignal") { - imgShouldGetVec.clear(); - imgShouldGetIndex = 0; - for (int i = 1; i < dataList.size(); i++) - imgShouldGetVec.push_back(dataList[i].toInt()); - } - } - else - { - m_flag = false; - expourseTimeList.clear(); - gainList.clear(); - } - //Username= data.toStdString(); - return true; -} -//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1... -bool Hd_CameraModule_HIK_soft_GIGE::initParas(QByteArray& initData) -{ - QByteArrayList valueList = initData.split('+'); - Username = valueList[0]; - imgIndex = 0; - expourseTimeList.clear(); - gainList.clear(); - if (valueList.size() > 1) - for (int i = 1; i < valueList.size(); i++) - { - QString valuei = byteArrayToUnicode(valueList[i]); - //valuei.prepend(valueList[i]); - if (valuei.contains("expourseTime")) - { - QStringList expourseTimeL = valuei.split('#'); - if (expourseTimeL.size() > 1) - for (int j = 1; j < expourseTimeL.size(); j++) - expourseTimeList.enqueue(expourseTimeL[j].toFloat()); - } - if (valuei.contains("gain")) - { - QStringList gainL = valuei.split('#'); - if (gainL.size() > 1) - for (int j = 1; j < gainL.size(); j++) - gainList.enqueue(gainL[j].toFloat()); - } - - if (valuei.contains("是否为标准通信流程")) - { - if (valuei.contains("true")) - ifStandard = true; - } - if (valuei.contains("取图超时")) - { - QStringList gainL = valuei.split('#'); - if (gainL.size() > 1) - getImageTimeOut = gainL[1].toInt(); - if (getImageTimeOut < 50) - getImageTimeOut = 1000; - } - if (valuei.contains("OffsetX")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "OffsetX", valueL[1].toInt()); - } - if (valuei.contains("OffsetY")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "OffsetY", valueL[1].toInt()); - } - if (valuei.contains("Width")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "Width", valueL[1].toInt()); - } - if (valuei.contains("Height")) - { - QStringList valueL = valuei.split('#'); - if (valueL.size() > 1) - if (valueL[1].toInt() >= 0) - MV_CC_SetIntValue(handle, "Height", valueL[1].toInt()); - } - } - - bool ifOk = connectDevice(); - if (ifOk == true) - { - if (expourseTimeList.size() > 0) - SetExposureTime(expourseTimeList[0]); - if (gainList.size() > 0) - SetGain(gainList[0]); - } - imgIndex = 0; - return ifOk; -} - -bool Hd_CameraModule_HIK_soft_GIGE::run() -{ - //queuepic.clear(); - qDebug() << "[INFO] " << " run start" << QString::fromStdString(Username); - bool result = false; - ifRunning = true; - ifBreak = false; - - try - { - m_flag = false; - int mytime = 0; - int cnt = 0; - MV_CC_SetCommandValue(handle, "TriggerSoftware"); - while (true) - { - /* if (moduleStatus == false || mytime++ > getImageTimeOut || ifBreak == true) - { - result = false; - break; - }*/ - n_mutex->lock(); - cnt++; - if (queuepic.size() > 0) - { - n_mutex->unlock(); - result = true; - std::cout << "\n gotImg" << std::endl; - break; - } - if (cnt > 120) { - queuepic.push_back(cv::Mat(200, 200, CV_8UC1, cv::Scalar(0))); //返回空图 - std::cout << "timeout" << std::endl; - n_mutex->unlock(); - return true; - } - n_mutex->unlock(); - QThread::msleep(10); - } - //考虑到误触发、漏触发的图,在这里进行设置。 - //需要设置曝光时 - if (ifStandard == true) - { - imgIndex++; - if (expourseTimeList.size() > 1 && expourseTimeList[imgIndex % expourseTimeList.size()] != expourseTimeList[(imgIndex - 1) % expourseTimeList.size()]) - SetExposureTime(expourseTimeList[imgIndex % expourseTimeList.size()]); - if (gainList.size() > 1 && gainList[imgIndex % gainList.size()] != gainList[(imgIndex - 1) % gainList.size()]) - SetGain(gainList[imgIndex % gainList.size()]); - } - } - catch (QString ev) - { - qDebug() << "[Error] " << " ev:" << ev; - } - qDebug() << "[INFO] " << __LINE__ << " run end"; - return result; -} - -//相机连接状态:正常连接或断开 -bool Hd_CameraModule_HIK_soft_GIGE::checkStatus() -{ - //status = moduleStatus; - return moduleStatus; -} - diff --git a/subModule/Hd_CameraModule_HIK_soft_GIGE/Hd_CameraModule_HIK_soft_GIGE.h b/subModule/Hd_CameraModule_HIK_soft_GIGE/Hd_CameraModule_HIK_soft_GIGE.h deleted file mode 100644 index 294c838..0000000 --- a/subModule/Hd_CameraModule_HIK_soft_GIGE/Hd_CameraModule_HIK_soft_GIGE.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef Hd_CameraModule_HIK_soft_GIGE_H -#define Hd_CameraModule_HIK_soft_GIGE_H -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace cv; -#pragma execution_character_set("utf-8") - -class Hd_CameraModule_HIK_soft_GIGE :public dsModuleBase -{ -public: - Hd_CameraModule_HIK_soft_GIGE(); - virtual ~Hd_CameraModule_HIK_soft_GIGE(); - //从类中读数据到实例对象 - bool readData(std::vector& mat, QByteArray& data); - //实例对象把数据写入到类 - bool writeData(std::vector& mat, QByteArray& data); - bool initParas(QByteArray& initData); - bool run(); - bool checkStatus(); -private: - std::vector imgShouldGetVec; - int imgShouldGetIndex = 0; - //MyThread *m_thread = nullptr; - //QMutex* m_mutex; -}; - -extern "C" -{ -Q_DECL_EXPORT Hd_CameraModule_HIK_soft_GIGE * create(); -Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_soft_GIGE * ptr); -} - -#endif // Hd_CameraModule_HIK_hard_H -//Hd_CameraModule_HIK_soft_GIGE diff --git a/subModule/Hd_SocketModule_FinsTcp/CMakeLists.txt b/subModule/Hd_SocketModule_FinsTcp/CMakeLists.txt deleted file mode 100644 index 13762e7..0000000 --- a/subModule/Hd_SocketModule_FinsTcp/CMakeLists.txt +++ /dev/null @@ -1,70 +0,0 @@ -# 获取获取当前目录名 -get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) -string(TIMESTAMP RUN_TIME) -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -STRING(REPLACE "/EHsc" "/EHa" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) -STRING(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /AI${CMAKE_CURRENT_SOURCE_DIR} /clr") -message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) - -set(DLL_NAMES "opencv") -foreach(child ${DLL_NAMES}) - LIST(APPEND ENV_INCLUDE ${${child}_include}) - LIST(APPEND ENV_LIB ${${child}_lib}) - LIST(APPEND ENV_TARGET ${${child}_target_link}) -endforeach() -message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) -message(" ENV_LIB : " ${ENV_LIB} ) -message(" ENV_TARGET : " ${ENV_TARGET} ) -include_directories( - ${ENV_INCLUDE} -) -link_directories ( - ${ENV_LIB} - -) - - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -FILE(GLOB HEAD_FILES "./*.h" ) -FILE(GLOB SRC_FILES "./*.cpp") -FILE(GLOB UI_FILES "./*.ui") - - -#find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network REQUIRED) - -add_library(${CURRENT_FOLDER} SHARED - ${HEAD_FILES} - ${SRC_FILES} - ${UI_FILES} - ) - - - - -set_target_properties(${CURRENT_FOLDER} PROPERTIES LINKER_LANGUAGE C - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} -) - -target_link_libraries(${CURRENT_FOLDER} PRIVATE - - ${opencv_target_link} - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Network -) - - -string(TIMESTAMP RUN_TIME) -message( " model end : " ${CURRENT_FOLDER}:${RUN_TIME}) diff --git a/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.cpp b/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.cpp deleted file mode 100644 index 886a2e1..0000000 --- a/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.cpp +++ /dev/null @@ -1,603 +0,0 @@ -#include "Hd_SocketModule_FinsTcp.h" -#include "qprocess.h" - - -static QQueue ReadPack; -//static QVector Failed_address; -//static QVector Failed_address; -static QQueue Failed_data; - -QMutex* readData_Mutex = new QMutex(); -QMutex* recive_Mutex = new QMutex(); -Hd_SocketModule_FinsTcp* create() -{ - qDebug() << "Hd_SocketModule_FinsTcp create success!"; - return new Hd_SocketModule_FinsTcp; -} - -void destory(Hd_SocketModule_FinsTcp* ptr) -{ - - if (ptr) - { - delete ptr; - ptr = nullptr; - } - qDebug() << " Hd_SocketModule_FinsTcp destory success!"; -} -bool ifRun = true; -Hd_SocketModule_FinsTcp::Hd_SocketModule_FinsTcp() -{ - ifRun = true; - *m_pFinsTcpNet = gcnew HslCommunication::Profinet::Omron::OmronFinsNet(); -} -bool m_IsFinsTcp = false; -Hd_SocketModule_FinsTcp::~Hd_SocketModule_FinsTcp() -{ - ifRun = false; - Sleep(100); - if (status == false) - Sleep(3000); - if (m_IsFinsTcp) - { - if ((*m_pFinsTcpNet)->ConnectClose()->IsSuccess) - { - qDebug() << " (*m_pFinsTcpNet)->ConnectClose() success!"; - }else { - qCritical() << " (*m_pFinsTcpNet)->ConnectClose() failed!"; - } - m_IsFinsTcp = false; - } - qDebug() << " ~Hd_SocketModule_FinsTcp success!"; -} - -// 从类中读数据到实例对象 -bool Hd_SocketModule_FinsTcp::readData(std::vector& vec_mat, QByteArray& data) -{ - Q_UNUSED(vec_mat); - QMutexLocker locker(readData_Mutex); - - QByteArray statusVaule; - /*if (tcp_Status) - { - statusVaule = "truee"; - } - else - { - statusVaule = "false"; - }*/ - - if (ReadPack.isEmpty()) - { - data = statusVaule; - return true; - } - else - { - data.append(statusVaule); - data.append(ReadPack.dequeue()); - //qDebug() << " ReadPack len: " << ReadPack.length() << " data: " << data; - } - return true; -} -bool ifRetryCMD = false; -// 实例对象把数据写入到类 -bool Hd_SocketModule_FinsTcp::writeData(std::vector& vec_mat, QByteArray& data) -{ - Q_UNUSED(vec_mat); - if (ifRetryCMD == false) - QMutexLocker locker(recive_Mutex); - Sleep(sleepvalue); - QString str = QString(data); - if ( data.isEmpty() ) - { - qCritical() << " str is null"; - return false; - } - - QList m_list = data.split('_'); - if (m_list.size() < 4) - { - qCritical() << data+" m_list.size() != 4;command err"; - return false; - } - QString m_value= m_list.at(3); - QString commond = m_list.at(0); - if ( commond == "init" ){ - System::String^ Code = gcnew System::String("b5f8f9f7-c075-4913-ae6e-d7d2cc6f2de1"); - if (HslCommunication::Authorization::SetAuthorizationCode(Code)) - { - std::cout << "Register HSLCode Success" << std::endl; - } - else - { - std::cout << "Register HSLCode Fail" << std::endl; - } - - if (m_list.length() < 6) - { - qCritical() << " m_list failed! " << m_list; - return false; - } - - m_IP = m_list.at(1); - m_port = m_list.at(2); - SA1 = m_list.at(3); - DA1 = m_list.at(4); - DA2 = m_list.at(5); - } - else if (commond == "read") { - //"read_byte_D3000_300", - while (ifRun) - { - //if (sleepvalue < 2) - // Sleep(2); // 读取速度过快,添加10ms延时 - //else - Sleep(sleepvalue); - - int length = m_list[3].toInt(); - System::String^ address = gcnew System::String(m_list[2].toStdString().c_str()); - HslCommunication::OperateResult^>^ result = (*m_pFinsTcpNet)->Read(address, length); - if (!result->IsSuccess) - { - tcp_Status = false; - qCritical() << " (*FinsTcp)->ReadInt16 failed! check DA1: " << DA1; - - QProcess pingProcess; - QString strArg = "ping " + m_IP + " -n 1 -i 2"; //strPingIP 为设备IP地址 - pingProcess.start(strArg, QIODevice::ReadOnly); - pingProcess.waitForFinished(-1); - - QString p_stdout = QString::fromLocal8Bit(pingProcess.readAllStandardOutput()); - - //qDebug() << p_stdout; - bool bPingSuccess = false; - - if (p_stdout.contains("TTL=")) //通过特殊字符串进行判断ping是否成功 - { - //printf("Ping true\n"); - bPingSuccess = true; - //QMessageBox::information(this, "ping PLC:", "success!"); - //qCritical() << __FUNCTION__ << " line:" << __LINE__ << " ping PLC success! "; - } - else - { - /*printf("Ping false\n"); - bPingSuccess = false; - QMessageBox::information(this, "ping PLC:", "failed!");*/ - qCritical() << __FUNCTION__ << " line:" << __LINE__ << " ping PLC failed! "; - } - // - if (!Failed_data.contains(data)) - Failed_data.enqueue(data); - //if (m_IsFinsTcp) - { - //(*m_pFinsTcpNet)->Dispose(); - //qDebug() << " (*m_pFinsTcpNet)->Dispose() success!"; - - if ((*m_pFinsTcpNet)->ConnectClose()->IsSuccess) - { - qDebug() << " (*m_pFinsTcpNet)->ConnectClose() success!"; - } - else { - qCritical() << " (*m_pFinsTcpNet)->ConnectClose() failed!"; - } - //m_IsFinsTcp = false; - delete* m_pFinsTcpNet; - Sleep(50); - *m_pFinsTcpNet = gcnew HslCommunication::Profinet::Omron::OmronFinsNet(); - (*m_pFinsTcpNet)->IpAddress = gcnew System::String(m_IP.toStdString().c_str()); - (*m_pFinsTcpNet)->Port = stoi(m_port.toStdString()); - Sleep(10); - } - - //if ((*m_pFinsTcpNet)->ConnectClose()->IsSuccess) - //{ - // qDebug() << " (*m_pFinsTcpNet)->ConnectClose() success!"; - //} - //else { - // qCritical() << " (*m_pFinsTcpNet)->ConnectClose() failed!"; - //} - int xunhuan_num = 20; - while (xunhuan_num && ifRun) { - qDebug() << " TRY xunhuan_num: "<< xunhuan_num; - (*m_pFinsTcpNet)->SA1 = (unsigned char)stoi(SA1.toStdString()); - (*m_pFinsTcpNet)->DA1 = (unsigned char)stoi(DA1.toStdString());//DA1.toStdString().c_str();//可以测试DA1累加1,不超过255 - (*m_pFinsTcpNet)->DA2 = (unsigned char)stoi(DA2.toStdString()); - (*m_pFinsTcpNet)->ConnectTimeOut = 1000; // 连接超时2秒 - (*m_pFinsTcpNet)->ReceiveTimeOut = 500; // 收发超时0.5秒 - if ((*m_pFinsTcpNet)->ConnectServer()->IsSuccess) - { - m_IsFinsTcp = true; - tcp_Status = true; - /*QVector Writefailpack; - for (QVector::iterator ii = WriteFailPack.begin(); ii != WriteFailPack.end(); ii++) - { - for (int val = 0; val < 5; val++) - { - if (!(*m_pFinsTcpNet)->Write(address, ii)->IsSuccess) - { - if (val == 4) Writefailpack.push_back(*ii); - continue; - } - else - { - break; - } - } - } - WriteFailPack.clear(); - WriteFailPack = Writefailpack; - Writefailpack.clear();*/ - qDebug() << " Connect Success! SA1: " << SA1 << "DA1 :" << DA1; - - ifRetryCMD = true; - for (int i = 0; i < Failed_data.size(); i++) - { - QByteArray try_data = Failed_data.dequeue(); - std::vector my_vec_mat; - qDebug() << " try_data:: " << try_data; - writeData(my_vec_mat, try_data); - Sleep(10); - } - ifRetryCMD = false; - return tcp_Status; - } - else - { - xunhuan_num--; - if (SA1 > 255) - SA1 = 50; - SA1 = QString::number(SA1.toInt() + 1); - if (DA1 > 255) - DA1 = 50; - DA1 = QString::number(DA1.toInt() + 1); - tcp_Status = false; - qCritical() << " Connect failed! SA1: " << SA1 << "DA1 : " << DA1; - Sleep(100); - } - } - return false; - //continue; - } - - unsigned char* valuePtr = new unsigned char[m_list[3].toInt() * 2]; - QByteArray byte; - for (int i = 0; i < length * 2; i++) - { - valuePtr[i] = result->Content[i]; - char v = result->Content[i]; - byte.append(v); - } - - ReadPack.append(byte); - if (valuePtr) { - delete[] valuePtr; - valuePtr = nullptr; - } - tcp_Status = true; - break; - } - - } - else if ( commond == "write" ) - { - //例"write_short_D1003_1","write_short_D1003_1,1,1,1", - if (m_list[1] == "short") - { - QString vecValue = m_list.at(3); - QStringList valueList = vecValue.split(","); - cli::array^ write_list = gcnew cli::array(valueList.length()); - for (int i = 0; i < valueList.length(); i++) - { - write_list[i] = valueList[i].toShort(); - } - - System::String^ address = gcnew System::String(m_list[2].toStdString().c_str()); - for (auto val = 0; val < 5; val++) - { - //Sleep(sleepvalue); - if (!(*m_pFinsTcpNet)->HslCommunication::Core::Net::NetworkDeviceBase::Write(address, write_list)->IsSuccess) - { - qCritical() << " val: " << val++ << " writeAll failed! m_list: " << m_list; - Failed_data.enqueue(data); - Sleep(sleepvalue); - } - else { - qDebug() << "[TCP] " << str << endl; - return true; - } - } - tcp_Status = false; - return false; - } - if (m_list[1] == "float") - { - QString vecValue = m_list.at(3); - QStringList valueList = vecValue.split(","); - cli::array^ write_list = gcnew cli::array(valueList.length()); - for (int i = 0; i < valueList.length(); i++) - { - write_list[i] = valueList[i].toFloat(); - } - - System::String^ address = gcnew System::String(m_list[2].toStdString().c_str()); - for (auto val = 0; val < 5; val++) - { - //Sleep(sleepvalue); - if (!(*m_pFinsTcpNet)->HslCommunication::Core::Net::NetworkDeviceBase::Write(address, write_list)->IsSuccess) - { - qCritical() << " val: " << val++ << " writeAll failed! m_list: " << m_list; - Failed_data.enqueue(data); - Sleep(sleepvalue); - } - else { - qDebug() << "[TCP] " << str << endl; - return true; - } - } - tcp_Status = false; - return false; - } - if (m_list[1] == "double") - { - QString vecValue = m_list.at(3); - QStringList valueList = vecValue.split(","); - cli::array^ write_list = gcnew cli::array(valueList.length()); - for (int i = 0; i < valueList.length(); i++) - { - write_list[i] = valueList[i].toDouble(); - } - - System::String^ address = gcnew System::String(m_list[2].toStdString().c_str()); - for (auto val = 0; val < 5; val++) - { - //Sleep(sleepvalue); - if (!(*m_pFinsTcpNet)->HslCommunication::Core::Net::NetworkDeviceBase::Write(address, write_list)->IsSuccess) - { - qCritical() << " val: " << val++ << " writeAll failed! m_list: " << m_list; - Failed_data.enqueue(data); - Sleep(sleepvalue); - } - else { - qDebug() << "[TCP] " << str << endl; - return true; - } - } - tcp_Status = false; - return false; - } - - - if (m_list[1] == "string") - { - System::String^ address = gcnew System::String(m_list[2].toStdString().c_str()); - System::String^ write_Value = gcnew System::String(m_list.at(3).toStdString().c_str()); - for (auto val = 0; val < 5; val++) - { - //Sleep(sleepvalue); - if (!(*m_pFinsTcpNet)->Write(address, write_Value)->IsSuccess) { - qCritical() << " val: " << val++ << " writeString failed! m_list: " << m_list; - Failed_data.enqueue(data); - Sleep(sleepvalue); - } - else { - qDebug() << "[TCP] " << str << endl; - return true; - } - } - tcp_Status = false; - return false; - } - } - else if (commond == "writeHeart") - { - //例"write_short_D1003_1","write_short_D1003_1,1,1,1", - if (m_list[1] == "short") - { - QString vecValue = m_list.at(3); - QStringList valueList = vecValue.split(","); - cli::array^ write_list = gcnew cli::array(valueList.length()); - for (int i = 0; i < valueList.length(); i++) - { - write_list[i] = valueList[i].toShort(); - } - - System::String^ address = gcnew System::String(m_list[2].toStdString().c_str()); - for (auto val = 0; val < 5; val++) - { - //Sleep(sleepvalue); - if (!(*m_pFinsTcpNet)->HslCommunication::Core::Net::NetworkDeviceBase::Write(address, write_list)->IsSuccess) - { - qCritical() << " val: " << val++ << " writeAll failed! m_list: " << m_list; - Failed_data.enqueue(data); - Sleep(sleepvalue); - } - else { - return true; - } - } - tcp_Status = false; - return false; - } - if (m_list[1] == "float") - { - QString vecValue = m_list.at(3); - QStringList valueList = vecValue.split(","); - cli::array^ write_list = gcnew cli::array(valueList.length()); - for (int i = 0; i < valueList.length(); i++) - { - write_list[i] = valueList[i].toFloat(); - } - - System::String^ address = gcnew System::String(m_list[2].toStdString().c_str()); - for (auto val = 0; val < 5; val++) - { - //Sleep(sleepvalue); - if (!(*m_pFinsTcpNet)->HslCommunication::Core::Net::NetworkDeviceBase::Write(address, write_list)->IsSuccess) - { - qCritical() << " val: " << val++ << " writeAll failed! m_list: " << m_list; - Failed_data.enqueue(data); - Sleep(sleepvalue); - } - else { - qDebug() << "[TCP] " << str << endl; - return true; - } - } - tcp_Status = false; - return false; - } - if (m_list[1] == "double") - { - QString vecValue = m_list.at(3); - QStringList valueList = vecValue.split(","); - cli::array^ write_list = gcnew cli::array(valueList.length()); - for (int i = 0; i < valueList.length(); i++) - { - write_list[i] = valueList[i].toDouble(); - } - - System::String^ address = gcnew System::String(m_list[2].toStdString().c_str()); - for (auto val = 0; val < 5; val++) - { - //Sleep(sleepvalue); - if (!(*m_pFinsTcpNet)->HslCommunication::Core::Net::NetworkDeviceBase::Write(address, write_list)->IsSuccess) - { - qCritical() << " val: " << val++ << " writeAll failed! m_list: " << m_list; - Failed_data.enqueue(data); - Sleep(sleepvalue); - } - else { - qDebug() << "[TCP] " << str << endl; - return true; - } - } - tcp_Status = false; - return false; - } - - - if (m_list[1] == "string") - { - System::String^ address = gcnew System::String(m_list[2].toStdString().c_str()); - System::String^ write_Value = gcnew System::String(m_list.at(3).toStdString().c_str()); - for (auto val = 0; val < 5; val++) - { - //Sleep(sleepvalue); - if (!(*m_pFinsTcpNet)->Write(address, write_Value)->IsSuccess) { - qCritical() << " val: " << val++ << " writeString failed! m_list: " << m_list; - Failed_data.enqueue(data); - Sleep(sleepvalue); - } - else { - qDebug() << "[TCP] " << str << endl; - return true; - } - } - tcp_Status = false; - return false; - } - } - return true; -} - -bool Hd_SocketModule_FinsTcp::initParas(QByteArray& data) -{ - - if (data.isEmpty()) - { - qWarning()<< "[TCP] " << " data is null!"; - } - else - { - QString initDat = QString::fromUtf8(data); - QStringList list = initDat.split("_"); - if (list.size() < 3) - { - qCritical() << "[TCP] " << " list size error :" << list.size(); - return false; - } - - QString sleepname = list.at(0); - sleepvalue = list.at(1).toInt(); - if (sleepvalue == 0)sleepvalue = 1; - /*if (sleepvalue <= 5) - sleepvalue = 30;*/ - QString readname = list.at(2); - QString readvalue = list.at(3); - QString write_type = list.at(4); - QString write_value = list.at(5); - } - - // 连接通讯 - *m_pFinsTcpNet = gcnew HslCommunication::Profinet::Omron::OmronFinsNet(); - (*m_pFinsTcpNet)->IpAddress = gcnew System::String(m_IP.toStdString().c_str()); - (*m_pFinsTcpNet)->Port = stoi(m_port.toStdString()); - int xunhuan_num = 20; - while (xunhuan_num && ifRun) { - (*m_pFinsTcpNet)->SA1 = (unsigned char)stoi(SA1.toStdString()); - (*m_pFinsTcpNet)->DA1 = (unsigned char)stoi(DA1.toStdString());//DA1.toStdString().c_str(); - (*m_pFinsTcpNet)->DA2 = (unsigned char)stoi(DA2.toStdString()); - (*m_pFinsTcpNet)->ConnectTimeOut = 500; // 连接超时0.5秒 - (*m_pFinsTcpNet)->ReceiveTimeOut = 500; // 收发超时0.5秒 - if ((*m_pFinsTcpNet)->ConnectServer()->IsSuccess) - { - m_IsFinsTcp = true; - tcp_Status = true; - qDebug() << " Connect Success! SA1: " << SA1; - return tcp_Status; - } - else - { - xunhuan_num--; - SA1 = QString::number(SA1.toInt() + 1); - tcp_Status = false; - qCritical() <<" Connect failed! SA1: " << SA1; - - } - Sleep(100); - } - return tcp_Status; - -} - -bool Hd_SocketModule_FinsTcp::run() -{ - // 没有用到 - //qDebug() << "[info] " << __FUNCTION__ << " line:" << __LINE__ << " success!"; - return true; -} - - -bool Hd_SocketModule_FinsTcp::decodeWriteResult(QByteArray byte, QVector& vec_ret) -{ - try - { - if (byte.isEmpty()) - { - qCritical() << __FUNCTION__ << "line:" << __LINE__ << " byte is null!"; - return false; - } - while (!byte.isEmpty()) - { - int len = 0; - QByteArray m_len = byte.mid(0, 4); - memcpy((void*)&len, (void*)m_len.data(), 4); - byte.remove(0, 4); - - QByteArray mm_data = byte.mid(0, len); - vec_ret.append(QString::fromUtf8(mm_data)); - byte.remove(0, len); - } - } - catch (QString ev) { - qCritical() << __FUNCTION__ << " line:" << __LINE__ << " ev:" << ev; - return false; - } - return true; -} -bool Hd_SocketModule_FinsTcp::checkStatus() -{ - return tcp_Status; -} \ No newline at end of file diff --git a/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.h b/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.h deleted file mode 100644 index 2b3f969..0000000 --- a/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef Hd_SocketModule_FinsTcp_H -#define Hd_SocketModule_FinsTcp_H - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#using "../../bin/HslCommunication.dll" - -using namespace HslCommunication; -using namespace cli; - -class Hd_SocketModule_FinsTcp :public dsModuleBase -{ -public: - Hd_SocketModule_FinsTcp(); - virtual ~Hd_SocketModule_FinsTcp(); - //bool readData(std::vector& vec_mat, QByteArray& data, nlohmann::json&); // readData将PLC读取或者发送的返回值发回给主线程,通过全局变量的方式逐条发送 - //bool writeData(std::vector& vec_mat, QByteArray& data, nlohmann::json&); // writeData调用PLC的收发,将需要的数据发给寄存器,返回OK/NG - bool readData(std::vector&, QByteArray&); - bool writeData(std::vector&, QByteArray&); - bool initParas(QByteArray&); - bool run(); - bool decodeWriteResult(QByteArray byteArray, QVector& vec_ret); - bool checkStatus(); -private: - gcroot* m_pFinsTcpNet = new gcroot; - bool tcp_Status = true; // 检查tcp状态 - QString m_IP; - QString SA1; - QString DA1; - QString DA2; - QString m_port; // 端口 - int sleepvalue=1; // 刷新间隔 -}; - -extern "C" -{ -Q_DECL_EXPORT Hd_SocketModule_FinsTcp * create(); -Q_DECL_EXPORT void destory(Hd_SocketModule_FinsTcp * ptr); -} - -#endif // Hd_SocketModule_FinsTcp_H diff --git a/subModule/Hd_SocketModule_FinsTcp/HslCommunication.dll b/subModule/Hd_SocketModule_FinsTcp/HslCommunication.dll deleted file mode 100644 index 8a764c1..0000000 Binary files a/subModule/Hd_SocketModule_FinsTcp/HslCommunication.dll and /dev/null differ diff --git a/subModule/Hd_VirtualCamera/CMakeLists.txt b/subModule/Hd_VirtualCamera/CMakeLists.txt index 0f64ccb..3a82d8e 100644 --- a/subModule/Hd_VirtualCamera/CMakeLists.txt +++ b/subModule/Hd_VirtualCamera/CMakeLists.txt @@ -28,7 +28,7 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -SET(CMAKE_AUTOUIC ON) +SET(CMAKE_AUTOUIC OFF) set(CMAKE_AUTORCC ON) FILE(GLOB HEAD_FILES "./*.h" ) diff --git a/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp b/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp index 2f04a31..e4af46a 100644 --- a/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp +++ b/subModule/Hd_VirtualCamera/Hd_VirtualCamera.cpp @@ -45,7 +45,7 @@ bool Hd_VirtualCamera::readData(std::vector& mat, QByteArray& data) n_mutex->unlock(); //for (int i=0;i具" + }, + "Timed out": { + "ms-MY": "Masa tamat", + "us-EN": "Timed out", + "zh-CN": "已超时" + }, + "Total Count": { + "ms-MY": "Jumlah Kiraan", + "us-EN": "Total Count", + "zh-CN": "总数量" + }, + "Type Validation Failed": { + "ms-MY": "Pengesahan Jenis Gagal", + "us-EN": "Type Validation Failed", + "zh-CN": "类型验证失败" + }, + "Unknown data type": { + "ms-MY": "Jenis data tidak diketahui", + "us-EN": "Unknown data type", + "zh-CN": "未知的数据类型" + }, + "User Management": { + "ms-MY": "Pengurusan Pengguna", + "us-EN": "User Management", + "zh-CN": "用户管理" + }, + "User created successfully!": { + "ms-MY": "Pengguna berjaya dicipta!", + "us-EN": "User created successfully!", + "zh-CN": "用户创建成功!" + }, + "User creation failed, username may already exist": { + "ms-MY": "Penciptaan pengguna gagal, nama pengguna mungkin sudah wujud", + "us-EN": "User creation failed, username may already exist", + "zh-CN": "用户创建失败,用户名可能已存在" + }, + "Username and password cannot be empty": { + "ms-MY": "Nama pengguna dan kata laluan tidak boleh kosong", + "us-EN": "Username and password cannot be empty", + "zh-CN": "用户名和密码不能为空" + }, + "Username:": { + "ms-MY": "Nama Pengguna:", + "us-EN": "Username:", + "zh-CN": "用户名:" + }, + "Value": { + "ms-MY": "Nilai", + "us-EN": "Value", + "zh-CN": "值" + }, + "Value:": { + "ms-MY": "Nilai:", + "us-EN": "Value:", + "zh-CN": "值:" + }, + "ViewImage": { + "ms-MY": "Lihat Imej", + "us-EN": "View Image", + "zh-CN": "查看图片" + }, + "Warning": { + "ms-MY": "Amaran", + "us-EN": "Warning", + "zh-CN": "警告" + }, + "Welcome!": { + "ms-MY": "Selamat Datang!", + "us-EN": "Welcome!", + "zh-CN": "欢迎!" + }, + "Width:": { + "ms-MY": "Lebar:", + "us-EN": "Width:", + "zh-CN": "宽度:" + }, + "Window Settings": { + "ms-MY": "Tetapan Tetingkap", + "us-EN": "Window Settings", + "zh-CN": "窗口设置" + }, + "You need administrator permissions to create users": { + "ms-MY": "Anda memerlukan kebenaran pentadbir untuk mencipta pengguna", + "us-EN": "You need administrator permissions to create users", + "zh-CN": "您需要管理员权限才能创建用户" + }, + "Zoom In": { + "ms-MY": "Zum Masuk", + "us-EN": "Zoom In", + "zh-CN": "放大窗口" + }, + "Zoom Out": { + "ms-MY": "Zum Keluar", + "us-EN": "Zoom Out", + "zh-CN": "缩小窗口" + }, + "hideConsole": { + "ms-MY": "Sembunyikan Konsol", + "us-EN": "Hide Console", + "zh-CN": "隐藏控制台" + }, + "refresh": { + "ms-MY": "Segarkan", + "us-EN": "Refresh", + "zh-CN": "刷新" + }, + "showConsole": { + "ms-MY": "Tunjukkan Konsol", + "us-EN": "Show Console", + "zh-CN": "显示控制台" + }, + "will change after restart": { + "ms-MY": "Akan berubah selepas restart", + "zh-CN": "重启后将会更改" + }, + "You do not have sufficient permissions to perform this action.\n\nRequired level: %1\nCurrent level: %2": { + "ms-MY": "Anda tidak mempunyai kebenaran yang mencukupi untuk melaksanakan tindakan ini.\n\nTahap diperlukan: %1\nTahap semasa: %2", + "us-EN": "You do not have sufficient permissions to perform this action.\n\nRequired level: %1\nCurrent level: %2", + "zh-CN": "您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2" + } + } +} \ No newline at end of file diff --git a/updateLog/2025-10-15/增加了点位监控.png b/updateLog/2025-10-15/增加了点位监控.png deleted file mode 100644 index 69ece90..0000000 Binary files a/updateLog/2025-10-15/增加了点位监控.png and /dev/null differ diff --git a/updateLog/2025-10-15/小窗放大.png b/updateLog/2025-10-15/小窗放大.png deleted file mode 100644 index adcb74c..0000000 Binary files a/updateLog/2025-10-15/小窗放大.png and /dev/null differ diff --git a/updateLog/2025-10-15/放在bin目录的tools文件夹中的中的快捷方式现在会出现在顶端.png b/updateLog/2025-10-15/放在bin目录的tools文件夹中的中的快捷方式现在会出现在顶端.png deleted file mode 100644 index 1683d7a..0000000 Binary files a/updateLog/2025-10-15/放在bin目录的tools文件夹中的中的快捷方式现在会出现在顶端.png and /dev/null differ diff --git a/updateLog/2025-10-15/自动填满窗口.png b/updateLog/2025-10-15/自动填满窗口.png deleted file mode 100644 index ef6c549..0000000 Binary files a/updateLog/2025-10-15/自动填满窗口.png and /dev/null differ diff --git a/updateLog/2025-10-17/屏幕截图 2025-10-17 095806.png b/updateLog/2025-10-17/屏幕截图 2025-10-17 095806.png deleted file mode 100644 index dee20f4..0000000 Binary files a/updateLog/2025-10-17/屏幕截图 2025-10-17 095806.png and /dev/null differ diff --git a/updateLog/2025-10-17/屏幕截图 2025-10-17 095811.png b/updateLog/2025-10-17/屏幕截图 2025-10-17 095811.png deleted file mode 100644 index 34d75cb..0000000 Binary files a/updateLog/2025-10-17/屏幕截图 2025-10-17 095811.png and /dev/null differ