Files
eUi/include/sxGlobal.h
T
RCiRoot 97462c8aab On main: V20260416-2.5.1
增加halconGuard类,用于防止halcon算法的输入输出和程序不一致而引起的报错,并且会检查算法文件是否存在,如不存在则会弹窗提示。
增加handleAiGpuThreadGuard类,用于防止因重复调用同一个模型而引起的报错,并且支持不停机更新模型,支持初始化时检测模型文件是否存在。
增加内存占用显示控件。
用户管理增加root权限,默认密码为dseuiroot,模型热更新时需要此权限。
支持缓存界面上的检测数据。
相机模块新增在回调后的指定时间没有取图时则清空容器的功能。
增加等待结果汇总功能,在启用时同一个SN的图片会等待总结果后再进行存图。
存图线程修改为多线程编码,单线程储存,提高IO效率。并且增加根据内存占用的百分比更新存图逻辑的功能,默认占用超过70%不储存OK原图,超过80%不储存原图,超过90%时不储存所有图片。
2026-04-26 12:25:13 +08:00

164 lines
7.9 KiB
C++

#pragma once
#include <missionBase.hpp>
#include <share.h>
#include <QObject>
#include <opencvPaintAlgo.hpp>
#include <paramSpecifications.h>
#pragma region 基础函数
#define CATCH_EXCEPTIONS \
catch (HDevEngineCpp::HDevEngineException& ex) { \
std::cout << "HDevEngineException: " << ex.Message() << std::endl; \
qCritical() << "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; \
qCritical() << "Halcon Exception Caught!"; \
qCritical() << "Error Code: " << ex.ErrorCode(); \
qCritical() << "Error Message: " << ex.ErrorMessage(); \
} \
catch (const std::exception& e) { \
std::cout << "Caught exception: " << e.what() << std::endl; \
qCritical() << "Caught exception: " << e.what(); \
}\
catch (...) {\
std::cout << "Caught exception: unexcepted"; \
qCritical() << "Caught exception: unexcepted"; \
}
struct sx_581_address {
int triggerAddr = -1;
int triggerValue = -1;
std::vector<int> snAddr;
QByteArray completeAddr = "-1";
QByteArray resultAddr = "-1";
int valueOffsetAddr = -1;
};
class detParams {
public:
};
#pragma endregion
//算法回调函数需要包含完整的算法流程以及发送信号,发送ui图表,捕获异常,处理异常等操作
//并且注意 异常可能会导致运行不到发送信号的函数,请在处理异常时发送异常结果
static bool generalAlgoTest(std::shared_ptr <detData> data, detParams* _detParams, sx_581_address address) {
try {
qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start";
///////////////////取图//处理//////////////////
if (data->getOriImgSize() < 1)
{
qCritical() << "图片数量不满足要求:" << data->getOriImgSize();
return false;
}
auto oriImgs = data->getOriImgVec();
if (oriImgs[0].rows == 100) {
cv::Mat Paint;
oriImgs[0].copyTo(Paint);
cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2);
return false;
}
cv::Mat Paint;
QMutex paintMutex;
clock_t start, finish;
start = clock();
cv::Mat src1 = oriImgs[0];
if (src1.channels() != 3)
cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR);
else
src1.copyTo(Paint);
TextRendererZH textPainter(Paint.cols, Paint.rows, 15);
textPainter.putText(Paint, "划伤", cv::Point(10,10), cv::Scalar(0, 255, 0));
cv::putText(Paint, "pos:" + data->additional["触发地址"].toString().toStdString(), cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 0, 0), 2);
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果
data->insertResultImg(Paint);
return true;
}
CATCH_EXCEPTIONS
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送异常结果
return false;
}
template <typename paramTemplte>
//此类适用于单相机多触发地址单次判断的情况,比如密封钉,三协机台
//例触发地址有4个,输入信号为 1 0 0 1 则按顺序触发1和4的地址拍照检测,2和3不做处理
class _581_SX_Single_triggerTemplate {
public:
paramTemplte* _detParams;
detCallbackChain<paramTemplte, sx_581_address>* generalDet;
std::string cameraName;
QString viewerName;
std::vector<sx_581_address>address;
int oneTriggerCaptrueTimes = 1;
/// <summary>
/// 初始化
/// </summary>
/// <param name="cameraNameIn">相机名</param>
/// <param name="viewerNameIN">窗口名</param>
/// <param name="startAddr">开始地址</param>
/// <param name="triggerCount">触发信号数</param>
/// <param name="oneTriggerCaptrueTimes">单次触发调用几次相机模块</param>
/// <param name="detParamsIn">参数输入</param>
/// <param name="_serviceManagerIn">默认</param>
/// <param name="bridgeIn">默认</param>
/// <param name="_processAlgoCallback">算法函数</param>
/// <param name="resultHandlerIn"></param>
void init(std::string cameraNameIn, QString viewerNameIN, std::vector<sx_581_address> addressIN, int oneTriggerCaptrueTimesIN,
paramTemplte* detParamsIn, ServiceManager* _serviceManagerIn, bSignalHub* bridgeIn,
typename detCallbackChain<paramTemplte, sx_581_address>::processAlgoCallback _processAlgoCallback,
QString saveObjectNameIN = "") {
viewerName = viewerNameIN;
cameraName = cameraNameIn;
_serviceManager = _serviceManagerIn;
_detParams = detParamsIn;
bridge = bridgeIn;
address = addressIN;
saveObjectName = saveObjectNameIN;
oneTriggerCaptrueTimes = oneTriggerCaptrueTimesIN;
generalDet = new detCallbackChain<paramTemplte, sx_581_address>(_serviceManager, _detParams, bridge);
generalDet->registerProcessAlgoCallback(_processAlgoCallback);
//单次触发器条件
for (int i = 0; i < addressIN.size(); i++) {
//注册单触发器 触发地址置1时触发
_serviceManager->_triggerManager->registerCallback(address[i].triggerAddr, address[i].triggerValue, [this, i](int triggerPos, int triggerValue, QByteArray& byteArray) {
evaluate(i, byteArray);}, "");
}
for (int i = 0; i < address.size(); i++) {
_serviceManager->_triggerManager->registerPlcValueViewer(viewerNameIN + "_" + QString::number(i),
{ {QString::number(address[i].triggerAddr) + "触发",address[i].triggerAddr },
{address[i].completeAddr + "反馈",address[i].completeAddr.toInt()},
{address[i].resultAddr + "结果",address[i].resultAddr.toInt()},
{QString::number(address[i].valueOffsetAddr) + "数值1",address[i].valueOffsetAddr},
{QString::number(address[i].valueOffsetAddr + 2) + "数值2",address[i].valueOffsetAddr + 2},
{QString::number(address[i].valueOffsetAddr + 4) + "数值3",address[i].valueOffsetAddr + 4} });
}
}
//获取图片并进行检测
void evaluate(int batteryOffset, QByteArray& byteArray) {
_serviceManager->_triggerManager->writeShort("D" + QByteArray::number(address[batteryOffset].triggerAddr) + "_0");//触发信号清零
std::string sn;
for (auto& snAddr : address[batteryOffset].snAddr) {
sn.append(_serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snAddr, true, -1));
if (snAddr != address[batteryOffset].snAddr.back()) {
sn.append("_");
}
}
auto camera = _serviceManager->_cameraManager->getCamera(cameraName);//获取相机
//camera->clearCache();//清除缓存 三协机台此功能不通用 按需启动
std::shared_ptr <detData> data = _serviceManager->_detDataManager->createDetData(
QString::fromStdString(cameraName), sn, oneTriggerCaptrueTimes, camera->config.oriSaveFormat);//创建数据包
data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图"));
data->saveObjectName = saveObjectName;
camera->captureImage(data);//拍照
generalDet->asyncProcess(data, address[batteryOffset], ("D" + address[batteryOffset].completeAddr + "_1"));//处理算法 并在取到图片后发送完成信号
qDebug() << data->uuid << "bind->" << QString::fromStdString(cameraName) << "|" << QString::fromStdString(sn) << "|" << address[batteryOffset].triggerAddr << "->" << address[batteryOffset].triggerValue;
}
private:
QString saveObjectName = "";
bSignalHub* bridge;
ServiceManager* _serviceManager = nullptr;
};