#include "MergerAllEngine.h" using namespace ai_matrix; namespace { std::map mapLoad = { {"C62", "60"}, {"C62B", "61"}, {"C63", "61"}, {"C64", "61"}, {"C65", "60"}, {"C70", "70"}, {"C80", "80"}, {"KM70", "70"}, {"KM81", "81"}, {"KM98", "98"} }; } MergerAllEngine::MergerAllEngine() {} MergerAllEngine::~MergerAllEngine() {} APP_ERROR MergerAllEngine::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"; //接受车厢范围 iPushDirection_ = MyYaml::GetIns()->GetIntValue("gc_push_direction"); mapPopPort_[strPort0_] = false; mapPopPort_[strPort1_] = false; mapPopPort_[strPort2_] = false; mapPopPort_[strPort3_] = true; //获取在用摄像头识别的目标(目标分为3大类,车号,定检期,集装箱 哪个识别监听哪个端口的数据) std::map mapUseDataSouceCfg = MyYaml::GetIns()->GetUseDataSourceConfig(); std::string delimiter(","); for (auto iter = mapUseDataSouceCfg.begin(); iter!=mapUseDataSouceCfg.end(); iter++) { std::vector vecSplit = MyUtils::getins()->split(iter->second.strTarget, delimiter); for (auto iter = vecSplit.begin(); iter != vecSplit.end(); iter++) { if (*iter == "NUM" && !mapPopPort_[strPort0_]) { mapPopPort_[strPort0_] = true; } else if (*iter == "CHKDATE" && !mapPopPort_[strPort1_]) { mapPopPort_[strPort1_] = true; } else if ((*iter == "CONTAINER" || *iter == "CONTAINER_T") && !mapPopPort_[strPort2_]) { mapPopPort_[strPort2_] = true; } } } for (auto iter = mapPopPort_.begin(); iter != mapPopPort_.end(); iter++) { if (iter->second) { iPopPortCnt_++; } } LogDebug << "iPopPortCnt_:" << iPopPortCnt_; InitParam(); bUploadFlag_ = (MyYaml::GetIns()->GetIntValue("gc_http_open") == 1 || MyYaml::GetIns()->GetIntValue("gc_mysql_open") == 1); LogInfo << "MergerAllEngine Init ok"; return APP_ERR_OK; } APP_ERROR MergerAllEngine::DeInit() { LogInfo << "MergerAllEngine DeInit ok"; return APP_ERR_OK; } /** * 初始化参数信息 * inParam : N/A * outParam: N/A * return : N/A */ void MergerAllEngine::InitParam() { iTrainIndex_ = 1; bHeadFrontFlag_ = false; } /** * push结果 * inParam : std::shared_ptr pTrain 合并后车厢信息 * outParam: N/A * return : N/A */ void MergerAllEngine::PushData(std::shared_ptr pTrain) { LogInfo << "\n ---所有信息合并结果--- \n" << "日期: " << pTrain->strTrainDate << "\n" << "车次: " << pTrain->strTrainName << "\n" << "车厢序号: " << pTrain->iCarXH << "\n" << "车型Id: " << pTrain->trainNum.iTrainTypeId << "\n" << "车型: " << pTrain->trainNum.strTrainType << "\n" << "车号: " << pTrain->trainNum.strTrainNum << "\n" << "载重: " << pTrain->trainPro.strLoad << "\n" << "自重: " << pTrain->trainPro.strSelf << "\n" << "容积: " << pTrain->trainPro.strVolume << "\n" << "换长: " << pTrain->trainPro.strChange << "\n" << "容量计表: " << pTrain->trainPro.strVolumeSurface << "\n" << "编号图片: " << pTrain->trainNum.strBestImg << "\n" << "属性图片: " << pTrain->trainPro.strBestImg << "\n" << "开始帧号: " << pTrain->iStartFrameId << "\n" << "结束帧号: " << pTrain->iEndFrameId << "\n" << "时间戳: " << pTrain->i64TimeStamp << "\n" << "定检期_段修: " << pTrain->chkDate.strChkDate1 << "\n" << "定检期_厂修: " << pTrain->chkDate.strChkDate2 << "\n" << "定检期图片: " << pTrain->chkDate.strBestImg << "\n" << "定检期时间戳: " << pTrain->chkDate.i64TimeStamp << "\n" << "集装箱1: " << pTrain->container1.strContainerNo << "\n" << "集装箱1图片: " << pTrain->container1.strBestImg << "\n" << "集装箱1时间戳: " << pTrain->container1.i64TimeStamp << "\n" << "集装箱2: " << pTrain->container2.strContainerNo << "\n" << "集装箱2图片: " << pTrain->container2.strBestImg << "\n" << "集装箱2时间戳: " << pTrain->container2.i64TimeStamp << "\n" << "车厢开始时间: " << MyUtils::getins()->Stamp2Time(pTrain->i64StartTimeStamp, true) << "\n" << "车厢结束时间: " << MyUtils::getins()->Stamp2Time(pTrain->i64EndTimeStamp, true) << "\n" << " ---所有信息合并结果 END--- "; if (pTrain->bIsEnd) { LogInfo << " ===============所有信息合并结束=============== "; } //3:敞车,6:平车 有集装箱; 其他车型无集装箱,有误识别时剔除 if (pTrain->trainNum.iTrainTypeId != 3 && pTrain->trainNum.iTrainTypeId != 6) { pTrain->container1.strContainerNo = ""; pTrain->container1.strBestImg = ""; pTrain->container2.strContainerNo = ""; pTrain->container2.strBestImg = ""; } pTrain->bMergerFlag = true; std::shared_ptr pTrainToCsv = std::make_shared(); *pTrainToCsv = *pTrain; if (bUploadFlag_) { queTrain_.push(pTrain); if (pTrain->iDirection == iPushDirection_ || iPushDirection_ == DIRECTION_UNKNOWN) { while (!queTrain_.empty()) { std::shared_ptr pTrainToHttp = queTrain_.front(); queTrain_.pop(); outputQueMap_[strPort0_]->push(std::static_pointer_cast(pTrainToHttp)); } } if (pTrain->bIsEnd) { while (!queTrain_.empty()) { std::shared_ptr pTrainTemp = queTrain_.front(); queTrain_.pop(); LogDebug << "carNO:" << pTrainTemp->iCarXH << " direction:" << pTrainTemp->iDirection << " not push to httpSrv"; } } } //push端口1,csv保存合并结果 outputQueMap_[strPort1_]->push(std::static_pointer_cast(pTrainToCsv)); } /** * 有数据队列的个数 * inParam : N/A * outParam: N/A * return : N/A */ int MergerAllEngine::QueueHaveDataCount() { int iHaveDataCnt = 0; iHaveDataCnt = queuePort0_.empty() ? iHaveDataCnt : iHaveDataCnt + 1; iHaveDataCnt = queuePort1_.empty() ? iHaveDataCnt : iHaveDataCnt + 1; iHaveDataCnt = queuePort2_.empty() ? iHaveDataCnt : iHaveDataCnt + 1; iHaveDataCnt = queuePort3_.empty() ? iHaveDataCnt : iHaveDataCnt + 1; LogDebug << "queuePort0_size:" << queuePort0_.size() << " queuePort1_size:" << queuePort1_.size() << " queuePort2_size:" << queuePort2_.size() << " queuePort3_size:" << queuePort3_.size(); return iHaveDataCnt; } /* 注:以下异常场景也要保证 (IsEnd-结束标识) push到该Engine中。否则数据无法推送到web端。 1. 摄像头异常 2. 未识别到内容 */ APP_ERROR MergerAllEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { bool bPopFlag = false; // pop端口0,车号 if (mapPopPort_[strPort0_]) { std::shared_ptr pVoidData0 = nullptr; inputQueMap_[strPort0_]->pop(pVoidData0); if (nullptr != pVoidData0) { LogInfo<<"pop0 data"; queuePort0_.push(pVoidData0); bPopFlag = true; } } // pop端口1,定检期 if (mapPopPort_[strPort1_]) { std::shared_ptr pVoidData1 = nullptr; inputQueMap_[strPort1_]->pop(pVoidData1); if (nullptr != pVoidData1) { LogDebug<<"pop1 data"; queuePort1_.push(pVoidData1); bPopFlag = true; } } // pop端口2,集装箱 if (mapPopPort_[strPort2_]) { std::shared_ptr pVoidData2 = nullptr; inputQueMap_[strPort2_]->pop(pVoidData2); if(nullptr != pVoidData2) { LogDebug<<"pop2 data"; queuePort2_.push(pVoidData2); bPopFlag = true; } } //pop端口3,车厢范围 if (mapPopPort_[strPort3_]) { std::shared_ptr pVoidData3 = nullptr; inputQueMap_[strPort3_]->pop(pVoidData3); if (nullptr != pVoidData3) { LogDebug << "pop3 data"; queuePort3_.push(pVoidData3); bPopFlag = true; } } if (!bPopFlag) { usleep(1000); // 1ms continue; } int iHaveDataCnt = QueueHaveDataCount(); //识别目标信息个数和获取信息个数相等,则合并信息推送web if (iHaveDataCnt == iPopPortCnt_) { std::shared_ptr pTrain = nullptr; std::shared_ptr pChkDate = nullptr; std::shared_ptr pTrainContainer = nullptr; std::shared_ptr pTrainRange = nullptr; if (!queuePort0_.empty()) { pTrain = std::static_pointer_cast(queuePort0_.front()); queuePort0_.pop(); } if (!queuePort1_.empty()) { pChkDate = std::static_pointer_cast(queuePort1_.front()); queuePort1_.pop(); } if (!queuePort2_.empty()) { pTrainContainer = std::static_pointer_cast(queuePort2_.front()); queuePort2_.pop(); } if (!queuePort3_.empty()) { pTrainRange = std::static_pointer_cast(queuePort3_.front()); queuePort3_.pop(); } //信息合并处理 if (nullptr != pTrain) { if (nullptr != pTrainRange) { pTrain->iStartFrameId = pTrainRange->iStartFrameId; pTrain->i64StartTimeStamp = pTrainRange->i64StartTimeStamp; pTrain->iEndFrameId = pTrainRange->iEndFrameId; pTrain->i64EndTimeStamp = pTrainRange->i64EndTimeStamp; pTrain->bIsEnd = pTrainRange->bIsEnd; } if (nullptr != pChkDate) { pTrain->chkDate = *pChkDate; } if (nullptr != pTrainContainer) { pTrain->container1 = pTrainContainer->container1; pTrain->container2 = pTrainContainer->container2; } //车头在前为第0节; 车头在后为最后一节+1 if(pTrain->trainNum.iTrainTypeId == 0 && iTrainIndex_ == 1) { iTrainIndex_ = 0; bHeadFrontFlag_ = true; } pTrain->iCarXH = iTrainIndex_++; /* 特殊处理:针对车头在后的且当前为最后一节,且未识别到车型,则默认设置为车头。 防止车尾间隔误识别,多切分车型,且web端无法过滤的问题。 */ if (!bHeadFrontFlag_ && pTrain->bIsEnd && pTrain->trainNum.iTrainTypeId == -1) { LogDebug << "cometime:" << pTrain->strTrainDate << " " << pTrain->strTrainName << " iCarXH:" << pTrain->iCarXH << " num:" << pTrain->trainNum.strTrainNum; pTrain->trainNum.iTrainTypeId = 0; } // 修正载重 for (std::map::iterator it = mapLoad.begin(); it != mapLoad.end(); ++it) { if (pTrain->trainNum.strTrainType.find(it->first) != std::string::npos) { pTrain->trainPro.strLoad = it->second; } } // if (pTrain->trainPro.strLoad.size() > 2 && pTrain->trainPro.strLoad[0] != '1') pTrain->trainPro.strLoad = ""; PushData(pTrain); //最后一节处理后,初始化参数 if (pTrain->bIsEnd) { InitParam(); } } } } return APP_ERR_OK; }