Files
ds-628/BaseModules/Hd_LogicDll_module/Logic_hdataintegration.cpp
T
2025-04-25 23:23:17 +08:00

561 lines
29 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Logic_hdataintegration.h"
#include <QDir>
#include <QDateTime>
void Logic_hdataintegration::set_Logic_taskthread(Logic_taskthread* taskthread)
{
my_Logic_taskthread = taskthread;
}
Logic_hdataintegration::~Logic_hdataintegration()
{
ifRun = false;
wait(100);
//exit();
}
void Logic_hdataintegration::init(QJsonObject obj)
{
m_stationKey = obj.value("工站名").toString();
if (m_stationKey.isEmpty())
{
qCritical() << "[Error] " << " m_stationKey is null!";
return;
}
m_moduleobj_array = obj.value("算法列表").toArray();
for (auto val = 0; val < m_moduleobj_array.size(); val++)
{
//判断obj解析的algorithmlist下面的"算法名称"对应的值,是否和静态变量相等
//静态变量m_algorithmKey为:Logic_processtask.cpp里调用setAlgorithmKey将配置文件的stationList下的algorithmlist的“key"值赋值过来;
QString m_key = m_moduleobj_array.at(val).toObject().value("算法名称").toString();
if (m_algorithmKey == m_key)
{
algorithmObject = m_moduleobj_array.at(val).toObject();
}
}
}
void Logic_hdataintegration::run()
{
//m_mutex单独的锁;
//一个算法模块,对应多个相机的情况,不加锁会丢数据
QMutexLocker locker(m_mutex);
clock_t start, stop;
start = clock();
int checkTimes=0;
ifCheckTimeOut = false;
checkResult = false;
//qDebug() << "m_algorithmKey::" << m_algorithmKey << " m_stationKey::" << m_stationKey <<" addDataNums::"<< addDataNums;
int maxTime = 0;
while (maxTime < maxCheckTime + 100 && ifRun==true)//Logic_taskthread最长需要7-8ms,8张图需要60ms左右;
{
maxTime++;
checkResult = triggerConditionList();
if (checkResult == true)
break;
if (ifalwaysRun == false && checkResult == true )
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " m_algorithmKey::" << m_algorithmKey << " Logic_hdataintegration checkResult true ::" ;
//设置一定延时,避免程序卡死
Sleep(1);
//stop = clock();
if(maxCheckTime > 0)
if (maxTime > maxCheckTime)
ifCheckTimeOut = true;
}
if (checkResult == false && maxCheckTime > 0)
{
ifCheckTimeOut = true;
triggerConditionList();
}
stop = clock();
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << " m_algorithmKey::" << m_algorithmKey << " Logic_hdataintegration cut Time ::" << stop - start ;
}
//根据是否有"汇总-触发信号",判断是汇总还是检测模块
//汇总:结果SN信息、汇总条件对应的检测结果,加到对应的算法执行容器类HAlgorithmExecData;
//检测:将SN数据HSnData、图片数据HCameraData,加到对应的算法执行容器类HAlgorithmExecData ;
// HAlgorithmExecData ,在Logic_taskthread里运行
//配置文件的,每一个"检测条件列表"创建一个此线程。
bool Logic_hdataintegration::triggerConditionList()
{
try
{
{
QString m_key = algorithmObject.value("算法名称").toString();
double time_Start = (double)clock();
for (int val = 0; val < trigger_condition.size(); val++)
{
QJsonObject task_obj = trigger_condition.at(val).toObject();
if (task_obj.contains("and"))
{
QJsonArray and_condition = task_obj.value("and").toArray();
int m_index = 0;
bool check_flag = false;
queue_vector_sn.clear();
//拍照面描述
QString Surface;
for (int iii = 0; iii < and_condition.size(); iii++)
{
QJsonObject and_task_obj = and_condition.at(iii).toObject();
QString trigger_signal = and_task_obj.value("汇总-触发信号").toString();
if (trigger_signal.isEmpty())
{
if (checkConditionData(and_task_obj, "and"))
{
m_index++;
}
else
{
if (ifCheckTimeOut == true)
{
timeOutCondition[iii] = 1;
m_index++;
}
else break;
}
}
else
{
//有触发信号的,是汇总算法,在Logic_myiothread里已经匹配过了
//if (trigger_signal == station_list.value(m_stationKey)->get_trigger_signal())//trigger_signal_condition_name)
{
m_index++;
}
}
if (m_index == and_condition.size())
{
check_flag = true;
}
}
// 满足条件去执行
if (check_flag)
{
std::vector<cv::Mat> vector_mats; // 汇总所有图得数据
QVector<QByteArray> vector_byte; // 汇总所有算法结果的数据
QString m_trigger_signal = nullptr;
//软件汇总;
//多机汇总,需要SN
testData detectData;
for (int iii = 0; iii < and_condition.size(); iii++)
{
QJsonObject get_task_obj = and_condition.at(iii).toObject();
QString m_type = get_task_obj.value("汇总-触发类型").toString();
QString m_and_key = get_task_obj.value("检测/汇总-触发条件").toString();
//都为空
//QString summary_index = get_task_obj.value("summary_index").toString();
QString trigger_signal = get_task_obj.value("汇总-触发信号").toString(); //作用和signal相同
if (trigger_signal != "")
m_trigger_signal = trigger_signal;
//5-2的相机7-8,一张图,对应2个产品;一张图的算法结果,输出2个;
QString algorithm_result_index = get_task_obj.value("汇总-算法结果列表序号").toString();
QJsonArray listArray = get_task_obj.value("检测/汇总-序号列表").toArray();
for (int lA = 0; lA < listArray.size(); lA++)
{
QString task_index = listArray.at(lA).toString(); // 只有一个下标
QString myStationKey = get_task_obj.value("汇总-工站名称").toString();
if (m_type.contains("data"))
{
HAlgorithmData* algorithm_ptr;
if (myStationKey.isEmpty())
algorithm_ptr = station_list.value(m_stationKey)->getAlgorithmData(m_and_key);
else algorithm_ptr = station_list.value(myStationKey)->getAlgorithmData(m_and_key);
if (algorithm_ptr)
{
//加入SN检查
//都为空
//if (summary_index.isEmpty())
QByteArray result_byte;
if (timeOutCondition[iii] == 0)
{
result_byte = algorithm_ptr->getAlgorithmData(SN_dataTime, task_index, algorithm_result_index);
if (result_byte.isEmpty())
{
result_byte = get_task_obj.value("超时插入NG数据").toString().toLocal8Bit();
}
}
else
{
result_byte = get_task_obj.value("超时插入NG数据").toString().toLocal8Bit();
timeOutCondition[iii] = 0; //超时标志
}
vector_byte.append(result_byte);
}
}
else if (m_type.contains("signal"))
{
continue;
}
else
{
//当触发信号是空时,表示为检测,如2D+3D检测
if (trigger_signal.isEmpty())
{
HCameraData* camera_ptr = station_list.value(m_stationKey)->getCameraData(m_and_key);
if (camera_ptr)
{
SnCameraData m_cameraData = camera_ptr->getCameraImageData(task_index);
if (m_cameraData.vector_mat.size() == 0)
continue;
//vector_mats.insert(vector_mats.end(), m_cameraData.vector_mat.begin(), m_cameraData.vector_mat.end()); // 追加
//使用深拷贝,避免图像重复情况
for (int i = 0; i < m_cameraData.vector_mat.size(); i++)
{
cv::Mat img = cv::Mat();
m_cameraData.vector_mat.at(i).copyTo(img);
detectData.dstImageMat.push_back(img);
}
if (lastMat.data)
{
//判断和上一张图,是否重复
int dataLength = detectData.dstImageMat[0].total() * detectData.dstImageMat[0].elemSize();
bool res = false;
if (lastMat.total() * lastMat.elemSize() == dataLength)
{
res = memcmp(lastMat.data, detectData.dstImageMat[0].data, dataLength) == 0;
if (res == true)
{
std::cout << " 1 detectData ,res == true !!!!!" << std::endl;
qDebug() << __FUNCTION__ << " line: " << __LINE__ << " 1 detectData ,res == true !!!!!";
}
}
}
lastMat = detectData.dstImageMat[0];
if (queue_vector_sn.isEmpty())
queue_vector_sn = m_cameraData.vector_snData;
else
{
//0731,检查SN
for (int sn_index = 0; sn_index < m_cameraData.vector_snData.size(); sn_index++)
if (queue_vector_sn[sn_index] != m_cameraData.vector_snData[sn_index])
qCritical() << __FUNCTION__ << " line: " << __LINE__ << " vector_snData not match: "
<< queue_vector_sn[sn_index] << " != " << m_cameraData.vector_snData[sn_index];
}
if (Surface == "")
Surface = m_cameraData.Surface;
detectData.cameraName.append(m_and_key); //相机key
detectData.task_index.append(task_index);
}
}
}
}
}
HAlgorithmExecData* algorithmData = station_list.value(m_stationKey)->getAlgorithmExecData(m_algorithmKey);
if (algorithmData == nullptr)
{
qCritical() << __FUNCTION__ << " line: " << __LINE__ << " getAlgorithmExecData is null! m_key:" << m_key;
return false;
}
if (queue_vector_sn.isEmpty() && SN_dataTime != "")
queue_vector_sn.append(SN_dataTime);
//软件汇总;
//多机汇总,需要SN
//testData detectData;
if (m_trigger_signal.isEmpty())
{
//提取所有条件去执行
//detectData.cameraName = m_key; //算法名称
//detectData.task_index = ""; // and 不需要任务下标;只考虑汇总,2D+3D检测?
}
else
{
QJsonObject get_task_obj = and_condition.at(0).toObject();
if (!get_task_obj.isEmpty())
{
detectData.cameraName.append(get_task_obj.value("汇总-触发信号").toString());
//实际为空,汇总算法
detectData.task_index.append(get_task_obj.value("检测/汇总-序号列表").toArray().at(0).toString()); // 只提取第一个下标 此处-7使用
}
}
if (queue_vector_sn.isEmpty())
{
qCritical() << __FUNCTION__ << " line: " << __LINE__ << " queue_vector_sn.isEmpty()!";
return false;
}
//927下料工位,一个信号,2个产品情况??
//每个算法,只读一个sn,即只对应一个产品;
QString reaultDir = savePath;
for (int ve = 0; ve < detectData.cameraName.size(); ve++)
reaultDir += "," + detectData.cameraName[ve] + "_" + detectData.task_index[ve];
if (queue_vector_sn.size() > 0)
{
if (queue_vector_sn[0].isEmpty())
std::cout << "queue_vector_sn[0].isEmpty()" << std::endl;
for (int ve = 0; ve < queue_vector_sn.size(); ve++)
reaultDir += "," + queue_vector_sn[ve];
}
else
reaultDir += ",errSN_errDataTime";
reaultDir += ",";
for (int ve = 0; ve < vector_byte.size(); ve++)
reaultDir += "#" + vector_byte[ve];
if (reaultDir.contains(",,"))
{
std::cout << "queue_vector_sn[0].isEmpty()" << std::endl;
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " reaultDir.contains(',,');queue_vector_sn[0].isEmpty()" << m_algorithmKey;
}
detectData.SN_dataTime = queue_vector_sn;
//or检测:保存路径,拍照面描述,相机key_第几张图,SN_时间戳
//and检测:保存路径,拍照面描述,相机key_第几张图,相机key_第几张图,SN_时间戳,SN_时间戳
//汇总:保存路径,触发信号_序号列表0,,SN_时间戳
detectData.byteArray = reaultDir.toLocal8Bit();// encodeData(vector_byte); // 结果汇总的数据编码
detectData.dstImageMat = vector_mats; // 不做图片汇总
detectData.Surface = Surface;
algorithmData->addDetectData(detectData);
for (int sss = 0; sss < queue_vector_sn.size(); sss++)
if (queue_vector_sn[sss].contains("null"))
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " m_algorithmKey::" << m_algorithmKey << " addDataNums::" << addDataNums++;
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " m_algorithmKey::" << m_algorithmKey << " addDataNums::" << addDataNums++;
return true;
//SN_dataTime = "";
}
}
else
{
bool ifCheckFalse = false;
//or
for (int val = 0; val < trigger_condition.size(); val++)
{
QJsonObject task_obj = trigger_condition.at(val).toObject();
//if (checkConditionData(task_obj))
{
QJsonArray or_condition = task_obj.value("or").toArray();
for (int iii = 0; iii < or_condition.size(); iii++)
{
QJsonObject get_task_obj = or_condition.at(iii).toObject();
QString key = get_task_obj.value("检测/汇总-触发条件").toString();
if (key != cameraKey)//只检查匹配的相机
continue;
clock_t start, stop;
start = clock();
bool or_conditionFlag = checkConditionData(get_task_obj, "or");
stop = clock();
double cutTime = stop - start;
if (ifalwaysRun == false && cutTime > 3)
qDebug() << __FUNCTION__ << " line:" << __LINE__ << "m_algorithmKey::" << m_algorithmKey << " Logic_hdataintegration getCameraImageData cut Time ::" << stop - start;
start = clock();
//qDebug() << "m_algorithmKey::" << m_algorithmKey << " Logic_hdataintegration checkConditionData Time ::" << stop - start;
if (or_conditionFlag == false)
continue;
// 提取图片和数据
QByteArray byteArray; // 传递算法数据的暂时做保留
QStringList index_list;
HCameraData* camera_ptr = station_list.value(m_stationKey)->getCameraData(key);
/* stop = clock();
cutTime = stop - start;
if (ifalwaysRun == false && cutTime > 3)
qDebug() << "m_algorithmKey::" << m_algorithmKey << " Logic_hdataintegration getCameraData cut Time ::" << stop - start;
start = clock();*/
for (int i = 0; i < get_task_obj.value("检测/汇总-序号列表").toArray().size(); i++)
{
if (camera_ptr)
{
QString task_index = get_task_obj.value("检测/汇总-序号列表").toArray().at(i).toString();
SnCameraData m_cameraData = camera_ptr->getCameraImageData(task_index); //偶尔需要26-30ms
QVector<QString> vec_snData = m_cameraData.vector_snData;
if (m_cameraData.vector_mat.empty())
continue;
HStationData* stationAlgorithmData = station_list.value(m_stationKey);
HAlgorithmExecData* algorithmData = stationAlgorithmData->getAlgorithmExecData(m_algorithmKey);
testData detectData;
detectData.cameraName.append(key); //相机key
detectData.task_index.append(task_index);
for (int i = 0; i < m_cameraData.vector_mat.size(); i++)
{
cv::Mat img = cv::Mat();
m_cameraData.vector_mat.at(i).copyTo(img);
detectData.dstImageMat.push_back(img);
}
//if (lastMat.data)
//{
// //判断和上一张图,是否重复
// int dataLength = detectData.dstImageMat[0].total() * detectData.dstImageMat[0].elemSize();
// bool res = false;
// if (lastMat.total() * lastMat.elemSize() == dataLength)
// {
// res = memcmp(lastMat.data, detectData.dstImageMat[0].data, dataLength) == 0;
// if (res == true)
// {
// std::cout << " 1 detectData ,res == true !!!!!" << std::endl;
// qDebug() << __FUNCTION__ << " line: " << __LINE__ << " 1 detectData ,res == true !!!!!";
// }
// }
//}
//lastMat = detectData.dstImageMat[0];
//detectData.dstImageMat = m_cameraData.vector_mat;
QString reaultDir = savePath + "," + m_cameraData.Surface + "," + key + "_" + task_index;
if (vec_snData.size() > 0)
{
for (int ve = 0; ve < vec_snData.size(); ve++)
reaultDir += "," + vec_snData[ve];
}
else
reaultDir += ",errSN_errDataTime";
detectData.byteArray = reaultDir.toLocal8Bit();// encodeSnData(vec_snData); //type:3;len:数据长度;data:数据内容(SN+时间戳)
//detectData.SN_dataTime = vec_snData; //可以用.byte来解析
detectData.Surface = m_cameraData.Surface;
algorithmData->addDetectData(detectData);
//qDebug() << "myTaskNum:" << myTaskNum <<" detectData.Surface:"<< detectData.Surface;
myTaskNum++;
ifCheckFalse = true;
break;
}
}
}
}
}
if (ifCheckFalse == false)
Sleep(1);
//0711修改
//if (my_Logic_taskthread->m_stoprun >=1) //还在运行中
if (myTaskNum == 0)
return false;
return true;
}
}
//double time_End = (double)clock();
//qDebug() << "[or]" << "Time:" << (time_End - time_Start) / 1000.0 << "s";
}
} catch (QString ev) {
qCritical() << __FUNCTION__ << " line: " << __LINE__ << " ev:" << ev;
}
return false;
}
//检查算法条件
bool Logic_hdataintegration::checkConditionData ( QJsonObject obj, QString andOr)
{
if ( obj.isEmpty() )
{
qCritical() << __FUNCTION__ << " line:" << __LINE__<<" check data is null!";
return false;
}
QString m_key = obj.value("检测/汇总-触发条件").toString();
QString trigger_signal = obj.value("汇总-触发信号").toString();
QString m_type = obj.value("汇总-触发类型").toString();
QString algorithm_result_index = obj.value("汇总-算法结果列表序号").toString();
//QString summary_index = obj.value("summary_index").toString();
QString NG_data = obj.value("超时插入NG数据").toString();
QString myStationKey = obj.value("汇总-工站名称").toString();
{
for (int i = 0; i < obj.value("检测/汇总-序号列表").toArray().size(); i++)
{
QString index = obj.value("检测/汇总-序号列表").toArray().at(i).toString();
if (m_key.isEmpty() || index.isEmpty())
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " key or index is null!";
return false;
}
if (myStationKey.isEmpty())
myStationKey = m_stationKey;
// 做数据检查
if (m_type.contains("data"))
{
//"检测/汇总-触发条件": "algorithm1","检测/汇总-序号列表": ["offline-camera1_0"]
if (station_list.value(myStationKey)->checkAlgorithmResultData(m_key, index,SN_dataTime) !=true) // 结果汇总中的index 存储的格式为 camera1_0
return false;
}
else
{
if (andOr == "or")
{
if (station_list.value(myStationKey)->checkCameraData(m_key, index) != true) // 相机取图中的index 存储格式为 0
continue;
else
{
return true;
}
}
else
{
if (station_list.value(myStationKey)->checkCameraData(m_key, index) != true) // 相机取图中的index 存储格式为 0
return false;
}
}
}
if (andOr == "or")
{
return false;
}
else
{
return true;
}
}
return false;
}
//未使用
//判断是否包含相机key
bool Logic_hdataintegration::ifContainsCamera(QString cameraKey)
{
for (int val = 0; val < trigger_condition.size(); val++)
{
QJsonObject task_obj = trigger_condition.at(val).toObject();
/*if (!run_flag)
{
return false;
}*/
//if (checkConditionData(task_obj)) //是否要检查?
{
//val++;
if (task_obj.contains("and"))
{
QJsonArray and_condition = task_obj.value("and").toArray();
for (int iii = 0; iii < and_condition.size(); iii++)
{
bool and_conditionFlag = true;
QJsonObject get_task_obj = and_condition.at(iii).toObject();
QString camera_key = get_task_obj.value("检测/汇总-触发条件").toString();
if (camera_key == cameraKey)
return true;
}
}
else
{
QJsonArray or_condition = task_obj.value("or").toArray();
for (int iii = 0; iii < or_condition.size(); iii++)
{
bool or_conditionFlag = true;
QJsonObject get_task_obj = or_condition.at(iii).toObject();
QString camera_key = get_task_obj.value("检测/汇总-触发条件").toString();
if (camera_key == cameraKey)
return true;
}
}
}
}
return false;
}