From 2cdb0c022aa887d70459ac30a806d8b92d352346 Mon Sep 17 00:00:00 2001 From: "Mr.V" Date: Thu, 25 Apr 2024 17:53:34 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=A2=9E=E5=8A=A0=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E8=AF=86=E5=88=AB=E8=BE=85=E5=8A=A9=E6=A3=80=E6=B5=8B=E6=9D=A5?= =?UTF-8?q?=E8=BD=A6=E7=8A=B6=E6=80=81=E5=8A=9F=E8=83=BD=E3=80=82=202?= =?UTF-8?q?=E3=80=81=E4=BF=AE=E6=94=B9RFID=E6=95=B0=E6=8D=AE=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E9=80=BB=E8=BE=91=E3=80=82=203=E3=80=81=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=AD=98=E5=82=A8=E6=97=A5=E5=BF=97=E7=9A=84=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E8=B7=AF=E5=BE=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 5 + ai_matrix/Config/Config.cpp | 23 ++- ai_matrix/Config/Config.h | 30 ++-- ai_matrix/Utils/FileUtil.cpp | 1 + ai_matrix/Utils/StringUtil.cpp | 4 + ai_matrix/Utils/StringUtil.h | 4 + code/BaseSocket/BaseSocket.cpp | 9 +- code/common/AppCommon.h | 7 + config/config.yaml | 28 +--- config/matrix.yaml | 2 + engine/DealRfidEngine/DealRfidEngine.cpp | 64 ++++++-- engine/DealRfidEngine/DealRfidEngine.h | 8 + engine/GetRfidEngine/GetRfidEngine.cpp | 4 +- engine/SaveRfidEngine/SaveRfidEngine.cpp | 8 +- .../VideoAuxiliaryEngine.cpp | 145 ++++++++++++++++++ .../VideoAuxiliaryEngine.h | 46 ++++++ 16 files changed, 308 insertions(+), 80 deletions(-) create mode 100644 engine/VideoAuxiliaryEngine/VideoAuxiliaryEngine.cpp create mode 100644 engine/VideoAuxiliaryEngine/VideoAuxiliaryEngine.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b54cea6..72e35ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,6 +115,10 @@ aux_source_directory(${PROJECT_SRC_ROOT}/engine/SaveResultEngine SaveResultEngin include_directories(${PROJECT_SRC_ROOT}/engine/SaveRfidEngine) aux_source_directory(${PROJECT_SRC_ROOT}/engine/SaveRfidEngine SaveRfidEngine_SRC) +# VideoAuxiliaryEngine +include_directories(${PROJECT_SRC_ROOT}/engine/VideoAuxiliaryEngine) +aux_source_directory(${PROJECT_SRC_ROOT}/engine/VideoAuxiliaryEngine VideoAuxiliaryEngine_SRC) + # 其他头文件 include_directories( @@ -182,6 +186,7 @@ file( ${HttpUpResultEngine_SRC} ${SaveResultEngine_SRC} ${SaveRfidEngine_SRC} + ${VideoAuxiliaryEngine_SRC} ) # 服务端 diff --git a/ai_matrix/Config/Config.cpp b/ai_matrix/Config/Config.cpp index 95b75cc..7232b6f 100644 --- a/ai_matrix/Config/Config.cpp +++ b/ai_matrix/Config/Config.cpp @@ -39,7 +39,6 @@ namespace ai_matrix this->baseConfig_.bTestModel = config_["base"]["test_model"].as(); this->baseConfig_.iConnectType = config_["base"]["connect_type"].as(); this->baseConfig_.bUpResult = config_["base"]["up_result"].as(); - this->baseConfig_.bUseSocketServer = config_["base"]["use_socket_server"].as(); this->baseConfig_.bHaveMagnetSteel = config_["base"]["have_magnet_steel"].as(); this->baseConfig_.strMagnetSteelOrder = config_["base"]["magnet_steel_order"].as(); this->baseConfig_.strRfidPath = config_["base"]["rfid_path"].as(); @@ -61,15 +60,11 @@ namespace ai_matrix this->ethernetConfig_.strIp = config_["ethernet"]["ip"].as(); this->ethernetConfig_.iPort = config_["ethernet"]["port"].as(); - // ftp服务器参数 - this->ftpConfig_.bIsUse = config_["ftp"]["is_use"].as(); - this->ftpConfig_.strType = config_["ftp"]["type"].as(); - this->ftpConfig_.strIp = config_["ftp"]["ip"].as(); - this->ftpConfig_.iPort = config_["ftp"]["port"].as(); - this->ftpConfig_.strUsername = config_["ftp"]["username"].as(); - this->ftpConfig_.strPassword = config_["ftp"]["password"].as(); - this->ftpConfig_.strPath = config_["ftp"]["path"].as(); - this->ftpConfig_.iQuitTime = config_["ftp"]["quit_time"].as(); + // 视频识别辅助来车状态检测 + this->videoAuxiliaryConfig_.bUseVideoAuxiliary = config_["video_auxiliary"]["use_video_auxiliary"].as(); + this->videoAuxiliaryConfig_.strIp = config_["video_auxiliary"]["ip"].as(); + this->videoAuxiliaryConfig_.iPort = config_["video_auxiliary"]["port"].as(); + this->videoAuxiliaryConfig_.iDelayedUpload = config_["video_auxiliary"]["delayed_upload"].as(); // http服务器参数 this->httpServerConfig_.bIsUse = config_["http_server"]["is_use"].as(); @@ -214,14 +209,14 @@ namespace ai_matrix this->ethernetConfig_ = ethernetConfig; } - FtpConfig Config::getFtpConfig() const + VideoAuxiliaryConfig Config::getVideoAuxiliaryConfig() const { - return this->ftpConfig_; + return this->videoAuxiliaryConfig_; } - void Config::setFtpConfig(const FtpConfig ftpConfig) + void Config::setVideoAuxiliaryConfig(const VideoAuxiliaryConfig videoAuxiliaryConfig) { - this->ftpConfig_ = ftpConfig; + this->videoAuxiliaryConfig_ = videoAuxiliaryConfig; } HttpServerConfig Config::getHttpServerConfig() const diff --git a/ai_matrix/Config/Config.h b/ai_matrix/Config/Config.h index e60b0ed..5a2d51c 100644 --- a/ai_matrix/Config/Config.h +++ b/ai_matrix/Config/Config.h @@ -31,8 +31,6 @@ namespace ai_matrix int iConnectType; // 是否上传识别结果 bool bUpResult; - // 是否使用外部接口辅助开关识别 - bool bUseSocketServer; // 是否存在磁钢 bool bHaveMagnetSteel; // 火车进厂的磁钢顺序 @@ -96,25 +94,17 @@ namespace ai_matrix std::string strPassword; }; - // FTP服务器参数 - struct FtpConfig + // 视频识别辅助来车状态检测 + struct VideoAuxiliaryConfig { - // 使用状态 - bool bIsUse; - // 上传方式 [ftp,sftp] - std::string strType; + // 是否使用外部接口辅助开关识别 + bool bUseVideoAuxiliary; // 服务器IP std::string strIp; - // 服务器端口 + // 端口号 int iPort; - // 服务器用户名 - std::string strUsername; - // 服务器密码 - std::string strPassword; - // 上传地址 - std::string strPath; - // X秒后自动断开时间 - int iQuitTime; + // 延迟上传的节数 + int iDelayedUpload; }; class Config final @@ -153,8 +143,8 @@ namespace ai_matrix HttpServerConfig getHttpServerConfig() const; void setHttpServerConfig(const HttpServerConfig httpServerConfig); // 获取FTP服务器参数 - FtpConfig getFtpConfig() const; - void setFtpConfig(const FtpConfig ftpConfig); + VideoAuxiliaryConfig getVideoAuxiliaryConfig() const; + void setVideoAuxiliaryConfig(const VideoAuxiliaryConfig videoAuxiliaryConfig); YAML::Node config_; @@ -187,7 +177,7 @@ namespace ai_matrix HttpServerConfig httpServerConfig_; // ftp服务器参数 - FtpConfig ftpConfig_; + VideoAuxiliaryConfig videoAuxiliaryConfig_; //定义一个嵌套类,负责释放内存,操作系统自动完成,不用担心内存泄露 class GarbageCollector diff --git a/ai_matrix/Utils/FileUtil.cpp b/ai_matrix/Utils/FileUtil.cpp index d8f561f..6a8e6d3 100644 --- a/ai_matrix/Utils/FileUtil.cpp +++ b/ai_matrix/Utils/FileUtil.cpp @@ -23,6 +23,7 @@ namespace ai_matrix } return ins; } + /** * 创建文件夹路径 * inParam : std::string strDirPath :文件夹路径 diff --git a/ai_matrix/Utils/StringUtil.cpp b/ai_matrix/Utils/StringUtil.cpp index c17c250..4121d28 100644 --- a/ai_matrix/Utils/StringUtil.cpp +++ b/ai_matrix/Utils/StringUtil.cpp @@ -164,4 +164,8 @@ namespace ai_matrix } return false; // 遍历完成未发现非字母数字字符,返回false } + + bool StringUtil::is_digits(const std::string &str) { + return all_of(str.begin(), str.end(), ::isdigit); + } } diff --git a/ai_matrix/Utils/StringUtil.h b/ai_matrix/Utils/StringUtil.h index 32f9508..c85d36b 100644 --- a/ai_matrix/Utils/StringUtil.h +++ b/ai_matrix/Utils/StringUtil.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace ai_matrix { @@ -37,6 +38,9 @@ namespace ai_matrix // 判断字符串中是否含有 字母和数字 之外的字符 bool containsNonAlphaNum(const std::string &str); + // 判断字符串中是否仅含有数字 + // 检查函数 + bool is_digits(const std::string& str); private: StringUtil() = default; diff --git a/code/BaseSocket/BaseSocket.cpp b/code/BaseSocket/BaseSocket.cpp index aad3a88..2d51162 100644 --- a/code/BaseSocket/BaseSocket.cpp +++ b/code/BaseSocket/BaseSocket.cpp @@ -105,9 +105,12 @@ int BaseSocket::Read() int BaseSocket::Monitor() { - memset(chbuffer, 0x00, sizeof(chbuffer)); - chbuffer[0] = 0x30; - int len = send(nSocketId, chbuffer, (sizeof(chbuffer) - 1), 0); +// memset(chbuffer, 0x00, sizeof(chbuffer)); +// chbuffer[0] = 0x30; +// int len = send(nSocketId, chbuffer, (sizeof(chbuffer) - 1), 0); + std::string heart = "matrixai"; + int len = send(nSocketId, heart.c_str(), (sizeof(heart) - 1), 0); + if(nConnectId < 0 || len == 0) bRun = false; return len; } diff --git a/code/common/AppCommon.h b/code/common/AppCommon.h index 36c81c2..da48402 100644 --- a/code/common/AppCommon.h +++ b/code/common/AppCommon.h @@ -77,6 +77,13 @@ typedef struct std::string strNowTime; } TrainInfo; +typedef struct +{ + std::string strComeTime; + int iDirection; + bool bComeTrain; +} ComeTrainInfo; + // 定义日期结构体 typedef struct Date { diff --git a/config/config.yaml b/config/config.yaml index ec0f93a..b823c27 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -8,8 +8,6 @@ base: connect_type: 0 # 是否上传识别结果 up_result: false - # 是否使用外部接口辅助开关识别 - use_socket_server: false # 是否存在磁钢 have_magnet_steel: true # 火车进厂的磁钢顺序 @@ -65,22 +63,12 @@ http_server: # 接口密码 password: "d55b0f642e817eea24725d2f2a31dd08" -# FTP服务器参数 -ftp: - # 启用状态 - is_use: false - # 通讯类型 [ftp, sftp] - type: "ftp" - # 服务器IP - ip: "192.168.2.211" - # 端口 - port: 21 - # 用户名 - username: "matrixai" - # 密码 - password: "123" - # 上传地址 - path: "" - # X秒后自动断开时间 - quit_time: 120 +# 视频识别辅助来车状态检测 +video_auxiliary: + # 是否使用外部接口辅助开关识别 + use_video_auxiliary: false + # IP + ip: "172.18.0.1" + # 端口号 + port: 7003 diff --git a/config/matrix.yaml b/config/matrix.yaml index d70e543..e8258f8 100644 --- a/config/matrix.yaml +++ b/config/matrix.yaml @@ -10,10 +10,12 @@ engines: HttpUpResultEngine: 0 SaveResultEngine: 0 DelExpiredEngine: 0 + VideoAuxiliaryEngine: 0 #engine连接 connects: GetRfidEngine_0_0: "DealRfidEngine_0_0 1024" + VideoAuxiliaryEngine_0_0: "DealRfidEngine_0_1 1024" DealRfidEngine_0_0: "SaveRfidEngine_0_0 1024" DealRfidEngine_0_1: "HttpUpResultEngine_0_0 1024" DealRfidEngine_0_2: "SaveResultEngine_0_0 1024" \ No newline at end of file diff --git a/engine/DealRfidEngine/DealRfidEngine.cpp b/engine/DealRfidEngine/DealRfidEngine.cpp index 39421b4..f4398e7 100644 --- a/engine/DealRfidEngine/DealRfidEngine.cpp +++ b/engine/DealRfidEngine/DealRfidEngine.cpp @@ -14,6 +14,7 @@ APP_ERROR DealRfidEngine::Init() strPort2_ = engineName_ + "_" + std::to_string(engineId_) + "_2"; this->baseConfig_ = Config::GetIns()->getBaseConfig(); + this->videoAuxiliaryConfig_ = Config::GetIns()->getVideoAuxiliaryConfig(); this->initParam(); @@ -32,6 +33,24 @@ APP_ERROR DealRfidEngine::Process() int iRet = APP_ERR_OK; while (!isStop_) { + if (this->videoAuxiliaryConfig_.bUseVideoAuxiliary) + { + //pop端口1 + std::shared_ptr pVoidData1 = nullptr; + iRet = inputQueMap_[strPort1_]->pop(pVoidData1); + if (nullptr != pVoidData1) + { + std::shared_ptr pComeTrainInfo = std::static_pointer_cast(pVoidData1); + this->videoHasTrain_ = pComeTrainInfo->bComeTrain; + this->identifyFlagUpdate(); + if (this->iVDirection_ == 0 && pComeTrainInfo->iDirection != 0) + { + LogInfo << "视频辅助检测来车状态 判定 来车方向:" << (pComeTrainInfo->iDirection > -1 ? (pComeTrainInfo->iDirection > 0 ? "需识别" : "待定") : "无需上传"); + this->iVDirection_ = pComeTrainInfo->iDirection; + } + } + } + //pop端口0 std::shared_ptr pVoidData0 = nullptr; iRet = inputQueMap_[strPort0_]->pop(pVoidData0); @@ -45,7 +64,6 @@ APP_ERROR DealRfidEngine::Process() this->tmpRfid_.append(pRfidData->strRfid); - LogDebug << "原文:" << this->tmpRfid_; if (this->tmpRfid_.substr(this->tmpRfid_.size()-1,1) != "&") { continue; @@ -55,7 +73,6 @@ APP_ERROR DealRfidEngine::Process() std::vector vecRfidSub = StringUtil::getins()->split(this->tmpRfid_, "@"); -// LogDebug << "--" << vecRfidSub.size(); this->tmpRfid_ = ""; auto split_lambda = [=](std::string strFirst, std::string strOther){ @@ -63,8 +80,6 @@ APP_ERROR DealRfidEngine::Process() { this->rfidHasTrain_ = false; LogInfo << "RFID-火车离开了"; - // 关功放信号 - // 需要结合 “来车状态”广播消息,确认是否真的车离开了; this->identifyFlagUpdate(); } else @@ -90,21 +105,19 @@ APP_ERROR DealRfidEngine::Process() for (const auto & i : vecRfidSub) { + if (i.empty()) continue; if (i.size() == 26 || i.size() == 24) { // 车厢信息 - std::string strTrainInfo = i.substr(0, 14); + std::string strTrainInfo = i.substr(1, 13); if (this->vecTrain_.empty() || !Utils::getins()->contains_vec(this->vecTrain_, strTrainInfo)) { - bool isNoCarriage = false; - int carT = StringUtil::getins()->string2int(strTrainInfo.substr(3, 2), isNoCarriage); + // 判断是否是车头 车头的第14位是 K或H (慎重) + if (!StringUtil::getins()->is_digits(i.substr(14, 1))) continue; + // 过滤掉车号中有非数字的 + if (!StringUtil::getins()->is_digits(strTrainInfo.substr(strTrainInfo.size() -7, 7))) continue; - if (isNoCarriage && carT >= 10) continue; - // 因信号不稳定 增加一行过滤 出现文字中带有字母及数字以外的字符时,过滤 - if (StringUtil::getins()->containsNonAlphaNum(strTrainInfo)) continue; - // 因信号不稳定 增加一行过滤 出现读到的数据里 空格替代了实际字符的情况 - if (StringUtil::getins()->trim(strTrainInfo.substr(7, 7)).size() < 7) continue; vecTrain_.emplace_back(strTrainInfo); int train_order = vecTrain_.size(); LogInfo << "第" << train_order << "节 " << strTrainInfo; @@ -114,11 +127,24 @@ APP_ERROR DealRfidEngine::Process() this->rfidSourceInfo_ = ""; std::shared_ptr pTrainInfo = std::make_shared(); + TrainInfo tmpTrainInfo; this->makeTrainInfo(rfidinfo, pTrainInfo); + queueTmpTrainInfo_.Push(pTrainInfo); if (this->needIdentify_) { - // 上传识别结果 - iRet = outputQueMap_[strPort1_]->push(std::static_pointer_cast(pTrainInfo)); + if (this->iVDirection_ < 0) + { + queueTmpTrainInfo_.Clear(); + } + if (this->iVDirection_ > 0) + { + while (!queueTmpTrainInfo_.IsEmpty()) + { + queueTmpTrainInfo_.Pop(pTrainInfo); + // 上传识别结果 + iRet = outputQueMap_[strPort1_]->push(std::static_pointer_cast(pTrainInfo)); + } + } } // 存储识别结果 iRet = outputQueMap_[strPort2_]->push(std::static_pointer_cast(pTrainInfo)); @@ -170,6 +196,8 @@ void DealRfidEngine::initParam() { this->videoHasTrain_ = false; // RFID识别有火车标志 this->rfidHasTrain_ = false; + // + this->iVDirection_ = 0; } /** @@ -181,7 +209,6 @@ void DealRfidEngine::identifyFlagUpdate() { if (!this->needIdentify_) { LogInfo << "--- 来车了 ---"; -// this->mkRfidLog(); this->vecTrain_.clear(); this->needIdentify_ = true; this->trainTime_ = TimeUtil::getins()->getDateTime(); @@ -202,8 +229,11 @@ void DealRfidEngine::identifyFlagUpdate() { void DealRfidEngine::makeTrainInfo(const std::string rfidinfo, std::shared_ptr pTrainInfo) { std::string info = this->vecTrain_.back(); int order = this->vecTrain_.size(); - - info = info.substr(1,info.size() - 1); + if (order > this->videoAuxiliaryConfig_.iDelayedUpload && this->iVDirection_ == 0) + { + this->iVDirection_ = 1; + } + if (!this->videoAuxiliaryConfig_.bUseVideoAuxiliary) this->iVDirection_ = 1; if (this->trainTime_.empty()) this->trainTime_ = TimeUtil::getins()->getDateTime(); pTrainInfo->strCarriageType = StringUtil::getins()->trim(info.substr(0, 6)); diff --git a/engine/DealRfidEngine/DealRfidEngine.h b/engine/DealRfidEngine/DealRfidEngine.h index bb030d2..04c344c 100644 --- a/engine/DealRfidEngine/DealRfidEngine.h +++ b/engine/DealRfidEngine/DealRfidEngine.h @@ -9,9 +9,11 @@ #include "Config.h" #include "EngineBase.h" #include "EngineFactory.h" +#include "CommandParser.h" #include "TimeUtil.h" #include "StringUtil.h" #include "Utils.h" +#include "BlockingQueue.h" class DealRfidEngine : public ai_matrix::EngineBase { @@ -34,6 +36,8 @@ private: // 核心配置 ai_matrix::BaseConfig baseConfig_; + // 视频辅助来车状态检测配置 + ai_matrix::VideoAuxiliaryConfig videoAuxiliaryConfig_; // 临时存储的接收数据 std::string tmpRfid_; // 识别方向正确标志 @@ -42,10 +46,14 @@ private: bool videoHasTrain_; // RFID识别有火车标志 bool rfidHasTrain_; + // 视频识别判定的方向 0:暂未确认方向 1:需要识别 -1 不需要识别 + int iVDirection_; // RFID源数据 std::string rfidSourceInfo_; // 本列车识别结果(临时存储) std::vector vecTrain_; + // 本列车识别结果临时队列 + BlockingQueue> queueTmpTrainInfo_; void identifyFlagUpdate(); void initParam(); diff --git a/engine/GetRfidEngine/GetRfidEngine.cpp b/engine/GetRfidEngine/GetRfidEngine.cpp index 853b4d7..734bf21 100644 --- a/engine/GetRfidEngine/GetRfidEngine.cpp +++ b/engine/GetRfidEngine/GetRfidEngine.cpp @@ -41,7 +41,7 @@ APP_ERROR GetRfidEngine::Process() if (this->iConnectType == AEI_SOCKET_TYPE) { - LogInfo << "服务端IP:" << this->ethernetConfig_.strIp << " 端口:" << this->ethernetConfig_.iPort; + LogInfo << "RFID服务端IP:" << this->ethernetConfig_.strIp << " 端口:" << this->ethernetConfig_.iPort; this->baseScoket_.Open(); this->baseScoket_.SetPort(this->ethernetConfig_.iPort, this->ethernetConfig_.strIp); this->baseScoket_.Init(); @@ -63,7 +63,7 @@ APP_ERROR GetRfidEngine::Process() { LogError << "通讯类型设置异常!"; } - LogInfo << "开启通讯..."; + LogInfo << "RFID开启通讯..."; while (!isStop_) { diff --git a/engine/SaveRfidEngine/SaveRfidEngine.cpp b/engine/SaveRfidEngine/SaveRfidEngine.cpp index 394e861..d39832b 100644 --- a/engine/SaveRfidEngine/SaveRfidEngine.cpp +++ b/engine/SaveRfidEngine/SaveRfidEngine.cpp @@ -41,18 +41,18 @@ APP_ERROR SaveRfidEngine::Process() try { if (pRfidInfo->strTrainTime == "") continue; - std::string strTrainPath = this->baseConfig_.strResultPath + "/" + TimeUtil::getins()->getDate() + "/"; + std::string strTrainPath = this->baseConfig_.strRfidPath + "/" + TimeUtil::getins()->getDate() + "/"; - //1. 创建保存路径 (固定路径/YYYY-MM-DD/hh-mm-ss/iDataSoure/) + //1. 创建保存路径 if (!FileUtil::getins()->CreateDirPath(strTrainPath)) { LogError << "结果目录:" << strTrainPath << " 创建失败!"; return false; } - std::string strLogName = this->baseConfig_.strRfidPath + "/" + pRfidInfo->strTrainTime + "_source.log"; + std::string strLogName = pRfidInfo->strTrainTime + "_source.log"; strLogName = StringUtil::getins()->replace_all_distinct(strLogName, ":", "-"); strLogName = StringUtil::getins()->replace_all_distinct(strLogName, " ", "T"); - std::string strLogPath = strTrainPath + strLogName; + std::string strLogPath = strTrainPath + "/" + strLogName; std::ofstream fs(strLogPath, std::ios::app); if (!fs) diff --git a/engine/VideoAuxiliaryEngine/VideoAuxiliaryEngine.cpp b/engine/VideoAuxiliaryEngine/VideoAuxiliaryEngine.cpp new file mode 100644 index 0000000..3a88c7c --- /dev/null +++ b/engine/VideoAuxiliaryEngine/VideoAuxiliaryEngine.cpp @@ -0,0 +1,145 @@ + +#include "VideoAuxiliaryEngine.h" + +using namespace ai_matrix; + +VideoAuxiliaryEngine::VideoAuxiliaryEngine() {} + +VideoAuxiliaryEngine::~VideoAuxiliaryEngine() {} + +APP_ERROR VideoAuxiliaryEngine::Init() +{ + strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; + this->videoAuxiliaryConfig_ = Config::GetIns()->getVideoAuxiliaryConfig(); + + this->carType_ = "0"; + + LogInfo << "VideoAuxiliaryEngine Init ok"; + return APP_ERR_OK; +} + +APP_ERROR VideoAuxiliaryEngine::DeInit() +{ + this->baseScoket_.Close(); + + LogInfo << "VideoAuxiliaryEngine DeInit ok"; + return APP_ERR_OK; +} + +APP_ERROR VideoAuxiliaryEngine::Process() +{ + int iRet = APP_ERR_OK; + + if (!this->videoAuxiliaryConfig_.bUseVideoAuxiliary) + { + return APP_ERR_OK; + } + + this->baseScoket_.Open(); + this->baseScoket_.SetPort(this->videoAuxiliaryConfig_.iPort, this->videoAuxiliaryConfig_.strIp); + this->baseScoket_.Init(); + LogInfo << "视频辅助 服务端IP:" << this->videoAuxiliaryConfig_.strIp << " 端口:" << this->videoAuxiliaryConfig_.iPort; + LogInfo << "开启通讯..."; + + while (!isStop_) + { + char chbuffer[AEI_COMM_BUFFER_SIZE] = {0}; + int nRevSize = 0; + memset(chbuffer, 0x00, sizeof(chbuffer)); + + if (!this->baseScoket_.bRuning()) + { + LogError << "TCP 连接失败,重启中 ..."; + usleep(20 * 1000 * 1000); // 20秒后重试 + this->baseScoket_.Close(); + this->baseScoket_.Open(); + this->baseScoket_.Init(); + + continue; + } + + nRevSize = this->baseScoket_.Read(); + if (nRevSize <= 0) + { + this->baseScoket_.Monitor(); + continue; + } + else + { + memcpy(chbuffer, this->baseScoket_.chbuffer, nRevSize); + } + + this->dealSocketInfo(chbuffer); + + } + return APP_ERR_OK; +} + +bool VideoAuxiliaryEngine::getOrder(const std::string &recv, Json::Value &order) +{ + Json::CharReaderBuilder readerBuilder; + std::shared_ptr reader(readerBuilder.newCharReader()); + + JSONCPP_STRING errs; + if (!reader->parse(recv.data(), recv.data() + recv.size(), &order, &errs)) + return false; + + if (order.isArray()) { + if (!order.empty()) order = order[0]; + return true; + } + return true; +} + +void VideoAuxiliaryEngine::dealSocketInfo(const std::string &info) { + std::string vedioInfo = info; + StringUtil::getins()->replace_all_distinct(vedioInfo, "}{", "}&{"); + std::vector vecJson = StringUtil::getins()->split(vedioInfo, "&"); + for (int i = 0; i < vecJson.size(); ++i) + { + Json::Value feedBack; + if (!this->getOrder(vecJson[i], feedBack)) + { + LogWarn << "接收到视频识别反馈的来车状态信息,未能解析成JSON格式。"; + continue; + } + + std::shared_ptr pComeTrainInfo = std::make_shared(); + + std::string tmpCarType = feedBack.get("type", "").asString(); + int iDirection = feedBack.get("direction", 0).asInt(); + + if (tmpCarType != this->carType_) + { + if (this->carType_ == "0") + { + // 来车 + pComeTrainInfo->bComeTrain = true; + pComeTrainInfo->iDirection = 0; + if (iDirection != 0) pComeTrainInfo->iDirection = iDirection; + outputQueMap_[strPort0_]->push(pComeTrainInfo); + this->carType_ = tmpCarType; + } + else if (this->carType_ == "1") + { + // 无车 + pComeTrainInfo->bComeTrain = false; + pComeTrainInfo->iDirection = 0; + outputQueMap_[strPort0_]->push(pComeTrainInfo); + this->carType_ = tmpCarType; + } + else + { + LogWarn << "视频辅助检测来车状态,反馈的来车状态无法识别"; + continue; + } + + if (tmpCarType == this->carType_ && iDirection != 0) + { + pComeTrainInfo->bComeTrain = true; + pComeTrainInfo->iDirection = iDirection; + outputQueMap_[strPort0_]->push(pComeTrainInfo); + } + } + } +} \ No newline at end of file diff --git a/engine/VideoAuxiliaryEngine/VideoAuxiliaryEngine.h b/engine/VideoAuxiliaryEngine/VideoAuxiliaryEngine.h new file mode 100644 index 0000000..9307457 --- /dev/null +++ b/engine/VideoAuxiliaryEngine/VideoAuxiliaryEngine.h @@ -0,0 +1,46 @@ +/** + * 视频辅助判定来车状态 + * */ + +#ifndef VIDEOAUXILIARYENGINE_H +#define VIDEOAUXILIARYENGINE_H + +#include "AppCommon.h" + +#include "EngineBase.h" +#include "EngineFactory.h" +#include "Config.h" +#include "TimeUtil.h" +#include "StringUtil.h" +#include "BaseSocket.h" +#include "BaseComPort.h" +#include "json/json.h" + +#define AEI_SOCKET_TYPE 0 +#define AEI_COM_TYPE 1 + +class VideoAuxiliaryEngine : public ai_matrix::EngineBase +{ +public: + VideoAuxiliaryEngine(); + ~VideoAuxiliaryEngine(); + + APP_ERROR Init() override; + APP_ERROR DeInit() override; + APP_ERROR Process() override; + +private: + + std::string strPort0_; + + ai_matrix::VideoAuxiliaryConfig videoAuxiliaryConfig_; + BaseSocket baseScoket_; + std::string carType_; + + bool getOrder(const std::string &recv, Json::Value &order); + void dealSocketInfo(const std::string &info); +}; + +ENGINE_REGIST(VideoAuxiliaryEngine) + +#endif \ No newline at end of file