V20260109-2.3.5
boost模块完善,并做对应调整。 部分逻辑修复。
|
After Width: | Height: | Size: 466 KiB |
|
After Width: | Height: | Size: 755 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 466 KiB |
|
After Width: | Height: | Size: 755 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 3.0 MiB |
|
After Width: | Height: | Size: 3.2 MiB |
|
After Width: | Height: | Size: 3.4 MiB |
|
After Width: | Height: | Size: 3.8 MiB |
|
After Width: | Height: | Size: 3.1 MiB |
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 3.3 MiB |
|
After Width: | Height: | Size: 3.2 MiB |
|
After Width: | Height: | Size: 231 KiB |
@@ -11,7 +11,7 @@
|
||||
#include <QDir>
|
||||
|
||||
#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
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
boost会创建两个连接,一个用于读数据,一个用于写数据。
|
||||
static会创建一个连接,读写共用。如果写入较慢可以调整读取间隔。
|
||||
@@ -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<cv::Mat>& 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<cv::Mat>& vec_mat, QByteArray& data) {
|
||||
QList<QByteArray> 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<QByteArray> 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<cv::Mat>& vec_mat, QByteArray& data){
|
||||
QList<QByteArray> 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<QByteArray> commands = data.split('#');
|
||||
|
||||
int threadIndex = -1;
|
||||
{
|
||||
QMutexLocker locker(&threadUseIndexMutex);
|
||||
threadIndex = threadUseIndex;
|
||||
if (++threadUseIndex >= write_JsonRpcClients.size()) threadUseIndex = 0;
|
||||
}
|
||||
for (auto& command : commands) {//分割命令
|
||||
QList<QByteArray> 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<QThread*, JsonRpcClientWorker*>& 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<std::pair<QThread*, JsonRpcClientWorker*>>(threadCount);
|
||||
write_JsonRpcClients = std::vector<std::pair<QThread*, JsonRpcClientWorker*>>(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<QPair<QString, QJsonObject>> 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;
|
||||
}
|
||||
@@ -20,6 +20,10 @@
|
||||
#include <QHostAddress>
|
||||
#include <qmap.h>
|
||||
#include <qthread.h>
|
||||
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<int> 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<QThread*, JsonRpcClientWorker*>&, const int& i);
|
||||
@@ -97,6 +109,22 @@ private:
|
||||
QQueue<QByteArray> readDataQueue;
|
||||
QMutex threadUseIndexMutex;
|
||||
int threadUseIndex = 0;
|
||||
//预打包数据
|
||||
std::atomic<int> 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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,11 @@ public:
|
||||
#pragma endregion
|
||||
#pragma region 存图相关
|
||||
QString saveObjectName;
|
||||
std::vector<std::string> oriFormat;//原图格式 如果数量不一致直接全存bmp
|
||||
//PATH_SAMPLE : "{imgSaveRootDir}/{yyyy-MM-dd}/{HH}H/{imageType}/{processResult}/{SN}/"
|
||||
//NAME_SAMPLE {SN}_{cameraName}_{index}}
|
||||
QString customPath = "", customFileName = "";
|
||||
std::vector<std::pair <QString, QString>>customImageSaveTemplateParams;
|
||||
int getResultImgSize() {
|
||||
QMutexLocker locker(&resultMutex);
|
||||
return resultImgs.size();
|
||||
@@ -155,12 +160,6 @@ public:
|
||||
oriImgs.erase(oriImgs.begin() + index);
|
||||
return true;
|
||||
}
|
||||
std::vector<std::string> oriFormat;//原图格式 如果数量不一致直接全存bmp
|
||||
|
||||
//PATH_SAMPLE : "{imgSaveRootDir}/{yyyy-MM-dd}/{HH}H/{imageType}/{processResult}/{SN}/"
|
||||
//NAME_SAMPLE {SN}_{cameraName}_{index}}
|
||||
QString customPath = "",customFileName = "";
|
||||
std::vector<std::pair <QString, QString>>customImageSaveTemplateParams;
|
||||
#pragma endregion
|
||||
#pragma region 结果相关
|
||||
bool aiDetOK = true;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -191,21 +191,6 @@ public:
|
||||
|
||||
return true;
|
||||
}
|
||||
//仅在boost模块中有效 按顺序顺序写入
|
||||
bool sequentialWriteShort(const std::vector<QByteArray>& 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<QByteArray>& 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();
|
||||
|
||||
@@ -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": {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#include <601_YH_JX.h>
|
||||
|
||||
mission* createMission() {
|
||||
return new _601_YuHan_hanqian();
|
||||
}
|
||||
void destroyMission(mission* _mission) {
|
||||
delete _mission;
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
#include <missionBase.hpp>
|
||||
#include <sxGlobal.h>
|
||||
#pragma region 算法
|
||||
#include <simpleAlgo.h>
|
||||
#include <hdevengine/HDevEngineCpp.h>
|
||||
#include <opencvPaintAlgo.hpp>
|
||||
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 <detData> data, yuHanParams* detParams, sx_581_address address) {
|
||||
try{
|
||||
|
||||
//存图数据加保存队列,加锁,避免数据访问冲突
|
||||
std::vector<std::string>defects;
|
||||
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
|
||||
@@ -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})
|
||||