diff --git a/include/qtBridge.h b/include/qtBridge.h index f21c3c1..780e8b9 100644 --- a/include/qtBridge.h +++ b/include/qtBridge.h @@ -12,6 +12,7 @@ #include #include +#include enum initStatus{ NotInit, InitFailure, @@ -28,7 +29,7 @@ struct showImgPack{ }; enum valueType { - finsInt, + finsShort, finsFloat }; @@ -37,6 +38,7 @@ struct PlcValueViewerStruct { QString valueName; int valueAddr; valueType type; + QVariant value = -999; }; class qtFuncBridge : public QObject { @@ -90,7 +92,7 @@ signals: //排障 void runCommand_addBtn(const QString& btnName, const QString& tip, const QString& uuid); void runCommand_addPlcValueViewer(QString groupName, std::vector> viewerNameAndAddress); - void runCommand_refeshPlcValueViewer(int address,int value); + void runCommand_refeshPlcValueViewer(int address,QString value); //性能监测 void sendTriggerManagerLoopData(int loopCounterPerMin,int maxInterval); diff --git a/include/yhGlobal.h b/include/yhGlobal.h index f4b6e3b..bac7b8d 100644 --- a/include/yhGlobal.h +++ b/include/yhGlobal.h @@ -85,6 +85,8 @@ static bool generalAlgoTest(std::shared_ptr data, detParams* _detParam 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->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.123");//发送数据1 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2)+ "_0.456");//发送数据2 data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 data->service->_missionResultHandle->handleAllResult(data->SNcode, !defects.size() > 0, defects);//发送图标操作 data->resultImgs.push_back(Paint); @@ -156,9 +158,9 @@ public: { {"触发",address[i].triggerAddr }, {"反馈",address[i].completeAddr.toInt()}, {"结果",address[i].resultAddr.toInt()}, - {"数值1",address[i].valueOffsetAddr}, - {"数值2",address[i].valueOffsetAddr + 2}, - {"数值3",address[i].valueOffsetAddr + 4} }); + {"数值1",address[i].valueOffsetAddr,finsFloat}, + {"数值2",address[i].valueOffsetAddr + 2,finsFloat}, + {"数值3",address[i].valueOffsetAddr + 4,finsFloat} }); } } //获取图片并进行检测 diff --git a/src/Core/back/triggerManager.h b/src/Core/back/triggerManager.h index 2a99925..bcc48c2 100644 --- a/src/Core/back/triggerManager.h +++ b/src/Core/back/triggerManager.h @@ -19,6 +19,34 @@ class detThreadManager; class detDataManager; class lightSourceManager; class detProcess; + +// 将此静态函数加入到类 triggerManager 的合适位置(如 private 部分) +static float readFinsFloatFromQByteArray(const QByteArray& buf, int startByteIndex, bool highLowConversion) { + if (startByteIndex < 0 || startByteIndex + 3 >= buf.size()) { + return std::numeric_limits::quiet_NaN(); + } + + auto u8 = [&buf](int i)->uint8_t { return static_cast(buf.at(i)); }; + uint8_t b0 = u8(startByteIndex + 0); + uint8_t b1 = u8(startByteIndex + 1); + uint8_t b2 = u8(startByteIndex + 2); + uint8_t b3 = u8(startByteIndex + 3); + + // highLowConversion == true -> 不交换,顺序 b0 b1 b2 b3 + // highLowConversion == false -> 每个 16-bit word 内高低位需要互换,得到 b1 b0 b3 b2 + if (!highLowConversion) { + std::swap(b0, b1); + std::swap(b2, b3); + } + + uint32_t u = (static_cast(b0) << 24) | + (static_cast(b1) << 16) | + (static_cast(b2) << 8) | + (static_cast(b3)); + float f; + std::memcpy(&f, &u, sizeof(f)); + return f; +} //防止重复触发 class triggerLockerT { public: @@ -396,7 +424,7 @@ public: void registerPlcValueViewer(const QString& groupName, const std::vector& viewerDatas) { for (auto& data : viewerDatas) { if (data.valueAddr < 0)continue; - plcValueViewerDatas.push_back({ data.valueAddr, -999 }); + plcValueViewerDatas.push_back(data); } std::vector> forShow; for (auto& data : viewerDatas) { @@ -404,19 +432,27 @@ public: } emit bridge->runCommand_addPlcValueViewer(groupName, forShow); } + void checkPlcValueViewer(readAllStruct& _struct, QByteArray& byteArray) { QMutexLocker locer(&mutex); for (auto& data : plcValueViewerDatas) { - int checkPos = (data.first - _struct.startPos) * 2 + 1; - if(checkPos< byteArray.size() && checkPos >= 0) - if (byteArray.at(checkPos) != data.second) { - data.second = byteArray.at(checkPos); - emit bridge->runCommand_refeshPlcValueViewer(data.first, data.second); + int checkPos = (data.valueAddr - _struct.startPos) * 2 + 1; + if (checkPos < byteArray.size() && checkPos >= 0) { + QVariant newValue; + if (data.type == finsFloat) { + newValue = readFinsFloatFromQByteArray(byteArray, checkPos, false); } + else + newValue = byteArray.at(checkPos); + if (newValue != data.value) { + data.value = newValue; + emit bridge->runCommand_refeshPlcValueViewer(data.valueAddr, data.value.toString()); + } + } } } - std::vector>plcValueViewerDatas; + std::vectorplcValueViewerDatas; private: QElapsedTimer lostConnectionCountTimer,lostConnectionRePrintTimer; qtFuncBridge* bridge; diff --git a/src/launcher/GUI/uiModule/uiModule_runCommand.h b/src/launcher/GUI/uiModule/uiModule_runCommand.h index 754baf7..ca2e0c2 100644 --- a/src/launcher/GUI/uiModule/uiModule_runCommand.h +++ b/src/launcher/GUI/uiModule/uiModule_runCommand.h @@ -97,9 +97,9 @@ public slots: auto widget = new plcValueViewer(groupName, viewerNameAndAddress, plcViwerLineedits); plcValueViewerLayout->addWidget(widget->widget,Qt::AlignTop); } - void refreshPlcValueViewer(int address, QVariant value) { + void refreshPlcValueViewer(int address, QString value) { for (auto& lineedit : plcViwerLineedits[address]) { - lineedit->setText(value.toString()); + lineedit->setText(value); } } private: diff --git a/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h b/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h index e96f91d..ba9d31d 100644 --- a/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h +++ b/src/mission/581-Mfd_yh_mh_hh/581-Mfd.h @@ -1,334 +1,297 @@ #include #include -#include "cal_disJiao.h" class mfd_detParams { public: int biaoding = 0; }; #pragma region 算法 - #include #include #include -# include "HalconCpp.h" -using namespace HDevEngineCpp; -using namespace HalconCpp; - -static bool ManHan(std::shared_ptr data, mfd_detParams* _detParams, yh_581_address address){ - HObject ho_in_image; - - HTuple hv_out_standardPar; - HTuple hv_out_flat; - HTuple in_ProductType; - HTuple hv_out_disLeftVertical; - HTuple hv_out_LeftVerticalLinePar; - HTuple hv_out_disLeftLevel; - HTuple hv_out_LeftLevelLinePar; - HTuple hv_out_disRightVertical; - HTuple hv_out_RightVerticalLinePar; - HTuple hv_out_disRightLevel; - HTuple hv_out_RightLevelLinePar; - cv::Mat img = cv::imread("D:/CCD/2025-10-04-19-57-14-928_04QCB6CJ27501JFA40006167_camera4_3.bmp", -1); - cv::cvtColor(img, img, cv::COLOR_BGR2GRAY); - cv::threshold(img, img, 60, 255, cv::THRESH_BINARY); - std::vector> contours; - cv::findContours(img, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); - if (contours.size() != 0) - { - for (int j = 0; j < contours.size(); j++) - { - cv::Rect rect = cv::boundingRect(contours[j]); - - if (rect.width > 1000 && rect.height > 900 ) - { - return true; - } - } - } - //cv::cvtColor(img, img, cv::COLOR_GRAY2BGR); - ho_in_image = MatToHObject(img); - in_ProductType = "181-2"; - cal_distanceJiao_4(ho_in_image, in_ProductType, &hv_out_standardPar, &hv_out_flat, - &hv_out_disLeftVertical, &hv_out_LeftVerticalLinePar, &hv_out_disLeftLevel, - &hv_out_LeftLevelLinePar, &hv_out_disRightVertical, &hv_out_RightVerticalLinePar, - &hv_out_disRightLevel, &hv_out_RightLevelLinePar); - int falg = hv_out_flat.I(); - return true; - std::map sqlMapData; - sqlMapData["项目"] = "上钉"; - sqlMapData["相机"] = "相机" + address.triggerAddr; - qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; - - ///////////////////取图//处理////////////////// - if (data->oriImgs.size() != 1) - { - qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); - return false; - } - if (data->oriImgs[0].rows == 100) { - cv::Mat Paint; - data->oriImgs[0].copyTo(Paint); - cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); - return false; - } - +void exceptionResume(std::shared_ptr data, mfd_detParams* _detParams, yh_581_address address, QString why = "") { + qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode) << why; cv::Mat Paint; - cv::Mat src1 = data->oriImgs[0]; - if (src1.channels() != 3) - cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR); - else - src1.copyTo(Paint); - //处理算法 -#pragma region halcon处理 - QString singal_sign = data->additional["触发地址"].toString(); - std::string cameraNumberStr = "1", FixtureNumber = "1"; + data->oriImgs[0].copyTo(Paint); + if (Paint.channels() == 1) + cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR); + TextRendererZH textPainter(Paint.cols, Paint.rows, 100); + textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 255, 0)); + cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5); + data->resultImgs.push_back(Paint); + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//结果反馈 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.01");//结果反馈 + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.01");//结果反馈 +} +using namespace HDevEngineCpp; +static bool ManHan(std::shared_ptr data, mfd_detParams* _detParams, yh_581_address address){ + try { + data->_saveMode = saveMode::oneFile; + std::map sqlMapData; + sqlMapData["项目"] = "满焊"; + sqlMapData["相机"] = "相机" + address.triggerAddr; + qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; - if (singal_sign.contains("20000")) { - cameraNumberStr = "1"; - FixtureNumber = "1"; - } - else if (singal_sign.contains("20002")) { - cameraNumberStr = "1"; - FixtureNumber = "2"; - } - else if (singal_sign.contains("20200")) { - cameraNumberStr = "2"; - FixtureNumber = "3"; - } - else if (singal_sign.contains("20202")) { - cameraNumberStr = "2"; - FixtureNumber = "4"; - } - else if (singal_sign.contains("20400")) { - cameraNumberStr = "3"; - FixtureNumber = "5"; - } - else if (singal_sign.contains("20402")) { - cameraNumberStr = "3"; - FixtureNumber = "6"; - } - else if (singal_sign.contains("20600")) { - cameraNumberStr = "4"; - FixtureNumber = "7"; - } - else if (singal_sign.contains("20602")) { - cameraNumberStr = "4"; - FixtureNumber = "8"; - } - HalconCpp::HObject in_Image = MatToHObject(src1); - HDevEngineCpp::HDevProcedure proc("_9_manhan"); - HDevProcedureCall procedureCall(proc); - procedureCall.SetInputIconicParamObject("in_Image", in_Image); - procedureCall.SetInputCtrlParamTuple("in_ProductionType", _detParams->biaoding); - procedureCall.SetInputCtrlParamTuple("in_CameraNumber", HTuple(cameraNumberStr.c_str())); - procedureCall.SetInputCtrlParamTuple("in_FixtureNumber", HTuple(FixtureNumber.c_str())); - procedureCall.SetInputCtrlParamTuple("in_FilePath1", HTuple("./halconFiles/template_manHan/")); - procedureCall.SetInputCtrlParamTuple("in_FilePath2", HTuple("./halconFiles/base_manHan/")); - procedureCall.Execute(); - // *output(HTuple) : < / c> - // *out_Circle, 圆心坐标(y, x, radius) < / c > - // * out_Flag, 算法执行成功标志位, 0 : 算法执行失败 1 : 算法执行成功< / c> - // *out_OffsetX : 模组X轴的补偿量(mm) < / c > - // *out_OffsetY : 模组Y轴的补偿量(mm) < / c > - HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle"); - HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); - HTuple out_OffsetX = procedureCall.GetOutputCtrlParamTuple("out_OffsetX"); - HTuple out_OffsetY = procedureCall.GetOutputCtrlParamTuple("out_OffsetY"); -#pragma endregion - int outFlag = out_Flag.D(); - //qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << ",放钉算法结果;" << out_Flag[0].D(); - TextRendererZH textPainter(Paint.cols, Paint.rows, 150); - if (outFlag == 1) { //-1为失败,无结果 - //先处理数据 - double offsetX; - double offsetY; - offsetX = 0 - out_OffsetX.D(); - offsetY = 0 - out_OffsetY.D(); - //if (singal_sign.contains("D18800")) - // offsetX -= 0.2; - //else if (singal_sign.contains("D19000")) { - // offsetX -= 0.15; - // offsetY += 0.1; - //} - //else if (singal_sign.contains("D19400")) { - // offsetY -= 0.2; - //} - if (abs(offsetX) >= 6000 || abs(offsetY) >= 6000) + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } + cv::Mat Paint; + cv::Mat src1 = data->oriImgs[0]; + + if (src1.channels() != 3) + cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR); + else + src1.copyTo(Paint); + //处理算法 +#pragma region halcon处理 + std::string cameraNumberStr = "1", FixtureNumber = "1"; + + if (address.triggerAddr == 20000) { + cameraNumberStr = "1"; + FixtureNumber = "1"; + } + else if (address.triggerAddr == 20002) { + cameraNumberStr = "1"; + FixtureNumber = "2"; + } + else if (address.triggerAddr == 20200) { + cameraNumberStr = "2"; + FixtureNumber = "3"; + } + else if (address.triggerAddr == 20202) { + cameraNumberStr = "2"; + FixtureNumber = "4"; + } + else if (address.triggerAddr == 20400) { + cameraNumberStr = "3"; + FixtureNumber = "5"; + } + else if (address.triggerAddr == 20402) { + cameraNumberStr = "3"; + FixtureNumber = "6"; + } + else if (address.triggerAddr == 20600) { + cameraNumberStr = "4"; + FixtureNumber = "7"; + } + else if (address.triggerAddr == 20602) { + cameraNumberStr = "4"; + FixtureNumber = "8"; + } + data->SNcode = "相机" + cameraNumberStr + "孔" + FixtureNumber + "_" + data->SNcode; + HalconCpp::HObject in_Image = MatToHObject(src1); + HDevEngineCpp::HDevProcedure proc("_9_manhan"); + HDevProcedureCall procedureCall(proc); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_ProductionType", _detParams->biaoding); + procedureCall.SetInputCtrlParamTuple("in_CameraNumber", HTuple(cameraNumberStr.c_str())); + procedureCall.SetInputCtrlParamTuple("in_FixtureNumber", HTuple(FixtureNumber.c_str())); + procedureCall.SetInputCtrlParamTuple("in_FilePath1", HTuple("./halconFiles/template_manHan/")); + procedureCall.SetInputCtrlParamTuple("in_FilePath2", HTuple("./halconFiles/base_manHan/")); + procedureCall.Execute(); + // *output(HTuple) : < / c> + // *out_Circle, 圆心坐标(y, x, radius) < / c > + // * out_Flag, 算法执行成功标志位, 0 : 算法执行失败 1 : 算法执行成功< / c> + // *out_OffsetX : 模组X轴的补偿量(mm) < / c > + // *out_OffsetY : 模组Y轴的补偿量(mm) < / c > + HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + HTuple out_OffsetX = procedureCall.GetOutputCtrlParamTuple("out_OffsetX"); + HTuple out_OffsetY = procedureCall.GetOutputCtrlParamTuple("out_OffsetY"); +#pragma endregion + int outFlag = out_Flag.D(); + //qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << ",放钉算法结果;" << out_Flag[0].D(); + TextRendererZH textPainter(Paint.cols, Paint.rows, 150); + textPainter.putText(Paint, "相机:" + cameraNumberStr + " 孔" + FixtureNumber, cv::Point(50, 0), cv::Scalar(0, 255, 0)); + if (outFlag == 1) { //-1为失败,无结果 + //先处理数据 + double offsetX = 0 - out_OffsetX.D() * 1000;//和激光交流后要求我们*1000 + double offsetY = 0 - out_OffsetY.D() * 1000; + double X_Circle = out_Circle[1].D(); + double Y_Circle = out_Circle[0].D(); + + + if (abs(offsetX) >= 6000 || abs(offsetY) >= 6000) + { + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123");//发送偏移Y + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送结果 + qDebug() << __FUNCTION__ << " line:" << __LINE__ << " 满焊X偏移abs(resultData[0]) >= 6000,may err,set 0"; + data->halconOK = false; + } + else { + sqlMapData["偏移X"] = offsetX; + sqlMapData["偏移Y"] = offsetY; + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(offsetX));//发送偏移X + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(offsetY));//发送偏移Y + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + data->halconOK = true; + } + //圆及十字 + cv::circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 20); + cv::line(Paint, cv::Point(out_Circle[1].D() - 300, out_Circle[0].D()), cv::Point(out_Circle[1].D() + 300, out_Circle[0].D()), cv::Scalar(0, 255, 0), 15); + cv::line(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D() - 300), cv::Point(out_Circle[1].D(), out_Circle[0].D() + 300), cv::Scalar(0, 255, 0), 15); + + textPainter.putText(Paint, "X偏移:" + std::to_string(offsetX), cv::Point(50, 150), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "Y偏移:" + std::to_string(offsetY), cv::Point(50, 350), cv::Scalar(0, 255, 0)); + //textPainter.putText(Paint, "圆心X坐标:" + std::to_string(X_Circle), cv::Point(50, 150), cv::Scalar(0, 255, 0)); + //textPainter.putText(Paint, "圆心Y坐标:" + std::to_string(offsetY), cv::Point(50, 350), cv::Scalar(0, 255, 0)); + + + } + else { + data->halconOK = false; data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123");//发送偏移Y data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送结果 - qDebug() << __FUNCTION__ << " line:" << __LINE__ << " 满焊X偏移abs(resultData[0]) >= 6000,may err,set 0"; - data->halconOK = false; + textPainter.putText(Paint, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255)); + } + + if (data->halconOK == true) { + textPainter.putText(Paint, "OK", cv::Point(50, 550), cv::Scalar(0, 255, 0)); + sqlMapData["结果"] = "OK"; } else { - sqlMapData["偏移X"] = offsetX; - sqlMapData["偏移Y"] = offsetY; - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(offsetX));//发送偏移X - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(offsetY));//发送偏移Y - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - data->halconOK = true; + textPainter.putText(Paint, "NG", cv::Point(50, 500), cv::Scalar(0, 0, 255)); + sqlMapData["结果"] = "NG"; } - //圆及十字 - cv::circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 20); - cv::line(Paint, cv::Point(out_Circle[1].D() - 300, out_Circle[0].D()), cv::Point(out_Circle[1].D() + 300, out_Circle[0].D()), cv::Scalar(0, 255, 0), 15); - cv::line(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D() - 300), cv::Point(out_Circle[1].D(), out_Circle[0].D() + 300), cv::Scalar(0, 255, 0), 15); - - textPainter.putText(Paint, "X偏移:" + std::to_string(offsetX), cv::Point(50, 150), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "Y偏移:" + std::to_string(offsetY), cv::Point(50, 350), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "相机:" + cameraNumberStr, cv::Point(50, 0), cv::Scalar(0, 255, 0)); - + data->service->_csvWriter->addData(QString::fromStdString(data->SNcode), sqlMapData); + data->resultImgs.push_back(Paint); + return true; } - else{ - data->halconOK = false; - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123");//发送偏移Y - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送结果 - textPainter.putText(Paint, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255)); - } - - if (data->halconOK == true) { - textPainter.putText(Paint, "OK", cv::Point(50, 550), cv::Scalar(0, 255, 0)); - sqlMapData["结果"] = "OK"; - } - else { - textPainter.putText(Paint, "NG", cv::Point(50, 500), cv::Scalar(0, 0, 255)); - sqlMapData["结果"] = "NG"; - } - data->service->_csvWriter->addData(QString::fromStdString(data->SNcode), sqlMapData); - data->resultImgs.push_back(Paint); - - return true; + CATCH_EXCEPTIONS + exceptionResume(data, _detParams, address, "异常"); } static bool YuHan(std::shared_ptr data, mfd_detParams* _detParams, yh_581_address address){ - qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start"; - std::map sqlMapData; - sqlMapData["项目"] = "预焊"; - sqlMapData["相机"] = "相机" + address.triggerAddr; - ///////////////////取图//处理////////////////// - if (data->oriImgs.size() != 1){ - qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); - return false; - } - if (data->oriImgs[0].rows == 100) { - cv::Mat Paint; - data->oriImgs[0].copyTo(Paint); - cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2); - return false; - } + try { + data->_saveMode = saveMode::oneFile; + std::map sqlMapData; + sqlMapData["项目"] = "预焊"; + sqlMapData["相机"] = "相机" + address.triggerAddr; + ///////////////////取图//处理////////////////// + if (data->oriImgs.size() != 1) { + qCritical() << "图片数量不满足要求:" << data->oriImgs.size(); + return false; + } - cv::Mat Paint; - cv::Mat src1 = data->oriImgs[0]; - if (src1.channels() != 3) - cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR); - else - src1.copyTo(Paint); - //处理算法 + cv::Mat Paint; + cv::Mat src1 = data->oriImgs[0]; + //src1 = cv::imread("D://ceshi/15H/1/333.bmp",-1); + if (src1.channels() != 3) + cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR); + else + src1.copyTo(Paint); + //处理算法 #pragma region halcon处理 - QString singal_sign = address.triggerAddr; - std::string cameraNumberStr = "1", FixtureNumber = "1"; - if (singal_sign.contains("19600")) { - cameraNumberStr = "1"; - FixtureNumber = "1"; - } - else if (singal_sign.contains("19602")) { - cameraNumberStr = "1"; - FixtureNumber = "3"; - } - else if (singal_sign.contains("19800")) { - cameraNumberStr = "2"; - FixtureNumber = "2"; - } - else if (singal_sign.contains("19802")) { - cameraNumberStr = "2"; - FixtureNumber = "4"; - } - HDevEngineCpp::HDevProcedure proc("_9_yuhan"); - HalconCpp::HObject in_Image = MatToHObject(src1); - HDevProcedureCall procedureCall(proc); - procedureCall.SetInputIconicParamObject("in_Image", in_Image); - procedureCall.SetInputCtrlParamTuple("in_ProductionType", 0); - procedureCall.SetInputCtrlParamTuple("in_Resolution", HTuple(0.00749026)); - procedureCall.SetInputCtrlParamTuple("in_CameraNumber", HTuple(cameraNumberStr.c_str())); - procedureCall.SetInputCtrlParamTuple("in_FixtureNumber", HTuple(FixtureNumber.c_str())); - procedureCall.SetInputCtrlParamTuple("in_FilePath1", HTuple("./halconFiles/yuhan_template/")); - procedureCall.SetInputCtrlParamTuple("in_FilePath2", HTuple("./halconFiles/yuhan_base/")); - procedureCall.Execute(); - // *output(HTuple) : < / c> - // *out_Circle, 圆心坐标(y, x, radius) < / c > - // * out_Flag, 算法执行成功标志位, 0 : 算法执行失败 1 : 算法执行成功< / c> - // *out_OffsetX : 模组X轴的补偿量(mm) < / c > - // *out_OffsetY : 模组Y轴的补偿量(mm) < / c > - HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle"); - HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); - HTuple out_OffsetX = procedureCall.GetOutputCtrlParamTuple("out_OffsetX"); - HTuple out_OffsetY = procedureCall.GetOutputCtrlParamTuple("out_OffsetY"); + std::string cameraNumberStr = "1", FixtureNumber = "1"; + if (address.triggerAddr == 19600) { + cameraNumberStr = "1"; + FixtureNumber = "1"; + } + else if (address.triggerAddr == 19602) { + cameraNumberStr = "1"; + FixtureNumber = "3"; + } + else if (address.triggerAddr == 19800) { + cameraNumberStr = "2"; + FixtureNumber = "2"; + } + else if (address.triggerAddr == 19802) { + cameraNumberStr = "2"; + FixtureNumber = "4"; + } + data->SNcode = "相机" + cameraNumberStr + "孔" + FixtureNumber + "_" + data->SNcode; + HDevEngineCpp::HDevProcedure proc("_9_yuhan"); + HalconCpp::HObject in_Image = MatToHObject(src1); + HDevProcedureCall procedureCall(proc); + procedureCall.SetInputIconicParamObject("in_Image", in_Image); + procedureCall.SetInputCtrlParamTuple("in_ProductionType", 0); + procedureCall.SetInputCtrlParamTuple("in_Resolution", HTuple(0.0069699)); + procedureCall.SetInputCtrlParamTuple("in_CameraNumber", HTuple(cameraNumberStr.c_str())); + procedureCall.SetInputCtrlParamTuple("in_FixtureNumber", HTuple(FixtureNumber.c_str())); + procedureCall.SetInputCtrlParamTuple("in_FilePath1", HTuple("./halconFiles/template_yuhan/")); + procedureCall.SetInputCtrlParamTuple("in_FilePath2", HTuple("./halconFiles/base_yuhan/")); + procedureCall.SetInputCtrlParamTuple("in_NailType", 1);//1:平钉 2:凹钉; + procedureCall.Execute(); + // *output(HTuple) : < / c> + // *out_Circle, 圆心坐标(y, x, radius) < / c > + // * out_Flag, 算法执行成功标志位, 0 : 算法执行失败 1 : 算法执行成功< / c> + // *out_OffsetX : 模组X轴的补偿量(mm) < / c > + // *out_OffsetY : 模组Y轴的补偿量(mm) < / c > + HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle"); + HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag"); + HTuple out_OffsetX = procedureCall.GetOutputCtrlParamTuple("out_OffsetX"); + HTuple out_OffsetY = procedureCall.GetOutputCtrlParamTuple("out_OffsetY"); #pragma endregion - int outFlag = out_Flag.D(); - //qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << ",放钉算法结果;" << out_Flag[0].D(); - TextRendererZH textPainter(Paint.cols, Paint.rows, 150); - if (outFlag == 1) { //-1为失败,无结果 - double offsetX; - double offsetY; - offsetX = 0 - out_OffsetX.D(); - offsetY = 0 - out_OffsetY.D(); - //if (singal_sign.contains("D18800")) - // offsetX -= 0.2; - //else if (singal_sign.contains("D19000")) { - // offsetX -= 0.15; - // offsetY += 0.1; - //} - //else if (singal_sign.contains("D19400")) { - // offsetY -= 0.2; - //} - if (abs(offsetX) >= 6000 || abs(offsetY) >= 6000){ + int outFlag = out_Flag.D(); + //qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << ",放钉算法结果;" << out_Flag[0].D(); + TextRendererZH textPainter(Paint.cols, Paint.rows, 150); + textPainter.putText(Paint, "相机:" + cameraNumberStr + " 孔位" + FixtureNumber, cv::Point(50, 0), cv::Scalar(0, 255, 0)); + if (outFlag == 1) { //-1为失败,无结果 + double offsetX = out_OffsetX.D(); + double offsetY = out_OffsetY.D(); + //if (address.triggerAddr == 19600) + // offsetX -= 0.2; + //else if (address.triggerAddr == 19602) { + // offsetX -= 0.15; + // offsetY += 0.1; + //} + //else (address.triggerAddr == 19800) { + // offsetY -= 0.2; + //} + if (abs(offsetX) >= 6000 || abs(offsetY) >= 6000) { + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123");//发送偏移Y + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送结果 + qDebug() << __FUNCTION__ << " line:" << __LINE__ << " 预焊X偏移abs(resultData[0]) >= 6000,may err,set 0"; + data->halconOK = false; + } + else { + sqlMapData["偏移X"] = offsetX; + sqlMapData["偏移Y"] = offsetY; + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(offsetX));//发送偏移X + data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(offsetY));//发送偏移Y + data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 + data->halconOK = true; + } + //圆及十字 + cv::circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 20); + cv::line(Paint, cv::Point(out_Circle[1].D() - 300, out_Circle[0].D()), cv::Point(out_Circle[1].D() + 300, out_Circle[0].D()), cv::Scalar(0, 255, 0), 15); + cv::line(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D() - 300), cv::Point(out_Circle[1].D(), out_Circle[0].D() + 300), cv::Scalar(0, 255, 0), 15); + + textPainter.putText(Paint, "X偏移:" + std::to_string(offsetX), cv::Point(50, 150), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "Y偏移:" + std::to_string(offsetY), cv::Point(50, 350), cv::Scalar(0, 255, 0)); + + textPainter.putText(Paint, "圆心坐标X:" + std::to_string(out_Circle[1].D()), cv::Point(50, 750), cv::Scalar(0, 255, 0)); + textPainter.putText(Paint, "圆心坐标Y:" + std::to_string(out_Circle[0].D()), cv::Point(50, 950), cv::Scalar(0, 255, 0)); + } + else { + data->halconOK = false; data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123");//发送偏移Y data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送结果 - qDebug() << __FUNCTION__ << " line:" << __LINE__ << " 预焊X偏移abs(resultData[0]) >= 6000,may err,set 0"; - data->halconOK = false; + textPainter.putText(Paint, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255)); + } + + if (data->halconOK == true) { + textPainter.putText(Paint, "OK", cv::Point(50, 550), cv::Scalar(0, 255, 0)); + sqlMapData["结果"] = "OK"; } else { - sqlMapData["偏移X"] = offsetX; - sqlMapData["偏移Y"] = offsetY; - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(offsetX));//发送偏移X - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(offsetY));//发送偏移Y - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果 - data->halconOK = true; + textPainter.putText(Paint, "NG", cv::Point(50, 500), cv::Scalar(0, 0, 255)); + sqlMapData["结果"] = "NG"; } - //圆及十字 - cv::circle(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 20); - cv::line(Paint, cv::Point(out_Circle[1].D() - 300, out_Circle[0].D()), cv::Point(out_Circle[1].D() + 300, out_Circle[0].D()), cv::Scalar(0, 255, 0), 15); - cv::line(Paint, cv::Point(out_Circle[1].D(), out_Circle[0].D() - 300), cv::Point(out_Circle[1].D(), out_Circle[0].D() + 300), cv::Scalar(0, 255, 0), 15); + data->service->_csvWriter->addData(QString::fromStdString(data->SNcode), sqlMapData); + data->resultImgs.push_back(Paint); - textPainter.putText(Paint, "X偏移:" + std::to_string(offsetX), cv::Point(50, 150), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "Y偏移:" + std::to_string(offsetY), cv::Point(50, 350), cv::Scalar(0, 255, 0)); - textPainter.putText(Paint, "相机:" + cameraNumberStr + " 孔位" + FixtureNumber, cv::Point(50, 0), cv::Scalar(0, 255, 0)); + return true; } - else{ - data->halconOK = false; - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_0.0123");//发送偏移X - data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_0.0123");//发送偏移Y - data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送结果 - textPainter.putText(Paint, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255)); - } - - if (data->halconOK == true){ - textPainter.putText(Paint, "OK", cv::Point(50, 550), cv::Scalar(0, 255, 0)); - sqlMapData["结果"] = "OK"; - } - else{ - textPainter.putText(Paint, "NG", cv::Point(50, 500), cv::Scalar(0, 0, 255)); - sqlMapData["结果"] = "NG"; - } - data->service->_csvWriter->addData(QString::fromStdString(data->SNcode), sqlMapData); - data->resultImgs.push_back(Paint); - - return true; + CATCH_EXCEPTIONS + exceptionResume(data, _detParams, address, "异常"); } - - #pragma endregion class _581_Mfd : public mission { public: @@ -348,20 +311,20 @@ public: detParams _detParams; void onConfigReloaded() { HDevEngineCpp::HDevEngine myEngine; - myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_602.hdpl"); + myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl"); } bool initCustom() { #pragma region 注册触发器回调 - yh_1.init("Camera1", "预焊1", 19600, 2, 1, &_params, _serviceManager, bridge, YuHan); - yh_2.init("Camera2", "预焊2", 19800, 2, 1, &_params, _serviceManager, bridge, YuHan); + yh_1.init("Camera1", "预焊1", 19600, 2, 1, &_params, _serviceManager, bridge, YuHan, "预焊CCD"); + yh_2.init("Camera2", "预焊2", 19800, 2, 1, &_params, _serviceManager, bridge, YuHan, "预焊CCD"); - mh_1.init("Camera3", "满焊1", 20000, 2, 1, &_params, _serviceManager, bridge, ManHan); - mh_2.init("Camera4", "满焊2", 20200, 2, 1, &_params, _serviceManager, bridge, ManHan); - mh_3.init("Camera5", "满焊3", 20400, 2, 1, &_params, _serviceManager, bridge, ManHan); - mh_4.init("Camera6", "满焊4", 20600, 2, 1, &_params, _serviceManager, bridge, ManHan); + mh_1.init("Camera3", "满焊1", 20000, 2, 1, &_params, _serviceManager, bridge, ManHan, "满焊CCD"); + mh_2.init("Camera4", "满焊2", 20200, 2, 1, &_params, _serviceManager, bridge, ManHan, "满焊CCD"); + mh_3.init("Camera5", "满焊3", 20400, 2, 1, &_params, _serviceManager, bridge, ManHan, "满焊CCD"); + mh_4.init("Camera6", "满焊4", 20600, 2, 1, &_params, _serviceManager, bridge, ManHan, "满焊CCD"); - hh_2D.init("Camera7", "焊后2d", 20800, 2, 1, &_detParams, _serviceManager, bridge, generalAlgoTest); - hh_3D.init("Camera8", "焊后3d", 21000, 2, 1, &_detParams, _serviceManager, bridge, generalAlgoTest); + hh_2D.init("Camera7", "焊后2d", 20800, 2, 1, &_detParams, _serviceManager, bridge, generalAlgoTest, "焊后CCD"); + hh_3D.init("Camera8", "焊后3d", 21000, 2, 1, &_detParams, _serviceManager, bridge, generalAlgoTest, "焊后CCD"); #pragma endregion return true; }