#include "SelectBestEngine.h" #include "myutils.h" using namespace ai_matrix; SelectBestEngine::SelectBestEngine() {} SelectBestEngine::~SelectBestEngine() {} APP_ERROR SelectBestEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1"; iSelectBestMode_ = MyYaml::GetIns()->GetIntValue("gc_select_best_mode"); strResultPath_ = MyYaml::GetIns()->GetPathValue("gc_result_path"); strBestPath_ = MyYaml::GetIns()->GetPathValue("gc_best_path"); //获取几个摄像头识别车号 std::map mapUseDataSouceCfg = MyYaml::GetIns()->GetUseDataSourceConfig(); for (auto iter = mapUseDataSouceCfg.begin(); iter != mapUseDataSouceCfg.end(); iter++) { if (iter->second.strTarget.find("NUM") != std::string::npos) { mapDataSourceIsEnd_[iter->first] = false; } } InitParam(); LogInfo << "SelectBestEngine Init ok"; return APP_ERR_OK; } APP_ERROR SelectBestEngine::DeInit() { LogInfo << "SelectBestEngine DeInit ok"; return APP_ERR_OK; } /** * push数据到队列,队列满时则休眠一段时间再push * inParam : const std::string strPort push的端口 : const std::shared_ptr &pTrain push的数据 * outParam: N/A * return : N/A */ void SelectBestEngine::PushData(const std::string &strPort, const std::shared_ptr &pTrain) { while (true) { int iRet = outputQueMap_[strPort]->push(std::static_pointer_cast(pTrain)); if (iRet != 0) { LogDebug << "num:" << pTrain->trainNum.strTrainNum << " push fail iRet:" << iRet; if (iRet == 2) { usleep(10000); // 10ms continue; } } break; } } /** * 初始化车号参数信息 * inParam : N/A * outParam: N/A * return : N/A */ void SelectBestEngine::InitNumParam() { mapTrainTypeId_.clear(); mapNumInfo_.clear(); strBestNumImg_ = ""; i64TimeStampNum_ = 0; fMaxScoreSumNum_ = 0; memset(&step1LocationBestNum_, 0, sizeof(step1LocationBestNum_)); iDataSourceNum_ = 0; } /** * 初始化属性参数信息 * inParam : N/A * outParam: N/A * return : N/A */ void SelectBestEngine::InitProParam() { mapProInfo_.clear(); strBestProImg_ = ""; i64TimeStampPro_ = 0; fMaxScoreSumPro_ = 0; memset(&step1LocationBestPro_, 0, sizeof(step1LocationBestPro_)); iDataSourcePro_ = 0; } /** * 初始化车号参数信息(只有车结束调用) * inParam : N/A * outParam: N/A * return : N/A */ void SelectBestEngine::InitHeadParam() { mapHeadInfo_.clear(); strBestHeadImg_ = ""; i64TimeStampHead_ = 0; fMaxScoreSumHead_ = 0; memset(&step1LocationBestHead_, 0, sizeof(step1LocationBestHead_)); iDataSourceHead_ = 0; } /** * 初始化参数信息 * inParam : N/A * outParam: N/A * return : N/A */ void SelectBestEngine::InitParam() { iNumIndex_ = 1; iProIndex_ = 1; InitNumParam(); InitProParam(); InitHeadParam(); for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++) { iter->second = false; } } /** * 获取最优长度 * inParam : std::vector &vecAllTransInfo 待汇总取优的结果集 * : TargetMaxLen iMaxLen 目标最大长度 * outParam: N/A * return : 最优长度 */ int SelectBestEngine::GetBestLength(std::vector &vecAllTransInfo, TargetMaxLen iMaxLen) { //1.获取结果中每种长度出现的次数 std::map mapResultSize; for (size_t i = 0; i < vecAllTransInfo.size(); i++) { int iNowSize = vecAllTransInfo[i].vecValue.size(); if (mapResultSize.find(iNowSize) != mapResultSize.end()) { mapResultSize[iNowSize]++; continue; } mapResultSize[iNowSize] = 1; } int iBestLen = 0; //2.获取最优长度 if (iSelectBestMode_ == FREQUENCY) { //2.1 按长度出现的频次最多,作为最优长度 int iCnt = 0; for (auto it = mapResultSize.begin(); it != mapResultSize.end(); it++) { if (iCnt < it->second && it->first <= iMaxLen) { iCnt = it->second; iBestLen = it->first; } } } else if (iSelectBestMode_ == LENGTH) { //2.2 按最长长度且不能大于最大长度,作为最优长度 for (auto rit = mapResultSize.rbegin(); rit != mapResultSize.rend(); rit++) { if (rit->first <= iMaxLen) { iBestLen = rit->first; break; } } } return iBestLen; } /** * 获取最优结果 * inParam : std::vector &vecAllTransInfo 待汇总取优的结果集 * : TargetMaxLen iMaxLen 目标最大长度 * outParam: N/A * return : 最优结果 */ std::string SelectBestEngine::GetBest(std::vector &vecAllTransInfo, TargetMaxLen iMaxLen) { std::string strValue = ""; if (vecAllTransInfo.size() <= 0) { return strValue; } //优先使用校验通过的数据选优。 std::vector vecTransInfoTemp; for (size_t i = 0; i < vecAllTransInfo.size(); i++) { TransInfo transInfo = vecAllTransInfo[i]; if (transInfo.IsChkFlag) { vecTransInfoTemp.emplace_back(transInfo); } } if (vecTransInfoTemp.size() > 0) { vecAllTransInfo = vecTransInfoTemp; } else { // 此处因车厢太脏。识别效果很差,难以与RFID识别结果融合,所以增加eles return strValue; } //获取最优长度 int iBestLen = GetBestLength(vecAllTransInfo, iMaxLen); //初始化最优结果 TransInfo transInfoBest; transInfoBest.vecScore.reserve(iBestLen); transInfoBest.vecValue.reserve(iBestLen); for (int i = 0; i < iBestLen; i++) { transInfoBest.vecScore.emplace_back(0); transInfoBest.vecValue.emplace_back(""); } std::map mapResult; //符合最优长度的结果集 [key:结果; value:结果出现次数] for (size_t iIndex = 0; iIndex < vecAllTransInfo.size(); iIndex++) { if (vecAllTransInfo[iIndex].vecValue.size() != iBestLen) { continue; } std::string strValueTemp; for (int j = 0; j < iBestLen; j++) { strValueTemp += vecAllTransInfo[iIndex].vecValue[j]; if (transInfoBest.vecScore[j] < vecAllTransInfo[iIndex].vecScore[j]) { transInfoBest.vecScore[j] = vecAllTransInfo[iIndex].vecScore[j]; transInfoBest.vecValue[j] = vecAllTransInfo[iIndex].vecValue[j]; } } if (mapResult.find(strValueTemp) != mapResult.end()) { mapResult[strValueTemp]++; } else { mapResult[strValueTemp] = 1; } } //按字符最高得分汇总结果 for (size_t i = 0; i < transInfoBest.vecValue.size(); ++i) { strValue += transInfoBest.vecValue[i]; } //按出现次数汇总结果 int iMaxCnt = 0; std::string strValue2; for (auto iter = mapResult.begin(); iter != mapResult.end(); iter++) { if (iter->second > iMaxCnt) { iMaxCnt = iter->second; strValue2 = iter->first; } } //最高得分汇总和最高次数汇总不相等,且识别同一结果次数大于等于3次,则使用按次数汇总结果。 if (strValue != strValue2) { LogWarn << "engineId:" << engineId_ << " value1:" << strValue << " value2:" << strValue2 << " not equal value2cnt:" << iMaxCnt; if (iMaxCnt >= 3) { strValue = strValue2; } } return strValue; } /** * 车号数据加入到待选优集合中 * inParam : std::shared_ptr pProcessData :处理帧数据 : TransSubData &transSubData :转换后子数据 * outParam: N/A * return : N/A */ void SelectBestEngine::NumAddSelectBestMap(std::shared_ptr pProcessData, TransSubData &transSubData) { for (size_t i = 0; i < transSubData.vecTransInfo.size(); i++) { TransInfo transInfo = transSubData.vecTransInfo[i]; mapNumInfo_[transInfo.iLine].emplace_back(transInfo); } //记录车厢类型ID if (mapTrainTypeId_.find(transSubData.iBigClassId) != mapTrainTypeId_.end()) { mapTrainTypeId_[transSubData.iBigClassId]++; } else { mapTrainTypeId_[transSubData.iBigClassId] = 1; } //最高分和最优帧号 if (fMaxScoreSumNum_ < transSubData.fScoreSum) { fMaxScoreSumNum_ = transSubData.fScoreSum; strBestNumImg_ = std::to_string(pProcessData->iFrameId) + ".jpg"; i64TimeStampNum_ = pProcessData->i64TimeStamp; step1LocationBestNum_ = transSubData.step1Location; iDataSourceNum_ = pProcessData->iDataSource; } } /** * 属性数据加入到待选优集合中 * inParam : std::shared_ptr pProcessData :处理帧数据 : TransSubData &transSubData :转换后子数据 * outParam: N/A * return : N/A */ void SelectBestEngine::ProAddSelectBestMap(std::shared_ptr pProcessData, TransSubData &transSubData) { for (size_t i = 0; i < transSubData.vecTransInfo.size(); i++) { TransInfo transInfo = transSubData.vecTransInfo[i]; mapProInfo_[transInfo.iLine].emplace_back(transInfo); } //最高分和最优帧号 if (fMaxScoreSumPro_ < transSubData.fScoreSum) { fMaxScoreSumPro_ = transSubData.fScoreSum; strBestProImg_ = std::to_string(pProcessData->iFrameId) + ".jpg"; i64TimeStampPro_ = pProcessData->i64TimeStamp; step1LocationBestPro_ = transSubData.step1Location; iDataSourcePro_ = pProcessData->iDataSource; } } /** * 车头数据加入到待选优集合中 * inParam : std::shared_ptr pProcessData :处理帧数据 : TransSubData &transSubData :转换后子数据 * outParam: N/A * return : N/A */ void SelectBestEngine::HeadAddSelectBestMap(std::shared_ptr pProcessData, TransSubData &transSubData) { for (size_t i = 0; i < transSubData.vecTransInfo.size(); i++) { TransInfo transInfo = transSubData.vecTransInfo[i]; mapHeadInfo_[transInfo.iLine].emplace_back(transInfo); } //记录车头大框识别次数 auto iter = mapTrainTypeId_.find(0); if (iter == mapTrainTypeId_.end()) { mapTrainTypeId_.insert(std::make_pair(0, 1)); } else { iter->second++; } //最高分和最优帧号 if (fMaxScoreSumHead_ < transSubData.fScoreSum) { fMaxScoreSumHead_ = transSubData.fScoreSum; strBestHeadImg_ = std::to_string(pProcessData->iFrameId) + ".jpg"; i64TimeStampHead_ = pProcessData->i64TimeStamp; step1LocationBestHead_ = transSubData.step1Location; iDataSourceHead_ = pProcessData->iDataSource; } } /** * 汇总车头最佳值 * inParam : N/A * outParam: N/A * return : N/A */ bool SelectBestEngine::GetHeadBest(std::shared_ptr pProcessData) { //2.无识别车头信息,不汇总 if (mapHeadInfo_.empty()) { LogDebug << "engineId:" << engineId_ << " no head info"; return false; } std::shared_ptr pTrain = std::make_shared(); pTrain->trainNum.iDataSource = iDataSourceHead_; pTrain->trainNum.bIsEnd = pProcessData->bIsEnd; pTrain->trainNum.strTrainDate = pProcessData->strTrainDate; pTrain->trainNum.strTrainName = pProcessData->strTrainName; pTrain->trainNum.iDirection = pProcessData->iDirection; //车头型号 if (mapHeadInfo_.find(0) != mapHeadInfo_.end()) { pTrain->trainNum.strTrainType = GetBest(mapHeadInfo_.at(0), TYPE_MAXLEN); } //车头编号 if (mapHeadInfo_.find(1) != mapHeadInfo_.end()) { pTrain->trainNum.strTrainNum = GetBest(mapHeadInfo_.at(1), NUM_MAXLEN); } pTrain->trainNum.strBestImg = strBestHeadImg_; pTrain->trainNum.iCarXH = 0; pTrain->trainNum.step1Location = step1LocationBestHead_; pTrain->trainNum.i64TimeStamp = i64TimeStampHead_; pTrain->trainNum.iTrainTypeId = 0; //车头 //push端口1,车头属性 pTrain->trainPro.iDataSource = iDataSourceHead_; pTrain->trainPro.bIsEnd = pProcessData->bIsEnd; pTrain->trainPro.strTrainDate = pProcessData->strTrainDate; pTrain->trainPro.strTrainName = pProcessData->strTrainName; pTrain->trainPro.iDirection = pProcessData->iDirection; pTrain->trainPro.iCarXH = 0; pTrain->strTrainDate = pTrain->trainNum.strTrainDate; pTrain->strTrainName = pTrain->trainNum.strTrainName; pTrain->iDirection = pTrain->trainNum.iDirection; pTrain->iDataSource = pTrain->trainNum.iDataSource >= pTrain->trainPro.iDataSource ? pTrain->trainNum.iDataSource : pTrain->trainPro.iDataSource; LogInfo << "\n ---汇总结果--- \n" << "日期时间: " << pTrain->strTrainDate << " " << 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->iDirection << "\n" << " ---汇总结果 END--- "; //拷贝最优图片到最优路径下 CopyBestImgToBestPath(pTrain); std::shared_ptr pTrainToCsv = std::make_shared(); *pTrainToCsv = *pTrain; PushData(strPort0_, pTrain); PushData(strPort1_, pTrainToCsv); return true; } /** * 汇总车号最佳值 * inParam : std::shared_ptr pProcessData * outParam: TrainNum &trainNum * return : N/A */ void SelectBestEngine::GetNumBest(TrainNum &trainNum, std::shared_ptr pProcessData) { trainNum.iDataSource = iDataSourceNum_; trainNum.bIsEnd = pProcessData->bIsEnd; trainNum.strTrainDate = pProcessData->strTrainDate; trainNum.strTrainName = pProcessData->strTrainName; trainNum.iDirection = pProcessData->iDirection; trainNum.iCarXH = pProcessData->iTrainIndex; //车型 if (mapNumInfo_.find(0) != mapNumInfo_.end()) { trainNum.strTrainType = GetBest(mapNumInfo_.at(0), TYPE_MAXLEN); } //编号 if (mapNumInfo_.find(1) != mapNumInfo_.end()) { trainNum.strTrainNum = GetBest(mapNumInfo_.at(1), NUM_MAXLEN); } //按出现次数选车厢类型ID int iMaxCnt = 0; for (auto iter = mapTrainTypeId_.begin(); iter != mapTrainTypeId_.end(); iter++) { if (iter->second > iMaxCnt) { iMaxCnt = iter->second; trainNum.iTrainTypeId = iter->first; } } trainNum.strBestImg = strBestNumImg_; trainNum.fScoreSum = fMaxScoreSumNum_; trainNum.iCarXH = iNumIndex_++; trainNum.step1Location = step1LocationBestNum_; trainNum.i64TimeStamp = i64TimeStampNum_; //初始化车号信息 InitNumParam(); } /** * 汇总属性最佳值 * inParam : std::shared_ptr pProcessData * outParam: TrainPro &trainPro * return : N/A */ void SelectBestEngine::GetProBest(TrainPro &trainPro, std::shared_ptr pProcessData) { trainPro.iDataSource = iDataSourcePro_; trainPro.bIsEnd = pProcessData->bIsEnd; trainPro.strTrainDate = pProcessData->strTrainDate; trainPro.strTrainName = pProcessData->strTrainName; trainPro.iDirection = pProcessData->iDirection; trainPro.iCarXH = pProcessData->iTrainIndex; //载重 if (mapProInfo_.find(0) != mapProInfo_.end()) { trainPro.strLoad = GetBest(mapProInfo_.at(0), LOAD_MAXLEN); } //自重 if (mapProInfo_.find(1) != mapProInfo_.end()) { trainPro.strSelf = GetBest(mapProInfo_.at(1), SELF_MAXLEN); if (trainPro.strSelf.length() == 3) { trainPro.strSelf = trainPro.strSelf.substr(0, 2) + "." + trainPro.strSelf.substr(2, 1); } } //容积 if (mapProInfo_.find(2) != mapProInfo_.end()) { trainPro.strVolume = GetBest(mapProInfo_.at(2), VOLUME_MAXLEN); //棚车容器一般为1开头得三位整数,因此不需要额外补小数点处理。 if (trainPro.strVolume.length() == 3 && trainPro.strVolume.substr(0, 1) != "1") { trainPro.strVolume = trainPro.strVolume.substr(0, 2) + "." + trainPro.strVolume.substr(2, 1); } } //换长 if (mapProInfo_.find(3) != mapProInfo_.end()) { trainPro.strChange = GetBest(mapProInfo_.at(3), CHANGE_MAXLEN); if (trainPro.strChange.length() == 1) { if (trainPro.strChange.at(0) != '1') { trainPro.strChange = "1." + trainPro.strChange; } } else if (trainPro.strChange.length() == 2) { trainPro.strChange = trainPro.strChange.substr(0, 1) + "." + trainPro.strChange.substr(1, 1); } } //罐车容量记表 if (mapProInfo_.find(4) != mapProInfo_.end()) { trainPro.strVolumeSurface = GetBest(mapProInfo_.at(4), VOLUMESURFACE_MAXLEN); } trainPro.strBestImg = strBestProImg_; trainPro.fScoreSum = fMaxScoreSumPro_; trainPro.iCarXH = iProIndex_++; trainPro.step1Location = step1LocationBestPro_; trainPro.i64TimeStamp = i64TimeStampPro_; //初始化属性信息 InitProParam(); } /** * 拷贝最优图片到最优路径下 * inParam : N/A * outParam: N/A * return : N/A */ void SelectBestEngine::CopyBestImgToBestPath(const std::shared_ptr &pTrain) { //拷贝最优图片到最优路径下 if (!pTrain->trainNum.strBestImg.empty()) { char szCameraNo[6] = {0}; //车号最优图片路径 sprintf(szCameraNo, "/%03d/", pTrain->trainNum.iDataSource + 1); std::string strDes = strBestPath_ + pTrain->strTrainDate + "/" + pTrain->strTrainName + szCameraNo; if (!MyUtils::getins()->CreateDirPath(strDes)) { LogError << "engineId:" << engineId_ << " CreateDirPath err strDes:" << strDes; return; } std::string strSrc = strResultPath_ + pTrain->strTrainDate + "/" + pTrain->strTrainName + szCameraNo + pTrain->trainNum.strBestImg; strDes += pTrain->trainNum.strBestImg; MyUtils::getins()->copyFile(strSrc, strDes); } if (!pTrain->trainPro.strBestImg.empty()) { char szCameraNo[6] = {0}; //车号最优图片路径 sprintf(szCameraNo, "/%03d/", pTrain->trainPro.iDataSource + 1); std::string strDes = strBestPath_ + pTrain->strTrainDate + "/" + pTrain->strTrainName + szCameraNo; if (!MyUtils::getins()->CreateDirPath(strDes)) { LogError << "engineId:" << engineId_ << " CreateDirPath err strDes:" << strDes; return; } std::string strSrc = strResultPath_ + pTrain->strTrainDate + "/" + pTrain->strTrainName + szCameraNo + pTrain->trainPro.strBestImg; strDes += pTrain->trainPro.strBestImg; MyUtils::getins()->copyFile(strSrc, strDes); } } /** * 汇总车厢最佳值 * inParam : N/A * outParam: N/A * return : N/A */ void SelectBestEngine::GetTrainBest(std::shared_ptr pProcessData) { std::shared_ptr pTrain = std::make_shared(); //1.汇总车号信息 GetNumBest(pTrain->trainNum, pProcessData); //2.汇总属性信息 GetProBest(pTrain->trainPro, pProcessData); /*按车型删除误识别的属性 1.非罐车删除容量计表 2.平车删除容积 */ if (pTrain->trainNum.iTrainTypeId != 5 && pTrain->trainNum.iTrainTypeId != -1) { pTrain->trainPro.strVolumeSurface = ""; } if (pTrain->trainNum.iTrainTypeId == 6) { pTrain->trainPro.strVolume = ""; } pTrain->strTrainDate = pTrain->trainNum.strTrainDate; pTrain->strTrainName = pTrain->trainNum.strTrainName; pTrain->iDirection = pTrain->trainNum.iDirection; pTrain->iCarXH = pTrain->trainNum.iCarXH; pTrain->iDataSource = pTrain->trainNum.iDataSource >= pTrain->trainPro.iDataSource ? pTrain->trainNum.iDataSource : pTrain->trainPro.iDataSource; LogInfo << "\n ---汇总结果--- \n" << "日期时间: " << pTrain->strTrainDate << " " << 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->iDirection << "\n" << " ---汇总结果 END--- "; //拷贝最优图片到最优路径下 CopyBestImgToBestPath(pTrain); std::shared_ptr pTrainToCsv = std::make_shared(); *pTrainToCsv = *pTrain; PushData(strPort0_, pTrain); PushData(strPort1_, pTrainToCsv); } APP_ERROR SelectBestEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { //pop端口0 std::shared_ptr pVoidData0 = nullptr; iRet = inputQueMap_[strPort0_]->pop(pVoidData0); if (nullptr == pVoidData0) { usleep(1000); continue; } std::shared_ptr pProcessData = std::static_pointer_cast(pVoidData0); std::shared_ptr pTransData = std::static_pointer_cast(pProcessData->pVoidData); if (pProcessData->bIsEnd) { mapDataSourceIsEnd_[pProcessData->iDataSource] = pProcessData->bIsEnd; } for (size_t i = 0; i < pTransData->vecTransSubData.size(); i++) { TransSubData transSubData = pTransData->vecTransSubData[i]; //车头 if (transSubData.iBigClassId == 0) { //车头加入待汇总集合中 HeadAddSelectBestMap(pProcessData, transSubData); } //属性 else if (transSubData.iBigClassId == 1) { //属性加入待汇总集合中 ProAddSelectBestMap(pProcessData, transSubData); } //车号 else if (transSubData.iBigClassId >= 2 && transSubData.iBigClassId <= 6) { //车号加入待汇总集合中 NumAddSelectBestMap(pProcessData, transSubData); } } //3. 结束帧,需汇总 bool bAllEnd = true; for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++) { bAllEnd = bAllEnd && iter->second; } if (bAllEnd) { bool bHeadFlag = false; //第一节或最后一节汇总车头 //(注:针对2个车头的场景,除判断第一节和最后一节外,额外增加车头的次数,当车头大框次数大于3次时,则认为车头。因此后续第一个节和最后一节的条件可以删除) if (pProcessData->iTrainIndex == 1 || pProcessData->bIsTrainEnd || (mapTrainTypeId_.find(0) != mapTrainTypeId_.end() && (mapTrainTypeId_[0] >= 2 || mapTrainTypeId_.size() == 1))) { bHeadFlag = GetHeadBest(pProcessData); } //汇总车厢 车号和属性 if (!bHeadFlag) { GetTrainBest(pProcessData); } //初始化参数变量 InitParam(); } } return APP_ERR_OK; }