Files

437 lines
12 KiB
C++
Raw Permalink Normal View History

2024-09-27 14:31:22 +08:00
#include "Logic_transfer.h"
#include "qmutex.h"
#include "qfuture.h"
#include "QtConcurrent/qtconcurrent"
#include "qmessagebox.h"
2024-10-17 16:37:42 +08:00
2024-09-27 14:31:22 +08:00
QMutex log_mutex;
void LogMsgOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{
Q_UNUSED(context);
QMutexLocker locker(&log_mutex);
QByteArray localMsg = msg.toLocal8Bit();
QString log;
QString log_info;
QString nowTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
QString m_msg;
QString m_name;
QStringList msg_list;
switch (type)
{
case QtDebugMsg:
log.append(QString("[%1] [info] %2").arg(nowTime).arg(msg));
break;
case QtInfoMsg:
m_msg = msg;
msg_list = m_msg.split("/");
if (msg_list.size() >= 2)
{
m_name = msg_list.at(1);
m_msg.remove(0, m_name.size() + 2);
}
else
{
m_name = "null";
}
log_info.append(QString("[%1] [info] %2").arg(nowTime).arg(m_msg));
break;
case QtWarningMsg:
log.append(QString("[%1] [warning] %2").arg(nowTime).arg(msg));
break;
case QtCriticalMsg:
log.append(QString("[%1] [critical] %2").arg(nowTime).arg(msg));
break;
case QtFatalMsg:
log.append(QString("[%1] [fatal] %2").arg(nowTime).arg(msg));
abort();
}
QFile savefile;
QString logTime = QDateTime::currentDateTime().toString("yyyy-MM-dd");
if (log != nullptr)
{
QDir m_dir = QApplication::applicationDirPath();
QString m_path = m_dir.path();
QDir m_checkdir = m_path + "/log/";
if (!m_checkdir.exists())
{
m_checkdir.mkdir(m_checkdir.path());
}
m_path = m_path + "/log/" + QString("%1_HanddleAI.log").arg(logTime);
// m_path = m_path + "/log/" + QString("HanddleAI.log");
savefile.setFileName(m_path);
if (!savefile.open(QIODevice::ReadWrite | QIODevice::Append))
{
QString erinfo = savefile.errorString();
std::cout << " erinfo: " << erinfo.toStdString() << std::endl;
return;
}
QTextStream out(&savefile);
out << "\r" << log;
savefile.close();
}
if (log_info != nullptr)
{
QDir m_dir = QApplication::applicationDirPath();
QString m_path = m_dir.path();
QDir m_checkdir = m_path + "/log/";
if (!m_checkdir.exists())
{
m_checkdir.mkdir(m_checkdir.path());
}
m_path = m_path + "/log/" + QString("%1_%2.log").arg(logTime).arg(m_name);
// m_path = m_path + "/log/" + QString("HanddleAI.log");
savefile.setFileName(m_path);
if (!savefile.open(QIODevice::ReadWrite | QIODevice::Append))
{
QString erinfo = savefile.errorString();
std::cout << " erinfo: " << erinfo.toStdString() << std::endl;
return;
}
QTextStream out(&savefile);
out << "\r" << log_info;
savefile.close();
}
int k = 0;
// log_info.append(log);
}
QJsonObject Logic_transfer::load_camera_cfg(QString cfg)
{
QDir dir = QApplication::applicationDirPath();
currPath = dir.path();
json_cfg_file_path = currPath + "/config/" + cfg;//camera_cfg.json";
QJsonObject json_object;
try
{
QJsonParseError jsonError;
if (json_cfg_file_path.isEmpty())
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " JsonPath is null!";
return json_object;
}
QFile JsonFile;
JsonFile.setFileName(json_cfg_file_path);
if (!JsonFile.isReadable())
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " camera_cfg.json not isReadable!";
//return json_object;
}
JsonFile.open(QIODevice::ReadOnly);
QByteArray m_Byte = JsonFile.readAll();
if (m_Byte.isEmpty())
{
qDebug() << __FUNCTION__ << " line:" << __LINE__ << json_cfg_file_path + " Content is empty";
JsonFile.close();
return json_object;
}
QJsonDocument jsonDocument(QJsonDocument::fromJson(m_Byte, &jsonError));
if (!jsonDocument.isNull() && jsonError.error == QJsonParseError::NoError)
{
if (jsonDocument.isObject())
{
json_object = jsonDocument.object();
JsonFile.close();
return json_object;
}
}
else
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << json_cfg_file_path + " is error!";
}
JsonFile.close();
}
catch (QString ev)
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " ev:" << ev;
}
return json_object;
}
bool ifRuntransfer = false;
Logic_transfer::Logic_transfer()
{
showMutex = new QMutex;
ifRuntransfer = true;
//通用逻辑接口
//加载逻辑dll
QLibrary* m_lib = new QLibrary("Hd_LogicDll_module.dll");
bool flag = m_lib->load();
if (!m_lib->isLoaded())
{
qDebug() << __FUNCTION__ << __LINE__ << " Loaded error:" << m_lib->errorString();
delete m_lib;
m_lib = nullptr;
//return false;
}
else
{
CreateFunction createFun = (CreateFunction)m_lib->resolve("create");
ReleaseFunction releaseFun = (ReleaseFunction)m_lib->resolve("destory");
if (createFun && releaseFun)
{
Logic_ptr = nullptr;
Logic_ptr = createFun();
destory_Logic = releaseFun;
//加载并检查配置文件:bin/camera_cfg.json
//m_jsonObj =load_camera_cfg();
//check_cmeraCfg();
//Logic_ptr->setJsonObject(m_jsonObj);
//信号与槽
if(Logic_ptr) {
//connect(Logic_ptr, SIGNAL(Logic_sendImage(QString, cv::Mat)), this, SLOT(base_Logic_sendImage(QString, cv::Mat))); // 传递图片
connect(Logic_ptr, SIGNAL(Logic_writeData(QString, QString, QString, QByteArray)), this, SLOT(base_Logic_writeData(QString, QString, QString, QByteArray)));// 传递数据
QFuture<void>muf = QtConcurrent::run(this, &Logic_transfer::check_sendImgStruct);
connect(Logic_ptr, SIGNAL(Logic_sendTcpStatus(bool)), this, SLOT(base_Logic_sendTcpStatus(bool)));// 通信状态
connect(Logic_ptr, SIGNAL(Logic_cameraDisconnect(QString, bool)), this, SLOT(base_Logic_cameraDisconnect(QString,bool)));// x相机状态
}
}
}
Sleep(50);
2024-10-17 16:37:42 +08:00
2024-09-27 14:31:22 +08:00
}
void Logic_transfer::check_sendImgStruct()
{
while (ifRuntransfer)
{
QQueue< sendImgStruct> myS;
//if (Logic_ptr->queue_sendImgStruct.size() > 0)
if (Logic_ptr->get_sendImgStruct(myS))
{
//QMutexLocker locker(sendImgStructMutex); // 加锁
//sendImgStruct mS;
//mS.send_Mat = myL.send_Mat;
//mS.cameraKey_index = myL.cameraKey_index;
////堆积了,只显示最新的
//for (int i = 0; i < queue_sendImgStruct.size(); i++)
// if (myL.cameraKey_index == queue_sendImgStruct[i].cameraKey_index)
// {
// queue_sendImgStruct.removeAt(i);
// break;
// }
//queue_sendImgStruct.enqueue(mS);
for (int i = 0; i < myS.size(); i++)
{
decodeImage(myS[i].cameraKey_index, myS[i].send_Mat);
}
myS.clear();
//Sleep(1);
}
Sleep(10);
}
}
bool Logic_transfer::getShowQImage(QQueue< showImgStruct>& my_showImgStruct)
{
QMutexLocker locker(showMutex); // 加锁
//showImgStruct mS;
if (queue_showImgStruct.size() > 0)
{
my_showImgStruct.append(queue_showImgStruct);// .dequeue();
queue_showImgStruct.clear();
return true;
}
return false;
}
void Logic_transfer::decodeImage(QString key, cv::Mat mtx)
{
try
{
if (!mtx.empty()) {
2024-10-17 16:37:42 +08:00
//if ((mtx.dataend - mtx.datastart) != mtx.cols * mtx.rows * mtx.channels()) //尝试能否解决mtx内容异常问题
//{
// qCritical() << __FUNCTION__ << " line:" << __LINE__ << " mtx.dataend - mtx.datastart err!!:";
// return;// false;
//}
2024-09-27 14:31:22 +08:00
cv::Mat rgb;
//while (mtx.cols > 2000 && mtx.rows > 2000)
// cv::resize(mtx, mtx, cv::Size(), 0.1, 0.1); //吃cpu性能,i7 8700,4800*4800的resize耗时100ms;QImage*的scaled缩放,耗时200ms
QImage* itemImage = nullptr;
if (mtx.type() == CV_8UC1)
{
rgb = mtx.clone(); //mtx.data检查后,只有2个数据,clone崩溃
itemImage = new QImage(QSize(rgb.cols, rgb.rows), QImage::Format_Grayscale8);
QImage qim((const unsigned char*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_Grayscale8);
*itemImage = qim.copy();
}
else if (mtx.type() == CV_16U) // 双通道转单通道显示
{
cv::normalize(mtx, mtx, 0, 255, cv::NORM_MINMAX);
cv::convertScaleAbs(mtx, rgb);
itemImage = new QImage(QSize(rgb.cols, rgb.rows), QImage::Format_Grayscale8);
QImage qim((const unsigned char*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_Grayscale8);
*itemImage = qim.copy();
}
else if (mtx.type() == CV_8UC3)
{
cv::cvtColor(mtx, rgb, cv::COLOR_BGR2RGB);
itemImage = new QImage(QSize(rgb.cols, rgb.rows), QImage::Format_RGB888);
QImage qim((const unsigned char*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_RGB888);
*itemImage = qim.copy();
}
else if (mtx.type() == CV_8UC4)
{
cv::cvtColor(mtx, rgb, cv::COLOR_BGRA2RGBA);
itemImage = new QImage(QSize(rgb.cols, rgb.rows), QImage::Format_ARGB32);
QImage qim((const unsigned char*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_ARGB32);
*itemImage = qim.copy();
}
//emit LogicTransfer_sendImage(key, itemImage);
QMutexLocker locker(showMutex); // 加锁
showImgStruct mS;
mS.show_QImage = itemImage;
mS.cameraKey_index = key;
////堆积了,只显示最新的
//for (int i = 0; i < queue_showImgStruct.size(); i++)
// if (key == queue_showImgStruct[i].cameraKey_index)
// {
// queue_showImgStruct.removeAt(i);
// break;
// }
queue_showImgStruct.enqueue(mS);
}
}
catch (QString ev)
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " ev:" << ev;
return;// false;
}
return;// true;
}
Logic_transfer::~Logic_transfer()
{
ifRuntransfer = false;
Sleep(100);
//通用逻辑接口
destory_Logic(Logic_ptr);
}
void Logic_transfer::base_Logic_sendTcpStatus(bool flag)
{
//emit LogicTransfer_sendTcpStatus(flag);
if (flag)
emit LogicTransfer_writeData("sendTcpStatus_true", "TCP", "TCP", "TCP");
else
emit LogicTransfer_writeData("sendTcpStatus_false", "TCP", "TCP", "TCP");
}
void Logic_transfer::base_Logic_writeData(QString key, QString cameraName, QString snInfo, QByteArray byte)
{
emit LogicTransfer_writeData(key, cameraName, snInfo, byte);
}
void Logic_transfer::base_Logic_cameraDisconnect(QString msg, bool status)
{
//emit LogicTransfer_cameraDisconnect(msg, status);
if (status)
emit LogicTransfer_writeData("cameraDisconnect_true", msg, "TCP", "TCP");
else
emit LogicTransfer_writeData("cameraDisconnect_false", msg, "TCP", "TCP");
}
//void Logic_transfer::base_Logic_CommunicationDisconnect(QString msg, bool status)
//{
// emit LogicTransfer_CommunicationDisconnect(msg, status);
//}
//2、检查配置文件,返回检查结果(true表示配置文件正常,false表示异常)及字符串
//配置文件正常也有字符串返回,可按照返回结果进行弹窗提示。
bool Logic_transfer::checkJsonObject(QJsonObject obj, QString& errMessage)
{
if (Logic_ptr)
return Logic_ptr->checkJsonObject(obj, errMessage);
else return false;
}
//3、传递配置文件到通用逻辑框架
bool Logic_transfer::setJsonObject(QJsonObject obj)
{
2024-10-17 16:37:42 +08:00
QString saveLog = obj.value("是否写入日志").toString();
if (saveLog == "true")
{
//自动写Log日志功能;bin/Log
qInstallMessageHandler(LogMsgOutput);
}
2024-09-27 14:31:22 +08:00
if (Logic_ptr)
return Logic_ptr->setJsonObject(obj);
else return false;
return true;
}
//4、初始化任务
bool Logic_transfer::initTask()
{
if (Logic_ptr)
return Logic_ptr->initTask();
else return false;
return true;
}
//5、开始任务
bool Logic_transfer::startTask()
{
if (Logic_ptr)
return Logic_ptr->startTask();
else return false;
return true;
}
//6、停止任务、清理数据
bool Logic_transfer::stopTask()
{
if (Logic_ptr)
return Logic_ptr->stopTask();
else return false;
return true;
}
//7、退出所有类、释放模块
bool Logic_transfer::exitTask()
{
if (Logic_ptr)
{
Logic_ptr->disconnect();
return Logic_ptr->exitTask();
}
else return false;
return true;
}
//8、重新运行
bool Logic_transfer::restartTask()
{
if (Logic_ptr)
return Logic_ptr->restartTask();
else return false;
return true;
}
//发送指令给PLC
bool Logic_transfer::sendPLC(QString cmd)
{
if (Logic_ptr)
return Logic_ptr->sendPLC(cmd);
else return false;
return true;
}
//重新加载配置文件json,设置参数
bool Logic_transfer::reLoadJsonSetParameter(QStringList moduleKeyList)
{
if (Logic_ptr)
return Logic_ptr->reLoadJsonSetParameter(moduleKeyList);
else return false;
return true;
}