551 lines
29 KiB
C++
551 lines
29 KiB
C++
#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);
|
||
auto detDataPtr = dManager->getDetData(m_cameraData.uuid);
|
||
if (detDataPtr->imageVec.size() == 0)
|
||
continue;
|
||
detectData.uuid = detDataPtr->uuid;
|
||
//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;
|
||
auto detDataPtr = dManager->getDetData(m_cameraData.uuid);
|
||
if (detDataPtr->imageVec.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);
|
||
detectData.uuid = m_cameraData.uuid;
|
||
//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;
|
||
} |