优化:

1. 通过内存池解决丢帧问题;
2. 解析惯导卫星个数,并通过socket发送给psdk;
3. 取消通过sbg卫星时间设置linux系统时间,此功能交给psdk做;
This commit is contained in:
tangchao0503
2022-12-24 16:59:41 +08:00
parent da57cc8e87
commit e96953b54a
9 changed files with 506 additions and 46 deletions

View File

@ -21,6 +21,15 @@ XimeaImager::XimeaImager()
m_recordTempThread->start();
connect(this, SIGNAL(recordXimeaTemperatureSignal(QString)),m_ximeaTemperature, SLOT(recordTemperature(QString)));
writeData2DiskThread = new QThread();
writeData2Disk = new WriteData2Disk();
writeData2Disk->moveToThread(writeData2DiskThread);
writeData2DiskThread->start(QThread::HighestPriority);
connect(this, SIGNAL(startWriteDiskSignal()), writeData2Disk, SLOT(write2Disk()));
m_pool = new MemoryPool<DataBuffer>;
q = new queue<DataBuffer *>;
}
void XimeaImager::openImger()
@ -77,6 +86,7 @@ void XimeaImager::openImger()
int frameSizeAuto = m_imager.getBufferSizeOfOneFrame();
m_iFrameSizeInByte = frameSizeAuto;
std::cout<<"每一帧的字节数:-------------------------------"<< m_iFrameSizeInByte <<std::endl;
m_buffer = new unsigned short[m_iFrameSizeInByte];
@ -441,65 +451,66 @@ void XimeaImager::startRecord(double TimeDifferenceBetweensOSAndSbg,QString base
m_iFrameCounter=0;
m_bRecordControl=true;
m_imager.start();
m_baseFileName=baseFileName;
QString imageFileName=m_baseFileName+".bil";
QString timesFileName=m_baseFileName+".times";
//
FILE *hFile=fopen(imageFileName.toStdString().c_str(),"w+b");
QString timesFileName=m_baseFileName+".times";
FILE *hHimesFile=fopen(timesFileName.toStdString().c_str(),"w+");
using namespace std;
ofstream timesFileHandle(timesFileName.toStdString()+"_ofstream");
// ofstream timesFileHandle(timesFileName.toStdString()+"_ofstream");
writeData2Disk->setParm(q,m_baseFileName,m_iFrameSizeInByte, m_pool);
emit startWriteDiskSignal();
m_imager.start();
struct timeval timeStart, timeEnd;
double runTime=0;
gettimeofday(&timeStart, NULL);
while (m_bRecordControl)
{
unsigned short *x=m_imager.get_frame(m_buffer);
//fwrite(m_buffer,2,getBandCount()*getSampleCount(),hFile);
fwrite(m_imager.m_image.bp,static_cast<int>(m_imager.m_image.bp_size),1,hFile);
// fwrite(m_imager.m_image.bp,static_cast<int>(m_imager.m_image.bp_size),1,hFile);
//fflush(hFile);//只保证了将IO缓冲写入系统缓冲中使IO读操作能成功但系统什么时候写入磁盘由系统决定一般是达到一定量时系统他就写入磁盘。
//sync();//强制系统将系统文件缓冲的内容写入磁盘
m_iFrameCounter+=1;
// if(m_iFrameCounter==100)
// break;
r_qtx.lock();
DataBuffer * buffer = m_pool->newElement();
r_qtx.unlock();
// m_pool->construct(buffer);
// memcpy(buffer->data,(unsigned short *)m_imager.m_image.bp,m_iFrameSizeInByte/2);
memcpy((void *)buffer->data,m_imager.m_image.bp,m_iFrameSizeInByte);
r_qtx.lock();
q->push(buffer);
r_qtx.unlock();//
// std::cout<<"XimeaImager::startRecord队列长度为"<< q->size() <<std::endl;//
// fwrite(buffer,1,m_iFrameSizeInByte,hFile);
m_iFrameCounter+=1;
double sbgTime=getSbgTime(TimeDifferenceBetweensOSAndSbg);
fprintf(hHimesFile,"%f\n",sbgTime);
//fwrite(&sbgTime,sizeof(double),1,hHimesFile);
timesFileHandle << sbgTime << "\n";
// timesFileHandle << sbgTime << "\n";
// std::cout<<"XimeaImager::startRecord---std::cout: "<<sbgTime<<std::endl;
// //用于测试是否漏帧
// if(m_iFrameCounter==getFramerate()*20)
// {
// break;
// }
// if(m_iFrameCounter/getFramerate() > 5*60) //这个判断会导致丢帧率的大幅升高5% → 20%,推测原因:除法耗时;
// {
// break;
// }
// unsigned char pixel = *(unsigned char*)image.bp;//Default value: XI_MONO8
// unsigned short pixel =*(unsigned short*)image.bp;//XI_RAW16
// printf("Image %d (%dx%d) received from camera. First pixel value: %d\n", m_iFrameCounter, (int)image.width, (int)image.height, pixel);
}
gettimeofday(&timeEnd, NULL);
runTime = (timeEnd.tv_sec - timeStart.tv_sec ) + (double)(timeEnd.tv_usec -timeStart.tv_usec)/1000000;
m_imager.stop();
double frameInTheory=runTime * getFramerate();
double frameLossed=frameInTheory - m_iFrameCounter;
@ -514,12 +525,10 @@ void XimeaImager::startRecord(double TimeDifferenceBetweensOSAndSbg,QString base
std::cout<<"丢失帧数为: "<<frameLossed<<std::endl;
std::cout<<"丢帧率为: "<<frameLossRate * 100<< "%" <<std::endl;
fclose(hFile);
fclose(hHimesFile);
timesFileHandle.close();
// timesFileHandle.close();
printf("Stopping acquisition...\n");
m_imager.stop();
writeHdr();
@ -704,6 +713,14 @@ int XimeaImager::getFrameCounter()
return m_iFrameCounter;
}
DataBuffer::DataBuffer()
{
}
DataBuffer::~DataBuffer()
{
}
RecordXimeaTemperature::RecordXimeaTemperature(Iris::IrisXimeaImager * imager)
{
m_imager = imager;
@ -739,3 +756,61 @@ void RecordXimeaTemperature::recordTemperature(QString filePath= nullptr)
ximeaTemperatureFile.close();
}
WriteData2Disk::WriteData2Disk()
{
}
void WriteData2Disk::write2Disk()
{
QString imageFileName=m_QbaseFileName+".bil";
FILE *hFile=fopen(imageFileName.toStdString().c_str(),"w+b");
int sleepCounters=1;
int frameCounter = 0;
unsigned short * dataBuffer = new unsigned short[m_iFrameSizeInByte/2];
while(true)
{
r_qtx.lock();
bool bempty=m_q->empty();
r_qtx.unlock();
if(bempty)
{
QThread::msleep(sleepCounters * sleepCounters * 10);
// std::cout<<"WriteData2Disk::write2Disk-----------------------队列第几次为空:" << sleepCounters <<std::endl;
sleepCounters++;
if (sleepCounters == 10 && frameCounter != 0)//如果sleepCounters == 10时队列还是空就代表相机停止采集 → 退出此线程
{
break;
}
continue;
}
sleepCounters = 1;
r_qtx.lock();
DataBuffer * buffer = m_q->front();
memcpy(dataBuffer,buffer->data,m_iFrameSizeInByte);
// m_pool->destroy(m_q->front());
m_pool->deleteElement(buffer);
m_q->pop();
r_qtx.unlock();
// std::cout<<"WriteData2Disk::write2Disk-----------------------正在写磁盘!" << m_pool->max_size() <<std::endl;//
fwrite(dataBuffer,1,m_iFrameSizeInByte, hFile);
frameCounter++;
}
std::cout<<"WriteData2Disk::write2Disk-----------------------写磁盘线程将退出,内存池可达到的最多元素数:" << m_pool->max_size() <<std::endl;
std::cout<<"WriteData2Disk::write2Disk-----------------------写磁盘线程将退出,共写帧数:" << frameCounter <<std::endl;
}
void WriteData2Disk::setParm(queue<DataBuffer *> * q, QString baseFileName, int frameSizeInByte, MemoryPool<DataBuffer> * pool)
{
m_q = q;
m_QbaseFileName = baseFileName;
m_iFrameSizeInByte = frameSizeInByte;
m_pool = pool;
}