382 lines
16 KiB
C++
382 lines
16 KiB
C++
#include <imgSaveThreadManager.h>
|
|
#include <appCore.hpp>
|
|
#include <appConfig.h>
|
|
#include <lightSource.hpp>
|
|
#include <cameraManager.h>
|
|
#include <manualDetThread.h>
|
|
#include <triggerManager.h>
|
|
#include <qthread.h>
|
|
#include <simpleSiemensTcp.hpp>
|
|
|
|
class detProcess : public QThread
|
|
{
|
|
public:
|
|
detProcess()
|
|
{
|
|
_threadManager.initialization(this);
|
|
_manualDetThread.initialization(this);
|
|
_cameraManager.initialization();
|
|
_handleAiModelManager.initialization();
|
|
_triggerManager.initialization(this);
|
|
detProcessCallbackRegister();
|
|
|
|
}
|
|
//初始化
|
|
void run()
|
|
{
|
|
_cameraManager.start();
|
|
_handleAiModelManager.start();
|
|
_lightSourceManager.start();
|
|
_triggerManager.start();
|
|
bool res1 = waitrForInitResult(&_cameraManager);
|
|
bool res2 = waitrForInitResult(&_handleAiModelManager);
|
|
bool res3 = waitrForInitResult(&_triggerManager);
|
|
std::cout << std::to_string(res1) << "," << std::to_string(res2) << "," << std::to_string(res3) << "," << std::endl;
|
|
}
|
|
bool waitrForInitResult(serviceModule* ptr)
|
|
{
|
|
int timecnt = 0;
|
|
while (timecnt < 100)
|
|
{
|
|
if (ptr->status != NotInit)
|
|
break;
|
|
}
|
|
if (timecnt > 100)
|
|
return false;
|
|
return true;
|
|
}
|
|
simpleSiemensTcp _simpleSiemensTcp;
|
|
detDataManager _detDataManager;//检测中的数据 不需要初始化
|
|
imgSaveThreadManager _imgSaveThreadManager;//存图线程 不需要初始化
|
|
detThreadManager _threadManager;//异步检测线程 不需要初始化
|
|
|
|
handleAiModelManager _handleAiModelManager;//模型
|
|
cameraManager _cameraManager;//相机
|
|
lightSourceManager _lightSourceManager;//光源
|
|
|
|
triggerManager _triggerManager;//MODBUS触发器
|
|
manualDetThread _manualDetThread;//手动触发线程
|
|
|
|
///////////////////////////////
|
|
std::string currentSn;
|
|
void detProcessCallbackRegister()
|
|
{
|
|
_triggerManager.registerCallback(259, 1, [this](QByteArray& byteArray) {startDetection(byteArray); }, "检测启动");
|
|
_triggerManager.registerCallback(261, 1, [this](QByteArray& byteArray) {calibrationFunc(byteArray); }, "激光校准");
|
|
_triggerManager.registerCallback(300, 1, [this](QByteArray& byteArray) {captureImageAndDetection(byteArray); }, "拍照并检测");
|
|
_triggerManager.registerCallback(361, 1, [this](QByteArray& byteArray) {detectionSwitch1(byteArray); }, "检测开始");
|
|
_triggerManager.registerCallback(361, 2, [this](QByteArray& byteArray) {detectionSwitch2(byteArray); }, "检测结束1");
|
|
_triggerManager.registerCallback(362, 1, [this](QByteArray& byteArray) {detectionEnd(byteArray); }, "检测结束2");
|
|
|
|
_threadManager.registerCallback([this](std::shared_ptr<detData>data) {detectionResultHandle(data); });
|
|
}
|
|
//检测程序是否在运行
|
|
bool armIsRunning = false;
|
|
int backArmIndex = -1;
|
|
bool currentBack = false;
|
|
//激光校准数据缓存 //SN 数据
|
|
correctionStruct laserDataCache;
|
|
//总流程开始,机器人发送1至寄存器259
|
|
//上位机确认OK之后,清零寄存器259,并发送1至寄存器260
|
|
//如产品型号为Product_1且为正面,则上位机发送1至寄存器256,发送0至寄存器257
|
|
//之后机器人确认之后需发送测量点位总数具体值至寄存器258
|
|
//检测启动 259
|
|
void startDetection(QByteArray& byteArray)
|
|
{
|
|
emit _core._qtFunc.uiModuleHistoryListWidget_reset();
|
|
_lightSourceManager.getLightSourcePtr("COM9")->setValue(lightSourceChannel::DChannel, 0);
|
|
_triggerManager.sendFinsMsg("write_short_259_0");//触发信号清零
|
|
_triggerManager.sendFinsMsg("write_short_260_1");//开始检测信号
|
|
emit _core._qtFunc.uiModuleLocationMap_ResetToDefault();
|
|
emit _core._qtFunc.uiModuleSummaryDataManager_Reset();
|
|
emit _core._qtFunc.uiModuleBackContinueDetDialog_hide();
|
|
emit _core._qtFunc.switchStartBtnStatusSignal(false);
|
|
backArmIndex = -1;
|
|
}
|
|
//机器人激光当前点位 264 1...9
|
|
//机器人到达激光点位1时,寄存器261至1,264至1,并将机器人在激光点位1坐标XYZ按照定义规则,保存进寄存器265~270
|
|
//上位机确认机器人到达点位1(264)时,确认OK后,寄存器262至1,261至0,取点完成后,发送寄存器263至1
|
|
//校准函数 261
|
|
void calibrationFunc(QByteArray& byteArray)
|
|
{
|
|
QThread::msleep(3000);
|
|
int armPos = _triggerManager.getValue(264, byteArray);
|
|
|
|
int xValue1 = _triggerManager.getValue(265, byteArray);
|
|
int xValue2 = _triggerManager.getValue(266, byteArray);
|
|
int xValue3 = _triggerManager.getValue(267, byteArray);
|
|
|
|
int yValue1 = _triggerManager.getValue(268, byteArray);
|
|
int yValue2 = _triggerManager.getValue(269, byteArray);
|
|
int yValue3 = _triggerManager.getValue(270, byteArray);
|
|
|
|
int zValue1 = _triggerManager.getValue(271, byteArray);
|
|
int zValue2 = _triggerManager.getValue(272, byteArray);
|
|
int zValue3 = _triggerManager.getValue(273, byteArray);
|
|
|
|
double xValue = (xValue1 == 1 ? 1 : -1) * ((double)xValue2 + ((double)xValue3) / (std::pow(10, std::to_string(xValue3).length())));
|
|
double yValue = (yValue1 == 1 ? 1 : -1) * ((double)yValue2 + ((double)yValue3) / (std::pow(10, std::to_string(yValue3).length())));
|
|
double zValue = (zValue1 == 1 ? 1 : -1) * ((double)zValue2 + ((double)zValue3) / (std::pow(10, std::to_string(zValue3).length())));
|
|
auto cameraPtr = _cameraManager.getCamera("181964");
|
|
if (cameraPtr == nullptr)
|
|
return;
|
|
std::vector<double> values;
|
|
for (int i = 0; i < 10; i++)//弃用
|
|
{
|
|
cameraPtr->trigger();
|
|
double rangeData1 = cameraPtr->getCameraValue();
|
|
}
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
cameraPtr->trigger();
|
|
double rangeData1 = cameraPtr->getCameraValue();
|
|
values.push_back(rangeData1);
|
|
}
|
|
|
|
double avgData = 0;
|
|
for (auto data : values)
|
|
{
|
|
avgData += data;
|
|
}
|
|
avgData /= values.size();
|
|
|
|
double maxData = *std::max_element(values.begin(), values.end());
|
|
double minData = *std::min_element(values.begin(), values.end());
|
|
double rangeData = avgData;
|
|
qDebug() << " max:" << maxData << " min:" << minData << " avg:" << avgData;
|
|
std::cout << " max:" << maxData << " min:" << minData << " avg:" << avgData << std::endl;
|
|
qDebug() << "jiaozhun xValue:" << xValue << " yValue:" << yValue << " zValue:" << zValue << " rangeData:" << rangeData;
|
|
std::cout << "jiaozhun xValue:" << xValue << " yValue:" << yValue << " zValue:" << zValue << " rangeData:" << rangeData << std::endl;
|
|
if (rangeData == 0)
|
|
{
|
|
std::cout << "激光取图错误" << std::endl;
|
|
return;
|
|
}
|
|
|
|
if (armPos == 1)//第一次
|
|
laserDataCache = correctionStruct();
|
|
|
|
if (armPos <= 3)
|
|
{
|
|
laserDataCache.in_X_X0Y.push_back(xValue);
|
|
laserDataCache.in_Y_X0Y.push_back(yValue);
|
|
laserDataCache.in_Z_X0Y.push_back(zValue);
|
|
laserDataCache.in_Z_X0Y_Value.push_back(rangeData);
|
|
}
|
|
else if (armPos <= 6)
|
|
{
|
|
laserDataCache.in_X_X0Z.push_back(xValue);
|
|
laserDataCache.in_Y_X0Z.push_back(yValue);
|
|
laserDataCache.in_Z_X0Z.push_back(zValue);
|
|
laserDataCache.in_Y_X0Z_Value.push_back(rangeData);
|
|
}
|
|
else if (armPos <= 9)
|
|
{
|
|
laserDataCache.in_X_Y0Z.push_back(xValue);
|
|
laserDataCache.in_Y_Y0Z.push_back(yValue);
|
|
laserDataCache.in_Z_Y0Z.push_back(zValue);
|
|
laserDataCache.in_X_Y0Z_Value.push_back(rangeData);
|
|
}
|
|
_triggerManager.sendFinsMsg("write_short_261_0");//清零
|
|
_triggerManager.sendFinsMsg("write_short_262_1");
|
|
_triggerManager.sendFinsMsg("write_short_263_1");
|
|
//上位机校正完成,将寄存器274置为1,并将结果按照定义XYZ规则放入310~336中
|
|
if (armPos == 9)
|
|
{
|
|
std::shared_ptr <detData> data = _detDataManager.insertDetData("181964", "TEST", 0, 0);
|
|
data->productType = _core._detGlobalData.productType;
|
|
data->_productDataStruct = _core._appConfig.productDatas[_core._detGlobalData.productType];
|
|
data->imgAmountMin = 0;
|
|
data->laserData = laserDataCache;
|
|
_threadManager.addTask(data);//添加任务
|
|
laserDataCache = correctionStruct();
|
|
}
|
|
}
|
|
//拍照并检测 300
|
|
void captureImageAndDetection(QByteArray& byteArray)
|
|
{
|
|
_lightSourceManager.getLightSourcePtr("COM9")->setValue(lightSourceChannel::DChannel, 255);
|
|
QThread::msleep(2000);//延时等待机械臂停稳
|
|
_triggerManager.sendFinsMsg("write_short_300_0");//触发信号清零
|
|
_triggerManager.sendFinsMsg("write_short_301_1");//开始检测信号
|
|
int Pos = _triggerManager.getValue(303, byteArray);
|
|
emit _core._qtFunc.uiModuleLocationMap_SetProductSignStatus(Pos,1);
|
|
std::cout << "arm @Pos:" << Pos;
|
|
|
|
std::shared_ptr <detData> data = _detDataManager.insertDetData("Camera1", currentSn, 1, 1);
|
|
data->oriShowIndex = 0;
|
|
data->resShowIndex = 0;
|
|
data->armPos = Pos;
|
|
data->productType = _core._detGlobalData.productType;
|
|
data->_productDataStruct = _core._appConfig.productDatas[_core._detGlobalData.productType];
|
|
auto camera = _cameraManager.getCamera("Camera1");//查找相机
|
|
if (camera != nullptr)
|
|
camera->captureImage(data);//拍照
|
|
data->imgSaveFileParameter.push_back(_core._detGlobalData.productTypeStr);//设置部分文件名
|
|
data->imgSaveFileParameter.push_back("Pos" + std::to_string(Pos));//设置部分文件名
|
|
|
|
_threadManager.addTask(data);//添加任务
|
|
|
|
QThread::msleep(1000);//延时一秒完成拍照,后续改成拍完直接发送
|
|
_triggerManager.sendFinsMsg("write_short_302_1");//开始检测信号
|
|
}
|
|
//机械臂状态切换 361 1 空闲
|
|
void detectionSwitch1(QByteArray& byteArray)
|
|
{
|
|
//if (armIsRunning == false)
|
|
{
|
|
_lightSourceManager.getLightSourcePtr("COM9")->setValue(lightSourceChannel::DChannel, 0);
|
|
armIsRunning = true;
|
|
emit _core._qtFunc.switchStartBtnStatusSignal(true);
|
|
emit _core._qtFunc.simpleSiemensTcp_Write100False();
|
|
}
|
|
}
|
|
//机械臂状态切换 361 2 运行中
|
|
void detectionSwitch2(QByteArray& byteArray)
|
|
{
|
|
//if(armIsRunning == true)
|
|
{
|
|
emit _core._qtFunc.uiModuleBackContinueDetDialog_hide();
|
|
//armIsRunning = false;
|
|
emit _core._qtFunc.switchStartBtnStatusSignal(false);
|
|
emit _core._qtFunc.simpleSiemensTcp_Write100True();
|
|
}
|
|
}
|
|
//机械臂结束
|
|
void detectionEnd(QByteArray& byteArray)
|
|
{
|
|
_simpleSiemensTcp.writeDM100FALSE();
|
|
_lightSourceManager.getLightSourcePtr("COM9")->setValue(lightSourceChannel::DChannel, 0);
|
|
int currentProductIndex = _core._appConfig._switchProductWidgetDataPtr.currentProductIndex;
|
|
if (currentBack == true)
|
|
currentBack = false;
|
|
else if (_core._appConfig.productDatas[currentProductIndex].isBackExist == true)
|
|
{
|
|
backArmIndex = _core._appConfig.productDatas[currentProductIndex].backArmIndex;
|
|
emit emit _core._qtFunc.uiModuleBackContinueDetDialog_show();
|
|
}
|
|
if (armIsRunning == true)
|
|
{
|
|
armIsRunning = false;
|
|
_triggerManager.sendFinsMsg("write_short_362_0");
|
|
auto productData = _core._productDataCache.get(currentSn);
|
|
productData->writeProductData(currentSn, _core._appConfig.productDatas[_core._detGlobalData.productType]);
|
|
productData->saveData("D://CCD//result.xlsx");
|
|
if(productData->ngPinCount >0 || productData->ngCount>0)
|
|
emit _core._qtFunc.uiModuleSummaryDataManager_SetSummaryResultText("NG", Qt::red);
|
|
else
|
|
emit _core._qtFunc.uiModuleSummaryDataManager_SetSummaryResultText("OK", Qt::green);
|
|
std::cout << "detprocess runEnd" << std::endl;
|
|
}
|
|
|
|
}
|
|
//检测结果处理
|
|
void detectionResultHandle(std::shared_ptr<detData>data)
|
|
{
|
|
//发送图片
|
|
if (data->resultImgs.size() > 0)
|
|
{
|
|
int cnt = 0;
|
|
for (auto showMat : data->resultImgs)
|
|
{
|
|
//打包发送
|
|
QPixmap pixmap = cvMatToQPixMap(showMat);
|
|
showImgPack* pack = new showImgPack();
|
|
pack->img = pixmap;
|
|
pack->type = imgWidgetRes;
|
|
pack->index = data->resShowIndex + cnt;
|
|
emit _core._qtFunc.sendPixmapImageWidget(pack);
|
|
|
|
historyPack _historyPack;
|
|
_historyPack.img = pixmap;
|
|
_historyPack.filePath = std::shared_ptr<std::string>(new std::string);
|
|
data->resImgSavePath.push_back(_historyPack.filePath);
|
|
auto it = _core._appConfig.productDatas[_core._detGlobalData.productType].productSign.find(data->armPos);
|
|
if (it != _core._appConfig.productDatas[_core._detGlobalData.productType].productSign.end())
|
|
_historyPack.text.push_back(it->second.sign);
|
|
emit _core._qtFunc.addHistoryDataSignal((data->aiDetOK == true && data->halconOK == true), _historyPack);
|
|
cnt++;
|
|
pixmap = QPixmap();
|
|
}
|
|
}
|
|
//发送检测结果发送到界面
|
|
if (data->armPos != -1)
|
|
{
|
|
emit _core._qtFunc.addDashBoardData(0, data->halconOK);
|
|
emit _core._qtFunc.addDashBoardData(1, data->aiDetOK);
|
|
emit _core._qtFunc.uiModuleLocationMap_SetProductSignStatus(data->armPos,
|
|
(data->halconOK==true&& data->aiDetOK==true)?2:3);
|
|
bool finalOk = (data->halconOK == true || data->aiDetOK == true)? true :false;
|
|
if(finalOk=false)
|
|
{
|
|
for (auto showMat : data->resultImgs)
|
|
{
|
|
QPixmap pixmap;
|
|
cvMatToQPixMap(showMat, pixmap);
|
|
showImgPack* pack = new showImgPack();
|
|
emit _core._qtFunc.uiModuleImageDoubleCheckQdialog_ShowWindows(pixmap);
|
|
}
|
|
}
|
|
auto productData = _core._productDataCache.get(currentSn);
|
|
if (finalOk = false)
|
|
productData->ngCount++;
|
|
perConnector _perConnectorData;
|
|
_perConnectorData.aiOk = data->aiDetOK;
|
|
_perConnectorData.halconOk = data->halconOK;
|
|
_perConnectorData.maxPinDetValue = data->maxPinDetValue;
|
|
productData->connectorResults.push_back(_perConnectorData);
|
|
}
|
|
//ct计算以及发送到界面
|
|
auto totalCt = std::chrono::duration_cast<std::chrono::milliseconds>(data->halconEndTime - data->algoStartTime);
|
|
auto aiCt = std::chrono::duration_cast<std::chrono::milliseconds>(data->handleAiEndTime - data->algoStartTime);
|
|
auto halconCt = std::chrono::duration_cast<std::chrono::milliseconds>(data->halconEndTime - data->handleAiEndTime);
|
|
if (totalCt.count() > 0)
|
|
emit _core._qtFunc.addCtData(0, totalCt.count());
|
|
if (aiCt.count() > 0)
|
|
emit _core._qtFunc.addCtData(1, aiCt.count());
|
|
if (halconCt.count() > 0)
|
|
emit _core._qtFunc.addCtData(2, halconCt.count());
|
|
|
|
//SQL
|
|
std::vector<sqlData> sqlDatas;
|
|
for (auto sqlData : data->sqlVec)
|
|
sqlDatas.push_back({ sqlData.first, std::to_string(sqlData.second) });
|
|
_core._appConfig._sqlManager.addData(data->SNcode, sqlDatas);
|
|
|
|
//写入plc
|
|
for (auto writeBackStr : data->writeBackData)
|
|
_triggerManager.sendFinsMsg(writeBackStr);
|
|
|
|
//储存结果图
|
|
std::async(std::launch::async, &imgSaveThreadManager::saveRes, &_imgSaveThreadManager, data);
|
|
|
|
//删除 不再持有
|
|
detDataManager* dManager = data->dManager;
|
|
data->dManager->deleteDetData(data->timeCode);
|
|
}
|
|
|
|
|
|
public slots:
|
|
void runBackDet()
|
|
{
|
|
if (backArmIndex != -1)
|
|
{
|
|
currentBack = true;
|
|
_triggerManager.sendFinsMsg("write_short_350_" + QString::number(backArmIndex));//清零
|
|
_triggerManager.sendFinsMsg("write_short_351_1");
|
|
}
|
|
}
|
|
void writeArmStartSignal(int productTypeIn, QString SN)
|
|
{
|
|
_core._appConfig.productDatasMutex.lock();
|
|
_core._detGlobalData.productTypeStr = _core._appConfig.productDatas[productTypeIn].name;
|
|
_core._appConfig.productDatasMutex.unlock();
|
|
_core._detGlobalData.productType = productTypeIn;
|
|
if(_core._detGlobalData.currentSn!="")
|
|
_core._detGlobalData.currentSn = SN.toStdString();
|
|
currentSn = SN.toStdString();
|
|
_triggerManager.sendFinsMsg("write_short_350_" + QString::number(_core._appConfig.productDatas[productTypeIn].indexOfArm));
|
|
_triggerManager.sendFinsMsg("write_short_351_1");
|
|
}
|
|
};
|
|
#pragma once |