#include "DealRfidEngine.h" using namespace ai_matrix; DealRfidEngine::DealRfidEngine() {} DealRfidEngine::~DealRfidEngine() {} APP_ERROR DealRfidEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1"; strPort2_ = engineName_ + "_" + std::to_string(engineId_) + "_2"; strPort3_ = engineName_ + "_" + std::to_string(engineId_) + "_3"; this->baseConfig_ = Config::GetIns()->getBaseConfig(); this->videoAuxiliaryConfig_ = Config::GetIns()->getVideoAuxiliaryConfig(); this->deviceWarnConfig_ = Config::GetIns()->getDeviceWarnConfig(); this->initParam(); LogInfo << "DealRfidEngine Init ok"; return APP_ERR_OK; } APP_ERROR DealRfidEngine::DeInit() { LogInfo << "DealRfidEngine DeInit ok"; return APP_ERR_OK; } 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); if (nullptr == pVoidData0) { usleep(1000); continue; } std::shared_ptr pRfidData = std::static_pointer_cast(pVoidData0); this->tmpRfid_.append(pRfidData->strRfid); if (this->tmpRfid_.substr(this->tmpRfid_.size()-1,1) != "&") { continue; } this->tmpRfid_ = StringUtil::getins()->replace_all_distinct(this->tmpRfid_, "&", ""); std::vector vecRfidSub = StringUtil::getins()->split(this->tmpRfid_, "@"); this->tmpRfid_ = ""; auto split_lambda = [=](std::string strFirst, std::string strOther){ if (strFirst == "0") { this->rfidHasTrain_ = false; LogInfo << "RFID-火车离开了"; this->identifyFlagUpdate(); } else { // 注意: 此处按照4个磁钢来配置,可能存在一定限制 if (strOther == "000000") // 第一次检测来车时(前提是上一次功放已关闭) { if (strFirst == this->baseConfig_.strMagnetSteelOrder.substr(0, 1) || strFirst == this->baseConfig_.strMagnetSteelOrder.substr(1, 1)) { this->rfidHasTrain_ = true; LogInfo << "RFID-来车了"; this->identifyFlagUpdate(); } else { LogInfo << "RFID-列车出厂"; this->rfidHasTrain_ = false; } } } }; for (const auto & i : vecRfidSub) { if (i.empty()) continue; if (i.size() == 26 || i.size() == 24) { // 车厢信息 std::string strTrainInfo = i.substr(1, 13); if (this->vecTrain_.empty() || !Utils::getins()->contains_vec(this->vecTrain_, strTrainInfo)) { // 判断是否是车头 车头的第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; vecTrain_.emplace_back(strTrainInfo); int train_order = vecTrain_.size(); LogInfo << "第" << train_order << "节 " << strTrainInfo; // 将接收到的RFID使用@符拼接起来,以待后续上传web this->rfidSourceInfo_.append("@" + i); std::string rfidinfo = this->rfidSourceInfo_; this->rfidSourceInfo_ = ""; std::shared_ptr pTrainInfo = std::make_shared(); TrainInfo tmpTrainInfo; this->makeTrainInfo(rfidinfo, pTrainInfo); queueTmpTrainInfo_.Push(pTrainInfo); if (this->needIdentify_) { if (this->iVDirection_ < 0) { queueTmpTrainInfo_.Clear(); } if (this->iVDirection_ > 0) { while (!queueTmpTrainInfo_.IsEmpty()) { queueTmpTrainInfo_.Pop(pTrainInfo); if (!Utils::getins()->contains_vec(this->vecLastTrain_, strTrainInfo)) { // 上传识别结果 iRet = outputQueMap_[strPort1_]->push(std::static_pointer_cast(pTrainInfo)); } else { LogWarn << "第" << train_order << "节 " << strTrainInfo << " 与上一列车识别的信息重复,不上传"; } } } } // 存储识别结果 iRet = outputQueMap_[strPort2_]->push(std::static_pointer_cast(pTrainInfo)); } } else if (i.size() == 7) { // 不使用磁钢的情况下 过滤掉磁钢信号 if (!this->baseConfig_.bHaveMagnetSteel) continue; // 磁钢信号 std::string strFirst = i.substr(0,1); std::string strOther = i.substr(1, i.size() - 1); // 将接收到的RFID使用@符拼接起来,以待后续上传web this->rfidSourceInfo_.append("@" + i); split_lambda(strFirst, strOther); } else if (i.size() == 14) // 特殊情况,来车信号少了&符 { // 不使用磁钢的情况下 过滤掉磁钢信号 if (!this->baseConfig_.bHaveMagnetSteel) continue; for (int j = 0; j < i.size(); j+=7) { std::string rfid_cg = i.substr(j, 7); std::string strFirst = rfid_cg.substr(0, 1); std::string strOther = rfid_cg.substr(1, 6); // 将接收到的RFID使用@符拼接起来,以待后续上传web this->rfidSourceInfo_.append("@" + rfid_cg); split_lambda(strFirst, strOther); } } std::shared_ptr pSaveRfidData = std::make_shared(); pSaveRfidData->strRfid = pRfidData->strRfid; pSaveRfidData->strTime = pRfidData->strTime; pSaveRfidData->strTrainTime = this->trainTime_; // 存储原始数据 iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast(pSaveRfidData)); } } return APP_ERR_OK; } /** * 参数初始化 */ void DealRfidEngine::initParam() { this->rfidSourceInfo_ = ""; this->trainTime_ = ""; this->vecLastTrain_ = this->vecTrain_.empty() ? this->vecLastTrain_ : this->vecTrain_; this->vecTrain_.clear(); this->tmpRfid_ = ""; // 识别方向正确标志 this->needIdentify_ = false; // 视频识别有火车标志(使用socket服务时才有用) this->videoHasTrain_ = false; // RFID识别有火车标志 this->rfidHasTrain_ = false; // this->iVDirection_ = 0; // 清空上一列的信息 queueTmpTrainInfo_.Clear(); } /** * 修改识别状态 */ void DealRfidEngine::identifyFlagUpdate() { if (this->rfidHasTrain_ || this->videoHasTrain_) { if (!this->needIdentify_) { LogInfo << "--- 来车了 ---"; this->vecTrain_.clear(); this->needIdentify_ = true; this->trainTime_ = TimeUtil::getins()->getDateTime(); } } else if (!this->rfidHasTrain_ && !this->videoHasTrain_) { if (this->vecTrain_.size() < this->deviceWarnConfig_.iMinTrainSize && this->iVDirection_ > 0 && (this->rfidSourceInfo_.size() > 128 || this->vecTrain_.size() > 1)) { std::shared_ptr pDeviceStatus = std::make_shared(); pDeviceStatus->strDeviceName = "RFID设备"; pDeviceStatus->strDeviceRunningStatus = "异常"; pDeviceStatus->strNetworkStatus = "正常"; pDeviceStatus->strDeviceSn = this->baseConfig_.strTrackName + "股道"; pDeviceStatus->strDeviceWarnInfo = "火车驶过,疑似RFID设备故障,读取到的车厢号有丢失"; outputQueMap_[strPort3_]->push(std::static_pointer_cast(pDeviceStatus)); } this->initParam(); LogInfo << "--- 火车离开了 ---"; } } /** * 组织识别数据 * @param rfidinfo * @param pTrainInfo */ void DealRfidEngine::makeTrainInfo(const std::string rfidinfo, std::shared_ptr pTrainInfo) { std::string info = this->vecTrain_.back(); int order = this->vecTrain_.size(); 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)); pTrainInfo->strCarriageNum = StringUtil::getins()->trim(info.substr(6, info.size() - 6)); pTrainInfo->strOrder = std::to_string(order); pTrainInfo->strTrainTime = this->trainTime_; pTrainInfo->strRfidInfo = rfidinfo; pTrainInfo->strNowTime = TimeUtil::getins()->getDateTime_usec(); }