Files

561 lines
29 KiB
C++
Raw Permalink Normal View History

2024-09-27 15:54:45 +08:00
#include "Logic_hdataintegration.h"
2024-09-27 14:31:22 +08:00
#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); // 结果汇总的数据编码
2024-09-27 14:31:22 +08:00
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
{
2024-09-27 15:54:45 +08:00
bool ifCheckFalse = false;
2024-09-27 14:31:22 +08:00
//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; // 传递算法数据的暂时做保留
2024-09-27 14:31:22 +08:00
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);
}
2024-09-27 15:54:45 +08:00
//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];
2024-09-27 14:31:22 +08:00
//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+时间戳)
2024-09-27 14:31:22 +08:00
//detectData.SN_dataTime = vec_snData; //可以用.byte来解析
detectData.Surface = m_cameraData.Surface;
algorithmData->addDetectData(detectData);
2024-09-27 15:54:45 +08:00
//qDebug() << "myTaskNum:" << myTaskNum <<" detectData.Surface:"<< detectData.Surface;
2024-09-27 14:31:22 +08:00
myTaskNum++;
2024-09-27 15:54:45 +08:00
ifCheckFalse = true;
break;
2024-09-27 14:31:22 +08:00
}
}
}
}
}
2024-09-27 15:54:45 +08:00
if (ifCheckFalse == false)
Sleep(1);
2024-09-27 14:31:22 +08:00
//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;
2024-09-27 15:54:45 +08:00
else
{
return true;
}
2024-09-27 14:31:22 +08:00
}
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;
}