Train_Identify_arm/nvidia_ascend_engine/common_engine/TransEngine/TransTrainEngine.cpp

1 line
29 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "TransTrainEngine.h"
#include "myutils.h"
#include <regex>
#include <deque>
using namespace ai_matrix;
namespace
{
//按照x坐标排列
bool CompareX(const SingleData &v1, const SingleData &v2)
{
return (v1.fLTX < v2.fLTX);
}
//自定义比较规则
bool CmpVec(const pair<string, uint32_t> &P1, const pair<string, uint32_t> &P2)
{
return P1.second < P2.second;
}
}
TransTrainEngine::TransTrainEngine() {}
TransTrainEngine::~TransTrainEngine() {}
APP_ERROR TransTrainEngine::Init()
{
bUseEngine_ = MyUtils::getins()->ChkIsHaveTarget("NUM");
if (!bUseEngine_)
{
LogWarn << "engineId_:" << engineId_ << " not use engine";
return APP_ERR_OK;
}
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
modelConfig_ = MyYaml::GetIns()->GetModelConfig("TrainStepTwoEngine");
strResultPath_ = MyYaml::GetIns()->GetPathValue("gc_result_path");
//读取模型参数信息文件
Json::Value jvModelInfo;
if (!MyUtils::getins()->ReadJsonInfo(jvModelInfo, modelConfig_.strModelInfoPath))
{
LogError << "ModelInfoPath:" << modelConfig_.strModelInfoPath << " doesn't exist or read failed!";
return APP_ERR_COMM_NO_EXIST;
}
for (int i = 0; i < jvModelInfo["class"].size(); i++)
{
vecClassNames_.push_back(jvModelInfo["class"][i].asString());
}
// 获取几个摄像头识别车号
std::map<int, ai_matrix::DataSourceConfig> mapUseDataSouceCfg = MyYaml::GetIns()->GetUseDataSourceConfig();
for (auto iter = mapUseDataSouceCfg.begin(); iter != mapUseDataSouceCfg.end(); iter++)
{
iSkipInterval_ = iter->second.iSkipInterval;
if (iter->second.strTarget.find("NUM") != std::string::npos)
{
LogDebug << "sourceid:" << iter->first << " deal Num";
mapDataSourceIsEnd_[iter->first] = false;
}
}
InitParam();
LogInfo << "TransTrainEngine Init ok";
return APP_ERR_OK;
}
APP_ERROR TransTrainEngine::DeInit()
{
if (!bUseEngine_)
{
LogWarn << "engineId_:" << engineId_ << " not use engine";
return APP_ERR_OK;
}
LogInfo << "TransTrainEngine DeInit ok";
return APP_ERR_OK;
}
/**
* 初始化参数信息
* inParam : N/A
* outParam: N/A
* return : N/A
*/
void TransTrainEngine::InitParam()
{
for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++)
{
iter->second = false;
}
mapNumInfo_.clear();
mapPreFrameId_.clear();
}
/**
* 校验车型是否符合验证
* inParam : int classId 大框类别id
* : const std::string &trainNum 车型字符信息
* outParam: N/A
* return : true:符合; false:不符合
*/
bool TransTrainEngine::AuthTransNum(int classId, const std::string &trainNum)
{
// LogInfo << "classId:" << classId << " trainNum:" << trainNum;
switch (classId)
{
case TRAIN_HEAD: // 车头上的编号
break;
case K_TRAIN_NUM: // 编号 矿车、煤炭漏斗车(兖矿自备、枣矿自备)
{
if (trainNum == "K13" || trainNum == "KM100AH")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 4:
reg = "^K[1FMZ]{1}[36789]{1}[018ABKNT]{1}";
break;
case 5:
reg = "^K[1M]{1}[368]{1}[1ABDN]{1}[AGKNT]{1}";
break;
case 6:
reg = "^K[MF]{1}[69]{1}[80]{1}A[KH]{1}";
break;
default:
LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
case C_TRAIN_NUM: // 敞车 特殊车型 C5D CF CFK
{
if (trainNum == "CF" || trainNum == "C62A(N)")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 3:
reg = "^C[15678F]{1}[0123456DK]{1}";
break;
case 4:
reg = "^C[1678]{1}[012346]{1}[0ABCEFHKMTY]{1}";
break;
case 5:
reg = "^C[1678]{1}[01246]{1}[0ABCEY]{1}[KAFHNT]{1}";
break;
case 6:
reg = "^C[17]{1}0[0E]{1}[A-]{1}[AH]{1}";
break;
default:
LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
case P_TRAIN_NUM: // 编号 棚车
{
if (trainNum == "P70(H)" || trainNum == "P62(N)")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 3:
reg = "^P[1678]{1}[012345]{1}";
break;
case 4:
reg = "^P[678]{1}[023456]{1}[ABHKNST]{1}";
break;
case 5:
reg = "^P6[24]{1}[ANG]{1}[KT]{1}";
break;
default:
LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
case G_TRAIN_NUM: // 编号 罐车
{
if (trainNum == "GY100SK")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 2:
reg = "^G[HLS]{1}";
break;
case 3:
reg = "^[GL]{1}[1567HL]{1}[01246789K]{1}";
break;
case 4:
reg = "^[GU]{1}[167FJLNQSWY]{1}[170689]{1}[KSABDGTM075W]{1}";
break;
case 5:
reg = "^[GU]{1}[17FHNQY6]{1}[1706A89]{1}[SBDAM057W]{1}[KEHTB0ZAS]{1}";
break;
case 6:
reg = "^[UG]{1}[6YH]{1}[1489A]{1}[057W]{1}[Z0LSA]{1}[KSAT]{1}";
break;
default:
LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
case NX_TRAIN_NUM: // 编号 平车
{
if (trainNum == "N6")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 3:
reg = "^[NQX]{1}[1234678T]{1}[0124567HK]{1}";
break;
case 4:
reg = "^[BNX]{1}[16X]{1}[17BC]{1}[07AGKT]{1}";
break;
case 5:
reg = "^[NX]{1}[16NX]{1}[17C]{1}[07AGT]{1}[KTABH]{1}";
break;
case 6:
reg = "^NX17[AB]{1}[KTH]{1}";
break;
default:
LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
case J_TRAIN_NUM: // 编号 牲畜车 特种车
{
if (trainNum == "TP64GK")
{
return true;
}
std::regex reg;
switch (trainNum.size())
{
case 2:
reg = "^[DT]{1}[2678]{1}";
break;
case 3:
reg = "^[DST]{1}[12346789LQ]{1}[012578ADFGP]{1}";
break;
case 4:
reg = "^[DJNT]{1}[12356AFKQS]{1}[012345678DFQS]{1}[A12345679GHKQ]{1}";
break;
case 5:
reg = "^[DJQT]{1}[2KNSH1P]{1}[613XQ2]{1}[A761234B]{1}[KA70G]{1}";
break;
default:
LogWarn << "Unknow train classId: " << classId << " trainNum:" << trainNum;
return false;
}
return std::regex_match(trainNum, reg);
}
default:
LogWarn << "Unknow trainclassId:" << classId << " trainNum:" << trainNum;
return false;
}
return true;
}
/**
* 过滤第二步字段代号的误识别
* inParam : std::vector<SingleData> &vecObjs
* : TargetMaxLen iMaxLen
* outParam: N/A
* return : N/A
*/
void TransTrainEngine::FilterSingleData(std::vector<SingleData> &vecObjs, TargetMaxLen iMaxLen)
{
/*误识别场景
例: 车厢容积属性只有2位时但因误识别导致自重的某个字符字段代号错误划归到容积中这样实际只有2位的容积变为3位。导致选优时错误。
只处理1个字段代号的误识别若有多个字段代号同时错误无法区分哪些字符字段代号是正确的。(字段代号误识别较多时,则增强模型训练)
排除一个最大和最小值后计算平局坐标值,每个框左上角和平局值左上角高度差大于平局值的高度则剔除.
*/
if (vecObjs.size() != iMaxLen || vecObjs.size() <= 2)
{
return;
}
std::deque<SingleData> dqObjs(vecObjs.begin(), vecObjs.end());
std::sort(dqObjs.begin(), dqObjs.end(), [](SingleData &a, SingleData &b)
{
return a.fLTY < b.fLTY;
});
dqObjs.pop_front();
dqObjs.pop_back();
SingleData singleDataAvg;
for (auto iter = dqObjs.begin(); iter != dqObjs.end(); iter++)
{
singleDataAvg.fLTX += iter->fLTX;
singleDataAvg.fLTY += iter->fLTY;
singleDataAvg.fRBX += iter->fRBX;
singleDataAvg.fRBY += iter->fRBY;
}
singleDataAvg.fLTX = singleDataAvg.fLTX / dqObjs.size();
singleDataAvg.fLTY = singleDataAvg.fLTY / dqObjs.size();
singleDataAvg.fRBX = singleDataAvg.fRBX / dqObjs.size();
singleDataAvg.fRBY = singleDataAvg.fRBY / dqObjs.size();
float fAvgHeight = singleDataAvg.fRBY - singleDataAvg.fLTY;
//剔除位置错误的字符信息
for (auto iter = vecObjs.begin(); iter != vecObjs.end(); iter++)
{
float fTemp = fabs(iter->fLTY - singleDataAvg.fLTY);
if (fTemp > (fAvgHeight - 5))
{
std::string strOne = vecClassNames_.at(iter->iClassId);
LogWarn << "engineId:" << engineId_ << " " << strOne << " Line wrong ";
vecObjs.erase(iter);
break;
}
}
}
/**
* 属性框内容转换
* inParam : std::map<int, std::vector<SingleData>> &mapLine
* outParam: TransSubData &transSubData
* return : N/A
*/
void TransTrainEngine::TransPro(TransSubData &transSubData, std::map<int, std::vector<SingleData>> &mapLine)
{
//载重
if (mapLine.find(0) != mapLine.end())
{
TransInfo loadInfo;
loadInfo.iLine = 0;
std::string strTemp = "";
for (auto j = 0; j < mapLine.at(0).size(); j++)
{
//过滤非数字
std::string strOne = vecClassNames_.at(mapLine.at(0).at(j).iClassId);
if (strOne[0] < '0' || strOne[0] > '9')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in load";
continue;
}
strTemp += strOne;
loadInfo.vecValue.emplace_back(strOne);
loadInfo.vecScore.emplace_back(mapLine.at(0).at(j).fScore);
transSubData.fScoreSum += mapLine.at(0).at(j).fScore;
}
//匹配正则表达式
//std::regex reg("^[0-9]{2}");
std::regex reg("^([4,5,6,7,8,9]{1}[0-9]{1}|[1]{1}[0-3]{1}[0-9]{1})$"); //(第1位棚车:4 5; K自备车:1 5 7 8 9; 平车:7; 罐车:6 7; 敞车:6 7 8)
if (std::regex_match(strTemp, reg))
{
loadInfo.IsChkFlag = true;
}
transSubData.vecTransInfo.emplace_back(loadInfo);
}
//自重
if (mapLine.find(1) != mapLine.end())
{
FilterSingleData(mapLine.at(1), SELF_MAXLEN);
TransInfo selfInfo;
selfInfo.iLine = 1;
std::string strTemp = "";
for (auto j = 0; j < mapLine.at(1).size(); j++)
{
//过滤非数字
std::string strOne = vecClassNames_.at(mapLine.at(1).at(j).iClassId);
if (strOne[0] < '0' || strOne[0] > '9')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in self";
continue;
}
strTemp += strOne;
selfInfo.vecValue.emplace_back(strOne);
selfInfo.vecScore.emplace_back(mapLine.at(1).at(j).fScore);
transSubData.fScoreSum += mapLine.at(1).at(j).fScore;
}
//匹配正则表达式
std::regex reg("^[1,2,3]{1}[0-9]{1,2}$");
if (std::regex_match(strTemp, reg))
{
selfInfo.IsChkFlag = true;
}
transSubData.vecTransInfo.emplace_back(selfInfo);
}
//容积
if (mapLine.find(2) != mapLine.end())
{
FilterSingleData(mapLine.at(2), VOLUME_MAXLEN);
TransInfo volumeInfo;
volumeInfo.iLine = 2;
std::string strTemp = "";
for (auto j = 0; j < mapLine.at(2).size(); j++)
{
//过滤非数字
std::string strOne = vecClassNames_.at(mapLine.at(2).at(j).iClassId);
if (strOne[0] < '0' || strOne[0] > '9')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in volume";
continue;
}
strTemp += strOne;
volumeInfo.vecValue.emplace_back(strOne);
volumeInfo.vecScore.emplace_back(mapLine.at(2).at(j).fScore);
transSubData.fScoreSum += mapLine.at(2).at(j).fScore;
}
//匹配正则表达式
//std::regex reg("^[0-9]{2,3}$");
std::regex reg("^[1,6,7,8,9]{1}[0-9]{1,2}$"); //(第1位棚车:1; K自备车:1或9; 罐车:6或7; 敞车:7或8)
if (std::regex_match(strTemp, reg))
{
volumeInfo.IsChkFlag = true;
}
transSubData.vecTransInfo.emplace_back(volumeInfo);
}
//换长
if (mapLine.find(3) != mapLine.end())
{
TransInfo changeInfo;
changeInfo.iLine = 3;
std::string strTemp = "";
for (auto j = 0; j < mapLine.at(3).size(); j++)
{
//过滤非数字
std::string strOne = vecClassNames_.at(mapLine.at(3).at(j).iClassId);
if (strOne[0] < '0' || strOne[0] > '9')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in change";
continue;
}
strTemp += strOne;
changeInfo.vecValue.emplace_back(strOne);
changeInfo.vecScore.emplace_back(mapLine.at(3).at(j).fScore);
transSubData.fScoreSum += mapLine.at(3).at(j).fScore;
}
//匹配正则表达式
//std::regex reg("^[0-9]{2}$");
std::regex reg("^[1]{1}[0-9]{1}$");
if (std::regex_match(strTemp, reg))
{
changeInfo.IsChkFlag = true;
}
transSubData.vecTransInfo.emplace_back(changeInfo);
}
//罐车容量计表
if (mapLine.find(4) != mapLine.end())
{
TransInfo volumeSurfaceInfo;
volumeSurfaceInfo.iLine = 4;
std::string strTemp = "";
for (auto j = 0; j < mapLine.at(4).size(); j++)
{
strTemp += vecClassNames_.at(mapLine.at(4).at(j).iClassId);
volumeSurfaceInfo.vecValue.emplace_back(vecClassNames_.at(mapLine.at(4).at(j).iClassId));
volumeSurfaceInfo.vecScore.emplace_back(mapLine.at(4).at(j).fScore);
transSubData.fScoreSum += mapLine.at(4).at(j).fScore;
}
volumeSurfaceInfo.IsChkFlag = true; //暂不校验
transSubData.vecTransInfo.emplace_back(volumeSurfaceInfo);
}
}
/**
* 车号框内容转换
* inParam : std::map<int, std::vector<SingleData>> &mapLine
* outParam: TransSubData &transSubData
* return : N/A
*/
void TransTrainEngine::TransNum(TransSubData &transSubData, std::map<int, std::vector<SingleData>> &mapLine)
{
//车型
if (mapLine.find(0) != mapLine.end())
{
TransInfo typeInfo;
typeInfo.iLine = 0;
std::string strTemp = "";
for (auto j = 0; j < mapLine.at(0).size(); j++)
{
std::string strOne = vecClassNames_.at(mapLine.at(0).at(j).iClassId);
/*20230117 该逻辑删除有厂区发现有C70C DF4DD等车型。 针对重复印刷的场景需想其他方法处理。
//注:车型多次印刷会导致之前印刷的个别字符会识别,导致最终的识别内容变多。针对车型没有重复字符的特点,因此剔除重复的字符
auto iter = find(typeInfo.vecValue.begin(), typeInfo.vecValue.end(), strOne);
if (iter != typeInfo.vecValue.end())
{
LogWarn << "Possible duplicate recognition strOne:" << strOne;
continue;
}
*/
strTemp += strOne;
typeInfo.vecValue.emplace_back(strOne);
typeInfo.vecScore.emplace_back(mapLine.at(0).at(j).fScore);
transSubData.fScoreSum += mapLine.at(0).at(j).fScore;
}
//校验车型是否符合验证
typeInfo.IsChkFlag = AuthTransNum(transSubData.iBigClassId, strTemp);
// LogInfo << "--->>> 符合正则吗?" << typeInfo.IsChkFlag << " --- " << strTemp;
transSubData.vecTransInfo.emplace_back(typeInfo);
}
//编号
if (mapLine.find(1) != mapLine.end())
{
TransInfo numInfo;
numInfo.iLine = 1;
std::string strTemp = "";
for (auto j = 0; j < mapLine.at(1).size(); j++)
{
std::string strOne = vecClassNames_.at(mapLine.at(1).at(j).iClassId);
//过滤非数字
if (strOne[0] < '0' || strOne[0] > '9')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in num";
continue;
}
strTemp += strOne;
numInfo.vecValue.emplace_back(strOne);
numInfo.vecScore.emplace_back(mapLine.at(1).at(j).fScore);
transSubData.fScoreSum += mapLine.at(1).at(j).fScore;
}
//匹配正则表达式
std::regex reg("^[0-9]{7}$"); //车厢编号固定7位
if (std::regex_match(strTemp, reg))
{
numInfo.IsChkFlag = true;
}
transSubData.vecTransInfo.emplace_back(numInfo);
}
}
/**
* 车头框内容转换
* inParam : std::map<int, std::vector<SingleData>> &mapLine
* outParam: TransSubData &transSubData
* return : N/A
*/
void TransTrainEngine::TransHead(TransSubData &transSubData, std::map<int, std::vector<SingleData>> &mapLine)
{
//车头型号
if (mapLine.find(0) != mapLine.end())
{
TransInfo typeInfo;
typeInfo.iLine = 0;
std::string strTemp = "";
for (auto j = 0; j < mapLine.at(0).size(); j++)
{
strTemp += vecClassNames_.at(mapLine.at(0).at(j).iClassId);
typeInfo.vecValue.emplace_back(vecClassNames_.at(mapLine.at(0).at(j).iClassId));
typeInfo.vecScore.emplace_back(mapLine.at(0).at(j).fScore);
transSubData.fScoreSum += mapLine.at(0).at(j).fScore;
}
//不做结果校验IsChkFlag默认为true
typeInfo.IsChkFlag = true;
transSubData.vecTransInfo.emplace_back(typeInfo);
}
//车头编号
if (mapLine.find(1) != mapLine.end())
{
TransInfo numInfo;
numInfo.iLine = 1;
std::string strTemp = "";
for (auto j = 0; j < mapLine.at(1).size(); j++)
{
std::string strOne = vecClassNames_.at(mapLine.at(1).at(j).iClassId);
//过滤非数字
if (strOne[0] < '0' || strOne[0] > '9')
{
LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in headnum";
continue;
}
strTemp += strOne;
numInfo.vecValue.emplace_back(strOne);
numInfo.vecScore.emplace_back(mapLine.at(1).at(j).fScore);
transSubData.fScoreSum += mapLine.at(1).at(j).fScore;
}
//不做结果校验IsChkFlag默认为true
numInfo.IsChkFlag = true;
transSubData.vecTransInfo.emplace_back(numInfo);
}
}
/**
* 记录在画面中间位置识别的车号
* inParam : const TransSubData &transSubData 车号信息
: const std::shared_ptr<ProcessData> &pProcessData 帧数据
* outParam: N/A
* return : N/A
*/
void TransTrainEngine::RecordNum(const TransSubData &transSubData, const std::shared_ptr<ProcessData> &pProcessData)
{
int iCenterX = transSubData.step1Location.fLTX + (transSubData.step1Location.fRBX - transSubData.step1Location.fLTX) / 2;
int iImgL = pProcessData->iWidth / 3;
int iImgR = pProcessData->iWidth / 3 * 2;
if (iCenterX <= iImgL || iCenterX >= iImgR)
{
return;
}
std::string strValue;
for (size_t i = 0; i < transSubData.vecTransInfo.size(); i++)
{
TransInfo transInfo = transSubData.vecTransInfo[i];
if (transInfo.iLine != 1)
{
continue;
}
for (size_t j = 0; j < transInfo.vecValue.size(); j++)
{
strValue += transInfo.vecValue[j];
}
}
bool bIntervalFlag = ((int)(pProcessData->iFrameId - mapPreFrameId_[pProcessData->iDataSource]) > iSkipInterval_ * 2);
if (mapNumInfo_[pProcessData->iDataSource].find(strValue) == mapNumInfo_[pProcessData->iDataSource].end())
{
LogDebug << " frameid:" << pProcessData->iFrameId << " NUM:" << strValue
<< " bIntervalFlag:" << bIntervalFlag;
if (bIntervalFlag)
{
mapNumInfo_[pProcessData->iDataSource][strValue] = pProcessData->iFrameId;
}
}
// LogDebug << " preframeid:" << mapPreFrameId_[pProcessData->iDataSource]
// << " frameid:" << pProcessData->iFrameId << " mapsize:" << mapNumInfo_[pProcessData->iDataSource].size();
mapPreFrameId_[pProcessData->iDataSource] = pProcessData->iFrameId;
}
/**
* 保存中间位置识别车号信息到csv中
* inParam : std::shared_ptr<Train> pTrain :列车信息
* outParam:
* return : true/false
*/
bool TransTrainEngine::SaveMiddleNumCsv(const std::vector<pair<string, uint32_t>> &vecNums, const std::shared_ptr<ProcessData> &pProcessData,
int iSourceId)
{
//1. 创建保存路径 (固定路径/YYYY-MM-DD/hh-mm-ss/)
std::string strTrainPath = strResultPath_ + pProcessData->strTrainDate + "/" + pProcessData->strTrainName + "/";
if (!MyUtils::getins()->CreateDirPath(strTrainPath))
{
LogError << "fail CreateDirPath:" << strTrainPath;
return false;
}
//2. 保存csv
std::string strCsvName = pProcessData->strTrainDate + pProcessData->strTrainName + "_" + std::to_string(iSourceId) + ".csv";
strCsvName = MyUtils::getins()->replace_all_distinct(strCsvName, std::string("-"), std::string(""));
strTrainPath += strCsvName;
try
{
// 写文件
std::ofstream outFile;
outFile.open(strTrainPath, std::ios::app);
outFile << "num" << ',' << "frameid" << std::endl;
for (auto iterVec = vecNums.begin(); iterVec != vecNums.end(); iterVec++)
{
outFile << iterVec->first << "," << iterVec->second << std::endl;
}
outFile.close();
}
catch (const std::exception &)
{
LogError << "fail open dirPath:" << strTrainPath;
return false;
}
return true;
}
/**
* push数据到队列队列满时则休眠一段时间再push
* inParam : const std::string strPort push的端口
: const std::shared_ptr<ProcessData> &pProcessData push的数据
* outParam: N/A
* return : N/A
*/
void TransTrainEngine::PushData(const std::string &strPort, const std::shared_ptr<ProcessData> &pProcessData)
{
while (true)
{
int iRet = outputQueMap_[strPort]->push(std::static_pointer_cast<void>(pProcessData));
if (iRet != 0)
{
LogDebug << "sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId << " push fail iRet:" << iRet;
if (iRet == 2)
{
usleep(10000); // 10ms
continue;
}
}
break;
}
}
APP_ERROR TransTrainEngine::Process()
{
if (!bUseEngine_)
{
LogWarn << "engineId_:" << engineId_ << " not use engine";
return APP_ERR_OK;
}
int iRet = APP_ERR_OK;
while (!isStop_)
{
std::shared_ptr<void> pVoidData0 = nullptr;
inputQueMap_[strPort0_]->pop(pVoidData0);
if (nullptr == pVoidData0)
{
usleep(1000); //1ms
continue;
}
std::shared_ptr<ProcessData> pProcessData = std::static_pointer_cast<ProcessData>(pVoidData0);
//第2步后处理结果
std::shared_ptr<PostData> pPostData = std::static_pointer_cast<PostData>(pProcessData->pVoidData);
//最后一节的最后一帧为整列车的结束
if (pProcessData->bIsTrainEnd && pProcessData->bIsEnd)
{
mapDataSourceIsEnd_[pProcessData->iDataSource] = true;
}
//组织输出数据
std::shared_ptr<TransData> pTransData = std::make_shared<TransData>();
for (size_t i = 0; i < pPostData->vecPostSubData.size(); i++)
{
PostSubData postSubData = pPostData->vecPostSubData[i];
//按字段代号分类
std::map<int, std::vector<SingleData>> mapLine;
for (size_t j = 0; j < postSubData.vecSingleData.size(); j++)
{
mapLine[postSubData.vecSingleData.at(j).iLine].push_back(postSubData.vecSingleData.at(j));
}
//每一行按x坐标排序
for (auto it = mapLine.begin(); it != mapLine.end(); it++)
{
std::sort(it->second.begin(), it->second.end(), CompareX);
std::string strTemp = "";
for (auto j = 0; j < it->second.size(); j++)
{
strTemp += vecClassNames_.at(it->second.at(j).iClassId);
}
// LogDebug << "step2 char sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId
// << " bigclassId:" << postSubData.iBigClassId << " line:" << it->first << "," << strTemp;
}
TransSubData transSubData;
transSubData.iBigClassId = postSubData.iBigClassId;
transSubData.iCarXH = postSubData.iCarXH;
transSubData.step1Location = postSubData.step1Location;
//按大类处理
if(postSubData.iBigClassId == 1)
{
TransPro(transSubData, mapLine);
}
else if (postSubData.iBigClassId >= 2 && postSubData.iBigClassId <= 6)
{
TransNum(transSubData, mapLine);
RecordNum(transSubData, pProcessData);
}
else if(postSubData.iBigClassId == 0)
{
TransHead(transSubData, mapLine);
RecordNum(transSubData, pProcessData);
}
else
{
continue;
}
pTransData->vecTransSubData.emplace_back(transSubData);
}
//是否全部结束
bool bAllEnd = true;
for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++)
{
bAllEnd = bAllEnd && iter->second;
}
pProcessData->pVoidData = std::static_pointer_cast<void>(pTransData);
// push端口0车号属性选优处理
PushData(strPort0_, pProcessData);
if (bAllEnd)
{
for(auto iter = mapNumInfo_.begin(); iter != mapNumInfo_.end(); iter++)
{
std::vector<pair<string, uint32_t>> vecTemp(iter->second.begin(), iter->second.end());
sort(vecTemp.begin(), vecTemp.end(), CmpVec); //按帧号排序
SaveMiddleNumCsv(vecTemp, pProcessData, iter->first);
// for(auto iterVec = vecTemp.begin(); iterVec != vecTemp.end(); iterVec++)
// {
// LogDebug << "sourceid:" << iter->first << " num:" << iterVec->first << " frameid:" << iterVec->second;
// }
}
//转个json数组发送后面用于比较。(车厢个数和该json数据是否相等相等则不处理。不相等则挨个比较下。)
//初始化参数变量
InitParam();
}
}
return APP_ERR_OK;
}