343 lines
15 KiB
C++
343 lines
15 KiB
C++
#include "TrainParationMgr.h"
|
||
|
||
using namespace ai_matrix;
|
||
|
||
TrainParationMgr::TrainParationMgr() {}
|
||
|
||
TrainParationMgr::~TrainParationMgr() {}
|
||
|
||
APP_ERROR TrainParationMgr::Init()
|
||
{
|
||
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
|
||
strResultPath_ = MyYaml::GetIns()->GetPathValue("gc_result_path");
|
||
//获取主摄像头信息
|
||
mainCfg_ = MyYaml::GetIns()->GetDataSourceConfigById(0);
|
||
|
||
nFrameRate = 25;
|
||
InitParam();
|
||
nTailPixOffset = getTailPixOffset();
|
||
LogInfo << "TrainParationMgr Init ok";
|
||
return APP_ERR_OK;
|
||
}
|
||
|
||
APP_ERROR TrainParationMgr::DeInit()
|
||
{
|
||
LogInfo << "TrainParationMgr DeInit ok";
|
||
return APP_ERR_OK;
|
||
}
|
||
|
||
int TrainParationMgr::getTailPixOffset()
|
||
{
|
||
LogInfo << "TrainParationMgr getTailPixOffset start";
|
||
// 单位计算
|
||
// 帧宽像素/米
|
||
float fframewidth_meter = ((METHOD_BASE_WIDTH * 1.0) / (TRAIN_IN_CAMERA_WIDTH));
|
||
// 车尾车钩像素位置
|
||
float fOffsetPosistion = TRAIN_WIDTH * fframewidth_meter;
|
||
int nretOffset = (int)fOffsetPosistion;
|
||
return nretOffset;
|
||
}
|
||
|
||
/**
|
||
* 参数初始化(列车结束时需调用)
|
||
* inParam : N/A
|
||
* outParam: N/A
|
||
* return : N/A
|
||
*/
|
||
void TrainParationMgr::InitParam()
|
||
{
|
||
|
||
}
|
||
|
||
/**
|
||
* 计算车钩移动的像素值
|
||
* inParam : 行车速度(单位:米/秒)
|
||
* inParam : 宽度
|
||
* inParam : 相机帧率(单位:帧/秒)
|
||
* outParam: N/A
|
||
* return : 间隔帧
|
||
*/
|
||
int TrainParationMgr::getCouplerOffsetPosition(float fspeed, int nframeindex)
|
||
{
|
||
LogInfo << "TrainAnaEngine getCouplerOffsetPosition start";
|
||
//单位换算
|
||
// 米/秒 -> 米/帧
|
||
// 米/帧 = 米/秒 * 秒/帧(即:1/帧率)
|
||
float fmeter_frame = fspeed / nFrameRate;
|
||
// 米/帧 -> 像素/帧
|
||
// 像素/帧 = 米/帧 * 像素/米
|
||
float fpix_frame = fmeter_frame * (METHOD_BASE_WIDTH / TRAIN_IN_CAMERA_WIDTH);
|
||
|
||
int nretPixOffet = (int)fpix_frame;
|
||
nretPixOffet = nretPixOffet * nframeindex;
|
||
LogInfo << "TrainAnaEngine getCouplerOffsetPosition nretPixOffet:" << nretPixOffet;
|
||
LogInfo << "TrainAnaEngine getCouplerOffsetPosition end";
|
||
return nretPixOffet;
|
||
}
|
||
|
||
/**
|
||
* 计算车钩移动的像素值
|
||
* inParam : 行车速度(单位:米/秒)
|
||
* inParam : 宽度
|
||
* inParam : 相机帧率(单位:帧/秒)
|
||
* outParam: N/A
|
||
* return : 间隔帧
|
||
*/
|
||
int TrainParationMgr::getCouplerOffsetPix(float fspeed, int noffsetPix)
|
||
{
|
||
LogInfo << "TrainAnaEngine getCouplerOffsetPix start";
|
||
LogInfo << "TrainAnaEngine getCouplerOffsetPix fspeed:" << fspeed;
|
||
// LogInfo << "TrainAnaEngine getCouplerOffsetPix start:" << nframeindex;
|
||
//单位换算
|
||
// 米/秒 -> 米/帧
|
||
// 米/帧 = 米/秒 * 秒/帧(即:1/帧率)
|
||
float fmeter_frame = fspeed / nFrameRate;
|
||
LogInfo << "TrainAnaEngine getCouplerOffsetPix fmeter_frame:" << fmeter_frame;
|
||
// 米/帧 -> 像素/帧
|
||
// 像素/帧 = 米/帧 * 像素/米
|
||
float fpix_frame = fmeter_frame * (METHOD_BASE_WIDTH / TRAIN_IN_CAMERA_WIDTH);
|
||
LogInfo << "TrainAnaEngine getCouplerOffsetPix fpix_frame:" << fpix_frame;
|
||
|
||
int nretPixOffet = (int)fpix_frame;
|
||
nretPixOffet = (noffsetPix - (METHOD_BASE_WIDTH / 2)) / nretPixOffet;
|
||
LogInfo << "TrainAnaEngine getCouplerOffsetPix nretPixOffet:" << nretPixOffet;
|
||
LogInfo << "TrainAnaEngine getCouplerOffsetPix end";
|
||
return nretPixOffet;
|
||
}
|
||
|
||
/**
|
||
* 计算车钩从中间到边缘的间隔帧
|
||
* inParam : 行车速度(单位:米/秒)
|
||
* inParam : 宽度
|
||
* inParam : 相机帧率(单位:帧/秒)
|
||
* outParam: N/A
|
||
* return : 间隔帧
|
||
*/
|
||
int TrainParationMgr::getOffsetFrame(float fspeed, int width, int nFrameRate)
|
||
{
|
||
LogInfo << "TrainAnaEngine getOffsetFrame start";
|
||
LogInfo << "TrainAnaEngine getOffsetFrame fspeed:" << fspeed;
|
||
LogInfo << "TrainAnaEngine getOffsetFrame width:" << width;
|
||
LogInfo << "TrainAnaEngine getOffsetFrame nFrameRate:" << nFrameRate;
|
||
//LogInfo << "TrainAnaEngine getOffsetFrame nLatestFrame:" << nLatestFrame;
|
||
//偏移值 = (中间到边缘的宽度(米) / 速度(米/秒)->时间(秒))* 帧率(帧/秒)
|
||
float ftmp = width * (float) nFrameRate;
|
||
LogInfo << "TrainAnaEngine getOffsetFrame start end:" << ftmp;
|
||
ftmp = ftmp / fspeed;
|
||
LogInfo << "TrainAnaEngine getOffsetFrame start end:" << ftmp;
|
||
int nRet = (int) ftmp;
|
||
LogInfo << "TrainAnaEngine getOffsetFrame start end:" << nRet;
|
||
return nRet;
|
||
}
|
||
|
||
|
||
|
||
APP_ERROR TrainParationMgr::Process()
|
||
{
|
||
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<PartionInfo> pPartionInfo = std::static_pointer_cast<PartionInfo>(pVoidData0);
|
||
|
||
int nSize = lstPartInfo.size();
|
||
int nPartionIndex = nSize - 1;
|
||
int nPrePartionIndex = nPartionIndex;
|
||
|
||
//当然车厢通过的数量
|
||
if (nSize == 0) {
|
||
PartionInfo stTempInfo;
|
||
stTempInfo.endframe = pPartionInfo->modelSpaceFrame;
|
||
stTempInfo.i64EndTimeStamp = pPartionInfo->i64EndTimeStamp;
|
||
stTempInfo.nindex = 1;
|
||
//第一节车厢开始帧为跳帧数,开始帧时间设置为来车时间
|
||
stTempInfo.startframe = mainCfg_.iSkipInterval;
|
||
std::string strTemp = pPartionInfo->strTrainDate + " " + pPartionInfo->strTrainName;
|
||
stTempInfo.i64StartTimeStamp = MyUtils::getins()->GetParamTimeMilliSeconds(strTemp);
|
||
stTempInfo.fspeed = TRAIN_DEFAULT_SPEED;
|
||
stTempInfo.fLTX = (abs(pPartionInfo->fLTX - pPartionInfo->fRBX) / 2) + pPartionInfo->fLTX;
|
||
lstPartInfo.push_back(stTempInfo);
|
||
//lstPartInfo.push_back(stTempInfo);
|
||
nPartionIndex++;
|
||
}
|
||
{
|
||
lstPartInfo[nPartionIndex].i64EndTimeStamp = pPartionInfo->i64EndTimeStamp;
|
||
lstPartInfo[nPartionIndex].endframe = pPartionInfo->modelSpaceFrame;
|
||
// 根据开始帧时间戳和结束帧时间错 计算当节车厢的行车速度
|
||
// LogInfo << "TrainAnaEngine checkPartion bPartion == true lstPartInfo[nPrePartionIndex].ftime:" << abs(lstPartInfo[nPrePartionIndex].i64EndTimeStamp - lstPartInfo[nPrePartionIndex].i64StartTimeStamp);
|
||
// 根据时间戳计算时间差
|
||
|
||
LogInfo << "-测试-----测试-----测试------测试-";
|
||
|
||
float nTimePassed = (abs(lstPartInfo[nPartionIndex].i64EndTimeStamp - lstPartInfo[nPartionIndex].i64StartTimeStamp)) * 1.0;
|
||
//防止停车导致速度过小
|
||
if(pPartionInfo->nStatus != TRAIN_PAUSE && nTimePassed <= 50000) {
|
||
lstPartInfo[nPartionIndex].fspeed = (TRAIN_WIDTH * 1000.0) /nTimePassed;
|
||
} else {
|
||
if (nPartionIndex >= 1){
|
||
lstPartInfo[nPartionIndex].fspeed = lstPartInfo[nPartionIndex - 1].fspeed / 3;
|
||
} else {
|
||
lstPartInfo[nPartionIndex].fspeed = TRAIN_DEFAULT_SPEED / 10;
|
||
}
|
||
}
|
||
|
||
//
|
||
//nSamePartionIgnoreCount = (nTimePassed / (3 * 5000)) * nFrameRate;
|
||
// 结束帧为当前帧再往后 (除以2的原因:中间为车钩,车钩后的车体宽度为整个镜头的宽度除以2)
|
||
//lstPartInfo[nPrePartionIndex].endframe = pPartionInfo->modelSpaceFrame;
|
||
//LogInfo << "TrainAnaEngine checkPartion bPartion == true lstPartInfo[nPrePartionIndex].endframe" << lstPartInfo[nPrePartionIndex].endframe;
|
||
lstPartInfo[nPartionIndex].bmodelconfirmed = true;
|
||
}
|
||
LogInfo << "-测试3-----测试3-----测试3------测试3-";
|
||
|
||
/// write json info to file
|
||
|
||
//先读取文本内容,追加新的信息后再写入
|
||
//划分信息 JSON格式
|
||
Json::Value jvPartionInfo;
|
||
//JSON保存路径
|
||
std::string strFilePath;
|
||
bool brightcome = false;
|
||
int nrightoffset = 0;
|
||
|
||
if (pPartionInfo->nStatus == 1) {
|
||
brightcome = true;
|
||
// nrightoffset = -1;
|
||
}
|
||
|
||
//检测到车厢划分信息
|
||
{
|
||
|
||
LogInfo << "-测试2-----测试2-----测试2------测试2-";
|
||
|
||
// if (nPartionIndex == 0) {
|
||
// lstPartInfo[nPartionIndex].endframe = lstPartInfo[nPartionIndex].endframe - nrightoffset * (lstPartInfo[nPartionIndex].fLTX - METHOD_BASE_WIDTH) / 10;
|
||
// } else {
|
||
// lstPartInfo[nPartionIndex].endframe = lstPartInfo[nPartionIndex].endframe - nrightoffset * getCouplerOffsetPix(lstPartInfo[nPartionIndex].fspeed, lstPartInfo[nPartionIndex].endframe);
|
||
// }
|
||
//lstPartInfo[nPartionIndex].endframe = lstPartInfo[nPartionIndex].endframe + getOffsetFrame(lstPartInfo[nPartionIndex].fspeed, (TRAIN_IN_CAMERA_WIDTH / 2), nFrameRate);
|
||
strFilePath = strResultPath_ + pPartionInfo->strTrainDate + "/" + pPartionInfo->strTrainName + "/"
|
||
+ std::to_string(nPartionIndex + 1) + ".txt";
|
||
|
||
// 首部车钩的偏移位置 (单位帧)
|
||
int headpos = 0;
|
||
// 尾部车钩的偏移位置 (单位帧)
|
||
int tailpos = (0 - nTailPixOffset);
|
||
|
||
//if (nPartionIndex == 0)
|
||
{
|
||
headpos = METHOD_BASE_WIDTH / 2;
|
||
tailpos = tailpos + headpos;
|
||
}
|
||
// 是否位右侧来车
|
||
|
||
if (brightcome == true)
|
||
{
|
||
//brightcome = true;
|
||
// 右侧来车 首部车钩从画面最右侧开始
|
||
headpos = METHOD_BASE_WIDTH / 2;
|
||
// 右侧来车 尾部车钩从画面最右侧+车厢宽的像素值
|
||
tailpos = headpos + nTailPixOffset;
|
||
/*
|
||
if (nPartionIndex == 0)
|
||
{
|
||
headpos = METHOD_BASE_WIDTH / 2;
|
||
tailpos = tailpos - headpos;
|
||
}
|
||
*/
|
||
}
|
||
|
||
LogInfo << "TrainAnaEngine Process lstPartInfo[nPartionIndex].startframe:" << lstPartInfo[nPartionIndex].startframe ;
|
||
LogInfo << "TrainAnaEngine Process lstPartInfo[nPartionIndex].endframe:" << lstPartInfo[nPartionIndex].endframe;
|
||
//从当节车厢的开始帧到结束帧计算首部车钩和尾部车钩的偏移值
|
||
// for (int nplayframe = lstPartInfo[nPartionIndex].startframe; nplayframe <= lstPartInfo[nPartionIndex].endframe; nplayframe++)
|
||
// {
|
||
// Json::Value jvposInfo;
|
||
// // 当前车厢的第几几帧
|
||
// int noffsetindex = (nplayframe - lstPartInfo[nPartionIndex].startframe);
|
||
// // 根据车速计算车钩位置量(单位 像素)
|
||
// int noffsetpos = getCouplerOffsetPosition(lstPartInfo[nPartionIndex].fspeed, noffsetindex);
|
||
// // 初始化首部车钩偏移量(单位 像素)
|
||
// jvposInfo["headpos"] = -1;
|
||
// // 初始化尾部车钩偏移量(单位 像素)
|
||
// jvposInfo["tailpos"] = -1;
|
||
|
||
// if (brightcome == false) {
|
||
// // 左侧来车
|
||
// // 首部车钩和尾部车钩 每帧加 车钩偏移值
|
||
// jvposInfo["headpos"] = (headpos + noffsetpos);
|
||
// jvposInfo["tailpos"] = (tailpos + noffsetpos);
|
||
// } else {
|
||
// // 右侧来车
|
||
// // 首部车钩和尾部车钩 每帧减 车钩偏移值
|
||
// jvposInfo["headpos"] = (headpos - noffsetpos);
|
||
// jvposInfo["tailpos"] = (tailpos - noffsetpos);
|
||
// }
|
||
// //LogInfo << "TrainAnaEngine Process jvposInfo[headpos]" << jvposInfo["headpos"];
|
||
// // LogInfo << "TrainAnaEngine Process jvposInfo[tailpos]:" << jvposInfo["tailpos"];
|
||
// //LogInfo << "TrainAnaEngine Process jvPartionListInfo.append";
|
||
// jvPartionInfo[std::to_string(nplayframe)] = jvposInfo;
|
||
// }
|
||
|
||
PartionInfo stTempInfo;
|
||
// 开始记录新的一节车厢信息(从索引变成序号+1 ,新增一节车厢信息+1)
|
||
stTempInfo.nindex = nPartionIndex + 2;
|
||
// 上一节车厢的结束帧 - (偏移帧 = (镜头内的车体宽度/ (速度) -> 通过时间) * 帧/秒 ) 作为下一节车厢的开始帧
|
||
int ntempOffsetFrame = lstPartInfo[nPartionIndex].endframe;
|
||
//
|
||
//- (int)(((TRAIN_IN_CAMERA_WIDTH / 2) / lstPartInfo[nPartionIndex].fspeed) * nFrameRate);
|
||
//LogInfo << "TrainAnaEngine Process ntempOffsetFrame:" << ntempOffsetFrame;
|
||
stTempInfo.startframe = ntempOffsetFrame;
|
||
stTempInfo.i64StartTimeStamp = pPartionInfo->i64EndTimeStamp;
|
||
// 初始化下一节的结束帧
|
||
//stTempInfo.endframe = 0;
|
||
|
||
lstPartInfo.push_back(stTempInfo);
|
||
|
||
// 记录过车日期
|
||
jvPartionInfo["trainDate"] = pPartionInfo->strTrainDate;
|
||
// 记录过车时间
|
||
jvPartionInfo["trainName"] = pPartionInfo->strTrainName;
|
||
// 记录车厢节数 (索引从0开始 所以这里+1)
|
||
jvPartionInfo["trainNo"] = nPartionIndex + 1;
|
||
// 记录行车开始帧
|
||
jvPartionInfo["startFrameId"] = lstPartInfo[nPartionIndex].startframe;
|
||
jvPartionInfo["startTimeStamp"] = lstPartInfo[nPartionIndex].i64StartTimeStamp;
|
||
// 记录行车结束帧
|
||
jvPartionInfo["endFrameId"] = lstPartInfo[nPartionIndex].endframe;
|
||
jvPartionInfo["endTimeStamp"] = lstPartInfo[nPartionIndex].i64EndTimeStamp;
|
||
// 记录车厢是否完全通过
|
||
jvPartionInfo["isEnd"] = pPartionInfo->bIsEnd;
|
||
|
||
//是否是间隔模型切分的车厢
|
||
jvPartionInfo["modelconfirmed"] = pPartionInfo->bmodelconfirmed;
|
||
|
||
// 记录当前车厢的信息到JSON文件
|
||
MyUtils::getins()->WriteJsonInfo(jvPartionInfo, strFilePath);
|
||
std::shared_ptr<TrainRange> pTrainRange = std::make_shared<TrainRange>();
|
||
pTrainRange->strTrainDate = jvPartionInfo["trainDate"].asString();
|
||
pTrainRange->strTrainName = jvPartionInfo["trainName"].asString();
|
||
pTrainRange->iTrainIndex = jvPartionInfo["trainNo"].asInt();
|
||
pTrainRange->iStartFrameId = jvPartionInfo["startFrameId"].asInt();
|
||
pTrainRange->i64StartTimeStamp = jvPartionInfo["startTimeStamp"].asInt64();
|
||
pTrainRange->iEndFrameId = jvPartionInfo["endFrameId"].asInt();
|
||
pTrainRange->i64EndTimeStamp = jvPartionInfo["endTimeStamp"].asInt64();
|
||
pTrainRange->bIsEnd = jvPartionInfo["isEnd"].asBool();
|
||
pTrainRange->bmodelconfirmed = jvPartionInfo["modelconfirmed"].asBool();
|
||
iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pTrainRange));
|
||
}
|
||
|
||
if (pPartionInfo->bIsEnd) {
|
||
lstPartInfo.clear();
|
||
}
|
||
}
|
||
return APP_ERR_OK;
|
||
}
|