#include "Logic_hdataintegration.h" #include #include 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 vector_mats; // 汇总所有图得数据 QVector 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 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; }