diff --git a/doc/602赢合机台地址表/入壳机地址表和交互逻辑/602入壳机地址表.xlsx b/doc/602赢合机台地址表/入壳机地址表和交互逻辑/602入壳机地址表.xlsx new file mode 100644 index 0000000..e0a367b Binary files /dev/null and b/doc/602赢合机台地址表/入壳机地址表和交互逻辑/602入壳机地址表.xlsx differ diff --git a/doc/602赢合机台地址表/入壳机地址表和交互逻辑/7547431e284aa1d710515a1867104d2.jpg b/doc/602赢合机台地址表/入壳机地址表和交互逻辑/7547431e284aa1d710515a1867104d2.jpg new file mode 100644 index 0000000..dc28086 Binary files /dev/null and b/doc/602赢合机台地址表/入壳机地址表和交互逻辑/7547431e284aa1d710515a1867104d2.jpg differ diff --git a/doc/602赢合机台地址表/入壳机地址表和交互逻辑/da8068dfa37d25045cfcd13e10e4ce9.jpg b/doc/602赢合机台地址表/入壳机地址表和交互逻辑/da8068dfa37d25045cfcd13e10e4ce9.jpg new file mode 100644 index 0000000..3322f91 Binary files /dev/null and b/doc/602赢合机台地址表/入壳机地址表和交互逻辑/da8068dfa37d25045cfcd13e10e4ce9.jpg differ diff --git a/doc/602赢合机台地址表/入壳机地址表和交互逻辑/交互逻辑.jpg b/doc/602赢合机台地址表/入壳机地址表和交互逻辑/交互逻辑.jpg new file mode 100644 index 0000000..1eb827c Binary files /dev/null and b/doc/602赢合机台地址表/入壳机地址表和交互逻辑/交互逻辑.jpg differ diff --git a/doc/602赢合机台地址表/包膜机地址表和交互逻辑/602包膜机地址表 相机.xlsx b/doc/602赢合机台地址表/包膜机地址表和交互逻辑/602包膜机地址表 相机.xlsx new file mode 100644 index 0000000..81f2cd0 Binary files /dev/null and b/doc/602赢合机台地址表/包膜机地址表和交互逻辑/602包膜机地址表 相机.xlsx differ diff --git a/doc/602赢合机台地址表/包膜机地址表和交互逻辑/7547431e284aa1d710515a1867104d2.jpg b/doc/602赢合机台地址表/包膜机地址表和交互逻辑/7547431e284aa1d710515a1867104d2.jpg new file mode 100644 index 0000000..dc28086 Binary files /dev/null and b/doc/602赢合机台地址表/包膜机地址表和交互逻辑/7547431e284aa1d710515a1867104d2.jpg differ diff --git a/doc/602赢合机台地址表/包膜机地址表和交互逻辑/da8068dfa37d25045cfcd13e10e4ce9.jpg b/doc/602赢合机台地址表/包膜机地址表和交互逻辑/da8068dfa37d25045cfcd13e10e4ce9.jpg new file mode 100644 index 0000000..3322f91 Binary files /dev/null and b/doc/602赢合机台地址表/包膜机地址表和交互逻辑/da8068dfa37d25045cfcd13e10e4ce9.jpg differ diff --git a/doc/602赢合机台地址表/包膜机地址表和交互逻辑/交互逻辑.jpg b/doc/602赢合机台地址表/包膜机地址表和交互逻辑/交互逻辑.jpg new file mode 100644 index 0000000..1eb827c Binary files /dev/null and b/doc/602赢合机台地址表/包膜机地址表和交互逻辑/交互逻辑.jpg differ diff --git a/doc/602赢合机台地址表/密封钉焊接机地址表/602密封钉地址表和交互逻辑(电解液+上钉).xlsx b/doc/602赢合机台地址表/密封钉焊接机地址表/602密封钉地址表和交互逻辑(电解液+上钉).xlsx new file mode 100644 index 0000000..69718ca Binary files /dev/null and b/doc/602赢合机台地址表/密封钉焊接机地址表/602密封钉地址表和交互逻辑(电解液+上钉).xlsx differ diff --git a/doc/602赢合机台地址表/密封钉焊接机地址表/602密封钉地址表和交互逻辑(预焊满焊焊后).xlsx b/doc/602赢合机台地址表/密封钉焊接机地址表/602密封钉地址表和交互逻辑(预焊满焊焊后).xlsx new file mode 100644 index 0000000..e824343 Binary files /dev/null and b/doc/602赢合机台地址表/密封钉焊接机地址表/602密封钉地址表和交互逻辑(预焊满焊焊后).xlsx differ diff --git a/doc/602赢合机台地址表/顶盖焊侧焊地址表/顶盖焊填丝补焊地址表.xlsx b/doc/602赢合机台地址表/顶盖焊侧焊地址表/顶盖焊填丝补焊地址表.xlsx new file mode 100644 index 0000000..e6de2b4 Binary files /dev/null and b/doc/602赢合机台地址表/顶盖焊侧焊地址表/顶盖焊填丝补焊地址表.xlsx differ diff --git a/doc/602赢合机台地址表/顶盖焊侧焊地址表/顶盖焊短边地址表.xlsx b/doc/602赢合机台地址表/顶盖焊侧焊地址表/顶盖焊短边地址表.xlsx new file mode 100644 index 0000000..bfa3e12 Binary files /dev/null and b/doc/602赢合机台地址表/顶盖焊侧焊地址表/顶盖焊短边地址表.xlsx differ diff --git a/doc/602赢合机台地址表/顶盖焊侧焊地址表/顶盖焊长边地址表.xlsx b/doc/602赢合机台地址表/顶盖焊侧焊地址表/顶盖焊长边地址表.xlsx new file mode 100644 index 0000000..0a54793 Binary files /dev/null and b/doc/602赢合机台地址表/顶盖焊侧焊地址表/顶盖焊长边地址表.xlsx differ diff --git a/doc/三协CCD-PLC信号交互表(1)(3).xlsx b/doc/三协CCD-PLC信号交互表(1)(3).xlsx new file mode 100644 index 0000000..12fa46d Binary files /dev/null and b/doc/三协CCD-PLC信号交互表(1)(3).xlsx differ diff --git a/doc/顶盖焊对应数据/20260107-162323.jpg b/doc/顶盖焊对应数据/20260107-162323.jpg new file mode 100644 index 0000000..2311265 Binary files /dev/null and b/doc/顶盖焊对应数据/20260107-162323.jpg differ diff --git a/doc/顶盖焊对应数据/20260107-162333.jpg b/doc/顶盖焊对应数据/20260107-162333.jpg new file mode 100644 index 0000000..7b4ca0e Binary files /dev/null and b/doc/顶盖焊对应数据/20260107-162333.jpg differ diff --git a/doc/顶盖焊对应数据/20260107-162340.jpg b/doc/顶盖焊对应数据/20260107-162340.jpg new file mode 100644 index 0000000..812117b Binary files /dev/null and b/doc/顶盖焊对应数据/20260107-162340.jpg differ diff --git a/doc/顶盖焊对应数据/20260107-162346.jpg b/doc/顶盖焊对应数据/20260107-162346.jpg new file mode 100644 index 0000000..a3496b6 Binary files /dev/null and b/doc/顶盖焊对应数据/20260107-162346.jpg differ diff --git a/doc/顶盖焊对应数据/20260107-162354.jpg b/doc/顶盖焊对应数据/20260107-162354.jpg new file mode 100644 index 0000000..e234fe4 Binary files /dev/null and b/doc/顶盖焊对应数据/20260107-162354.jpg differ diff --git a/doc/顶盖焊对应数据/20260107-162400.jpg b/doc/顶盖焊对应数据/20260107-162400.jpg new file mode 100644 index 0000000..42daa5f Binary files /dev/null and b/doc/顶盖焊对应数据/20260107-162400.jpg differ diff --git a/doc/顶盖焊对应数据/20260107-162408.jpg b/doc/顶盖焊对应数据/20260107-162408.jpg new file mode 100644 index 0000000..71f5c7c Binary files /dev/null and b/doc/顶盖焊对应数据/20260107-162408.jpg differ diff --git a/doc/顶盖焊对应数据/20260107-162413.jpg b/doc/顶盖焊对应数据/20260107-162413.jpg new file mode 100644 index 0000000..1796b1b Binary files /dev/null and b/doc/顶盖焊对应数据/20260107-162413.jpg differ diff --git a/doc/顶盖焊对应数据/20260107-162420.jpg b/doc/顶盖焊对应数据/20260107-162420.jpg new file mode 100644 index 0000000..b95565a Binary files /dev/null and b/doc/顶盖焊对应数据/20260107-162420.jpg differ diff --git a/include/global.h b/include/global.h index bb46c32..a757714 100644 --- a/include/global.h +++ b/include/global.h @@ -11,7 +11,7 @@ #include #pragma execution_character_set("utf-8") -const std::string softwareVersion = "20260105-2.3.4"; +const std::string softwareVersion = "20260109-2.3.5"; const std::string euiJsonVersion = "1.0.6"; #define savePathToDataBase true #define GigaByte 1073741824 diff --git a/rpcModule/boost和static的区别.txt b/rpcModule/boost和static的区别.txt new file mode 100644 index 0000000..2fbaedb --- /dev/null +++ b/rpcModule/boost和static的区别.txt @@ -0,0 +1,2 @@ +boost会创建两个连接,一个用于读数据,一个用于写数据。 +static会创建一个连接,读写共用。如果写入较慢可以调整读取间隔。 \ No newline at end of file diff --git a/rpcModule/rpc_finsTcp_boost/json_rpc_server_1_1_1.exe b/rpcModule/rpc_finsTcp_boost/json_rpc_server_1_1_2.exe similarity index 95% rename from rpcModule/rpc_finsTcp_boost/json_rpc_server_1_1_1.exe rename to rpcModule/rpc_finsTcp_boost/json_rpc_server_1_1_2.exe index 8748f51..15c5020 100644 Binary files a/rpcModule/rpc_finsTcp_boost/json_rpc_server_1_1_1.exe and b/rpcModule/rpc_finsTcp_boost/json_rpc_server_1_1_2.exe differ diff --git a/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.cpp b/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.cpp index 51e657d..33a0632 100644 --- a/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.cpp +++ b/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.cpp @@ -42,11 +42,11 @@ void destory(rpc_finsTcp* ptr){ } qDebug() << " rpc_finsTcp destory success!"; } -bool ifRun = true; + rpc_finsTcp::rpc_finsTcp(){ - ifRun = true; + } -bool m_IsFinsTcp = false; + rpc_finsTcp::~rpc_finsTcp() { for (auto& client : write_JsonRpcClients) { @@ -114,21 +114,61 @@ 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); - ptr->writeCall("init", QJsonArray{ m_IP,m_port }, "finstcp"); + ptr->writeCall("init", QJsonArray{ m_IP,m_port }, "finstcp_read"); read_JsonRpcClient[data] = ptr; } - QByteArray resp = ptr->finsReadCall("excuteCli", QString(data), "finstcp"); + QByteArray resp = ptr->readCall("excuteCli", QString(data), "finstcp_read"); data = resp; // 已是解码后的原始字节 return true; } -bool ifRetryCMD = false; -// 实例对象把数据写入到类 +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 commond = m_list.at(0); + if (commond == "init") { + m_IP = m_list.at(1); + m_port = m_list.at(2).toInt(); + threadCount = m_list.at(3).toInt(); + } + else if (data.contains("read")) { + readDataQueue.append(data); + } + else { + if (data.contains("null")) + return true; + if (data.contains("Heart") == true) {//专门的发送心跳线程去发送此数据 + auto request = packageWriteRequest("excuteCli", QJsonArray{ QString(data) }, "finstcp_write"); + emit writeCallSignal(request.requestByte, request.id,data, -1); + return true; + } + //检查是不是复数命令 + QList commands = data.split('#'); -void startProcess(const QString& exePath) { + int threadIndex = -1; + { + QMutexLocker locker(&threadUseIndexMutex); + threadIndex = threadUseIndex; + if (++threadUseIndex >= write_JsonRpcClients.size()) threadUseIndex = 0; + } + auto request = packageWriteRequest("excuteCli", QJsonArray{ QString(data) }, "finstcp_write"); + emit writeCallSignal(request.requestByte, request.id, data, 0); + + // + } + return true; +} + + +void startProcess(const QString& exePath,bool enableLog = false) {//注意:日志文件很大 if (process) return; // 避免重复启动 process = new QProcess(); process->setProgram(exePath); + if (enableLog)process->setArguments({ "-l" }); process->start(); if (!process->waitForStarted(1000)) { @@ -173,53 +213,7 @@ void stopProcess() { 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 commond = m_list.at(0); - if (commond == "init") { - m_IP = m_list.at(1); - m_port = m_list.at(2).toInt(); - threadCount = m_list.at(3).toInt(); - } - else if(data.contains("read")) { - readDataQueue.append(data); - } - else { - if (data.contains("null")) - return true; - if (data.contains("Heart") == true) {//专门的发送心跳线程去发送此数据 - emit writeCallSignal("excuteCli", QJsonArray{ QString(data) }, "finstcp", -1); - return true; - } - //检查是不是复数命令 - QList commands = data.split('#'); - int threadIndex = -1; - { - QMutexLocker locker(&threadUseIndexMutex); - threadIndex = threadUseIndex; - if (++threadUseIndex >= write_JsonRpcClients.size()) threadUseIndex = 0; - } - for (auto& command : commands) {//分割命令 - QList commandSplit = command.split('_'); - if (commandSplit.size() >= 5) {//如果是指定发送线程的 - QString sendData = command.left(command.lastIndexOf("_")); - emit writeCallSignal("excuteCli", QJsonArray{ QString(sendData) }, "finstcp", m_list.at(4).toInt()); - } - else { - emit writeCallSignal("excuteCli", QJsonArray{ QString(command) }, "finstcp", threadIndex); - } - } - - // - } - return true; -} void rpc_finsTcp::initClientAndThread(std::pair& pairData,const int& i) { pairData.first = new QThread(); pairData.second = new JsonRpcClientWorker(i); @@ -265,9 +259,9 @@ void rpc_finsTcp::initHearBeatThread() { } bool rpc_finsTcp::initParas(QByteArray& data){ - startProcess("./json_rpc_server_1_1_1.exe"); + startProcess("./json_rpc_server_1_1_2.exe"); QThread::msleep(500); - write_JsonRpcClients = std::vector>(threadCount); + write_JsonRpcClients = std::vector>(1); for (int i = 0; i < write_JsonRpcClients.size(); i++) { initClientAndThread(write_JsonRpcClients[i],i); } @@ -275,15 +269,8 @@ bool rpc_finsTcp::initParas(QByteArray& data){ initHearBeatThread(); //qDebug() << "返回结果:" << result; emit initRpcClient(); - emit writeCallSignal("init", QJsonArray{ m_IP,m_port }, "finstcp", -1); - for (int i = 0; i < write_JsonRpcClients.size(); i++) - emit writeCallSignal("init", QJsonArray{ m_IP,m_port }, "finstcp", i); - //QList> batchList; - //batchList << qMakePair(QString("read_short"), params) - // << qMakePair(QString("read_bit"), QJsonObject{ {"bit", "M0"} }); - - //QJsonArray resultArray = _JsonRpcClient->batchCall(batchList); - //qDebug() << "批量结果:" << resultArray; + auto request = packageWriteRequest("init", QJsonArray{ m_IP,m_port }, "finstcp_write"); + emit writeCallSignal(request.requestByte, request.id,"init", - 1); return true; } @@ -354,7 +341,7 @@ QVariant JsonRpcClient::call(const QString& method, const QJsonArray& params, co return QVariant(); } -QByteArray JsonRpcClient::finsReadCall(const QString& method, const QString& params, const QString& module) { +QByteArray JsonRpcClient::readCall(const QString& method, const QString& params, const QString& module) { auto commands = params.split("_"); QMutexLocker locker(&mutex_); if (socket_.state() != QAbstractSocket::ConnectedState) { @@ -471,4 +458,31 @@ QJsonObject JsonRpcClient::sendRequestBuildAndAwait(const QJsonObject& req, int void JsonRpcClient::writeCall(const QString& method, const QJsonArray& params, const QString& module) { call(method, params, module); +} + +void JsonRpcClient::writeCall(const QByteArray& requestByte, const int& id) { + QMutexLocker locker(&mutex_); + if (socket_.state() != QAbstractSocket::ConnectedState) { + if (!reconnect()) { + qWarning() << "write failure: no connnection"; + return; + } + } + + QJsonObject resp; + if (socket_.write(requestByte) == -1 || !socket_.waitForBytesWritten(1000)) { + qWarning() << "write failure: failed"; + resp = QJsonObject{ {"error", QJsonObject{{"code", -1},{"message", "write failed"}}} }; + return; + } + + if (!waitAndReadResponse(id, resp, 8000)) { + qWarning() << "write failure: no response"; + return; + } + if (resp.contains("error")) { + qWarning() << "[JsonRpcClient] Error:" << QJsonDocument(resp["error"].toObject()).toJson(QJsonDocument::Compact); + return; + } + return; } \ No newline at end of file diff --git a/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.h b/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.h index 5afa870..9c8b81a 100644 --- a/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.h +++ b/rpcModule/rpc_finsTcp_boost/rpc_finsTcp.h @@ -20,6 +20,10 @@ #include #include #include +struct jsonRpcRequest { + QByteArray requestByte; + int id; +}; enum connectionStatus { None, Disconnected, @@ -31,8 +35,9 @@ public: connectionStatus _connectionStatus = None; JsonRpcClient(const QString& host = "127.0.0.1", quint16 port = 9000); void writeCall(const QString& method, const QJsonArray& params = {}, const QString& module = QString()); + void writeCall(const QByteArray& requestByte, const int& id); QVariant call(const QString& method, const QJsonArray& params = {}, const QString& module = QString()); - QByteArray finsReadCall(const QString& method, const QString& params = "", const QString& module = QString()); + QByteArray readCall(const QString& method, const QString& params = "", const QString& module = QString()); bool reconnect(); // 主动重连,或 call() 失败时调用 private: // 解析累计缓冲中的完整 JSON 帧(可能存在粘包/拆包) @@ -43,7 +48,7 @@ private: QTcpSocket socket_; QString host_; quint16 port_; - int idCounter_; + std::atomic idCounter_; QByteArray recvBuffer_; // 累计接收缓冲 }; class JsonRpcClientWorker : public QObject { @@ -59,12 +64,18 @@ public slots: _JsonRpcClient = new JsonRpcClient(); connection = _JsonRpcClient->_connectionStatus; } - void writeCallSlot(const QString& method, const QJsonArray& params, const QString& module = QString(),const int& threadIndex = -1) { + // void writeCallSlot(const QString& method, const QJsonArray& params, const QString& module = QString(),const int& threadIndex = -1) { + // if (_JsonRpcClient && threadId == threadIndex) { + // if (threadId != -1)qDebug() << params << threadId; + // _JsonRpcClient->call(method, params, module); + // } + //} + void writeCallSlot(const QByteArray& requestByte,const int& id, const QString& logString,const int& threadIndex = -1) { if (_JsonRpcClient && threadId == threadIndex) { - if (threadId != -1)qDebug() << params << threadId; - _JsonRpcClient->call(method, params, module); + if (threadId != -1)qDebug() << logString << threadId; + _JsonRpcClient->writeCall(requestByte,id); } - } + } private: int threadId = 0; JsonRpcClient* _JsonRpcClient = nullptr; @@ -81,7 +92,8 @@ public: bool run(); signals: void initRpcClient(); - void writeCallSignal(const QString& method, const QJsonArray& params, const QString& module,const int& threadId); + void writeCallSignal(const QByteArray& requestByte, const int& id, const QString& logString, const int& threadId); + //void writeCallSignal(const QString& method, const QJsonArray& params, const QString& module,const int& threadId); private: void initHearBeatThread(); void initClientAndThread(std::pair&, const int& i); @@ -97,6 +109,22 @@ private: QQueue readDataQueue; QMutex threadUseIndexMutex; int threadUseIndex = 0; + //预打包数据 + std::atomic idCounter; + jsonRpcRequest packageWriteRequest(const QString& method, const QJsonArray& params = {}, const QString& module = QString()) { + jsonRpcRequest request; + int myId = idCounter++; + QJsonObject req{ + {"jsonrpc", "2.0"}, + {"method", method}, + {"params", params}, + {"id", myId} + }; + if (!module.isEmpty()) req.insert("module", module); + request.requestByte = QJsonDocument(req).toJson(QJsonDocument::Compact); + request.id = myId; + return request; + } }; #pragma once diff --git a/rpcModule/rpc_finsTcp_static/rpc_finsTcp.cpp b/rpcModule/rpc_finsTcp_static/rpc_finsTcp.cpp index ea7e1fa..3a6548e 100644 --- a/rpcModule/rpc_finsTcp_static/rpc_finsTcp.cpp +++ b/rpcModule/rpc_finsTcp_static/rpc_finsTcp.cpp @@ -399,4 +399,4 @@ QJsonObject JsonRpcClient::sendRequestBuildAndAwait(const QJsonObject& req, int void JsonRpcClient::writeCall(const QString& method, const QJsonArray& params, const QString& module) { call(method, params, module); -} \ No newline at end of file +} diff --git a/src/core/service/detData.h b/src/core/service/detData.h index abe442f..627390b 100644 --- a/src/core/service/detData.h +++ b/src/core/service/detData.h @@ -44,6 +44,11 @@ public: #pragma endregion #pragma region 存图相关 QString saveObjectName; + std::vector oriFormat;//原图格式 如果数量不一致直接全存bmp + //PATH_SAMPLE : "{imgSaveRootDir}/{yyyy-MM-dd}/{HH}H/{imageType}/{processResult}/{SN}/" + //NAME_SAMPLE {SN}_{cameraName}_{index}} + QString customPath = "", customFileName = ""; + std::vector>customImageSaveTemplateParams; int getResultImgSize() { QMutexLocker locker(&resultMutex); return resultImgs.size(); @@ -155,12 +160,6 @@ public: oriImgs.erase(oriImgs.begin() + index); return true; } - std::vector oriFormat;//原图格式 如果数量不一致直接全存bmp - - //PATH_SAMPLE : "{imgSaveRootDir}/{yyyy-MM-dd}/{HH}H/{imageType}/{processResult}/{SN}/" - //NAME_SAMPLE {SN}_{cameraName}_{index}} - QString customPath = "",customFileName = ""; - std::vector>customImageSaveTemplateParams; #pragma endregion #pragma region 结果相关 bool aiDetOK = true; diff --git a/src/core/service/imgSaveThreadManager.h b/src/core/service/imgSaveThreadManager.h index 02fb486..c5587e1 100644 --- a/src/core/service/imgSaveThreadManager.h +++ b/src/core/service/imgSaveThreadManager.h @@ -181,7 +181,9 @@ struct saveJob { // 数据库存储线程类 class dbSaveThread : public QThread { public: - dbSaveThread(const QString& dbPath) : sqlDB(dbPath) {} + dbSaveThread(const QString& dbPath) : sqlDB(dbPath) { + sqlDB.setWALMode(false); + } void run() { try { diff --git a/src/core/service/triggerManager.h b/src/core/service/triggerManager.h index 94fd69f..96b08ef 100644 --- a/src/core/service/triggerManager.h +++ b/src/core/service/triggerManager.h @@ -191,21 +191,6 @@ public: return true; } - //仅在boost模块中有效 按顺序顺序写入 - bool sequentialWriteShort(const std::vector& write_byte) { - if (trigger == nullptr || write_byte.size() == 0) - return false; - QByteArray arraySend; - for (auto& byteArray : write_byte) { - arraySend += "write_short_" + byteArray + "#"; - } - arraySend.chop(1); - if (!trigger->writeData(vec_mat, arraySend) && trigger != nullptr) { - qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << arraySend; - return false; - } - return true; - } //useage "D9200_1" bool writeFloat(const QByteArray& write_byte) { @@ -247,21 +232,6 @@ public: return true; } - //仅在boost模块中有效 按顺序顺序写入 - bool sequentialWriteFloat(const std::vector& write_byte) { - if (trigger == nullptr || write_byte.size() == 0) - return false; - QByteArray arraySend; - for (auto& byteArray : write_byte) { - arraySend += "write_floatt_" + byteArray + "#"; - } - arraySend.chop(1); - if (!trigger->writeData(vec_mat, arraySend) && trigger != nullptr) { - qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << arraySend; - return false; - } - return true; - } #pragma endregion #pragma region 接收数据 void reciveCommond(); diff --git a/src/mission/601/601_YH_JX/581_YuHan_jixing.json b/src/mission/601/601_YH_JX/581_YuHan_jixing.json new file mode 100644 index 0000000..b5f5d64 --- /dev/null +++ b/src/mission/601/601_YH_JX/581_YuHan_jixing.json @@ -0,0 +1,117 @@ +{ + "ImageView": { + "极性检测-相机1": { + "viewer": [ + "结果图", + "原图" + ], + "xPos": 0, + "yPos": 0 + }, + "极性检测-相机2": { + "viewer": [ + "结果图", + "原图" + ], + "xPos": 1, + "yPos": 0 + }, + "极性检测-相机3": { + "viewer": [ + "结果图", + "原图" + ], + "xPos": 0, + "yPos": 1 + }, + "极性检测-相机4": { + "viewer": [ + "结果图", + "原图" + ], + "xPos": 1, + "yPos": 1 + } + }, + "backend": { + "CameraSetting": [ + { + "connectionName": "DA4203307#SOFTWARE#2000", + "dllPath": "Hd_CameraModule_HIK_General", + "imageShow": [ + "极性检测-相机1#原图" + ], + "key": "Camera1", + "oriSaveFormat": [ + "bmp" + ] + }, + { + "connectionName": "DA4203340#SOFTWARE#2000", + "dllPath": "Hd_CameraModule_HIK_General", + "imageShow": [ + "极性检测-相机2#原图" + ], + "key": "Camera2", + "oriSaveFormat": [ + "bmp" + ] + }, + { + "connectionName": "DA4203352#SOFTWARE#2000", + "dllPath": "Hd_CameraModule_HIK_General", + "imageShow": [ + "极性检测-相机3#原图" + ], + "key": "Camera3", + "oriSaveFormat": [ + "bmp" + ] + }, + { + "connectionName": "DA4203322#SOFTWARE#2000", + "dllPath": "Hd_CameraModule_HIK_General", + "imageShow": [ + "极性检测-相机4#原图" + ], + "key": "Camera4", + "oriSaveFormat": [ + "bmp" + ] + } + ], + "Triggers": { + "heartBeatCmd": [ + "writeHeart_short_D750_1" + ], + "initStr": "init_192.168.1.50_9600_128_6_0", + "key": "finstcp", + "moduleName": "rpc_finsTcp", + "readAllCmd": [ + "read_byte_D400_200" + ], + "heartBeatIntervalMS": 800, + "sleepIntervalMS": 1 + }, + "handleAiModel": { + "cls": {}, + "det": {}, + "seg": {} + }, + "imgSaveBasePath": "D://极性检测CCD存图", + "missionDllPath": "581_YuHan_jixing", + "missionSettings": { + "极性": { + "极性判定启用": true + }, + "通用设置": { + "存储Cls图": true, + "存储Seg图": true, + "存储原图": true, + "存储结果图": true + } + } + }, + "softwareTile": "极性检测", + "sublUiSetting": {} +} \ No newline at end of file diff --git a/src/mission/601/601_YH_JX/601_YH_JX.cpp b/src/mission/601/601_YH_JX/601_YH_JX.cpp new file mode 100644 index 0000000..cebba2a --- /dev/null +++ b/src/mission/601/601_YH_JX/601_YH_JX.cpp @@ -0,0 +1,8 @@ +#include <601_YH_JX.h> + +mission* createMission() { + return new _601_YuHan_hanqian(); +} +void destroyMission(mission* _mission) { + delete _mission; +} \ No newline at end of file diff --git a/src/mission/601/601_YH_JX/601_YH_JX.h b/src/mission/601/601_YH_JX/601_YH_JX.h new file mode 100644 index 0000000..98afe49 --- /dev/null +++ b/src/mission/601/601_YH_JX/601_YH_JX.h @@ -0,0 +1,146 @@ +#include +#include +#pragma region 算法 +#include +#include +#include +using namespace HDevEngineCpp; +#pragma endregion +class yuHanParams { +public: + + bool isTong = true; +}; +void putSnAndDetTime(cv::Mat& Paint, const std::string& sn, int textSize = 30, const std::string& extraText = "") { + TextRendererZH textPainter(Paint.cols, Paint.rows, textSize); + textPainter.putText(Paint, "SN:" + sn + QDateTime::currentDateTime().toString().toStdString() + extraText, cv::Point(0, 0), cv::Scalar(0, 255, 0)); +} +bool halconProcess(cv::Mat& sourceImg, cv::Mat& Paint) { + try { + HDevEngineCpp::HDevProcedure proc("YH_Color_Inspection"); + HDevEngineCpp::HDevProcedureCall procedureCall(proc); + HObject in_Image = MatToHObject(sourceImg); + procedureCall.SetInputIconicParamObject("in_Image", in_Image);//设置输入图像类变量 + procedureCall.Execute();//执行halcon程序 + HTuple out_ColorType; + HTuple out_Flag; + out_ColorType = procedureCall.GetOutputCtrlParamTuple("out_ColorType");//获取输出图像类变量 + out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量 + //相机2 OK为铜 NG为铝 + if (out_Flag.D() == 1) + { + if (out_ColorType.D() == 1)//铜 + { + //cv::putText(Paint, "OK", cv::Point(0, 550), 2, 10, cv::Scalar(0, 255, 0), 10); + return true; + } + else//铝 + { + //cv::putText(Paint, "NG", cv::Point(0, 550), 2, 10, cv::Scalar(0, 0, 255), 10); + return false; + } + } + else + { + //cv::putText(Paint, "NG", cv::Point(0, 550), 2, 10, cv::Scalar(0, 0, 255), 10); + return false; + } + } + catch (HDevEngineCpp::HDevEngineException& ex) { + + std::cout << "HDevEngineException: " << ex.Message() << std::endl; \ + qDebug() << "HDevEngineException: " << ex.Message(); \ + } + catch (HalconCpp::HException& ex) { + + std::cout << "Halcon Exception Caught!" << std::endl; \ + std::cout << "Error Code: " << ex.ErrorCode() << std::endl; \ + std::cout << "Error Message: " << ex.ErrorMessage() << std::endl; \ + qDebug() << "Halcon Exception Caught!"; \ + qDebug() << "Error Code: " << ex.ErrorCode(); \ + qDebug() << "Error Message: " << ex.ErrorMessage(); \ + } +} +bool jixingjiance(std::shared_ptr data, yuHanParams* detParams, sx_581_address address) { + try{ + + //存图数据加保存队列,加锁,避免数据访问冲突 + std::vectordefects; + bool jiXingEnable = data->service->_paramSyncManager->get("极性", "极性判定启用", true).toBool(); + QByteArray plcResult = "1"; + cv::Mat sourceImg; + data->getOriImg(0).copyTo(sourceImg); + cv::Mat Paint; + sourceImg.copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + putSnAndDetTime(Paint, data->SNcode, 50, "极性判定启用:" + std::to_string(jiXingEnable) + data->cameraKeyName); + bool isNG = halconProcess(sourceImg, Paint); + + TextRendererZH textPainter(Paint.cols, Paint.rows, 300); + if (isNG)//OK + { + textPainter.putText(Paint, "OK", cv::Point(100, 50), cv::Scalar(0, 255, 0)); + } + else + { + textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 0, 255)); + defects.push_back("极性错误"); + data->halconOK = false; + if(jiXingEnable == true) + plcResult = "2"; + } + if (jiXingEnable == false) + plcResult = "1";//强制OK + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈 + data->insertResultImg(Paint); + data->service->_missionResultHandle->toBarChart(data->SNcode, defects); + return true; + + } + CATCH_EXCEPTIONS + + qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + cv::Mat Paint; + data->getOriImg(0).copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + TextRendererZH textPainter(Paint.cols, Paint.rows, 15); + textPainter.putText(Paint, "NG", cv::Point(1000, 50), cv::Scalar(0, 255, 0)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->insertResultImg(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈 + return true; +} +class _601_YuHan_hanqian : public mission { +public: + _581_SX_Single_triggerTemplate< yuHanParams> in_lv_top_1; + _581_SX_Single_triggerTemplate< yuHanParams> in_lv_down_2; + _581_SX_Single_triggerTemplate< yuHanParams> in_tong_top_3; + _581_SX_Single_triggerTemplate< yuHanParams> in_tong_down_4; + + yuHanParams tongDetParams; + yuHanParams lvDetParams; + void onConfigReloaded() { + HDevEngineCpp::HDevEngine myEngine; + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_628_1.hdpl"); + + lvDetParams.isTong = false; + } + bool initCustom() { +#pragma region 注册触发器回调 + in_lv_top_1.init("Camera1", "极性检测-相机1", { { 400, 1,{410},"401","402",-1} }, 1, &lvDetParams, _serviceManager, bridge, jixingjiance); + in_lv_down_2.init("Camera2", "极性检测-相机2", { { 430, 1,{440},"431","432",-1 }}, 1, & lvDetParams, _serviceManager, bridge, jixingjiance); + in_tong_top_3.init("Camera3", "极性检测-相机3", { { 460,1,{470},"461","462",-1} }, 1, &tongDetParams, _serviceManager, bridge, jixingjiance); + in_tong_down_4.init("Camera4", "极性检测-相机4", { { 490, 1,{500},"491","492",-1 }}, 1, & tongDetParams, _serviceManager, bridge, jixingjiance); + +#pragma endregion + return true; + } +}; + + + + + +#pragma once \ No newline at end of file diff --git a/src/mission/601/601_YH_JX/CMakeLists.txt b/src/mission/601/601_YH_JX/CMakeLists.txt new file mode 100644 index 0000000..599e8f5 --- /dev/null +++ b/src/mission/601/601_YH_JX/CMakeLists.txt @@ -0,0 +1,78 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + ${PROJECT_ROOT_PATH}/src/core + ${PROJECT_ROOT_PATH}/src/core/handleAi + ${PROJECT_ROOT_PATH}/src/core/service + ${PROJECT_ROOT_PATH}/src/core/sql + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) +add_compile_options(/utf-8) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC OFF) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED) + +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ${PROJECT_ROOT_PATH}/include/interface.h + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Sql + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME}) +message( " header files "${HEAD_FILES})