367 lines
13 KiB
C++
367 lines
13 KiB
C++
#include <qdebug.h>
|
|
#include <qthread.h>
|
|
#include <subModuleBase.h>
|
|
#include <qlibrary.h>
|
|
#include <global.h>
|
|
#include <backStruct.h>
|
|
#include <functional>
|
|
#include <serviceModule.h>
|
|
#include <nlohmannJson.hpp>
|
|
#include <qelapsedtimer.h>
|
|
|
|
#define switchToRpc 1
|
|
#define debugTesting 0
|
|
using triggerCallback = std::function<void(int,int,QByteArray& byte)>;
|
|
class cameraManager;
|
|
class detThreadManager;
|
|
class detDataManager;
|
|
class lightSourceManager;
|
|
class detProcess;
|
|
//防止重复触发
|
|
class triggerLockerT {
|
|
public:
|
|
// 不存在则返回true
|
|
bool checkLocker(int pos) const {
|
|
return lockerVec.find(pos) == lockerVec.end();
|
|
}
|
|
|
|
// 如果和加锁的值不同则删除
|
|
void reFreshLocker(const QByteArray& input) {
|
|
for (auto it = lockerVec.begin(); it != lockerVec.end(); ) {
|
|
if (it->first >= input.size() || input.at(it->first) != it->second) {
|
|
it = lockerVec.erase(it); // erase 返回下一个迭代器
|
|
}
|
|
else {
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 添加锁
|
|
void addLocker(int pos, int val) {
|
|
lockerVec[pos] = val;
|
|
}
|
|
|
|
private:
|
|
std::unordered_map<int, int> lockerVec;
|
|
};
|
|
|
|
//触发器类 fins触发 tcp触发等 替代myiothread
|
|
class triggerManager : public serviceModule
|
|
{
|
|
public:
|
|
struct readAllStruct {
|
|
QByteArray readAllCmd;
|
|
int startPos;
|
|
int readLength;
|
|
};
|
|
std::vector<readAllStruct> readAllCmds;
|
|
|
|
//QByteArray readAllCmd;
|
|
QString triggerFileName;
|
|
QString IpAndPort;
|
|
QString triggerInitStr;
|
|
~triggerManager(){
|
|
runFlag = false;
|
|
this->stop();
|
|
this->terminate();
|
|
delete trigger;
|
|
}
|
|
triggerManager(detProcess*, qtFuncBridge* bridgeIn, nlohmann::ordered_json& triggerJson);
|
|
bool connectHost();
|
|
void run();
|
|
void stop(){
|
|
runFlag = false;
|
|
this->terminate();
|
|
}
|
|
|
|
|
|
#pragma region 发送数据
|
|
bool sendFinsMsg(QString cmdx){
|
|
if (trigger == nullptr)
|
|
return false;
|
|
if (!trigger->writeData(vec_mat, cmdx.toUtf8()))
|
|
{
|
|
qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << cmdx;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
bool sendFinsMsg(const char* cmdx){
|
|
QString str = cmdx;
|
|
if (trigger == nullptr)
|
|
return false;
|
|
if (!trigger->writeData(vec_mat, str.toUtf8()))
|
|
{
|
|
qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << cmdx;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
bool sendFinsMsg(QByteArray write_byte){
|
|
if (trigger == nullptr)
|
|
return false;
|
|
if (!trigger->writeData(vec_mat, write_byte) && trigger != nullptr)
|
|
{
|
|
qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << write_byte;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//FINS
|
|
|
|
//useage "D9200_1"
|
|
bool writeShort(QByteArray write_byte) {
|
|
if (trigger == nullptr)
|
|
return false;
|
|
QByteArray array("write_short_" + write_byte);
|
|
if (!trigger->writeData(vec_mat, array) && trigger != nullptr)
|
|
{
|
|
qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << write_byte;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//useage {"D9200_1","D9201_1"}
|
|
bool writeShort(std::vector<std::string> write_byte) {
|
|
if (trigger == nullptr)
|
|
return false;
|
|
for (auto& byteArray : write_byte) {
|
|
QByteArray array = QByteArray::fromStdString("write_short_" + byteArray);
|
|
if (!trigger->writeData(vec_mat, array) && trigger != nullptr) {
|
|
qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << array;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//useage {"D9200_1","D9201_1"}
|
|
bool writeFloat(std::vector<std::string> write_byte) {
|
|
if (trigger == nullptr)
|
|
return false;
|
|
for (auto& byteArray : write_byte) {
|
|
QByteArray array = QByteArray::fromStdString("write_float_" + byteArray);
|
|
if (!trigger->writeData(vec_mat, array) && trigger != nullptr) {
|
|
qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << array;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
bool writeFloat(QByteArray write_byte) {
|
|
if (trigger == nullptr)
|
|
return false;
|
|
QByteArray array = "write_float_" + write_byte;
|
|
if (!trigger->writeData(vec_mat, array) && trigger != nullptr) {
|
|
qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << array;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
bool writeFloat(std::vector<QByteArray> write_byte) {
|
|
if (trigger == nullptr)
|
|
return false;
|
|
for (auto& byteArray : write_byte) {
|
|
QByteArray array = "write_float_" + byteArray;
|
|
if (!trigger->writeData(vec_mat, array) && trigger != nullptr) {
|
|
qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << array;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
#pragma endregion
|
|
#pragma region 接收数据
|
|
void reciveCommond();
|
|
//int read(int dmPos, QByteArray byte)
|
|
//{
|
|
// int triggerPos = (dmPos - startPos) * 2;
|
|
// if (byte.size() < triggerPos)
|
|
// return false;
|
|
// int val1 = byte.at(triggerPos) * 256;
|
|
// int val2 = static_cast<unsigned char>(byte.at(triggerPos + 1));
|
|
// return val1 + val2;
|
|
//}
|
|
QVariant read(int dmPos) {
|
|
QByteArray readByte;
|
|
mutex.lock();
|
|
if (!sendFinsMsg("read_byte_D" + QString::number(dmPos) + "_2"))
|
|
qCritical() << "[TCP] " << " finstcp_ptr reciveData error!";
|
|
if (!reciveFinsMsg(readByte))
|
|
qCritical() << "[TCP] " << " finstcp_ptr readData error!";
|
|
mutex.unlock();
|
|
int val1 = readByte.at(0) * 256;
|
|
int val2 = static_cast<unsigned char>(readByte.at(1));
|
|
return val1 + val2;
|
|
}
|
|
#pragma endregion
|
|
|
|
//CALL BACK
|
|
struct triggerCallbackStruct{
|
|
int triggerAddress;
|
|
int triggerValue;
|
|
triggerCallback func;
|
|
std::string funcName;
|
|
};
|
|
bool registerCallback(int triggerAddress, int triggerValue, triggerCallback func, std::string funcName =""){
|
|
triggerCallbackStruct _triggerCallbackStruct;
|
|
_triggerCallbackStruct.triggerAddress = triggerAddress;
|
|
_triggerCallbackStruct.triggerValue = triggerValue;
|
|
_triggerCallbackStruct.func = func;
|
|
_triggerCallbackStruct.funcName = funcName;
|
|
for (auto& _struct : readAllCmds) {
|
|
if (triggerAddress >= _struct.startPos && triggerAddress < _struct.startPos + _struct.readLength) {
|
|
triggerCallbackFuncs[_struct.readAllCmd].push_back(_triggerCallbackStruct);
|
|
return true;
|
|
}
|
|
}
|
|
qCritical() << "触发器回调地址超限了" << triggerAddress << triggerValue;
|
|
return false;
|
|
}
|
|
std::map<QByteArray, std::vector<triggerCallbackStruct>> triggerCallbackFuncs;
|
|
void checkCallbackAndTrigger(readAllStruct& _struct,QByteArray & byteArray){//检查是否符合回调函数的触发条件
|
|
for (auto callback : triggerCallbackFuncs[_struct.readAllCmd])
|
|
{
|
|
if (checkTrigger(callback.triggerAddress, callback.triggerValue, _struct, byteArray) == true)
|
|
{
|
|
qDebug() << "func:" << QString::fromStdString(callback.funcName) << "->已触发";
|
|
std::thread([callback, byteArray]() mutable {
|
|
try {
|
|
callback.func(callback.triggerAddress, callback.triggerValue, byteArray); // 执行回调函数
|
|
}
|
|
catch (const std::exception& e) {
|
|
std::cerr << "Error in callback " << callback.funcName << ": " << e.what() << std::endl;
|
|
}
|
|
}).detach();
|
|
}
|
|
}
|
|
}
|
|
std::string readSnFromQByteArray(QByteArray plcByte, int dmPos,
|
|
bool highLowConversion, bool clearAfterRead, int Size){
|
|
int startPos = 0;
|
|
for (auto& _struct : readAllCmds) {
|
|
if (dmPos > _struct.startPos &&
|
|
dmPos < _struct.startPos + _struct.readLength)
|
|
startPos = _struct.startPos;
|
|
}
|
|
if (startPos == 0) {
|
|
qCritical() << "读条码越界";
|
|
return "ERROR_OUT_OF_RANGE";
|
|
}
|
|
int triggerPos = (dmPos - startPos) * 2;
|
|
if (triggerPos < 0){
|
|
std::cout << "Read SN error,trigger is DM:" << dmPos << ",but read start at DM:" << startPos << endl;
|
|
return "snErrorsnError" + getCurrentDateTime();
|
|
}
|
|
QString str;
|
|
if (plcByte.at(triggerPos + 1) == 0 && plcByte.at(triggerPos) == 0)
|
|
return "snErrorsnError" + getCurrentDateTime();
|
|
int snCount = 0;
|
|
if (highLowConversion == true){
|
|
while (plcByte.at(snCount + triggerPos) != 0 || plcByte.at(snCount + triggerPos + 1) != 0){
|
|
|
|
if (plcByte.at(snCount + triggerPos) != 0)
|
|
str += QChar(plcByte.at(snCount + triggerPos));
|
|
snCount++;
|
|
}
|
|
}
|
|
else{
|
|
while (plcByte.at(snCount + triggerPos) != 0 || plcByte.at(snCount + triggerPos + 1) != 0){
|
|
|
|
if (plcByte.at(snCount + triggerPos + 1) != 0)
|
|
str += QChar(plcByte.at(snCount + triggerPos + 1));
|
|
if (plcByte.at(snCount + triggerPos) != 0)
|
|
str += QChar(plcByte.at(snCount + triggerPos));
|
|
snCount += 2;
|
|
}
|
|
}
|
|
if (str.size() < Size && Size != -1)
|
|
return "snErrorsnError" + getCurrentDateTime();
|
|
//if (clearAfterRead == true)
|
|
// //for(int i=0;i< snCount;i++)
|
|
// bridge.back.sendFinsMsg(
|
|
//QString::fromStdString("writeALL_DM" + to_string(dmPos) + "_" + to_string(snCount) + "_0"));
|
|
return str.toStdString();
|
|
}
|
|
|
|
private:
|
|
QElapsedTimer lostConnectionCountTimer,lostConnectionRePrintTimer;
|
|
qtFuncBridge* bridge;
|
|
bool libLoadedflag = false;
|
|
QLibrary* m_lib = nullptr;
|
|
detProcess* _detProcess;
|
|
lightSourceManager* _lightSourceManager;
|
|
detThreadManager* _threadManager;
|
|
detDataManager* dManager;
|
|
cameraManager* _cameraManager;
|
|
std::map<QByteArray,triggerLockerT> tLocker;//防止重复触发,每次收到数据时检查数据是否与上次相同,如果相同checkTrigger会返回false
|
|
/// <summary>
|
|
/// 检测QByteArray中某位置的值是否和输入一样,使用了绝对位置
|
|
/// </summary>
|
|
/// <param name="dmPos">绝对位置</param>
|
|
/// <param name="value">值</param>
|
|
/// <param name="byte">QByteArray</param>
|
|
/// <returns></returns>
|
|
bool checkTrigger(int dmPos, int value, readAllStruct& _struct, QByteArray& byte, bool lockerDisable = false){
|
|
int triggerPos = (dmPos - _struct.startPos) * 2 + 1;
|
|
if (byte.size() < triggerPos)
|
|
return false;
|
|
if (byte.at(triggerPos) == value){
|
|
if (tLocker[_struct.readAllCmd].checkLocker(triggerPos) == false)
|
|
return false;
|
|
if (lockerDisable == false)
|
|
tLocker[_struct.readAllCmd].addLocker(triggerPos, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
bool checkTrigger_Unsafe(int dmPos, int value, readAllStruct& _struct, QByteArray& byte, bool lockerDisable = false) {
|
|
int triggerPos = (dmPos - _struct.startPos) * 2 + 1;
|
|
if (byte.at(triggerPos) == value) {
|
|
if (tLocker[_struct.readAllCmd].checkLocker(triggerPos) == false)
|
|
return false;
|
|
if (lockerDisable == false)
|
|
tLocker[_struct.readAllCmd].addLocker(triggerPos, value);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
//接受数据
|
|
bool reciveFinsMsg(QByteArray& readByte){
|
|
if (!trigger->readData(vec_mat, readByte))
|
|
{
|
|
qCritical() << "[TCP] " << " finstcp_ptr readData error!";
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
QMutex mutex; //互斥锁,防止多线程访问冲突
|
|
//解析并触发
|
|
void decodeCameraCMD(readAllStruct&,QByteArray byte);
|
|
//触发器的配置
|
|
int sleepIntervalMS = 50;//间隔
|
|
int heartBeatIntervalMS = 800;
|
|
int heartBeatCmdCnt = 0;
|
|
std::vector<QString> heartBeatCmds;
|
|
#if switchToRpc==0
|
|
ReleaseFunction destory_finstcp; //释放
|
|
dsModuleBase* trigger = nullptr;
|
|
#else
|
|
ReleaseRpcModuleBaseFunction destory_finstcp; //释放
|
|
rpcModuleBase* trigger = nullptr;
|
|
#endif
|
|
bool isConnected = true;
|
|
bool runFlag = true;
|
|
bool init = false;
|
|
std::vector<cv::Mat> vec_mat;//没啥用,一直保持为空就好
|
|
};
|
|
#pragma once |