diff --git a/CMakeLists.txt b/CMakeLists.txt index 56e691f..9dbf42d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -231,6 +231,7 @@ include_directories(${CMAKE_SOURCE_DIR}/include) if(ON) add_subdirectory(src) add_subdirectory(subModule) + add_subdirectory(rpcModule) # add_subdirectory(plugin) diff --git a/CMakeUserPresets.json b/CMakeUserPresets.json index 29c3c99..a5908b4 100644 --- a/CMakeUserPresets.json +++ b/CMakeUserPresets.json @@ -21,20 +21,56 @@ "CMAKE_BUILD_TYPE": "Release" } }, + { + "hidden": true, + "name": "1", + "inherits": "Qt", + "environment": { + "QTDIR": "D:/Qt/QT5.12.12/5.12.12/msvc2017_64" + }, + "architecture": { + "strategy": "external", + "value": "x64" + }, + "generator": "Ninja", + "vendor": { + "qt-project.org/Version": { + "checksum": "dLSmxWmTxzMhTDrWvKaNxnGQc8o=" + } + } + }, { "hidden": true, "name": "Qt-Default", - "inherits": null, + "inherits": "12", "vendor": { "qt-project.org/Default": { - "checksum": "VoalogTkyWuFomeO1TLFx0olLJ4=" + "checksum": "s89cFlmg97AfXdRXoqFbeL5UVRk=" + } + } + }, + { + "hidden": true, + "name": "12", + "inherits": "Qt", + "environment": { + "QTDIR": "D:/Qt/QT5.12.12/5.12.12/msvc2017_64" + }, + "architecture": { + "strategy": "external", + "value": "x64" + }, + "generator": "Ninja", + "vendor": { + "qt-project.org/Version": { + "checksum": "QpjRswAcEITNChgZ8cRu0YyWMFM=" } } } ], "vendor": { "qt-project.org/Presets": { - "checksum": "Isp/aHJ+aeyUOO6+L/cRr4cRTww=" + "checksum": "qHgPL414qYgD9ayjFD/Vp7akPGE=" } } } \ No newline at end of file diff --git a/eUi.zip b/eUi.zip new file mode 100644 index 0000000..5ae1054 Binary files /dev/null and b/eUi.zip differ diff --git a/include/interface.h b/include/interface.h index 127a8f2..5a44342 100644 --- a/include/interface.h +++ b/include/interface.h @@ -1,12 +1,13 @@ #include #include - +#include class IBackend { public: virtual ~IBackend() = default; virtual void test() = 0; virtual void init(qtFuncBridge*,nlohmann::json& json) = 0; virtual void cleanup() = 0; + virtual SQLiteDB* getDatabase() = 0; }; extern "C" { diff --git a/include/qtBridge.h b/include/qtBridge.h index 0f7d4f4..85aca8d 100644 --- a/include/qtBridge.h +++ b/include/qtBridge.h @@ -31,7 +31,7 @@ signals: void loadingWindow_clearLog(); // 登录结果 - void loginResult(initStatus result); + void initResult(initStatus result); // 图像显示 void displayWidget_sendImg(showImgPack* pack); diff --git a/src/core/sql/qSqlBase.h b/include/sql/qSqlBase.h similarity index 98% rename from src/core/sql/qSqlBase.h rename to include/sql/qSqlBase.h index eee7811..359e6f4 100644 --- a/src/core/sql/qSqlBase.h +++ b/include/sql/qSqlBase.h @@ -23,43 +23,14 @@ #include #include #include +#include class SQLiteDB { public: SQLiteDB(const QString& dbPath, const QString& dbName) : m_dbName(dbName), m_dbPath(dbPath) { + connect(); } - ~SQLiteDB() {}; - bool connect() { - // 检查数据库文件是否存在 - if (!QFile::exists(m_dbPath + m_dbName + ".db")) { - QDir().mkpath(m_dbPath); - qDebug() << "Database file does not exist. Creating a new database:" << m_dbName; - } - QCoreApplication::addLibraryPath("./"); - // 添加 SQLite 数据库驱动 - m_db = QSqlDatabase::addDatabase("QSQLITE"); - m_db.setDatabaseName(m_dbPath + m_dbName + ".db"); - - // 打开数据库 - if (!m_db.open()) { - qCritical() << "Failed to open or create database:" << m_db.lastError().text(); - return false; - } - - qDebug() << "Connected to SQLite database:" << m_dbPath + m_dbName; - createTable("setting", - { - {"id","INTEGER PRIMARY KEY AUTOINCREMENT"} , - }); - return true; - } - // 关闭数据库连接 - void disconnect() { - if (m_db.isOpen()) { - m_db.close(); - qDebug() << "Database closed."; - } - } + ~SQLiteDB() { disconnect(); }; // 执行无返回值的SQL语句(如插入、删除、更新) bool execute(const QString& queryStr, const QVariantList& args = {}) { QSqlQuery query; @@ -336,6 +307,11 @@ public: } ///////////////////EX//FUNC///////////////// + QList> queryTabelData(const QString& tableName) { + QString sql = QString("SELECT * FROM \"%1\"").arg(tableName); + return query(sql); + } + bool exportTableToCSV(const QString& tableName, const QString& filePath, std::mutex& _mutex) { using namespace std::chrono; // 便于使用 chrono 相关功能 // 记录开始时间 @@ -396,6 +372,37 @@ public: private: + bool connect() { + // 检查数据库文件是否存在 + if (!QFile::exists(m_dbPath + m_dbName + ".db")) { + QDir().mkpath(m_dbPath); + qDebug() << "Database file does not exist. Creating a new database:" << m_dbName; + } + QCoreApplication::addLibraryPath("./"); + // 添加 SQLite 数据库驱动 + m_db = QSqlDatabase::addDatabase("QSQLITE"); + m_db.setDatabaseName(m_dbPath + m_dbName + ".db"); + + // 打开数据库 + if (!m_db.open()) { + qCritical() << "Failed to open or create database:" << m_db.lastError().text(); + return false; + } + + qDebug() << "Connected to SQLite database:" << m_dbPath + m_dbName; + createTable("setting", + { + {"id","INTEGER PRIMARY KEY AUTOINCREMENT"} , + }); + return true; + } + // 关闭数据库连接 + void disconnect() { + if (m_db.isOpen()) { + m_db.close(); + qDebug() << "Database closed."; + } + } QString m_dbName; QString m_dbPath; QSqlDatabase m_db; @@ -521,11 +528,11 @@ private: // } // delete _db; //} - void init() + void init(SQLiteDB* database_ptr = nullptr) { std::lock_guard locker(_mutex); - _db = new SQLiteDB("./sqlDatabse/", "database"); - _db->connect(); + if(database_ptr == nullptr) + _db = new SQLiteDB("./sqlDatabse/", "database"); if (!_db->createTable(getLastProcessCsvName(), db_InitColumns)) { qDebug() << "Failed to create table " << getLastProcessCsvName(); } diff --git a/include/subModuleBase.h b/include/subModuleBase.h index 0255358..0982f55 100644 --- a/include/subModuleBase.h +++ b/include/subModuleBase.h @@ -1,14 +1,11 @@ -#ifndef __BASECLASS_H__ -#define __BASECLASS_H__ - +#pragma once #include #include #include #include -#include #include - -class subModuleBase +#include +class dsModuleBase { public: bool init_flag; //是否初始化,false,true @@ -17,13 +14,28 @@ public: cv::Mat m_mat; //传输图片 std::string moduleName; //模块名称 public: - subModuleBase() {} - virtual ~subModuleBase() {} - virtual bool readData(std::vector&,QByteArray&, nlohmann::json&json = nlohmann::json()){return true;} - virtual bool writeData(std::vector&,QByteArray&, nlohmann::json& json = nlohmann::json()){return true;} - virtual bool initParas(QByteArray&, nlohmann::json& json = nlohmann::json()){return true;} + dsModuleBase() {} + virtual ~dsModuleBase() {} + virtual bool readData(std::vector&,QByteArray&){return true;} + virtual bool writeData(std::vector&,QByteArray&){return true;} + virtual bool initParas(QByteArray&){return true;} virtual bool run() {return true;} }; +class rpcModuleBase : public QObject +{ +public: + bool init_flag; //是否初始化,false,true + bool status = true; //相机状态(判断相机是否断开连接) + std::string paras; //传输数据 + cv::Mat m_mat; //传输图片 + std::string moduleName; //模块名称 +public: + rpcModuleBase() {} + virtual ~rpcModuleBase() {} + virtual bool readData(std::vector&, QByteArray&) { return true; } + virtual bool writeData(std::vector&, QByteArray&) { return true; } + virtual bool initParas(QByteArray&) { return true; } + virtual bool run() { return true; } +}; -#endif diff --git a/python/finsTcp/finsTcp.py b/python/finsTcp/finsTcp.py deleted file mode 100644 index e69de29..0000000 diff --git a/rpcModule/CMakeLists.txt b/rpcModule/CMakeLists.txt new file mode 100644 index 0000000..766f160 --- /dev/null +++ b/rpcModule/CMakeLists.txt @@ -0,0 +1,12 @@ +# 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 ${}) + \ No newline at end of file diff --git a/rpcModule/rpc_finsTcp/CMakeLists.txt b/rpcModule/rpc_finsTcp/CMakeLists.txt new file mode 100644 index 0000000..33c8bb1 --- /dev/null +++ b/rpcModule/rpc_finsTcp/CMakeLists.txt @@ -0,0 +1,71 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "basler" "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 Network 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 + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt5::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " model end : " ${CURRENT_FOLDER}:${RUN_TIME}) diff --git a/rpcModule/rpc_finsTcp/rpc_finsTcp.cpp b/rpcModule/rpc_finsTcp/rpc_finsTcp.cpp new file mode 100644 index 0000000..5c10f31 --- /dev/null +++ b/rpcModule/rpc_finsTcp/rpc_finsTcp.cpp @@ -0,0 +1,275 @@ +#include "rpc_finsTcp.h" +#include "qprocess.h" +#include +#include +#include + +#include +#include +#include +#include +static QProcess* process = nullptr; +static HANDLE jobHandle = nullptr; +rpc_finsTcp* create() +{ + qDebug() << "rpc_finsTcp create success!"; + return new rpc_finsTcp; +} + +void destory(rpc_finsTcp* ptr) +{ + + if (ptr) + { + delete ptr; + ptr = nullptr; + } + qDebug() << " rpc_finsTcp destory success!"; +} +bool ifRun = true; +rpc_finsTcp::rpc_finsTcp() +{ + ifRun = true; +} +bool m_IsFinsTcp = false; +rpc_finsTcp::~rpc_finsTcp() +{ + + qDebug() << " ~rpc_finsTcp success!"; +} +QQueue readDataQueue; +// 从类中读数据到实例对象 +QByteArray variantListToByteArray(const QVariant& var) { + QByteArray byteArray; + + if (var.canConvert()) { + QVariantList list = var.toList(); + byteArray.reserve(list.size()); + + for (const QVariant& item : list) { + // 每个元素转为 uchar 存入 QByteArray + byteArray.append(static_cast(item.toInt())); + } + } + + return byteArray; +} +bool rpc_finsTcp::readData(std::vector& vec_mat, QByteArray& data) +{ + JsonRpcClient* ptr = read_JsonRpcClient[data]; + if(ptr == nullptr) { + ptr = new JsonRpcClient("127.0.0.1", 9000); + read_JsonRpcClient[data] = ptr; + } + auto result = read_JsonRpcClient[data]->call("excuteCli", QJsonArray{QString(data)}, "finstcp"); + data = variantListToByteArray(result); + return true; +} +bool ifRetryCMD = false; +// 实例对象把数据写入到类 + +void startProcess(const QString& exePath) { + if (process) return; // 避免重复启动 + + process = new QProcess(); + process->setProgram(exePath); + process->start(); + + if (!process->waitForStarted(1000)) { + qDebug() << "Process failed to start."; + delete process; + process = nullptr; + return; + } + + DWORD pid = process->processId(); + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); + + jobHandle = CreateJobObject(nullptr, nullptr); + if (jobHandle == nullptr) { + qDebug() << "Failed to create job object"; + return; + } + + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {}; + jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + SetInformationJobObject(jobHandle, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)); + + if (!AssignProcessToJobObject(jobHandle, hProcess)) { + qDebug() << "Failed to assign process to job object"; + } + + CloseHandle(hProcess); +} + +void stopProcess() { + if (process) { + if (process->state() == QProcess::Running) { + process->kill(); + process->waitForFinished(500); + } + delete process; + process = nullptr; + } + + if (jobHandle) { + CloseHandle(jobHandle); + jobHandle = nullptr; + } +} +bool rpc_finsTcp::writeData(std::vector& vec_mat, QByteArray& data){ + 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") { + m_IP = m_list.at(1); + m_port = m_list.at(2).toInt(); + + } + else if(data.contains("read")) { + readDataQueue.append(data); + } + else { + emit writeCallSignal("excuteCli", QJsonArray{ QString(data) }, "finstcp"); + //qDebug() << data; + } + return true; +} + +bool rpc_finsTcp::initParas(QByteArray& data){ + + startProcess("./json_rpc_server.exe"); + subThread = new QThread(this); + write_JsonRpcClient = new JsonRpcClientWorker(); + write_JsonRpcClient->moveToThread(subThread); + QObject::connect(this, &rpc_finsTcp::initRpcClient, + write_JsonRpcClient, &JsonRpcClientWorker::initClient, Qt::QueuedConnection); + emit initRpcClient(); + QObject::connect(this, &rpc_finsTcp::writeCallSignal, + write_JsonRpcClient, &JsonRpcClientWorker::writeCallSlot,Qt::QueuedConnection); + subThread->start(); + emit writeCallSignal("init", QJsonArray{ m_IP,m_port }, "finstcp"); + //qDebug() << "返回结果:" << result; + + //QList> batchList; + //batchList << qMakePair(QString("read_short"), params) + // << qMakePair(QString("read_bit"), QJsonObject{ {"bit", "M0"} }); + + //QJsonArray resultArray = _JsonRpcClient->batchCall(batchList); + //qDebug() << "批量结果:" << resultArray; + return true; + +} + +bool rpc_finsTcp::run() +{ + // 没有用到 + //qDebug() << "[info] " << __FUNCTION__ << " line:" << __LINE__ << " success!"; + return true; +} + + +JsonRpcClient::JsonRpcClient(const QString& host, quint16 port) + :host_(host), port_(port), idCounter_(1) { + + socket_.connectToHost(host_, port_); + if (!socket_.waitForConnected(3000)) { + qWarning() << "[JsonRpcClient] Initial connection failed:" << socket_.errorString(); + } + else { + qDebug() << "[JsonRpcClient] Connected to" << host_ << ":" << port_; + } +} + +bool JsonRpcClient::reconnect() { + if (socket_.state() == QAbstractSocket::ConnectedState) { + return true; + } + + socket_.abort(); // 清理旧连接 + socket_.connectToHost(host_, port_); + if (socket_.waitForConnected(3000)) { + qDebug() << "[JsonRpcClient] Reconnected successfully."; + return true; + } + else { + qWarning() << "[JsonRpcClient] Reconnection failed:" << socket_.errorString(); + return false; + } +} + +QVariant JsonRpcClient::call(const QString& method, const QJsonArray& params, const QString& module) { + QMutexLocker locker(&mutex_); // 确保线程安全 + if (socket_.state() != QAbstractSocket::ConnectedState) { + qWarning() << "[JsonRpcClient] Socket not connected, trying to reconnect..."; + if (!reconnect()) return QVariant(); + } + + QJsonObject request{ + {"jsonrpc", "2.0"}, + {"method", method}, + {"params", params}, + {"id", idCounter_++} + }; + if (!module.isEmpty()) { + request["module"] = module; + } + + QJsonDocument doc(request); + QByteArray data = doc.toJson(QJsonDocument::Compact); + + if (socket_.write(data) == -1 || !socket_.waitForBytesWritten(1000)) { + qWarning() << "[JsonRpcClient] Write failed:" << socket_.errorString(); + return QVariant(); + } + + if (!socket_.waitForReadyRead(3000)) { + qWarning() << "[JsonRpcClient] No response received:" << socket_.errorString(); + return QVariant(); + } + + QByteArray responseData = socket_.readAll(); + QJsonParseError parseError; + QJsonDocument respDoc = QJsonDocument::fromJson(responseData, &parseError); + + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "[JsonRpcClient] JSON parse error:" << parseError.errorString(); + return QVariant(); + } + + QJsonObject resp = respDoc.object(); + if (resp.contains("error")) { + qWarning() << "[JsonRpcClient] JSON-RPC error:" << resp["error"]; + return QVariant(); + } + return resp["result"].toVariant(); +} +void JsonRpcClient::writeCall(const QString& method, const QJsonArray& params, const QString& module) { + if (socket_.state() != QAbstractSocket::ConnectedState) { + qWarning() << "[JsonRpcClient] Socket not connected, trying to reconnect..."; + if (!reconnect()) return; + } + + QJsonObject request{ + {"jsonrpc", "2.0"}, + {"method", method}, + {"params", params}, + {"id", idCounter_++} + }; + if (!module.isEmpty()) { + request["module"] = module; + } + + QJsonDocument doc(request); + QByteArray data = doc.toJson(QJsonDocument::Compact); + + if (socket_.write(data) == -1 || !socket_.waitForBytesWritten(1000)) { + qWarning() << "[JsonRpcClient] Write failed:" << socket_.errorString(); + return; + } +} \ No newline at end of file diff --git a/rpcModule/rpc_finsTcp/rpc_finsTcp.h b/rpcModule/rpc_finsTcp/rpc_finsTcp.h new file mode 100644 index 0000000..5006888 --- /dev/null +++ b/rpcModule/rpc_finsTcp/rpc_finsTcp.h @@ -0,0 +1,91 @@ +#ifndef rpc_finsTcp_H +#define rpc_finsTcp_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +class JsonRpcClient : public QObject { + Q_OBJECT +public: + JsonRpcClient(const QString& host = "127.0.0.1", quint16 port = 9000); + void writeCall(const QString& method, const QJsonArray& params = {}, const QString& module = QString()); + QVariant call(const QString& method, const QJsonArray& params = {}, const QString& module = QString()); + bool reconnect(); // 主动重连,或 call() 失败时调用 +private: + QMutex mutex_; // 确保线程安全 + QTcpSocket socket_; + QString host_; + quint16 port_; + int idCounter_; + +}; +class JsonRpcClientWorker : public QObject { + Q_OBJECT +public: + QQueue readDataQueue; + JsonRpcClientWorker() { + + } +public slots: + void initClient() { + _JsonRpcClient = new JsonRpcClient(); + } + void writeCallSlot(const QString& method, const QJsonArray& params, const QString& module = QString()) { + if (_JsonRpcClient) { + qDebug() << params; + _JsonRpcClient->call(method, params, module); + } + } +private: + JsonRpcClient* _JsonRpcClient = nullptr; +}; +class rpc_finsTcp :public rpcModuleBase +{ + Q_OBJECT +public: + rpc_finsTcp(); + virtual ~rpc_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(); +signals: + void initRpcClient(); + void writeCallSignal(const QString& method, const QJsonArray& params, const QString& module); +private: + QMutex mutex; + QMap read_JsonRpcClient; // 存储多个 JsonRpcClient 实例 + QThread* subThread; + JsonRpcClientWorker* write_JsonRpcClient; + QString m_IP; + int m_port; + QQueue readDataQueue; +}; +#pragma once + + +extern "C" +{ +Q_DECL_EXPORT rpc_finsTcp * create(); +Q_DECL_EXPORT void destory(rpc_finsTcp * ptr); +} + +#endif // rpc_finsTcp_H diff --git a/src/Core/CMakeLists.txt b/src/Core/CMakeLists.txt index 6605e3c..be166f3 100644 --- a/src/Core/CMakeLists.txt +++ b/src/Core/CMakeLists.txt @@ -27,6 +27,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/basic ${CMAKE_CURRENT_SOURCE_DIR}/python ${CMAKE_CURRENT_SOURCE_DIR}/pluginManager + ${CMAKE_CURRENT_SOURCE_DIR}/subModule_pyFinsTcp ) link_directories ( diff --git a/src/Core/back/backStruct.h b/src/Core/back/backStruct.h index 712bd31..3016070 100644 --- a/src/Core/back/backStruct.h +++ b/src/Core/back/backStruct.h @@ -2,8 +2,8 @@ #include #include //#include -typedef subModuleBase* (*CreateFunction)(); -typedef void (*ReleaseFunction)(subModuleBase* animal); +typedef dsModuleBase* (*CreateFunction)(); +typedef void (*ReleaseFunction)(dsModuleBase* animal); struct correctionStruct { @@ -27,7 +27,7 @@ typedef struct { QString dllPath; // 模块名称 QString task_thread_index = "-1";// 存储当前算法属于那个任务线程 QByteArray m_initByte; // 传递初始化参数 - subModuleBase* module_ptr = nullptr; // 存储模块指针 + dsModuleBase* module_ptr = nullptr; // 存储模块指针 ReleaseFunction destory_ptr; // 释放 cameraStruct _cameraStruct;//外部传入数据 bool init = false; diff --git a/src/Core/back/cameraManager.cpp b/src/Core/back/cameraManager.cpp index 925836b..83e569b 100644 --- a/src/Core/back/cameraManager.cpp +++ b/src/Core/back/cameraManager.cpp @@ -28,7 +28,7 @@ static MV_CC_DEVICE_INFO_LIST searchMvDevice() return m_stDevList; } -camera::camera(cameraModule cameraModulePtrIn, int indexIn,qtFuncBridge* bridgeIn) +camera::camera(cameraModule cameraModulePtrIn, int indexIn, qtFuncBridge* bridgeIn) { bridge = bridgeIn; cameraModulePtr = cameraModulePtrIn; @@ -44,19 +44,19 @@ void camera::run() std::vectorcamera_mat; while (runFlag) { - int queueSize = requestQueue.size() ; - if (queueSize >0) + int queueSize = requestQueue.size(); + if (queueSize > 0) { QMutexLocker locker(&mutex); std::shared_ptr data = requestQueue.dequeue(); QMutexLocker locker2(&data->oriImgMutex); - while(1){ + while (1) { getCameraImg(data->oriImgs, data->imgAmountMin); - if (data->oriImgs.size() >= data->imgAmountMin){ + if (data->oriImgs.size() >= data->imgAmountMin) { qDebug() << data->uuid << " Min:" << data->imgAmountMin << " Get:" << data->oriImgs.size(); - if (lastUpdateTime.elapsed() > 200){//显示在界面 + if (lastUpdateTime.elapsed() > 200) {//显示在界面 lastUpdateTime.start(); // 记录本次更新时间 - for(int i = 0;i < data->oriImgs.size();i++){ + for (int i = 0; i < data->oriImgs.size(); i++) { QPixmap pixmap; cvMatToQPixMap(data->oriImgs[i], pixmap); showImgPack* pack = new showImgPack( @@ -70,9 +70,9 @@ void camera::run() if (imgShowCnt >= cameraModulePtr._cameraStruct.imageShowList.size()) imgShowCnt = 0; } - + } - else{ + else { showLost++; qDebug() << cameraModulePtr.dllPath << "Lost show"; } @@ -88,15 +88,15 @@ void camera::run() cameraManager::~cameraManager() { - for (auto camera : cameras){ + for (auto camera : cameras) { delete camera.second; } - for (auto module : camerasVec){ - subModuleBase* base_ptr = module.module_ptr; + for (auto module : camerasVec) { + dsModuleBase* base_ptr = module.module_ptr; delete base_ptr; } - + } void cameraManager::run() @@ -104,7 +104,7 @@ void cameraManager::run() if (initFlag == true) return; #pragma region 加载相机dll - for (auto val = 0; val < _cameraStructs.size(); val++){ + for (auto val = 0; val < _cameraStructs.size(); val++) { _cameraStructs[val].index = val; QString camera_key = QString::fromStdString(_cameraStructs[val].connectionName); QString dllPath = QString::fromStdString(_cameraStructs[val].dllPath);// 相机模块名 @@ -123,7 +123,7 @@ void cameraManager::run() MV_CC_DEVICE_INFO_LIST m_stDevList = searchMvDevice(); QByteArray mvDevices = MV_CC_DeviceInfoListToQByteArray(m_stDevList); - for (auto i = 0; i < camerasVec.size(); i++){ + for (auto i = 0; i < camerasVec.size(); i++) { cameraModule& m_module = camerasVec[i]; QString dllPath = m_module.dllPath; QString key = m_module.key; @@ -150,7 +150,7 @@ void cameraManager::run() } status = NotInit; - bool initReuslt = true; + bool initReuslt = true; for (auto i = 0; i < camerasVec.size(); i++) { cameraModule m_module = camerasVec.at(i); @@ -159,9 +159,9 @@ void cameraManager::run() QByteArray initByte = m_module.m_initByte; if (m_module.module_ptr->initParas(initByte)) { - camera* _camera = new camera(m_module, cameras.size(),bridge); + camera* _camera = new camera(m_module, cameras.size(), bridge); cameras.insert(std::make_pair(m_module.key.toStdString(), _camera)); - emit bridge->loadingWindow_appendLog ("相机"+m_module.key + "初始化成功","green"); + emit bridge->loadingWindow_appendLog("相机" + m_module.key + "初始化成功", "green"); qDebug() << "[INFO] " << " initParas success!"; m_module.init = true; } @@ -171,7 +171,7 @@ void cameraManager::run() m_module.module_ptr->readData(vec_mat, errorStr); initReuslt = false; qCritical() << "[Error] " << " moduleName:" << m_module.dllPath << " initParas failed!"; - emit bridge->loadingWindow_appendLog("相机" + m_module.key + "初始化失败->"+ errorStr,"red"); + emit bridge->loadingWindow_appendLog("相机" + m_module.key + "初始化失败->" + errorStr, "red"); } } if (initReuslt == true) @@ -187,7 +187,7 @@ bool cameraManager::loadModule(cameraStruct _cameraStruct) QString task_thread_index = 0; try { - QString keyName = QString::fromStdString(_cameraStruct.connectionName); + QString keyName = QString::fromStdString(_cameraStruct.key); QString dllPath = QString::fromStdString(_cameraStruct.dllPath);// 相机模块名 QString module_path = "./" + dllPath; qDebug() << "[INFO] " << " module_path:" << module_path; @@ -196,7 +196,7 @@ bool cameraManager::loadModule(cameraStruct _cameraStruct) if (m_usedDllPath[module_path] == true) { //命名格式: 模块名+1/2/3... QString originalPath = "./" + dllPath; - module_path = "./" + dllPath + "-"+QString::number(_cameraStruct.index); + module_path = "./" + dllPath + "-" + QString::number(_cameraStruct.index); if (QFile::exists(module_path + ".dll")) { QFile::remove(module_path + ".dll"); } @@ -223,7 +223,7 @@ bool cameraManager::loadModule(cameraStruct _cameraStruct) { cameraModule m_module; m_module.key = keyName; - //m_module.m_initByte = initByte; + m_module.m_initByte = QByteArray::fromStdString( _cameraStruct.connectionName); m_module.dllPath = dllPath; m_module.module_ptr = createFun(); m_module.destory_ptr = releaseFun; diff --git a/src/Core/back/detData.h b/src/Core/back/detData.h index cb9d519..7185d35 100644 --- a/src/Core/back/detData.h +++ b/src/Core/back/detData.h @@ -58,17 +58,7 @@ public: std::vector oriFormat;//原图格式 如果数量不一致直接全存bmp std::vector imgSaveNameParameter;//命名规则 str1_str2... 第一个参数已默认为相机名,在构造函数 #pragma endregion -//#pragma region 检测相关回调函数 -// resultHandleCallback _resultHandleCallback; -// void registerResultHandleCallback(resultHandleCallback func) { -// _resultHandleCallback = func; -// } -// algoEvaluateCallback _algoEvaluateCallback; -// void registerAlgoEvaluateCallback(algoEvaluateCallback func) { -// _algoEvaluateCallback = func; -// } -//#pragma endregion - + QMap additional; detData(std::string IN_cameraKeyName) { cameraKeyName = IN_cameraKeyName; imgSaveNameParameter.push_back(cameraKeyName); diff --git a/src/Core/back/imgSaveThreadManager.h b/src/Core/back/imgSaveThreadManager.h index facc3b9..58ba483 100644 --- a/src/Core/back/imgSaveThreadManager.h +++ b/src/Core/back/imgSaveThreadManager.h @@ -143,7 +143,7 @@ public: else okNgStr = "OK"; //detailNameStr - if ((data->SNcode).length() != 0) + if (data->SNcode.length() != 0 && data->SNcode.length() < 50) detailNameStr = QString::fromStdString(data->SNcode); else detailNameStr = QString::fromStdString(data->cameraKeyName); @@ -159,7 +159,10 @@ public: { std::vector resultFileNames; std::string fileName; - fileName += data->SNcode; + if (data->SNcode.length() != 0 && data->SNcode.length() < 50) + fileName += data->SNcode; + else + fileName += data->cameraKeyName; for (auto str : data->imgSaveNameParameter) fileName += str + "_"; switch (type) diff --git a/src/Core/back/triggerManager.cpp b/src/Core/back/triggerManager.cpp index 72f2b21..410a1df 100644 --- a/src/Core/back/triggerManager.cpp +++ b/src/Core/back/triggerManager.cpp @@ -6,7 +6,6 @@ #include #include -#define debugTesting 0 triggerManager::triggerManager(detProcess* _detProcessIn, qtFuncBridge* bridgeIn,nlohmann::json& triggerJson) { bridge = bridgeIn; @@ -28,14 +27,14 @@ triggerManager::triggerManager(detProcess* _detProcessIn, qtFuncBridge* bridgeIn void triggerManager::run(){ if(connectHost() == false) return; - QThread::msleep(3000); + QThread::msleep(1000); int cnt = 0; while (runFlag){ reciveCommond(); QThread::msleep(10); //心跳 cnt++; - if (cnt > 30) { + if (cnt > 100) { sendFinsMsg(heartBeatCmd); cnt = 0; // qDebug() << "heartbeat"; @@ -55,8 +54,13 @@ bool triggerManager::connectHost(){ return false; } if (libLoadedflag){ +#if switchToRpc == 0 CreateFunction createFun = (CreateFunction)m_lib->resolve("create"); ReleaseFunction releaseFun = (ReleaseFunction)m_lib->resolve("destory"); +#else + CreateRpcModuleBaseFunction createFun = (CreateRpcModuleBaseFunction)m_lib->resolve("create"); + ReleaseRpcModuleBaseFunction releaseFun = (ReleaseRpcModuleBaseFunction)m_lib->resolve("destory"); +#endif bool initFailure = false; if (createFun && releaseFun) { @@ -89,6 +93,7 @@ bool triggerManager::connectHost(){ return false; } void triggerManager::reciveCommond(){ +#if switchToRpc==0 //auto start = std::chrono::high_resolution_clock::now(); QByteArray readByte; mutex.lock(); @@ -99,6 +104,16 @@ void triggerManager::reciveCommond(){ mutex.unlock(); tLocker.reFreshLocker(readByte);//经过检查后再触发 decodeCameraCMD(readByte); +#else + //auto start = std::chrono::high_resolution_clock::now(); + QByteArray readByte = readAllCmd; + mutex.lock(); + if (!reciveFinsMsg(readByte)) + qCritical() << "[TCP] " << " finstcp_ptr readData error!"; + mutex.unlock(); + tLocker.reFreshLocker(readByte);//经过检查后再触发 + decodeCameraCMD(readByte); +#endif } void triggerManager::decodeCameraCMD(QByteArray byte) diff --git a/src/Core/back/triggerManager.h b/src/Core/back/triggerManager.h index b3d06bc..3b90f68 100644 --- a/src/Core/back/triggerManager.h +++ b/src/Core/back/triggerManager.h @@ -1,6 +1,4 @@ - #ifndef TRIGGERManager_H -#define TRIGGERManager_H -#include +#include #include #include #include @@ -9,6 +7,9 @@ #include #include #include + +#define switchToRpc 1 +#define debugTesting 0 using triggerCallback = std::function; class cameraManager; class detThreadManager; @@ -16,52 +17,35 @@ class detDataManager; class lightSourceManager; class detProcess; //防止重复触发 -class triggerLockerT -{ +class triggerLockerT { public: - triggerLockerT() - { - - } - ~triggerLockerT() - { + triggerLockerT() {} + ~triggerLockerT() { lockerList.clear(); } - bool checkLocker(int input) - { - for (int i = 0; i < lockerList.size(); i++) - { - if (input == lockerList[i].pos) - { + bool checkLocker(int pos) { + for (auto& it : lockerList) { + if (it == pos) { return false; } } return true; } - void reFreshLocker(QByteArray byte) - { - for (int i = 0; i < lockerList.size(); i++) - { - if (byte.at(lockerList[i].pos) != lockerList[i].value) - { - lockerList.removeAt(i); + void reFreshLocker(QByteArray& input) { + if (input.size() == 0)return; + for (auto& it : lockerList) { + if (input.at(it) == 0) { + lockerList.erase(std::remove(lockerList.begin(), lockerList.end(), it), lockerList.end()); } - } } - void adddLocker(int inputPos, int posValue) - { - lockerList.push_back(lockerStruct({ inputPos, posValue })); + void adddLocker(int pos) { + lockerList.push_back(pos); } - struct lockerStruct - { - int pos; - int value; - }; - QListlockerList; + std::vectorlockerList; private: -}; +}; //触发器类 fins触发 tcp触发等 替代myiothread class triggerManager : public serviceModule { @@ -282,7 +266,7 @@ private: /// 值 /// QByteArray /// - bool checkTrigger(int dmPos, int value, QByteArray byte, bool lockerDisable = false) + bool checkTrigger(int dmPos, int value, QByteArray& byte, bool lockerDisable = false) { int triggerPos = (dmPos - startPos) * 2 + 1; if (byte.size() < triggerPos) @@ -292,7 +276,7 @@ private: if (tLocker.checkLocker(triggerPos) == false) return false; if (lockerDisable == false) - tLocker.adddLocker(triggerPos, value); + tLocker.adddLocker(triggerPos); return true; } else @@ -317,11 +301,15 @@ private: int readNum = -1;//范围 int interval = 50;//间隔 QString heartBeatCmd; - +#if switchToRpc==0 ReleaseFunction destory_finstcp; //释放 - subModuleBase* trigger = nullptr; + dsModuleBase* trigger = nullptr; +#else + ReleaseRpcModuleBaseFunction destory_finstcp; //释放 + rpcModuleBase* trigger = nullptr; +#endif bool runFlag = true; bool init = false; std::vector vec_mat;//没啥用,一直保持为空就好 }; -#endif \ No newline at end of file +#pragma once \ No newline at end of file diff --git a/src/Core/backendInterface.cpp b/src/Core/backendInterface.cpp index 66a3fdf..6eb6546 100644 --- a/src/Core/backendInterface.cpp +++ b/src/Core/backendInterface.cpp @@ -25,6 +25,9 @@ public: ~Backend() { delete _detProcess; } + SQLiteDB* getDatabase() { + return _detProcess->dataBase; + } private: bool initOnce = false; detProcess* _detProcess; diff --git a/src/Core/detProcess.hpp b/src/Core/detProcess.hpp index 7f539c0..48f93f6 100644 --- a/src/Core/detProcess.hpp +++ b/src/Core/detProcess.hpp @@ -7,13 +7,11 @@ class detProcess : public QThread { public: + SQLiteDB* dataBase = nullptr; ServiceManager _serviceManager; bool initOnce = false; detProcess():_cliManager(&_serviceManager){ - //_threadManager.initialization(this); - //_manualDetThread.initialization(this); - //_cameraManager.initialization(); - //_triggerManager.initialization(this); + dataBase = new SQLiteDB("./DataBase/", "eui_db"); } void initConfig(nlohmann::json& jsonIn, qtFuncBridge* bridgeIn) { @@ -63,13 +61,11 @@ public: // 相机管理器 // lightSourceManager _lightSourceManager; // 光源管理器 - SQLiteDB* dataBase; - // hardwareMonitor _hardwareMonitor; // 硬件监控,如CPU、内存 // 初始化并运行主流程 void run() { #if 1 - dataBase = new SQLiteDB("./sqlDb/","generalDatabase"); + //_pythonLoader.cao(); _serviceManager._cameraManager->start(); _serviceManager._handleAiModelManager->start(); //_lightSourceManager.start(); @@ -95,15 +91,17 @@ public: // return _missionLoader._misson->processAlgo(data, _handleAiModelManager); // }); - emit bridge->loginResult(InitOK); + emit bridge->initResult(InitOK); } else { - emit bridge->loginResult(InitFailure); + emit bridge->initResult(InitFailure); } #endif } + void test() { + } private: nlohmann::json json; qtFuncBridge* bridge; diff --git a/src/core/struct.h b/src/core/struct.h index ca6b252..93b7459 100644 --- a/src/core/struct.h +++ b/src/core/struct.h @@ -235,16 +235,17 @@ struct _952BiaoDingSwitchData #include #pragma execution_character_set("utf-8") -typedef subModuleBase* (*CreateFunction)(); -typedef void (*ReleaseFunction)(subModuleBase* animal); - +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; // 传递初始化参数 - subModuleBase* module_ptr = nullptr; // 存储模块指针 + dsModuleBase* module_ptr = nullptr; // 存储模块指针 ReleaseFunction destory_ptr; // 释放 int showIndex; }MyModule; diff --git a/src/launcher/GUI/JsonEditorDialog.h b/src/launcher/GUI/JsonEditorDialog.h index 1abfe6f..a525b76 100644 --- a/src/launcher/GUI/JsonEditorDialog.h +++ b/src/launcher/GUI/JsonEditorDialog.h @@ -1,205 +1,45 @@ #pragma once + #include -#include +#include +#include #include #include #include #include -#include -#include -#include -#include +#include +#include #include -#include -class JsonEditor : public QDialog { +#include +class JsonParamTableEditor : public QDialog { Q_OBJECT public: - virtual nlohmann::json getJson() { return nlohmann::json(); }; -}; - -class JsonEditorGeneral : public JsonEditor { - Q_OBJECT -public: - JsonEditorGeneral(const nlohmann::json& json, QWidget* parent = nullptr) - : //QDialog(parent), - m_json(json), m_originalJson(json) - { - setWindowTitle("JSON 编辑器"); - resize(600, 400); - - m_textEdit = new QTextEdit(this); - m_textEdit->setText(QString::fromStdString(m_json.dump(4))); - - m_btnOk = new QPushButton("确定", this); - m_btnCancel = new QPushButton("取消", this); - - QHBoxLayout* btnLayout = new QHBoxLayout; - btnLayout->addStretch(); - btnLayout->addWidget(m_btnOk); - btnLayout->addWidget(m_btnCancel); - - QVBoxLayout* mainLayout = new QVBoxLayout(this); - mainLayout->addWidget(m_textEdit); - mainLayout->addLayout(btnLayout); - - connect(m_btnOk, &QPushButton::clicked, this, &JsonEditorGeneral::onAccept); - connect(m_btnCancel, &QPushButton::clicked, this, &QDialog::reject); - } - - nlohmann::json getJson() { return m_json; } - -private slots: - void onAccept() { - try { - if (!nlohmann::json::accept(m_textEdit->toPlainText().toStdString())) { - QMessageBox::warning(this, "错误", "JSON 格式错误,无法解析。"); - updateEditorText(m_originalJson); - return; - } - auto new_json = nlohmann::json::parse(m_textEdit->toPlainText().toStdString()); - - // 检查键名 - if (!hasSameKeys(new_json, m_originalJson)) { - QMessageBox::warning(this, "JSON错误", "键名不允许被修改,已恢复原始 JSON。"); - new_json = m_originalJson; // 恢复所有 - updateEditorText(new_json); - return; - } - - // 检查每个值的类型 - bool typeOk = true; - for (auto& [key, old_val] : m_originalJson.items()) { - auto& new_val = new_json.at(key); - if (!typeCompatible(old_val, new_val)) { - typeOk = false; - QMessageBox::warning(this, "类型错误", - QString("键 \"%1\" 的类型错误,已恢复原始值。") - .arg(QString::fromStdString(key))); - - // 恢复此键 - new_json[key] = old_val; - } - } - - if (!typeOk) { - updateEditorText(new_json); - return; - } - - m_json = new_json; - accept(); - } - catch (nlohmann::json::parse_error& e) { - QMessageBox::warning(this, "JSON格式错误", e.what()); - updateEditorText(m_originalJson); - } - catch (const std::exception& e) { - QMessageBox::warning(this, "JSON格式错误", e.what()); - // 恢复全部 - updateEditorText(m_originalJson); - } - catch (...) { - QMessageBox::warning(this, "未知错误", "JSON 解析时发生未知错误,已恢复默认值。"); - updateEditorText(m_originalJson); - } - } - - void updateEditorText(const nlohmann::json& json) { - m_textEdit->setPlainText(QString::fromStdString(json.dump(4))); - } - -private: - bool hasSameKeys(const nlohmann::json& a, const nlohmann::json& b) { - if (!a.is_object() || !b.is_object()) return false; - if (a.size() != b.size()) return false; - for (auto& [key, _] : a.items()) { - if (!b.contains(key)) return false; - } - return true; - } - - bool typeCompatible(const nlohmann::json& old_val, const nlohmann::json& new_val) { - return old_val.type() == new_val.type(); - } - - std::string typeName(const nlohmann::json& val) { - switch (val.type()) { - case nlohmann::json::value_t::string: return "string"; - case nlohmann::json::value_t::number_integer: return "integer"; - case nlohmann::json::value_t::number_unsigned: return "unsigned integer"; - case nlohmann::json::value_t::number_float: return "float"; - case nlohmann::json::value_t::boolean: return "boolean"; - case nlohmann::json::value_t::array: return "array"; - case nlohmann::json::value_t::object: return "object"; - case nlohmann::json::value_t::null: return "null"; - default: return "unknown"; - } - } - -private: - nlohmann::json m_json; - nlohmann::json m_originalJson; - - QTextEdit* m_textEdit; - QPushButton* m_btnOk; - QPushButton* m_btnCancel; -}; - -class JsonParamTableEditor : public JsonEditor { - Q_OBJECT -public: - JsonParamTableEditor(const nlohmann::json& json, QWidget* parent = nullptr) - : m_json(json), m_originalJson(json) - { - setWindowTitle("JSON 表格编辑器"); - resize(600, 400); - setWindowFlags(Qt::FramelessWindowHint); + explicit JsonParamTableEditor(QWidget* parent = nullptr) + : QDialog(parent) { + this->setWindowTitle("JSON 表格编辑器"); + this->resize(600, 400); + setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint); // 去掉边框 //现在、、 + //setAttribute(Qt::WA_TranslucentBackground); // 背景透明 this->setObjectName("JsonParamTableEditor"); this->setStyleSheet(QString("QDialog#JsonParamTableEditor {background-color: rgb(%1);border: 2px solid #000000;border-radius: 6px;}").arg(sColor_Blue)); - // ------------------- - // 表格 - m_tableWidget = new QTableWidget(this); - m_tableWidget->setColumnCount(2); - m_tableWidget->setHorizontalHeaderLabels({ "", "数值" }); - m_tableWidget->horizontalHeader()->setStretchLastSection(true); - m_tableWidget->verticalHeader()->hide(); // 不显示序号 + m_tableWidget = new QTableWidget(0, 2, this); + m_tableWidget->setHorizontalHeaderLabels({ "选项", "值" }); - int row = 0; - for (auto& [key, value] : m_json.items()) { - m_tableWidget->insertRow(row); + fancyButtonText* okBtn = new fancyButtonText(70, 22, "保存", ""); + fancyButtonText* cancelBtn = new fancyButtonText(70, 22, "取消", ""); - QTableWidgetItem* keyItem = new QTableWidgetItem(QString::fromStdString(key)); - keyItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - m_tableWidget->setItem(row, 0, keyItem); + connect(okBtn, &QPushButton::clicked, this, &JsonParamTableEditor::onAccept); + connect(cancelBtn, &QPushButton::clicked, this, &QDialog::reject); - QTableWidgetItem* valueItem = new QTableWidgetItem(QString::fromStdString(value.dump())); - m_tableWidget->setItem(row, 1, valueItem); - - row++; - } - - // ------------------- - // 底部按钮 - m_btnOk = new fancyButtonText(70,22,"保存", ""); - m_btnCancel = new fancyButtonText(70, 22, "取消", ""); - - QHBoxLayout* btnLayout = new QHBoxLayout; + QHBoxLayout* btnLayout = new QHBoxLayout(); btnLayout->addStretch(); - btnLayout->addWidget(m_btnOk); - btnLayout->addWidget(m_btnCancel); + btnLayout->addWidget(okBtn); + btnLayout->addWidget(cancelBtn); - // ------------------- - // 主布局 QVBoxLayout* mainLayout = new QVBoxLayout(this); mainLayout->addWidget(m_tableWidget); mainLayout->addLayout(btnLayout); - // ------------------- - // 信号槽 - connect(m_btnOk, &QPushButton::clicked, this, &JsonParamTableEditor::onAccept); - connect(m_btnCancel, &QPushButton::clicked, this, &QDialog::reject); - - m_tableWidget->setStyleSheet(QString(R"( QTableWidget { background-color: rgb(%1); @@ -215,75 +55,127 @@ public: )").arg(sColor_Blue).arg(sColor_GoldWithBlack)); } - nlohmann::json getJson() const { return m_json; } + void setJsonObject(const nlohmann::json& json) { + m_tableWidget->setRowCount(0); + if (!json.is_object()) return; + + for (auto it = json.begin(); it != json.end(); ++it) { + int row = m_tableWidget->rowCount(); + m_tableWidget->insertRow(row); + + m_tableWidget->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(it.key()))); + QString valueText = QString::fromStdString(it.value().dump()); + m_tableWidget->setItem(row, 1, new QTableWidgetItem(valueText)); + } + m_tableWidget->resizeColumnsToContents(); + + } + +signals: + void jsonAccepted(const nlohmann::json&); private slots: void onAccept() { - nlohmann::json newJson = m_originalJson; + nlohmann::json result = nlohmann::json::object(); for (int row = 0; row < m_tableWidget->rowCount(); ++row) { - QString key = m_tableWidget->item(row, 0)->text(); - QString valStr = m_tableWidget->item(row, 1)->text(); + auto* keyItem = m_tableWidget->item(row, 0); + auto* valItem = m_tableWidget->item(row, 1); + + if (!keyItem || !valItem) { + QMessageBox::warning(this, "错误", QString("第 %1 行数据不完整").arg(row + 1)); + return; + } + + QString key = keyItem->text().trimmed(); + QString valStr = valItem->text().trimmed(); + + if (key.isEmpty() || valStr.isEmpty()) { + QMessageBox::warning(this, "错误", QString("第 %1 行 key 或 value 为空").arg(row + 1)); + return; + } + + if (valStr.size() > 10240) { + QMessageBox::warning(this, "错误", QString("第 %1 行的值过大").arg(row + 1)); + return; + } try { - auto& oldVal = m_originalJson.at(key.toStdString()); - nlohmann::json parsed = nlohmann::json::parse(valStr.toStdString()); - - if (!typeCompatible(oldVal, parsed)) { - QMessageBox::warning(this, "类型错误", - QString("键 \"%1\" 的类型与原始不符,期望类型: %2") - .arg(key) - .arg(QString::fromStdString(typeName(oldVal)))); - return; - } - - newJson[key.toStdString()] = parsed; + result[key.toStdString()] = nlohmann::json::parse(valStr.toStdString()); } - catch (std::exception& e) { - QMessageBox::warning(this, "解析错误", - QString("键 \"%1\" 的值无法解析为 JSON: %2") - .arg(key) - .arg(e.what())); + catch (const std::exception& e) { + QMessageBox::critical(this, "JSON 解析失败", + QString("第 %1 行 value 解析失败:\n%2").arg(row + 1).arg(e.what())); return; } } - m_json = newJson; + emit jsonAccepted(result); accept(); } private: - bool typeCompatible(const nlohmann::json& old_val, const nlohmann::json& new_val) { - return old_val.type() == new_val.type(); + QTableWidget* m_tableWidget; +}; + + +class JsonEditorGeneral : public QDialog { + Q_OBJECT +public: + explicit JsonEditorGeneral(QWidget* parent = nullptr) + : QDialog(parent) { + setWindowTitle("通用 JSON 编辑"); + + m_textEdit = new QPlainTextEdit(this); + QPushButton* okBtn = new QPushButton("确定", this); + QPushButton* cancelBtn = new QPushButton("取消", 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(m_textEdit); + + QHBoxLayout* btnLayout = new QHBoxLayout(); + btnLayout->addStretch(); + btnLayout->addWidget(okBtn); + btnLayout->addWidget(cancelBtn); + + mainLayout->addLayout(btnLayout); } - std::string typeName(const nlohmann::json& val) { - switch (val.type()) { - case nlohmann::json::value_t::string: return "string"; - case nlohmann::json::value_t::number_integer: return "integer"; - case nlohmann::json::value_t::number_unsigned: return "unsigned integer"; - case nlohmann::json::value_t::number_float: return "float"; - case nlohmann::json::value_t::boolean: return "boolean"; - case nlohmann::json::value_t::array: return "array"; - case nlohmann::json::value_t::object: return "object"; - case nlohmann::json::value_t::null: return "null"; - default: return "unknown"; + void setJson(const nlohmann::json& json) { + m_textEdit->setPlainText(QString::fromStdString(json.dump(4))); + } + +signals: + void jsonAccepted(const nlohmann::json&); + +private slots: + void onAccept() { + QString text = m_textEdit->toPlainText().trimmed(); + + if (text.isEmpty()) { + QMessageBox::warning(this, "警告", "JSON 内容不能为空"); + return; + } + + if (text.size() > 102400) { + QMessageBox::warning(this, "警告", "JSON 内容过大,可能导致崩溃"); + return; + } + + try { + nlohmann::json parsed = nlohmann::json::parse(text.toStdString()); + emit jsonAccepted(parsed); + accept(); + } + catch (const std::exception& e) { + QMessageBox::critical(this, "解析错误", QString("JSON 解析失败:\n%1").arg(e.what())); } } private: - nlohmann::json m_json; - nlohmann::json m_originalJson; - - QTableWidget* m_tableWidget; - fancyButtonText* m_btnOk; - fancyButtonText* m_btnCancel; + QPlainTextEdit* m_textEdit; }; - -class JsonEditorSelector { -public: - static JsonEditor* selector(const nlohmann::json& json, QWidget* parent = nullptr) { - return new JsonParamTableEditor(json, parent); - } -}; -#pragma once \ No newline at end of file diff --git a/src/launcher/GUI/front/pages/displayPageWidget.h b/src/launcher/GUI/front/pages/displayPageWidget.h index 83059f8..a2e779a 100644 --- a/src/launcher/GUI/front/pages/displayPageWidget.h +++ b/src/launcher/GUI/front/pages/displayPageWidget.h @@ -79,10 +79,11 @@ public: fancyButtonText* btn = new fancyButtonText(200, 50, u8"修改检测参数", ""); connect(btn, &QPushButton::clicked, [=]() { - JsonEditor* dlg = JsonEditorSelector::selector(m_config->settingJson["backend"]["missionSettings"], this); + JsonParamTableEditor* dlg = new JsonParamTableEditor(this); + dlg->setJsonObject(m_config->settingJson["backend"]["missionSettings"]), dlg->setAttribute(Qt::WA_DeleteOnClose); - connect(dlg, &QDialog::accepted, this, [this, dlg]() { - m_config->settingJson["backend"]["missionSettings"] = dlg->getJson(); + connect(dlg, &JsonParamTableEditor::jsonAccepted, [this](const nlohmann::json& result) { + m_config->settingJson["backend"]["missionSettings"] = result; }); dlg->show(); }); diff --git a/src/launcher/GUI/front/pages/sqlControlWidget.h b/src/launcher/GUI/front/pages/sqlControlWidget.h index b183d06..ac107a1 100644 --- a/src/launcher/GUI/front/pages/sqlControlWidget.h +++ b/src/launcher/GUI/front/pages/sqlControlWidget.h @@ -53,7 +53,7 @@ public: Layout->setContentsMargins(0, 0, 0, 0); Layout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - Title = new QLabel(u8"SQL操作界面"); + Title = new QLabel(u8"数据库操作界面"); Title->setFont(font); Title->setPalette(palette); Title->setAlignment(Qt::AlignLeft); diff --git a/src/launcher/GUI/front/pages/summary_data_page.h b/src/launcher/GUI/front/pages/summary_data_page.h index 867a065..61bbef2 100644 --- a/src/launcher/GUI/front/pages/summary_data_page.h +++ b/src/launcher/GUI/front/pages/summary_data_page.h @@ -163,10 +163,11 @@ protected: private slots: void editJsonParameters() { - JsonEditor* dlg = JsonEditorSelector::selector(m_json, this); + JsonParamTableEditor* dlg = new JsonParamTableEditor(this); + dlg->setJsonObject(m_json); dlg->setAttribute(Qt::WA_DeleteOnClose); - connect(dlg, &QDialog::accepted, this, [this, dlg]() { - m_json = dlg->getJson(); + connect(dlg, &JsonParamTableEditor::jsonAccepted, [this](const nlohmann::json& result) { + m_json = result; applyJsonParams(); }); dlg->show(); @@ -283,6 +284,11 @@ private: class SummuaryDataPage :public QWidget { Q_OBJECT public: + std::vectorbtns; + std::vectorlayoutList; + QStackedWidget* stackedWidgets; + QHBoxLayout* btnLayout; + int currentPageIndex = 0; SummuaryDataPage(appConfig*config, nlohmann::json& json) :m_config(config),m_json(json){ QPalette palette; @@ -304,33 +310,70 @@ public: m_layout->addWidget(m_title); - m_mainWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_layout->addWidget(m_mainWidget); + stackedWidgets = new QStackedWidget(); + stackedWidgets->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + btnLayout = new QHBoxLayout(); + btnLayout->setContentsMargins(0, 0, 0, 0); + btnLayout->setAlignment(Qt::AlignLeft); + + m_layout->addLayout(btnLayout); + m_layout->addWidget(stackedWidgets); parsingJson(json); //costomFunc(); } void parsingJson(nlohmann::json& json) { - for (auto& jsonData : json) { - if (jsonData.at("widgetType") == "WaveFormWidget") { - addPlot(jsonData); + for (auto it = json.begin(); it != json.end(); ++it) { + std::string pageName = it.key(); + int page = addStackWidget(QString::fromStdString(pageName)); + for(auto& jsonData : it.value()) { + if (jsonData.at("widgetType") == "WaveFormWidget") { + addPlot(jsonData, page, QString::fromStdString(pageName)); + } } + } } + int addStackWidget(QString btnText) { + //切换配置页面 + int thistPageIndex = stackedWidgets->count(); + gradientButton* btn = new gradientButton(160, 50, btnText, ""); + btnLayout->addWidget(btn); + btns.push_back(btn); + connect(btn, &QPushButton::clicked, [=]() + { + for (auto btnPtr : btns) + btnPtr->toDefault(); + btn->pressed(); + currentPageIndex = thistPageIndex; + stackedWidgets->setCurrentIndex(thistPageIndex); + }); - void addPlot(nlohmann::json& json) { + //页面widget + QWidget* widget = new QWidget(); + stackedWidgets->addWidget(widget); + widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + QGridLayout* laytout = new QGridLayout(widget); + layoutList.push_back(laytout); + return layoutList.size() - 1; + } + + void addPlot(nlohmann::json& json,int page,const QString& pageName) { QString name = QString::fromStdString(json.at("key")); int x = json.at("x"); int y = json.at("y"); - m_waveFormMap[name] = new WaveFormWidget(json); - m_gridLayout->addWidget(m_waveFormMap[name], y, x,1,1); + m_waveFormMap[pageName + "#" + name] = new WaveFormWidget(json); + layoutList[page]->addWidget(m_waveFormMap[pageName + "#" + name], y, x, 1, 1); } void addData(QString name, double data) { + if(m_waveFormMap[name] == nullptr) { + qDebug() << "WaveFormWidget not found for name:" << name; + return; + } m_waveFormMap[name]->appendData(data); } QVBoxLayout* m_layout = new QVBoxLayout(this); std::map m_waveFormMap; - QWidget* m_mainWidget = new QWidget(); - QGridLayout* m_gridLayout = new QGridLayout(m_mainWidget); QLabel* m_title; QIcon m_toolbarIcon; private: diff --git a/src/launcher/GUI/mainwindow.cpp b/src/launcher/GUI/mainwindow.cpp index 39db360..d5bacd9 100644 --- a/src/launcher/GUI/mainwindow.cpp +++ b/src/launcher/GUI/mainwindow.cpp @@ -230,7 +230,7 @@ void MainWindow::leftBarInit(){ //SQL _sqlControlWidget = new sqlControlWidget(); - //registerPageBar(":/icon/icon/sql.png", u8"SQL可视化", _sqlControlWidget); + registerPageBar(":/icon/icon/sql.png", u8"数据库", _sqlControlWidget); //PLUGIN //registerPageBar(":/icon/icon/sql.png", u8"SQL可视化", _pluginManagerWidget); diff --git a/src/launcher/appConfig/appConfig.cpp b/src/launcher/appConfig/appConfig.cpp index 47d3a5d..b74db4b 100644 --- a/src/launcher/appConfig/appConfig.cpp +++ b/src/launcher/appConfig/appConfig.cpp @@ -7,7 +7,7 @@ void appConfig::parsingSettingJson() fs::path appWorkPath = fs::current_path(); originJson = readJsonFromPath(appWorkPath.string() + "/config/setting.json"); jsonVersion = originJson["jsonVersion"]; - if(jsonVersion != "1.0.1"){ + if(jsonVersion != "1.0.3"){ std::cout << "Json version mismatch, please update the config file." << std::endl; std::cout << "Json版本不匹配,请检查json配置文件" << std::endl; exit(1); diff --git a/src/launcher/appConfig/appConfig.h b/src/launcher/appConfig/appConfig.h index 8298d2e..0b0f14b 100644 --- a/src/launcher/appConfig/appConfig.h +++ b/src/launcher/appConfig/appConfig.h @@ -7,20 +7,17 @@ class appConfig public: void parsingSettingJson(); //sqlManager _sqlManager;//储存产品信息用 - appConfig(){ + appConfig() { parsingSettingJson(); //_sqlManager.initialization(this); } void saveSettingJson() { - originJson[objectSelect] = settingJson; saveJsonFromPath("./config/setting.json", originJson); saveJsonFromPath("./config/"+ objectSelect +".json", settingJson); } nlohmann::json settingJson; std::string softwareTile;//软件标题 std::string imgSavePath;//原图存储路径 - - //triggerStruct _triggerStruct; //std::vector< cameraStruct> _cameraStructs; diff --git a/src/launcher/appCore.hpp b/src/launcher/appCore.hpp index 015a38c..d8f2c93 100644 --- a/src/launcher/appCore.hpp +++ b/src/launcher/appCore.hpp @@ -5,31 +5,70 @@ #include //QT #include +#include +// +#include "interface.h" +#include -#define DISABLE_BACKEND_CHECK 0 -#define DISABLE_ALGO 0 #define HIDE_CONSOLE 1 -/// -/// APP BASIC -/// -class appCore -{ +class backEnd { +public: + IBackend* backend = nullptr; + HMODULE hDll; + bool loadCore(qtFuncBridge* bridgeIn, nlohmann::json& jsonIn) { + bridge = bridgeIn; + json = jsonIn; + hDll = LoadLibrary("core.dll"); + if (!hDll) { + std::cerr << "Failed to load DLL!" << std::endl; + return false; + } + + CreateBackend = (CreateBackendFunc)GetProcAddress(hDll, "CreateBackend"); + ReleaseBackend = (ReleaseBackendFunc)GetProcAddress(hDll, "ReleaseBackend"); + + if (CreateBackend && ReleaseBackend) { + backend = CreateBackend(); + } + else { + std::cerr << "Failed to get function pointers!" << std::endl; + return false; + } + backend->init(bridgeIn, jsonIn); + return true; + } + void releaseCore() { + backend->cleanup(); + ReleaseBackend(backend); + delete backend; + backend = nullptr; + FreeLibrary(hDll); + } +private: + qtFuncBridge* bridge; + nlohmann::json json; + CreateBackendFunc CreateBackend; + ReleaseBackendFunc ReleaseBackend; +}; +class appCore : public QObject{ + Q_OBJECT public: logService _logService; appConfig _appConfig; - appCore() - { + backEnd backend; + SQLiteDB* g_db = nullptr; + appCore(){ }; public slots: - void switchProductSignal() - { + void switchProductSignal(){ } + void recvInitFinished() { + g_db = backend.backend->getDatabase(); + } }; -// -//extern appCore _core; #pragma once \ No newline at end of file diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index 4d2bb12..0163a27 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -1,7 +1,6 @@ #include #include "client/windows/handler/exception_handler.h" #include -#include #include #include #include @@ -20,10 +19,8 @@ #include // TCHAR 相关操作 #include // SHELLEXECUTEINFO 结构体 #include // std::cout (如果需要打印信息) -#include #include -#include "interface.h" #pragma region 程序启动功能 bool appIsRuning() @@ -108,46 +105,6 @@ bool checkResourceExists(const QString& resourcePath) { } } -class backEnd{ - -public: - IBackend* backend = nullptr; - HMODULE hDll; - bool loadCore(qtFuncBridge* bridgeIn,nlohmann::json& jsonIn) { - bridge = bridgeIn; - json = jsonIn; - hDll = LoadLibrary("core.dll"); - if (!hDll) { - std::cerr << "Failed to load DLL!" << std::endl; - return false; - } - - CreateBackend = (CreateBackendFunc)GetProcAddress(hDll, "CreateBackend"); - ReleaseBackend = (ReleaseBackendFunc)GetProcAddress(hDll, "ReleaseBackend"); - - if (CreateBackend && ReleaseBackend) { - backend = CreateBackend(); - } - else { - std::cerr << "Failed to get function pointers!" << std::endl; - return false; - } - backend->init(bridgeIn,jsonIn); - return true; - } - void releaseCore() { - backend->cleanup(); - ReleaseBackend(backend); - delete backend; - backend = nullptr; - FreeLibrary(hDll); - } -private: - qtFuncBridge* bridge; - nlohmann::json json; - CreateBackendFunc CreateBackend; - ReleaseBackendFunc ReleaseBackend; -}; void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge* bridge) { QObject::connect(_core->_logService._logToQtWidget, &logToQtWidget::stdLogSignal, _MainWindow->_logWidget, &logWidget::recvStdLogMsg); @@ -166,8 +123,10 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge* _MainWindow, [=]() {_MainWindow->_loadingWidget.clearLog(); }); //登录界面 - QObject::connect(bridge, &qtFuncBridge::loginResult, + 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); @@ -176,56 +135,6 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge* QObject::connect(bridge, &qtFuncBridge::summaryData_addData, _MainWindow, &MainWindow::slot_summaryData_addData); } -//void connectSignalAndSlots(MainWindow* front, appCore* _core, detProcess* _detProcess) -//{ -// ///////////TEMP -// //QObject::connect(&_core->_qtFunc, &qtFunction::addCtData, front, &MainWindow::addCtData); -// QObject::connect(&_core->_qtFunc, &qtFunction::sendInitString, front, &MainWindow::recvInitString); -// QObject::connect(&_core->_qtFunc, &qtFunction::sendPixmapImageWidget, front, &MainWindow::recvPixmapImageWidget); -// -// QObject::connect(&_core->_qtFunc, &qtFunction::sendInitFinished, front, &MainWindow::recvInitFinished); -// //QObject::connect(&_core->_qtFunc, &qtFunction::addDashBoardData, front, &MainWindow::addDashBoardData); -// QObject::connect(&_core->_qtFunc, &qtFunction::addCtData, front, &MainWindow::addCtData); -// QObject::connect(&_core->_qtFunc, &qtFunction::addHistoryDataSignal, front, &MainWindow::addDetHistoryData); -// //QObject::connect(&_core->_qtFunc, &qtFunction::switchStartBtnStatusSignal, -// // front->_displayWidget->_switchProductWidget, &switchProductWidget::switchStartBtnStatus); -// //QObject::connect(&_core->_qtFunc, &qtFunction::uiModuleLocationMap_ResetToDefault, -// // front->_displayWidget->_uiModuleLocationMap, &uiModuleLocationMap::resetToDefault); -// //QObject::connect(&_core->_qtFunc, &qtFunction::uiModuleLocationMap_SetProductSignStatus, -// // front, &MainWindow::uiModuleLocationMapSetProductSignStatus); -// //uiModuleImageDoubleCheckQdialog -// QObject::connect(&_core->_qtFunc, &qtFunction::uiModuleImageDoubleCheckQdialog_ShowWindows, -// front, [=](QPixmap map) {front->_imageDoubleCheckQdialog->showAndSetImg(map); }); -// -// //uiModuleSummaryDataManager -// //QObject::connect(&_core->_qtFunc, &qtFunction::uiModuleSummaryDataManager_SetSummaryResultText, -// // front, [=](QString text, Qt::GlobalColor color) -// // {front->_displayWidget->_summaryDataManager->setSummaryResult(text, color); }); -// //QObject::connect(&_core->_qtFunc, &qtFunction::uiModuleSummaryDataManager_Reset, -// // front, [=]() {front->_displayWidget->_summaryDataManager->resetAllValue(); }); -// -// QObject::connect(&_core->_qtFunc, &qtFunction::uiModuleBackContinueDetDialog_show, -// front, [=]() {front->_backContinueDetDialog->show(); }); -// QObject::connect(&_core->_qtFunc, &qtFunction::uiModuleBackContinueDetDialog_hide, -// front, [=]() {front->_backContinueDetDialog->hide(); }); -// -// QObject::connect(&_core->_qtFunc, &qtFunction::uiModuleHistoryListWidget_reset, -// front, [=]() {front->_displayWidget->historyImgs->reset(); }); -// -// QObject::connect(&_detProcess->_manualDetThread, &manualDetThread::finishImgReadSignal, -// front->_manualDetWidget, &manualDetWidget::finishImgReadSlot); -// -// QObject::connect(front->_manualDetWidget, &manualDetWidget::startManualDetSignal, -// &_detProcess->_manualDetThread, &manualDetThread::startManualDetSlot); -// -// QObject::connect(front, &MainWindow::reInitSignal, -// _detProcess, [=]() {_detProcess->start(); }); -// QObject::connect(front->_loadingWidget.retryBtn, &QPushButton::clicked, -// _detProcess, [=]() {_detProcess->start(); }); -// /* QObject::connect(front->_displayWidget->_switchProductWidget, &switchProductWidget::startArmProgramSignal, -// front->_productDetDoubleCheck, &productDetDoubleCheck::showAndSetText);*/ -// -//} int main(int argc, char* argv[]) { @@ -234,8 +143,11 @@ int main(int argc, char* argv[]) // restartAsAdmin(); // exit(0); //} +#pragma region 设置显示控制栏 HWND hWnd = GetConsoleWindow(); ShowWindow(hWnd, SW_SHOW); +#pragma endregion +#pragma region 启动breakPad崩溃捕获 std::wstring dumpPath = L"./dumps"; CreateDirectoryW(dumpPath.c_str(), nullptr); @@ -247,13 +159,15 @@ int main(int argc, char* argv[]) /*context*/ nullptr, /*install_handler*/ true ); +#pragma endregion + appCore _core; qtFuncBridge bridge; // 创建 C++ 对象 //检测是否已运行 if (appIsRuning() == false) exit(0); ////////// - +#pragma region 注册信号槽变量 qRegisterMetaType("matPtr"); qRegisterMetaType("stdString"); qRegisterMetaType("historyPack"); @@ -262,14 +176,14 @@ int main(int argc, char* argv[]) qRegisterMetaType("showImgPack"); qRegisterMetaType("initStatus"); qRegisterMetaType("mat"); - +#pragma endregion QApplication a(argc, argv); MainWindow w(&_core._appConfig,&bridge, _core._appConfig.settingJson); connectSignalAndSlot(&_core, &w, &bridge); // 连接信号和槽 w.show(); - backEnd backend; // 创建后端对象 - backend.loadCore(&bridge, _core._appConfig.settingJson["backend"]); // 加载核心功能 + // 创建后端对象 + _core.backend.loadCore(&bridge, _core._appConfig.settingJson["backend"]); // 加载核心功能 #if HIDE_CONSOLE if (hWnd) { ShowWindow(hWnd, SW_HIDE); diff --git a/src/mission/628_12CamTest/628_12CamTest.cpp b/src/mission/628_12CamTest/628_12CamTest.cpp new file mode 100644 index 0000000..43f1c90 --- /dev/null +++ b/src/mission/628_12CamTest/628_12CamTest.cpp @@ -0,0 +1,8 @@ +#include <628_12CamTest.h> + +mission* createMission() { + return new M628_12CamTest(); +} +void destroyMission(mission* _mission) { + delete _mission; +} \ No newline at end of file diff --git a/src/mission/628_12CamTest/628_12CamTest.h b/src/mission/628_12CamTest/628_12CamTest.h new file mode 100644 index 0000000..c1703e8 --- /dev/null +++ b/src/mission/628_12CamTest/628_12CamTest.h @@ -0,0 +1,215 @@ +#include +#include +#include +#include +#include +#include +#include + + +struct M628_12CamTest_algoResult +{ + double LT_Distance = -1; + double RT_Distance = -1; + double LD_Distance = -1; + double RD_Distance = -1; + double L_Duiqidu = -1; + double R_Duiqidu = -1; + + bool aiResultIsOK = false; +}; +class handleAIModels { +public: + handleAiModelSeg* SEG_25D; + handleAiModelCls* CLS_25D; + bool liubai_Enforcement_OK = true; //留白检测结果强制OK + double liubai_MaxThreshold = 5.0; //留白最大阈值 + double liubai_MinThreshold = 0.0; //留白最小阈值 + + bool duiqidu_Enforcement_OK = true; //对齐度检测结果强制OK + double duiqidu_MaxThreshold = 5.0; //对齐度最大阈值 + double duiqidu_MinThreshold = 0.0; //对齐度最小阈值 + + bool handleAI_Enforcement_OK = true; // handleAI结果强制OK + int handleAI_WIDTH = 10; //handleAI最大阈值 + int handleAI_HEIGHT = 10; //handleAI最小阈值 + + double in_xResolution = 0.0323938; // 分辨率X + double in_yResolution = 0.0366128; // 分辨率Y +}; +#pragma region 算法 +#include +#include +#include +using namespace HDevEngineCpp; +static bool M628_12CamTest_25D_ALGO_HuaShangAI(std::shared_ptr data,cv::Mat& img, handleAIModels* _handleAiModels, cv::Mat& Paint, QMutex& paintMutex) { + cv::Mat segImg = ~_handleAiModels->SEG_25D->Evaluate(img); + 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 < _handleAiModels->handleAI_WIDTH && rect.height < _handleAiModels->handleAI_HEIGHT) continue; // 过滤掉小轮廓 + auto clsImgs = cutImg2ClsVec(rect, img,cv::Size(256,256)); + bool clsIsNg = false; + for (auto& clsImg : clsImgs) { + int clsResult = _handleAiModels->CLS_25D->Evaluate(clsImg); + if (clsResult == 1) { // 假设1表示NG + clsIsNg = 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::Mat imgTmp; + cv::cvtColor(img(rect), imgTmp, cv::COLOR_GRAY2BGR); + QMutexLocker locker(&paintMutex); + //imgTmp.copyTo(Paint(rect)); + cv::drawContours(Paint, contours, i, color, 2); + cv::putText(Paint, "NG"+std::to_string(i), cv::Point(rect.x + 10, rect.y - 20), cv::FONT_HERSHEY_SIMPLEX, 0.8, color, 2); + } + else { + cv::Mat imgTmp; + cv::cvtColor(img(rect), imgTmp, cv::COLOR_GRAY2BGR); + 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); + } + return isOK; +} + +static M628_12CamTest_algoResult M628_12CamTest_Algo(std::shared_ptr data, handleAIModels* _handleAIModels) +{ + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; + + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) + { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return M628_12CamTest_algoResult(); + } + 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 M628_12CamTest_algoResult(); + } + + cv::Mat Paint; + QMutex paintMutex; + clock_t start, finish; + start = clock(); + + cv::Mat src1 = data->oriImgs[0]; + + if (src1.channels() != 3) + cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR); + else + src1.copyTo(Paint); + cv::putText(Paint, "OK", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255,255,255), 2); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); // 缩小结果图 + data->resultImgs.push_back(Paint); + //data->aiDetOK = futureResult; // 如果任一检测结果为NG,则整体结果为NG + + finish = clock(); + qDebug() << "[Debug]2D useTime:" << finish - start << "ms"; + return M628_12CamTest_algoResult(); +} +#pragma endregion + +class M628_12CamTest : public mission { +public: + summaryData _summaryData; + std::vector>> algo_list; + std::vector cameralist; + handleAIModels _handleAIModels; + void parseJson(nlohmann::json& json) { + + } + bool init(ServiceManager* _serviceManagerIN, + nlohmann::json& _missionJson, + SQLiteDB* _SQLiteDB, qtFuncBridge* bridgeIn) { + + bridge = bridgeIn; + _serviceManager = _serviceManagerIN; + +#pragma region 初始化外部参数 + parseJson(_missionJson); + //HDevEngineCpp::HDevEngine myEngine; + //myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_952.hdpl"); +#pragma endregion + + for (auto& camera : _serviceManager->_cameraManager->cameras) { + cameralist.push_back(camera.second);//获取相机 + std::shared_ptr> algo = std::make_shared>(_serviceManager, &_handleAIModels); + algo_list.push_back(algo); + algo->registerProcessAlgoCallback(M628_12CamTest_Algo); + algo->registerResultHandleCallback(std::bind(&M628_12CamTest::generalCameraResultHandle, this, _1, _2)); + } + +#pragma region 注册触发器回调 + _serviceManager->_triggerManager->registerCallback(5500, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 0, 5530, 5500); }, "Cam1拍照触发"); + _serviceManager->_triggerManager->registerCallback(5510, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 1, 5530, 5510); }, "Cam2拍照触发"); + _serviceManager->_triggerManager->registerCallback(5520, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 2, 5530, 5520); }, "Cam3拍照触发"); + + _serviceManager->_triggerManager->registerCallback(5550, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 3, 5580, 5550); }, "Cam4拍照触发"); + _serviceManager->_triggerManager->registerCallback(5560, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 4, 5580, 5560); }, "Cam5拍照触发"); + _serviceManager->_triggerManager->registerCallback(5570, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 5, 5580, 5570); }, "Cam6拍照触发"); + + _serviceManager->_triggerManager->registerCallback(5700, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 6, 5730, 5700); }, "Cam7拍照触发"); + _serviceManager->_triggerManager->registerCallback(5710, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 7, 5730, 5710); }, "Cam8拍照触发"); + _serviceManager->_triggerManager->registerCallback(5720, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 8, 5730, 5720); }, "Cam9拍照触发"); + + _serviceManager->_triggerManager->registerCallback(5750, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 9, 5780, 5750); }, "Cam10拍照触发"); + _serviceManager->_triggerManager->registerCallback(5760, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 10, 5780, 5760); }, "Cam11拍照触发"); + _serviceManager->_triggerManager->registerCallback(5770, 1, [this](QByteArray& byteArray) {generalCameraTrigger(byteArray, 11, 5780, 5770); }, "Cam12拍照触发"); +#pragma endregion + + + + + return true; + } + //9200 1 + void generalCameraTrigger(QByteArray& byteArray,int index,int snPos,int triggerPos){ + _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(triggerPos) + "_0" );//清零 + std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1); + std::shared_ptr data = _serviceManager->_detDataManager->createDetData( + cameralist[index]->cameraName, sn, 1, {"bmp"});//创建数据包 + cameralist[index]->captureImage(data);//拍照 + data->resultImgShowSet.push_back(new showImgPack("Cam"+QString::number(index), "结果图")); + algo_list[index]->ansyncProcess(data, "D" + QByteArray::number(triggerPos+2) + "_1");//处理算法 拍照反馈信号 + data->additional["resultPos"] = triggerPos + 4; + } + + void generalCameraResultHandle(std::shared_ptr data, M628_12CamTest_algoResult resultData){ + //发送图片 + if (data->resultImgs.size() > 0){ + for (int i = 0; i < data->resultImgs.size() && i < data->resultImgShowSet.size(); i++){ + showImgPack* pack = data->resultImgShowSet[getMin(i, (int)data->resultImgShowSet.size() - 1)]; + QPixmap pixmap = cvMatToQPixMap(data->resultImgs[i]); + pack->img = pixmap; + emit bridge->displayWidget_sendImg(pack); + pixmap = QPixmap(); + } + } + _serviceManager->_triggerManager->writeShort("D" + QByteArray::number(data->additional["resultPos"].toInt()) + "_0"); + qDebug() << "SN:" << QString::fromStdString(data->SNcode) << "检测结束 结果获取完成" ; + } + +private: + qtFuncBridge* bridge; + ServiceManager* _serviceManager = nullptr; +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/628_12CamTest/CMakeLists.txt b/src/mission/628_12CamTest/CMakeLists.txt new file mode 100644 index 0000000..76bbff3 --- /dev/null +++ b/src/mission/628_12CamTest/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/back + ${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 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 + ) + + + +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/952_15_H_25D/952_15_H_25D.h b/src/mission/952_15_H_25D/952_15_H_25D.h index 8812f87..174d62a 100644 --- a/src/mission/952_15_H_25D/952_15_H_25D.h +++ b/src/mission/952_15_H_25D/952_15_H_25D.h @@ -268,6 +268,7 @@ public: } #pragma endregion #pragma region 注册触发器回调 + _serviceManager->_triggerManager->registerCallback(9250, 1, [this](QByteArray& byteArray) {reloadAlgo(byteArray); }, "25D-1拍照触发"); _serviceManager->_triggerManager->registerCallback(9200, 1, [this](QByteArray& byteArray) {HouDuan1(byteArray); }, "25D-1拍照触发"); _serviceManager->_triggerManager->registerCallback(9600, 1, [this](QByteArray& byteArray) {HouDuan2(byteArray); }, "25D-2拍照触发"); @@ -281,6 +282,9 @@ public: #pragma endregion return true; + } + void reloadAlgo(QByteArray& byteArray) { + } //9200 1 bool houduan1SecondTime = false; @@ -296,10 +300,14 @@ public: //data->oriImgs.push_back(cv::imread("I:\\952Code\\CODES\\bm\\2025-07-08-09361133675272.5D-H-1_09-27-32-22_Count2.bmp", -1)); - if(houduan1SecondTime == false) + if (houduan1SecondTime == false) { data->resultImgShowSet.push_back(new showImgPack("后段1-1", "结果图")); - else + data->additional["波形图"] = "外侧后段1"; + } + else { data->resultImgShowSet.push_back(new showImgPack("后段1-2", "结果图")); + data->additional["波形图"] = "外侧后段2"; + } houduan1SecondTime = !houduan1SecondTime; algo_liubai->ansyncProcess(data, "D9202_1");//处理算法 qDebug() << "[ Station 10 ] " << QString::fromUtf8("2.5D-1 后段检测开始 uuid :") << data->uuid << "SN" << QString::fromStdString(sn);; @@ -317,10 +325,14 @@ public: _25DCamera_2->captureImage(data);//拍照 - if (houduan2SecondTime == false) + if (houduan2SecondTime == false) { data->resultImgShowSet.push_back(new showImgPack("后段2-1", "结果图")); - else + data->additional["波形图"] = "内侧后段1"; + } + else { data->resultImgShowSet.push_back(new showImgPack("后段2-2", "结果图")); + data->additional["波形图"] = "内侧后段2"; + } houduan2SecondTime = !houduan2SecondTime; algo_liubai->ansyncProcess(data, "D9602_1");//处理算法 qDebug() << "[ Station 10 ] " << QString::fromUtf8("2.5D-2 后段检测开始 uuid :") << data->uuid << "SN" << QString::fromStdString(sn);; @@ -343,24 +355,13 @@ public: try { M952_15_H_algoResult* dataPtr = _summaryData.get(sn); *dataPtr = resultData; - if (data->cameraKeyName == "2.5D-H-1") { - emit bridge->summaryData_addData("后段1-左上留白", resultData.LT_Distance); - emit bridge->summaryData_addData("后段1-右上留白", resultData.RT_Distance); - emit bridge->summaryData_addData("后段1-左下留白", resultData.LD_Distance); - emit bridge->summaryData_addData("后段1-右下留白", resultData.RD_Distance); - emit bridge->summaryData_addData("后段1-左对齐度", resultData.L_Duiqidu); - emit bridge->summaryData_addData("后段1-右对齐度", resultData.R_Duiqidu); - } - else{ - emit bridge->summaryData_addData("后段2-左上留白", resultData.LT_Distance); - emit bridge->summaryData_addData("后段2-右上留白", resultData.RT_Distance); - emit bridge->summaryData_addData("后段2-左下留白", resultData.LD_Distance); - emit bridge->summaryData_addData("后段2-右下留白", resultData.RD_Distance); - emit bridge->summaryData_addData("后段2-左对齐度", resultData.L_Duiqidu); - emit bridge->summaryData_addData("后段2-右对齐度", resultData.R_Duiqidu); - - } - + QString firstStr = data->cameraKeyName == "2.5D-H-1" ? "包膜后外侧" : "包膜后内侧"; + emit bridge->summaryData_addData(data->additional["波形图"].toString() + "#" + firstStr + "-左上留白", resultData.LT_Distance); + emit bridge->summaryData_addData(data->additional["波形图"].toString() + "#" + firstStr + "-右上留白", resultData.RT_Distance); + emit bridge->summaryData_addData(data->additional["波形图"].toString() + "#" + firstStr + "-左下留白", resultData.LD_Distance); + emit bridge->summaryData_addData(data->additional["波形图"].toString() + "#" + firstStr + "-右下留白", resultData.RD_Distance); + emit bridge->summaryData_addData(data->additional["波形图"].toString() + "#" + firstStr + "-左对齐度", resultData.L_Duiqidu); + emit bridge->summaryData_addData(data->additional["波形图"].toString() + "#" + firstStr + "-右对齐度", resultData.R_Duiqidu); } catch (...) { qDebug() << "[ Station 10 ] " << QString::fromUtf8("后段检测结果数据异常 SN:") << QString::fromStdString(data->SNcode); @@ -384,44 +385,49 @@ public: _serviceManager->_triggerManager->sendFinsMsg("write_float_D9438_" + QString::number(dataPtr->LD_Distance));//左下留白 _serviceManager->_triggerManager->sendFinsMsg("write_float_D9440_" + QString::number(dataPtr->L_Duiqidu));//左对其度 - int result = 1; - //留白检测结果 - if (_handleAIModels.liubai_Enforcement_OK == false) - if (dataPtr->RT_Distance> _handleAIModels.liubai_MaxThreshold || - dataPtr->RD_Distance > _handleAIModels.liubai_MaxThreshold || - dataPtr->LT_Distance > _handleAIModels.liubai_MaxThreshold || - dataPtr->LD_Distance > _handleAIModels.liubai_MaxThreshold || - - dataPtr->RT_Distance < _handleAIModels.liubai_MinThreshold || - dataPtr->RD_Distance < _handleAIModels.liubai_MinThreshold || - dataPtr->LT_Distance < _handleAIModels.liubai_MinThreshold || - dataPtr->LD_Distance < _handleAIModels.liubai_MinThreshold) { - result = 2; - qDebug() << "通道1 SN:" << QString::fromStdString(sn) << " 留白检测结果NG"; + int lfTop_result = 1;//留白右左上 + int lfBot_result = 1;//留白右左下 + int duiQiDu_result = 1;//对齐度 + int ai_result = 1;//AI模型检测结果 + if (_handleAIModels.liubai_Enforcement_OK == false){//判断留白强制OK标志位 + if (dataPtr->RT_Distance > _handleAIModels.liubai_MaxThreshold || + dataPtr->LT_Distance > _handleAIModels.liubai_MaxThreshold || + dataPtr->RT_Distance < _handleAIModels.liubai_MinThreshold || + dataPtr->LT_Distance < _handleAIModels.liubai_MinThreshold) { + lfTop_result = 2; + qDebug() << "通道1 SN:" << QString::fromStdString(sn) << " 留白右左上结果NG"; + } + if(dataPtr->RD_Distance > _handleAIModels.liubai_MaxThreshold || + dataPtr->LD_Distance > _handleAIModels.liubai_MaxThreshold || + dataPtr->RD_Distance < _handleAIModels.liubai_MinThreshold || + dataPtr->LD_Distance < _handleAIModels.liubai_MinThreshold){ + lfBot_result = 2; + qDebug() << "通道1 SN:" << QString::fromStdString(sn) << " 留白右左下结果NG"; + } } - //对齐度检测结果 - if (_handleAIModels.duiqidu_Enforcement_OK == false) + + if (_handleAIModels.duiqidu_Enforcement_OK == false)//判断对齐度强制OK标志位 if (dataPtr->R_Duiqidu > _handleAIModels.duiqidu_MaxThreshold || dataPtr->L_Duiqidu > _handleAIModels.duiqidu_MaxThreshold || dataPtr->R_Duiqidu < _handleAIModels.duiqidu_MinThreshold || dataPtr->L_Duiqidu < _handleAIModels.duiqidu_MinThreshold) { - result = 2; + duiQiDu_result = 2; qDebug() << "通道1 SN:" << QString::fromStdString(sn) << " 对齐度检测结果NG"; } //AI模型检测结果 if (_handleAIModels.handleAI_Enforcement_OK == false)if (dataPtr->aiResultIsOK == false) { - result = 2; + ai_result = 2; qDebug() << "通道1 SN:" << QString::fromStdString(sn) << " AI模型检测结果NG"; } - - _serviceManager->_triggerManager->sendFinsMsg("write_short_D9402_" + QString::number(result)); - _serviceManager->_triggerManager->sendFinsMsg("write_short_D9404_" + QString::number(result)); _serviceManager->_triggerManager->writeShort({ - "D6200_1", "D6201_1", "D6202_1", "D6203_1", "D6204_1", + "D6200_1", "D6201_1", "D6202_1", "D6203_1", "D6204_" + std::to_string(ai_result), "D6205_1", "D6206_1", "D6207_1", "D6208_1", "D6209_1", - "D6210_1", "D6211_1", "D6212_1", "D6213_1", "D6214_1", - "D6215_1", "D6216_1", "D6217_1", "D6218_1", "D6219_1", - }); + "D6210_" + std::to_string(lfTop_result), "D6211_" + std::to_string(lfTop_result), + "D6212_" + std::to_string(duiQiDu_result), "D6213_1", "D6214_1", + "D6215_1", "D6216_1", "D6217_1", "D6218_1", "D6219_1"}); + _serviceManager->_triggerManager->sendFinsMsg("write_short_D9402_" + QString::number(lfTop_result)); + _serviceManager->_triggerManager->sendFinsMsg("write_short_D9404_" + QString::number(lfTop_result)); + qDebug() << "通道1 SN:" << QString::fromStdString(sn) << " 发送结果";//:\n左留白->" << dataPtr->leftLiuBai.toStdString() << "\n右留白->" << dataPtr->rightLiuBai.toStdString() << "\n对其度->" << dataPtr->duiqidu.toStdString()<_triggerManager->sendFinsMsg("write_float_D9838_" + QString::number(dataPtr->LD_Distance));//左下留白 _serviceManager->_triggerManager->sendFinsMsg("write_float_D9840_" + QString::number(dataPtr->L_Duiqidu));//左对其度 - int result = 1; - //留白检测结果 - if(_handleAIModels.liubai_Enforcement_OK == false) - if (dataPtr->RT_Distance > _handleAIModels.liubai_MaxThreshold || - dataPtr->RD_Distance> _handleAIModels.liubai_MaxThreshold || - dataPtr->LT_Distance > _handleAIModels.liubai_MaxThreshold || - dataPtr->LD_Distance > _handleAIModels.liubai_MaxThreshold || - - dataPtr->RT_Distance < _handleAIModels.liubai_MinThreshold || - dataPtr->RD_Distance < _handleAIModels.liubai_MinThreshold || - dataPtr->LT_Distance < _handleAIModels.liubai_MinThreshold || - dataPtr->LD_Distance < _handleAIModels.liubai_MinThreshold ) { - result = 2; - qDebug() << "通道2 SN:" << QString::fromStdString(sn) << " 留白检测结果NG"; - } - //对齐度检测结果 - if (_handleAIModels.duiqidu_Enforcement_OK == false) - if( dataPtr->R_Duiqidu > _handleAIModels.duiqidu_MaxThreshold || - dataPtr->L_Duiqidu > _handleAIModels.duiqidu_MaxThreshold || - dataPtr->R_Duiqidu < _handleAIModels.duiqidu_MinThreshold || - dataPtr->L_Duiqidu < _handleAIModels.duiqidu_MinThreshold) { - result = 2; - qDebug() << "通道2 SN:" << QString::fromStdString(sn) << " 对齐度检测结果NG"; - } - //AI模型检测结果 - if (_handleAIModels.handleAI_Enforcement_OK == false)if (dataPtr->aiResultIsOK == true) { - result = 2; - qDebug() << "通道2 SN:" << QString::fromStdString(sn) << " AI模型检测结果NG"; + int lfTop_result = 1;//留白右左上 + int lfBot_result = 1;//留白右左下 + int duiQiDu_result = 1;//对齐度 + int ai_result = 1;//AI模型检测结果 + if (_handleAIModels.liubai_Enforcement_OK == false) {//判断留白强制OK标志位 + if (dataPtr->RT_Distance > _handleAIModels.liubai_MaxThreshold || + dataPtr->LT_Distance > _handleAIModels.liubai_MaxThreshold || + dataPtr->RT_Distance < _handleAIModels.liubai_MinThreshold || + dataPtr->LT_Distance < _handleAIModels.liubai_MinThreshold) { + lfTop_result = 2; + qDebug() << "通道1 SN:" << QString::fromStdString(sn) << " 留白右左上结果NG"; + } + if (dataPtr->RD_Distance > _handleAIModels.liubai_MaxThreshold || + dataPtr->LD_Distance > _handleAIModels.liubai_MaxThreshold || + dataPtr->RD_Distance < _handleAIModels.liubai_MinThreshold || + dataPtr->LD_Distance < _handleAIModels.liubai_MinThreshold) { + lfBot_result = 2; + qDebug() << "通道1 SN:" << QString::fromStdString(sn) << " 留白右左下结果NG"; + } } - - _serviceManager->_triggerManager->sendFinsMsg("write_short_D9802_"+QString::number(result)); - _serviceManager->_triggerManager->sendFinsMsg("write_short_D9804_"+QString::number(result)); - _serviceManager->_triggerManager->writeShort({ - "D6220_1", "D6221_1", "D6222_1", "D6223_1", "D6224_1", - "D6225_1", "D6226_1", "D6227_1", "D6228_1", "D6229_1", - "D6230_1", "D6231_1", "D6232_1", "D6233_1", "D6234_1", - "D6235_1", "D6236_1", "D6237_1", "D6238_1", "D6239_1" - }); + if (_handleAIModels.duiqidu_Enforcement_OK == false)//判断对齐度强制OK标志位 + if (dataPtr->R_Duiqidu > _handleAIModels.duiqidu_MaxThreshold || + dataPtr->L_Duiqidu > _handleAIModels.duiqidu_MaxThreshold || + dataPtr->R_Duiqidu < _handleAIModels.duiqidu_MinThreshold || + dataPtr->L_Duiqidu < _handleAIModels.duiqidu_MinThreshold) { + duiQiDu_result = 2; + qDebug() << "通道1 SN:" << QString::fromStdString(sn) << " 对齐度检测结果NG"; + } + //AI模型检测结果 + if (_handleAIModels.handleAI_Enforcement_OK == false)if (dataPtr->aiResultIsOK == false) { + ai_result = 2; + qDebug() << "通道1 SN:" << QString::fromStdString(sn) << " AI模型检测结果NG"; + } + _serviceManager->_triggerManager->writeShort({ + "D6220_1", "D6221_1", "D6222_1", "D6223_1", "D6224_" + std::to_string(ai_result), + "D6225_1", "D6226_1", "D6227_1", "D6228_1", "D6229_1", + "D6230_" + std::to_string(lfTop_result), "D6231_" + std::to_string(lfTop_result), + "D6232_" + std::to_string(duiQiDu_result), "D6233_1", "D6234_1", + "D6235_1", "D6236_1", "D6237_1", "D6238_1", "D6239_1" }); + + + _serviceManager->_triggerManager->sendFinsMsg("write_short_D9802_" + QString::number(lfTop_result)); + _serviceManager->_triggerManager->sendFinsMsg("write_short_D9804_" + QString::number(lfTop_result)); qDebug() << "通道2 SN:" << QString::fromStdString(sn) << " 获取结果";//:\n左留白->" << dataPtr->leftLiuBai.toStdString() << "\n右留白->" << dataPtr->rightLiuBai.toStdString() << "\n对其度->" << dataPtr->duiqidu.toStdString() << std::endl; _summaryData.remove(sn); } diff --git a/src/mission/952_15_Q_2D3D/952_15_Q_2D3D.cpp b/src/mission/952_15_Q_2D3D/952_15_Q_2D3D.cpp index 3d4b053..3308a80 100644 --- a/src/mission/952_15_Q_2D3D/952_15_Q_2D3D.cpp +++ b/src/mission/952_15_Q_2D3D/952_15_Q_2D3D.cpp @@ -1,7 +1,7 @@ #include <952_15_Q_2D3D.h> mission* createMission() { - return new _952_15_Q_2D3D_1(); + return new _952_15_Q_2D3D(); } void destroyMission(mission* _mission) { delete _mission; diff --git a/src/mission/952_15_Q_2D3D/952_15_Q_2D3D.h b/src/mission/952_15_Q_2D3D/952_15_Q_2D3D.h index 098fae1..31af6ee 100644 --- a/src/mission/952_15_Q_2D3D/952_15_Q_2D3D.h +++ b/src/mission/952_15_Q_2D3D/952_15_Q_2D3D.h @@ -7,7 +7,7 @@ #include #include -struct _952_15_Q_2D3D_1_summaryData +struct _952_15_Q_2D3D_result { QString _2D_P_Result = "-1"; QString _2D_N_Result = "-1"; @@ -95,7 +95,7 @@ static bool _952_15_Q_2D_P_ALGO_ZangWuAI(cv::Mat& img, handleAIModels* _handleAi return isNg; } -static _952_15_Q_2D3D_1_summaryData _952_15_Q_2D_P_ALGO(std::shared_ptr data, handleAIModels* _handleAiModelManager) { +static _952_15_Q_2D3D_result _952_15_Q_2D_P_ALGO(std::shared_ptr data, handleAIModels* _handleAiModelManager) { //获取模型 qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; @@ -103,7 +103,7 @@ static _952_15_Q_2D3D_1_summaryData _952_15_Q_2D_P_ALGO(std::shared_ptr oriImgs.size() != 3) { qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); - return _952_15_Q_2D3D_1_summaryData(); + return _952_15_Q_2D3D_result(); } cv::Mat Paint; @@ -128,41 +128,41 @@ static _952_15_Q_2D3D_1_summaryData _952_15_Q_2D_P_ALGO(std::shared_ptr resultImgs.push_back(Paint); data->aiDetOK = huaShangResult || zangWuResult; // 如果任一检测结果为NG,则整体结果为NG - return _952_15_Q_2D3D_1_summaryData(); + return _952_15_Q_2D3D_result(); } -static _952_15_Q_2D3D_1_summaryData _952_15_Q_2D_N_ALGO(std::shared_ptr data, handleAIModels* _handleAiModelManager) { +static _952_15_Q_2D3D_result _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 _952_15_Q_2D3D_1_summaryData(); + return _952_15_Q_2D3D_result(); } cv::Mat Paint; cv::cvtColor(data->oriImgs[2], Paint, cv::COLOR_GRAY2BGR); putTextZH(Paint, "OK", cv::Point(100, 100), 150, cv::Scalar(0, 255, 0)); data->resultImgs.push_back(Paint); - return _952_15_Q_2D3D_1_summaryData(); + return _952_15_Q_2D3D_result(); } -static _952_15_Q_2D3D_1_summaryData _952_15_Q_3D_ALGO(std::shared_ptr data, handleAIModels* _handleAiModelManager) { +static _952_15_Q_2D3D_result _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 _952_15_Q_2D3D_1_summaryData(); + return _952_15_Q_2D3D_result(); } cv::Mat Paint; cv::cvtColor(data->oriImgs[2], Paint, cv::COLOR_GRAY2BGR); putTextZH(Paint, "OK", cv::Point(100, 100), 150, cv::Scalar(0, 255, 0)); data->resultImgs.push_back(Paint); - return _952_15_Q_2D3D_1_summaryData(); + return _952_15_Q_2D3D_result(); } #pragma endregion -class _952_15_Q_2D3D_1 : public mission { +class _952_15_Q_2D3D : public mission { public: #pragma region 由外部输入的参数 std::string _2D_P_Camera_Name; @@ -185,12 +185,14 @@ public: QString _3D_P_viewName; int summary_triggerPos; + std::vector summary_triggerReply; + int summary_snPos; #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; + 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_result> _summaryData; bool init(ServiceManager* _serviceManagerIN, nlohmann::json& _missionJson, SQLiteDB* _SQLiteDB, qtFuncBridge* bridgeIn) { @@ -225,21 +227,21 @@ public: _serviceManager->_triggerManager->registerCallback(summary_triggerPos, 1, [this](QByteArray& byteArray) {sumRequest1(byteArray); }, "结果获取触发"); #pragma endregion #pragma region 处理算法回调链 - algo_2D_P = std::make_shared>(_serviceManager, &_handleAIModels); + algo_2D_P = std::make_shared>(_serviceManager, &_handleAIModels); algo_2D_P->registerProcessAlgoCallback(_952_15_Q_2D_P_ALGO); - algo_2D_P->registerResultHandleCallback(([this](std::shared_ptr data, _952_15_Q_2D3D_1_summaryData sumdata) { + algo_2D_P->registerResultHandleCallback(([this](std::shared_ptr data, _952_15_Q_2D3D_result sumdata) { Qian_2D_P_ResultHandle(data); })); - algo_2D_N = std::make_shared>(_serviceManager, &_handleAIModels); + algo_2D_N = std::make_shared>(_serviceManager, &_handleAIModels); algo_2D_N->registerProcessAlgoCallback(_952_15_Q_2D_N_ALGO); - algo_2D_N->registerResultHandleCallback(([this](std::shared_ptr data, _952_15_Q_2D3D_1_summaryData sumdata) { + algo_2D_N->registerResultHandleCallback(([this](std::shared_ptr data, _952_15_Q_2D3D_result sumdata) { Qian_2D_P_ResultHandle(data); })); - algo_3D = std::make_shared>(_serviceManager, &_handleAIModels); + algo_3D = std::make_shared>(_serviceManager, &_handleAIModels); algo_3D->registerProcessAlgoCallback(_952_15_Q_3D_ALGO); - algo_3D->registerResultHandleCallback(([this](std::shared_ptr data, _952_15_Q_2D3D_1_summaryData sumdata) { + algo_3D->registerResultHandleCallback(([this](std::shared_ptr data, _952_15_Q_2D3D_result sumdata) { Qian_2D_P_ResultHandle(data); })); #pragma endregion @@ -270,6 +272,8 @@ public: _3D_snPos = _missionJson["_3D_snPos"].get(); _3D_P_viewName = QString::fromStdString(_missionJson["_3D_P_viewName"].get()); summary_triggerPos = _missionJson["summary_triggerPos"].get(); + summary_triggerReply = _missionJson["summary_triggerReply"].get>(); + summary_snPos = _missionJson["summary_snPos"].get(); } catch (const nlohmann::json::out_of_range& e) { std::cerr << "JSON out-of-range error: " << e.what() << std::endl; @@ -317,7 +321,7 @@ public: std::string sn = data->SNcode; try { - _952_15_Q_2D3D_1_summaryData* dataPtr = _summaryData.get(sn); + _952_15_Q_2D3D_result* 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(); @@ -400,7 +404,7 @@ public: std::string sn = data->SNcode; try { - _952_15_Q_2D3D_1_summaryData* dataPtr = _summaryData.get(sn); + _952_15_Q_2D3D_result* 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(); @@ -437,21 +441,10 @@ public: //8040 1 Summary1 void sumRequest1(QByteArray& byteArray){ - _serviceManager->_triggerManager->writeShort({ "D8040_0" ,"D9402_1","D9404_1"}); - int snPos = summary_triggerPos; + _serviceManager->_triggerManager->writeShort(summary_triggerReply); + int snPos = summary_snPos; 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);//右对其度 - + _952_15_Q_2D3D_result* dataPtr = _summaryData.get(sn); std::cout << "通道1 SN:" << sn << " 发送结果" << std::endl;//:\n左留白->" << dataPtr->leftLiuBai.toStdString() << "\n右留白->" << dataPtr->rightLiuBai.toStdString() << "\n对其度->" << dataPtr->duiqidu.toStdString()<&mat , QByteArray& data, nlohmann::json& json) +bool Hd_25DCameraVJ_module::readData(std::vector&mat , QByteArray& data) { Q_UNUSED(data) @@ -914,7 +914,7 @@ bool Hd_25DCameraVJ_module::readData(std::vector&mat , QByteArray& data return true; } -bool Hd_25DCameraVJ_module::writeData(std::vector& mat , QByteArray&data , nlohmann::json& json) +bool Hd_25DCameraVJ_module::writeData(std::vector& mat , QByteArray&data) { Q_UNUSED(mat) @@ -922,7 +922,7 @@ bool Hd_25DCameraVJ_module::writeData(std::vector& mat , QByteArray&dat return true; } -bool Hd_25DCameraVJ_module::initParas(QByteArray&, nlohmann::json& json) +bool Hd_25DCameraVJ_module::initParas(QByteArray&) { return true; #if 1 diff --git a/subModule/Hd_25DCameraVJ_module-ch1/Hd_25DCameraVJ_module1.h b/subModule/Hd_25DCameraVJ_module-ch1/Hd_25DCameraVJ_module1.h index 62b24ab..868df2a 100644 --- a/subModule/Hd_25DCameraVJ_module-ch1/Hd_25DCameraVJ_module1.h +++ b/subModule/Hd_25DCameraVJ_module-ch1/Hd_25DCameraVJ_module1.h @@ -28,14 +28,14 @@ signals: }; -class Hd_25DCameraVJ_module :public subModuleBase +class Hd_25DCameraVJ_module :public dsModuleBase { public: Hd_25DCameraVJ_module(); virtual ~Hd_25DCameraVJ_module(); - bool readData(std::vector&,QByteArray&, nlohmann::json& json); - bool writeData(std::vector&,QByteArray&, nlohmann::json& json); - bool initParas(QByteArray&, nlohmann::json& json = nlohmann::json()); + bool readData(std::vector&, QByteArray&); + bool writeData(std::vector&, QByteArray&); + bool initParas(QByteArray&); bool run(); std::string sTriggerSource; diff --git a/subModule/Hd_25DCameraVJ_module-ch2/Hd_25DCameraVJ_module2.cpp b/subModule/Hd_25DCameraVJ_module-ch2/Hd_25DCameraVJ_module2.cpp index fdf46b3..bcdf3e4 100644 --- a/subModule/Hd_25DCameraVJ_module-ch2/Hd_25DCameraVJ_module2.cpp +++ b/subModule/Hd_25DCameraVJ_module-ch2/Hd_25DCameraVJ_module2.cpp @@ -891,7 +891,7 @@ Hd_25DCameraVJ_module::~Hd_25DCameraVJ_module() qDebug() << "[info]" << __FUNCTION__ << "line:" << __LINE__ << " delete success!"; } -bool Hd_25DCameraVJ_module::readData(std::vector& mat, QByteArray& data, nlohmann::json& json) +bool Hd_25DCameraVJ_module::readData(std::vector& mat, QByteArray& data) { //Q_UNUSED(data) @@ -918,7 +918,7 @@ bool Hd_25DCameraVJ_module::readData(std::vector& mat, QByteArray& data return true; } -bool Hd_25DCameraVJ_module::writeData(std::vector& mat, QByteArray& data, nlohmann::json& json) +bool Hd_25DCameraVJ_module::writeData(std::vector& mat, QByteArray& data) { //Q_UNUSED(mat) @@ -926,7 +926,7 @@ bool Hd_25DCameraVJ_module::writeData(std::vector& mat, QByteArray& dat return true; } -bool Hd_25DCameraVJ_module::initParas(QByteArray&, nlohmann::json& json) +bool Hd_25DCameraVJ_module::initParas(QByteArray&) { return true; #if 1 diff --git a/subModule/Hd_25DCameraVJ_module-ch2/Hd_25DCameraVJ_module2.h b/subModule/Hd_25DCameraVJ_module-ch2/Hd_25DCameraVJ_module2.h index 62b24ab..9c2be41 100644 --- a/subModule/Hd_25DCameraVJ_module-ch2/Hd_25DCameraVJ_module2.h +++ b/subModule/Hd_25DCameraVJ_module-ch2/Hd_25DCameraVJ_module2.h @@ -28,14 +28,14 @@ signals: }; -class Hd_25DCameraVJ_module :public subModuleBase +class Hd_25DCameraVJ_module :public dsModuleBase { public: Hd_25DCameraVJ_module(); virtual ~Hd_25DCameraVJ_module(); - bool readData(std::vector&,QByteArray&, nlohmann::json& json); - bool writeData(std::vector&,QByteArray&, nlohmann::json& json); - bool initParas(QByteArray&, nlohmann::json& json = nlohmann::json()); + bool readData(std::vector&,QByteArray&); + bool writeData(std::vector&,QByteArray&); + bool initParas(QByteArray&); bool run(); std::string sTriggerSource; diff --git a/subModule/Hd_3DCameraLMI_module_OutLine/Hd_3DCameraLMI_module.cpp b/subModule/Hd_3DCameraLMI_module_OutLine/Hd_3DCameraLMI_module.cpp index 03ca3e6..f0818fc 100644 --- a/subModule/Hd_3DCameraLMI_module_OutLine/Hd_3DCameraLMI_module.cpp +++ b/subModule/Hd_3DCameraLMI_module_OutLine/Hd_3DCameraLMI_module.cpp @@ -260,7 +260,7 @@ Hd_3DCameraLMI_module::~Hd_3DCameraLMI_module() ExceptionCB(-1, NULL); } -bool Hd_3DCameraLMI_module::readData(std::vector& vecPic, QByteArray& data, nlohmann::json& json) +bool Hd_3DCameraLMI_module::readData(std::vector& vecPic, QByteArray& data) { @@ -286,7 +286,7 @@ bool Hd_3DCameraLMI_module::readData(std::vector& vecPic, QByteArray& d } -bool Hd_3DCameraLMI_module::writeData(std::vector &, QByteArray &qbyte, nlohmann::json& json) +bool Hd_3DCameraLMI_module::writeData(std::vector &, QByteArray &qbyte) { string reciveid = qbyte.toStdString(); @@ -295,7 +295,7 @@ bool Hd_3DCameraLMI_module::writeData(std::vector &, QByteArray &qbyte, return true; } -bool Hd_3DCameraLMI_module::initParas(QByteArray &, nlohmann::json& json) +bool Hd_3DCameraLMI_module::initParas(QByteArray &) { bool flag = InitLmi(id); //3D初始化 m_status = flag ? OK : UnInit; diff --git a/subModule/Hd_3DCameraLMI_module_OutLine/Hd_3DCameraLMI_module.h b/subModule/Hd_3DCameraLMI_module_OutLine/Hd_3DCameraLMI_module.h index dbe2edd..9def2b0 100644 --- a/subModule/Hd_3DCameraLMI_module_OutLine/Hd_3DCameraLMI_module.h +++ b/subModule/Hd_3DCameraLMI_module_OutLine/Hd_3DCameraLMI_module.h @@ -70,14 +70,14 @@ static bool m_lmiluminanceFlag = false; #pragma endregion -class Hd_3DCameraLMI_module:public subModuleBase +class Hd_3DCameraLMI_module:public dsModuleBase { public: Hd_3DCameraLMI_module(); virtual ~Hd_3DCameraLMI_module(); - bool readData(std::vector&, QByteArray&, nlohmann::json& json); - bool writeData(std::vector&, QByteArray&, nlohmann::json& json); - bool initParas(QByteArray&, nlohmann::json& json = nlohmann::json()); + bool readData(std::vector&, QByteArray&); + bool writeData(std::vector&, QByteArray&); + bool initParas(QByteArray&); bool run(); }; diff --git a/subModule/Hd_3DCameraLMI_module_PointCloud/Hd_3DCameraLMI_module.cpp b/subModule/Hd_3DCameraLMI_module_PointCloud/Hd_3DCameraLMI_module.cpp index 16f5572..0fc0ae8 100644 --- a/subModule/Hd_3DCameraLMI_module_PointCloud/Hd_3DCameraLMI_module.cpp +++ b/subModule/Hd_3DCameraLMI_module_PointCloud/Hd_3DCameraLMI_module.cpp @@ -250,7 +250,7 @@ Hd_3DCameraLMI_module::~Hd_3DCameraLMI_module() ExceptionCB(-1, NULL); } -bool Hd_3DCameraLMI_module::readData(std::vector& vecPic, QByteArray &data, nlohmann::json& json) +bool Hd_3DCameraLMI_module::readData(std::vector& vecPic, QByteArray &data) { if (data == "connect") @@ -287,7 +287,7 @@ bool Hd_3DCameraLMI_module::readData(std::vector& vecPic, QByteArray &d } -bool Hd_3DCameraLMI_module::writeData(std::vector &, QByteArray &qbyte, nlohmann::json& json) +bool Hd_3DCameraLMI_module::writeData(std::vector &, QByteArray &qbyte) { string reciveid = qbyte.toStdString(); @@ -296,7 +296,7 @@ bool Hd_3DCameraLMI_module::writeData(std::vector &, QByteArray &qbyte, return true; } -bool Hd_3DCameraLMI_module::initParas(QByteArray &, nlohmann::json& json) +bool Hd_3DCameraLMI_module::initParas(QByteArray &) { bool flag = InitLmi(id); //3D初始化 m_status = flag ? OK : UnInit; diff --git a/subModule/Hd_3DCameraLMI_module_PointCloud/Hd_3DCameraLMI_module.h b/subModule/Hd_3DCameraLMI_module_PointCloud/Hd_3DCameraLMI_module.h index 67adf20..bf64ce6 100644 --- a/subModule/Hd_3DCameraLMI_module_PointCloud/Hd_3DCameraLMI_module.h +++ b/subModule/Hd_3DCameraLMI_module_PointCloud/Hd_3DCameraLMI_module.h @@ -71,14 +71,14 @@ static bool m_lmiluminanceFlag = false; #pragma endregion -class Hd_3DCameraLMI_module:public subModuleBase +class Hd_3DCameraLMI_module:public dsModuleBase { public: Hd_3DCameraLMI_module(); virtual ~Hd_3DCameraLMI_module(); - bool readData(std::vector&, QByteArray&, nlohmann::json& json); - bool writeData(std::vector&, QByteArray&, nlohmann::json& json); - bool initParas(QByteArray&, nlohmann::json& json = nlohmann::json()); + bool readData(std::vector&, QByteArray&); + bool writeData(std::vector&, QByteArray&); + bool initParas(QByteArray&); bool run(); }; diff --git a/subModule/Hd_602CameraModule_HIK_soft/CMakeLists.txt b/subModule/Hd_602CameraModule_HIK_soft/CMakeLists.txt new file mode 100644 index 0000000..197039f --- /dev/null +++ b/subModule/Hd_602CameraModule_HIK_soft/CMakeLists.txt @@ -0,0 +1,70 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "basler" "opencv" "mvs") +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_602CameraModule_HIK_soft/Hd_CameraModule_HIK_soft.cpp b/subModule/Hd_602CameraModule_HIK_soft/Hd_CameraModule_HIK_soft.cpp new file mode 100644 index 0000000..b3b0cfd --- /dev/null +++ b/subModule/Hd_602CameraModule_HIK_soft/Hd_CameraModule_HIK_soft.cpp @@ -0,0 +1,708 @@ +#include "Hd_CameraModule_HIK_soft.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; +MV_CAM_TRIGGER_SOURCE initTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE; +MV_CAM_TRIGGER_SOURCE currentTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE; + + +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; +} + +#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() +{ + 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); + 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; + } + } + if (MV_OK != nRet) + { + return 0; + } + return -1; +} + +bool connctDevice() +{ + index = -1; + SearchDevice(); + if (index == -1) + { + //未匹配到相机 + qDebug() << "[Waring] " << "Hd_CameraModule_HIK_soft 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_SOFTWARE); + 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 (connctDevice() == true) + { + qWarning() << "[Hd_CameraModule_HIK_soft] " << " Hd_CameraModule_HIK_soft 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_soft* create() +{ + qDebug() << "[INFO] " << "Hd_CameraModule_HIK_soft create success!" ; + return new Hd_CameraModule_HIK_soft; +} + +void destory(Hd_CameraModule_HIK_soft * ptr) +{ + if(ptr) + { + delete ptr; + ptr = nullptr; + } + qDebug() << "[INFO] " << "Hd_CameraModule_HIK_soft destory success!"; +} +//回调函数; +//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题 +void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0) +{ + double timeStart = (double)clock(); + int frameNum = 0; + cv::Mat srcImage; + + if (pFrameInfo0) + { + if (pFrameInfo0->enPixelType == PixelType_Gvsp_Mono8) + { + srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC1, pData0); + } + else if (pFrameInfo0->enPixelType == PixelType_Gvsp_BGR8_Packed) + { + srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0); + } + else if (IsColor(pFrameInfo0->enPixelType)) + { + static std::vector convertBuffer; + size_t bufSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3; + if (convertBuffer.size() < bufSize) + convertBuffer.resize(bufSize); + + MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 }; + stConvertParam.nWidth = pFrameInfo0->nWidth; + stConvertParam.nHeight = pFrameInfo0->nHeight; + stConvertParam.pSrcData = pData0; + stConvertParam.nSrcDataLen = pFrameInfo0->nFrameLen; + stConvertParam.enSrcPixelType = pFrameInfo0->enPixelType; + stConvertParam.enDstPixelType = PixelType_Gvsp_BGR8_Packed; + stConvertParam.pDstBuffer = convertBuffer.data(); + stConvertParam.nDstBufferSize = bufSize; + + MV_CC_ConvertPixelType(handle, &stConvertParam); + + srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, stConvertParam.pDstBuffer).clone(); + } + } + + if (srcImage.empty()) + { + srcImage = cv::Mat(5, 5, CV_8UC1, cv::Scalar(0)); + } + + { + std::lock_guard locker(*n_mutex); + queuepic.push_back(srcImage); + m_flag = true; + } + + double timeEnd = (double)clock(); + qDebug() << "[INFO]" << __FUNCTION__ << "time:" << (timeEnd - timeStart) << "ms" + << "--CameraName:" << QString::fromStdString(Username) + << "imgIndex:" << imgIndex << "frameNum:" << frameNum; +} + + +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_soft::Hd_CameraModule_HIK_soft() +{ + 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_soft::~Hd_CameraModule_HIK_soft() +{ + 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_soft::readData(std::vector& mat, QByteArray& data) +{ + clock_t start = clock(); + cv::Mat img; + { + std::lock_guard locker(*n_mutex); + if (queuepic.isEmpty()) + { + qCritical() << __FUNCTION__ << " line:" << __LINE__ << " srcImage is null"; + return false; + } + img = queuepic.dequeue(); + queuepic.clear(); + } + + mat.push_back(img.clone()); + clock_t stop = clock(); + qDebug() << "[INFO]" << __FUNCTION__ << " line:" << __LINE__ + << " checkImg readData -- CameraName:" << QString::fromStdString(Username) + << "--imgIndex:" << imgIndex - 1 << "timeCost->" << stop - start; + return true; +} +//实例对象把数据写入到类 +bool Hd_CameraModule_HIK_soft::writeData(std::vector &mat,QByteArray &data) +{ +#if 0 + //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(); + 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 (data == "softwareTrigger") { + MV_CC_SetCommandValue(handle, "TriggerSoftware"); + qDebug() << "[INFO] " << "TriggerSoftware"; + } + 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());*/ + +#endif + if (data == "rest_newProductIn") + { + if (queuepic.size() > 0) + { + n_mutex->lock(); + queuepic.clear(); + n_mutex->unlock(); + qWarning() << __FUNCTION__ << " line: " << __LINE__ << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << QString::fromStdString(Username); + } + if (ifRunning == true) + { + ifBreak = true; + } + imgIndex = 0; + return true; + } + else if (data == "softwareTrigger") { + MV_CC_SetCommandValue(handle, "TriggerSoftware"); + qDebug() << "[INFO] " << "TriggerSoftware"; + } + qDebug() << "Hd_CameraModule_HIK_soft::writeData::" << data; + + m_flag = false; + //Username = data.toStdString(); + return true; +} + + +//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1... +bool Hd_CameraModule_HIK_soft::initParas(QByteArray& initData) +{ + QByteArrayList valueList = initData.split('+'); + Username = valueList[0]; + imgIndex = 0; + + expourseTimeList.clear(); + gainList.clear(); + + + bool ifOk = true; + if (handle == NULL) + ifOk = connctDevice(); + 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_soft::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; + qDebug() << "[INFO] " << " waite Img" << QString::fromStdString(Username); + while (true) + { + if (moduleStatus == false || mytime++ > getImageTimeOut || ifBreak == true )//|| m_flag==true) + { + result = false; + break; + } + n_mutex->lock(); + if (queuepic.size() > 0) + { + n_mutex->unlock(); + result = true; + break; + } + n_mutex->unlock(); + QThread::msleep(1); + } + QThread::msleep(1); + + //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_soft::checkStatus() +{ + //status = moduleStatus; + return moduleStatus; +} + +void MyThread::run() +{ + MV_CC_SetCommandValue(handle, "TriggerSoftware"); +} diff --git a/subModule/Hd_602CameraModule_HIK_soft/Hd_CameraModule_HIK_soft.h b/subModule/Hd_602CameraModule_HIK_soft/Hd_CameraModule_HIK_soft.h new file mode 100644 index 0000000..1fbeb22 --- /dev/null +++ b/subModule/Hd_602CameraModule_HIK_soft/Hd_CameraModule_HIK_soft.h @@ -0,0 +1,56 @@ +#ifndef Hd_CameraModule_HIK_soft_H +#define Hd_CameraModule_HIK_soft_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_soft :public dsModuleBase +{ +public: + Hd_CameraModule_HIK_soft(); + virtual ~Hd_CameraModule_HIK_soft(); + //从类中读数据到实例对象 + 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_soft * create(); +Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_soft * ptr); +} + +#endif // Hd_CameraModule_HIK_soft_H diff --git a/subModule/Hd_CameraModule_Basler_hard/Hd_CameraModule_Basler_hard.cpp b/subModule/Hd_CameraModule_Basler_hard/Hd_CameraModule_Basler_hard.cpp index 9f538f2..99966d8 100644 --- a/subModule/Hd_CameraModule_Basler_hard/Hd_CameraModule_Basler_hard.cpp +++ b/subModule/Hd_CameraModule_Basler_hard/Hd_CameraModule_Basler_hard.cpp @@ -421,7 +421,7 @@ Hd_CameraModule_Basler_hard::~Hd_CameraModule_Basler_hard() //从类中读数据到实例对象 -bool Hd_CameraModule_Basler_hard::readData(std::vector& mat, QByteArray& data, nlohmann::json& json) +bool Hd_CameraModule_Basler_hard::readData(std::vector& mat, QByteArray& data) { int cnt = 0; while (srcImage.empty()) @@ -440,7 +440,7 @@ bool Hd_CameraModule_Basler_hard::readData(std::vector& mat, QByteArray //实例对象把数据写入到类 -bool Hd_CameraModule_Basler_hard::writeData(std::vector& mat, QByteArray& data, nlohmann::json& json) +bool Hd_CameraModule_Basler_hard::writeData(std::vector& mat, QByteArray& data) { Q_UNUSED(mat) m_flag = false; @@ -448,7 +448,7 @@ bool Hd_CameraModule_Basler_hard::writeData(std::vector& mat, QByteArra return true; } -bool Hd_CameraModule_Basler_hard::initParas(QByteArray&, nlohmann::json& json) +bool Hd_CameraModule_Basler_hard::initParas(QByteArray&) { return ConnctDevice(); } diff --git a/subModule/Hd_CameraModule_Basler_hard/Hd_CameraModule_Basler_hard.h b/subModule/Hd_CameraModule_Basler_hard/Hd_CameraModule_Basler_hard.h index 36a4887..f216d85 100644 --- a/subModule/Hd_CameraModule_Basler_hard/Hd_CameraModule_Basler_hard.h +++ b/subModule/Hd_CameraModule_Basler_hard/Hd_CameraModule_Basler_hard.h @@ -26,7 +26,7 @@ static bool m_flag = false; static cv::Mat srcImage; static bool moduleStatus = true; static int index=-1; -class Hd_CameraModule_Basler_hard :public subModuleBase +class Hd_CameraModule_Basler_hard :public dsModuleBase , public Pylon::CImageEventHandler // Allows you to get notified about images received and grab errors. , public Pylon::CConfigurationEventHandler // Allows you to get notified about device removal. , public Pylon::CCameraEventHandler @@ -36,10 +36,10 @@ public: Hd_CameraModule_Basler_hard(); virtual ~Hd_CameraModule_Basler_hard(); //从类中读数据到实例对象 - bool readData(std::vector& mat, QByteArray& data, nlohmann::json& json); + bool readData(std::vector& mat, QByteArray& data); //实例对象把数据写入到类 - bool writeData(std::vector& mat, QByteArray& data, nlohmann::json& json); - bool initParas(QByteArray&, nlohmann::json& json = nlohmann::json()); + bool writeData(std::vector& mat, QByteArray& data); + bool initParas(QByteArray&); bool run(); bool checkStatus(); diff --git a/subModule/Hd_CameraModule_Basler_soft/Hd_CameraModule_Basler_soft.cpp b/subModule/Hd_CameraModule_Basler_soft/Hd_CameraModule_Basler_soft.cpp index 0300248..a19e0da 100644 --- a/subModule/Hd_CameraModule_Basler_soft/Hd_CameraModule_Basler_soft.cpp +++ b/subModule/Hd_CameraModule_Basler_soft/Hd_CameraModule_Basler_soft.cpp @@ -429,7 +429,7 @@ Hd_CameraModule_Basler_soft::~Hd_CameraModule_Basler_soft() qDebug() << "[info] " << " delete success!"; } //从类中读数据到实例对象 -bool Hd_CameraModule_Basler_soft::readData(std::vector& mat, QByteArray& data, nlohmann::json& json) +bool Hd_CameraModule_Basler_soft::readData(std::vector& mat, QByteArray& data) { int timeCnt = 0; while (srcImage.empty()) @@ -444,7 +444,7 @@ bool Hd_CameraModule_Basler_soft::readData(std::vector& mat, QByteArray return true; } //实例对象把数据写入到类 -bool Hd_CameraModule_Basler_soft::writeData(std::vector& mat, QByteArray& data, nlohmann::json& json) +bool Hd_CameraModule_Basler_soft::writeData(std::vector& mat, QByteArray& data) { Q_UNUSED(mat) m_flag = false; @@ -452,7 +452,7 @@ bool Hd_CameraModule_Basler_soft::writeData(std::vector& mat, QByteArra return true; } -bool Hd_CameraModule_Basler_soft::initParas(QByteArray&, nlohmann::json& json) +bool Hd_CameraModule_Basler_soft::initParas(QByteArray&) { return true; return ConnctDevice(); diff --git a/subModule/Hd_CameraModule_Basler_soft/Hd_CameraModule_Basler_soft.h b/subModule/Hd_CameraModule_Basler_soft/Hd_CameraModule_Basler_soft.h index 36b321e..950d8be 100644 --- a/subModule/Hd_CameraModule_Basler_soft/Hd_CameraModule_Basler_soft.h +++ b/subModule/Hd_CameraModule_Basler_soft/Hd_CameraModule_Basler_soft.h @@ -28,7 +28,7 @@ static bool m_flag = false; static cv::Mat srcImage; static bool moduleStatus = true; static int index=-1; -class Hd_CameraModule_Basler_soft :public subModuleBase +class Hd_CameraModule_Basler_soft :public dsModuleBase , public Pylon::CImageEventHandler // Allows you to get notified about images received and grab errors. , public Pylon::CConfigurationEventHandler // Allows you to get notified about device removal. , public Pylon::CCameraEventHandler @@ -38,10 +38,10 @@ public: Hd_CameraModule_Basler_soft(); virtual ~Hd_CameraModule_Basler_soft(); //从类中读数据到实例对象 - bool readData(std::vector& mat, QByteArray& data, nlohmann::json& json); + bool readData(std::vector& mat, QByteArray& data); //实例对象把数据写入到类 - bool writeData(std::vector& mat, QByteArray& data, nlohmann::json& json); - bool initParas(QByteArray&, nlohmann::json& json = nlohmann::json()); + bool writeData(std::vector& mat, QByteArray& data); + bool initParas(QByteArray&); bool run(); bool checkStatus(); diff --git a/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.cpp b/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.cpp index a29500f..886a2e1 100644 --- a/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.cpp +++ b/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.cpp @@ -52,7 +52,7 @@ Hd_SocketModule_FinsTcp::~Hd_SocketModule_FinsTcp() } // 从类中读数据到实例对象 -bool Hd_SocketModule_FinsTcp::readData(std::vector& vec_mat, QByteArray& data, nlohmann::json&) +bool Hd_SocketModule_FinsTcp::readData(std::vector& vec_mat, QByteArray& data) { Q_UNUSED(vec_mat); QMutexLocker locker(readData_Mutex); @@ -82,7 +82,7 @@ bool Hd_SocketModule_FinsTcp::readData(std::vector& vec_mat, QByteArray } bool ifRetryCMD = false; // 实例对象把数据写入到类 -bool Hd_SocketModule_FinsTcp::writeData(std::vector& vec_mat, QByteArray& data, nlohmann::json&) +bool Hd_SocketModule_FinsTcp::writeData(std::vector& vec_mat, QByteArray& data) { Q_UNUSED(vec_mat); if (ifRetryCMD == false) @@ -502,7 +502,7 @@ bool Hd_SocketModule_FinsTcp::writeData(std::vector& vec_mat, QByteArra return true; } -bool Hd_SocketModule_FinsTcp::initParas(QByteArray& data, nlohmann::json& json) +bool Hd_SocketModule_FinsTcp::initParas(QByteArray& data) { if (data.isEmpty()) diff --git a/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.h b/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.h index 6b3b3f8..2b3f969 100644 --- a/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.h +++ b/subModule/Hd_SocketModule_FinsTcp/Hd_SocketModule_FinsTcp.h @@ -17,16 +17,16 @@ using namespace HslCommunication; using namespace cli; -class Hd_SocketModule_FinsTcp :public subModuleBase +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&, nlohmann::json& json = nlohmann::json()); - bool writeData(std::vector&, QByteArray&, nlohmann::json& json = nlohmann::json()); - bool initParas(QByteArray&, nlohmann::json& json = nlohmann::json()); + bool readData(std::vector&, QByteArray&); + bool writeData(std::vector&, QByteArray&); + bool initParas(QByteArray&); bool run(); bool decodeWriteResult(QByteArray byteArray, QVector& vec_ret); bool checkStatus(); diff --git a/subModule/Hd_VirualCamera/Hd_VirualCamera.cpp b/subModule/Hd_VirualCamera/Hd_VirualCamera.cpp index d247ab0..b8f1865 100644 --- a/subModule/Hd_VirualCamera/Hd_VirualCamera.cpp +++ b/subModule/Hd_VirualCamera/Hd_VirualCamera.cpp @@ -24,7 +24,7 @@ Hd_VirualCamera::~Hd_VirualCamera() qDebug() << "[info]" << __FUNCTION__ << "line:" << __LINE__ << " delete success!"; } -bool Hd_VirualCamera::readData(std::vector& mat, QByteArray& data, nlohmann::json& json) +bool Hd_VirualCamera::readData(std::vector& mat, QByteArray& data) { Q_UNUSED(data) @@ -51,7 +51,7 @@ bool Hd_VirualCamera::readData(std::vector& mat, QByteArray& data, nloh return true; } -bool Hd_VirualCamera::writeData(std::vector& mat, QByteArray& data, nlohmann::json& json) +bool Hd_VirualCamera::writeData(std::vector& mat, QByteArray& data) { Q_UNUSED(mat) @@ -59,7 +59,7 @@ bool Hd_VirualCamera::writeData(std::vector& mat, QByteArray& data, nlo return true; } -bool Hd_VirualCamera::initParas(QByteArray&, nlohmann::json& json) +bool Hd_VirualCamera::initParas(QByteArray&n) { return true; } @@ -69,9 +69,14 @@ bool Hd_VirualCamera::run()// n_mutex->lock(); if (cameraName == "25D-1" || cameraName == "25D-2") { vector mats; - mats.push_back(cv::imread("E:\\952Code\\CODES\\16H\\A2250709-162941554918413\\A2250709-1629415549184132.5D-H-2_16-31-32-65_Count0.bmp", -1)); - mats.push_back(cv::imread("E:\\952Code\\CODES\\16H\\A2250709-162941554918413\\A2250709-1629415549184132.5D-H-2_16-31-32-65_Count1.bmp", -1)); - mats.push_back(cv::imread("E:\\952Code\\CODES\\16H\\A2250709-162941554918413\\A2250709-1629415549184132.5D-H-2_16-31-32-65_Count2.bmp", -1)); + mats.push_back(cv::imread("I:\\952Code\\CODES\\16H\\A2250709-162941554918413\\A2250709-1629415549184132.5D-H-2_16-31-32-65_Count0.bmp", -1)); + mats.push_back(cv::imread("I:\\952Code\\CODES\\16H\\A2250709-162941554918413\\A2250709-1629415549184132.5D-H-2_16-31-32-65_Count1.bmp", -1)); + mats.push_back(cv::imread("I:\\952Code\\CODES\\16H\\A2250709-162941554918413\\A2250709-1629415549184132.5D-H-2_16-31-32-65_Count2.bmp", -1)); + queuePic.enqueue(mats); + } + else { + vector mats; + mats.push_back(cv::Mat(150,150,CV_8UC3,cv::Scalar(0,0,255))); queuePic.enqueue(mats); } n_mutex->unlock(); diff --git a/subModule/Hd_VirualCamera/Hd_VirualCamera.h b/subModule/Hd_VirualCamera/Hd_VirualCamera.h index 33ce727..9860093 100644 --- a/subModule/Hd_VirualCamera/Hd_VirualCamera.h +++ b/subModule/Hd_VirualCamera/Hd_VirualCamera.h @@ -11,14 +11,14 @@ using namespace cv; using namespace std; #pragma execution_character_set("utf-8") -class Hd_VirualCamera :public subModuleBase +class Hd_VirualCamera :public dsModuleBase { public: Hd_VirualCamera(); virtual ~Hd_VirualCamera(); - bool readData(std::vector&, QByteArray&, nlohmann::json& json); - bool writeData(std::vector&, QByteArray&, nlohmann::json& json); - bool initParas(QByteArray&, nlohmann::json& json = nlohmann::json()); + bool readData(std::vector&, QByteArray&); + bool writeData(std::vector&, QByteArray&); + bool initParas(QByteArray&); bool run(); std::string sTriggerSource;