优化:

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

@ -41,7 +41,9 @@ add_executable(${CMAKE_PROJECT_NAME}
Source_Files/ximeaimager.cpp Source_Files/ximeaimager.cpp
Header_Files/ximeaimager.h Header_Files/ximeaimager.h
Source_Files/configfile.cpp Source_Files/configfile.cpp
Header_Files/configfile.h) Header_Files/configfile.h
Header_Files/MemoryPool.tcc
Header_Files/MemoryPool.h)
qt5_use_modules(${CMAKE_PROJECT_NAME} ${QT}) qt5_use_modules(${CMAKE_PROJECT_NAME} ${QT})
target_link_libraries(${CMAKE_PROJECT_NAME} target_link_libraries(${CMAKE_PROJECT_NAME}

98
Header_Files/MemoryPool.h Normal file
View File

@ -0,0 +1,98 @@
/*-
* Copyright (c) 2013 Cosku Acay, http://www.coskuacay.com
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef MEMORY_POOL_H
#define MEMORY_POOL_H
#include <climits>
#include <cstddef>
template <typename T, size_t BlockSize = 16368000>
class MemoryPool
{
public:
/* Member types */
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef const T* const_pointer;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef std::false_type propagate_on_container_copy_assignment;
typedef std::true_type propagate_on_container_move_assignment;
typedef std::true_type propagate_on_container_swap;
template <typename U> struct rebind {
typedef MemoryPool<U> other;
};
/* Member functions */
MemoryPool() noexcept;
MemoryPool(const MemoryPool& memoryPool) noexcept;
MemoryPool(MemoryPool&& memoryPool) noexcept;
template <class U> MemoryPool(const MemoryPool<U>& memoryPool) noexcept;
~MemoryPool() noexcept;
MemoryPool& operator=(const MemoryPool& memoryPool) = delete;
MemoryPool& operator=(MemoryPool&& memoryPool) noexcept;
pointer address(reference x) const noexcept;
const_pointer address(const_reference x) const noexcept;
// Can only allocate one object at a time. n and hint are ignored
pointer allocate(size_type n = 1, const_pointer hint = 0);
void deallocate(pointer p, size_type n = 1);
size_type max_size() const noexcept;
template <class U, class... Args> void construct(U* p, Args&&... args);
template <class U> void destroy(U* p);
template <class... Args> pointer newElement(Args&&... args);
void deleteElement(pointer p);
private:
union Slot_ {
value_type element;
Slot_* next;
};
typedef char* data_pointer_;
typedef Slot_ slot_type_;
typedef Slot_* slot_pointer_;
slot_pointer_ currentBlock_;
slot_pointer_ currentSlot_;
slot_pointer_ lastSlot_;
slot_pointer_ freeSlots_;
size_type padPointer(data_pointer_ p, size_type align) const noexcept;
void allocateBlock();
static_assert(BlockSize >= 2 * sizeof(slot_type_), "BlockSize too small.");
};
#include "MemoryPool.tcc"
#endif // MEMORY_POOL_H

235
Header_Files/MemoryPool.tcc Normal file
View File

@ -0,0 +1,235 @@
/*-
* Copyright (c) 2013 Cosku Acay, http://www.coskuacay.com
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef MEMORY_BLOCK_TCC
#define MEMORY_BLOCK_TCC
template <typename T, size_t BlockSize>
inline typename MemoryPool<T, BlockSize>::size_type
MemoryPool<T, BlockSize>::padPointer(data_pointer_ p, size_type align)
const noexcept
{
uintptr_t result = reinterpret_cast<uintptr_t>(p);
return ((align - result) % align);
}
template <typename T, size_t BlockSize>
MemoryPool<T, BlockSize>::MemoryPool()
noexcept
{
currentBlock_ = nullptr;
currentSlot_ = nullptr;
lastSlot_ = nullptr;
freeSlots_ = nullptr;
}
template <typename T, size_t BlockSize>
MemoryPool<T, BlockSize>::MemoryPool(const MemoryPool& memoryPool)
noexcept :
MemoryPool()
{}
template <typename T, size_t BlockSize>
MemoryPool<T, BlockSize>::MemoryPool(MemoryPool&& memoryPool)
noexcept
{
currentBlock_ = memoryPool.currentBlock_;
memoryPool.currentBlock_ = nullptr;
currentSlot_ = memoryPool.currentSlot_;
lastSlot_ = memoryPool.lastSlot_;
freeSlots_ = memoryPool.freeSlots;
}
template <typename T, size_t BlockSize>
template<class U>
MemoryPool<T, BlockSize>::MemoryPool(const MemoryPool<U>& memoryPool)
noexcept :
MemoryPool()
{}
template <typename T, size_t BlockSize>
MemoryPool<T, BlockSize>&
MemoryPool<T, BlockSize>::operator=(MemoryPool&& memoryPool)
noexcept
{
if (this != &memoryPool)
{
std::swap(currentBlock_, memoryPool.currentBlock_);
currentSlot_ = memoryPool.currentSlot_;
lastSlot_ = memoryPool.lastSlot_;
freeSlots_ = memoryPool.freeSlots;
}
return *this;
}
template <typename T, size_t BlockSize>
MemoryPool<T, BlockSize>::~MemoryPool()
noexcept
{
slot_pointer_ curr = currentBlock_;
while (curr != nullptr) {
slot_pointer_ prev = curr->next;
operator delete(reinterpret_cast<void*>(curr));
curr = prev;
}
}
template <typename T, size_t BlockSize>
inline typename MemoryPool<T, BlockSize>::pointer
MemoryPool<T, BlockSize>::address(reference x)
const noexcept
{
return &x;
}
template <typename T, size_t BlockSize>
inline typename MemoryPool<T, BlockSize>::const_pointer
MemoryPool<T, BlockSize>::address(const_reference x)
const noexcept
{
return &x;
}
template <typename T, size_t BlockSize>
void
MemoryPool<T, BlockSize>::allocateBlock()
{
// Allocate space for the new block and store a pointer to the previous one
data_pointer_ newBlock = reinterpret_cast<data_pointer_>
(operator new(BlockSize));
reinterpret_cast<slot_pointer_>(newBlock)->next = currentBlock_;
currentBlock_ = reinterpret_cast<slot_pointer_>(newBlock);
// Pad block body to staisfy the alignment requirements for elements
data_pointer_ body = newBlock + sizeof(slot_pointer_);
size_type bodyPadding = padPointer(body, alignof(slot_type_));
currentSlot_ = reinterpret_cast<slot_pointer_>(body + bodyPadding);
lastSlot_ = reinterpret_cast<slot_pointer_>
(newBlock + BlockSize - sizeof(slot_type_) + 1);
}
template <typename T, size_t BlockSize>
inline typename MemoryPool<T, BlockSize>::pointer
MemoryPool<T, BlockSize>::allocate(size_type n, const_pointer hint)
{
if (freeSlots_ != nullptr) {
pointer result = reinterpret_cast<pointer>(freeSlots_);
freeSlots_ = freeSlots_->next;
return result;
}
else {
if (currentSlot_ >= lastSlot_)
allocateBlock();
return reinterpret_cast<pointer>(currentSlot_++);
}
}
template <typename T, size_t BlockSize>
inline void
MemoryPool<T, BlockSize>::deallocate(pointer p, size_type n)
{
if (p != nullptr) {
reinterpret_cast<slot_pointer_>(p)->next = freeSlots_;
freeSlots_ = reinterpret_cast<slot_pointer_>(p);
}
}
template <typename T, size_t BlockSize>
inline typename MemoryPool<T, BlockSize>::size_type
MemoryPool<T, BlockSize>::max_size()
const noexcept
{
size_type maxBlocks = -1 / BlockSize;
return (BlockSize - sizeof(data_pointer_)) / sizeof(slot_type_) * maxBlocks;
}
template <typename T, size_t BlockSize>
template <class U, class... Args>
inline void
MemoryPool<T, BlockSize>::construct(U* p, Args&&... args)
{
new (p) U (std::forward<Args>(args)...);
}
template <typename T, size_t BlockSize>
template <class U>
inline void
MemoryPool<T, BlockSize>::destroy(U* p)
{
p->~U();
}
template <typename T, size_t BlockSize>
template <class... Args>
inline typename MemoryPool<T, BlockSize>::pointer
MemoryPool<T, BlockSize>::newElement(Args&&... args)
{
pointer result = allocate();
construct<value_type>(result, std::forward<Args>(args)...);
return result;
}
template <typename T, size_t BlockSize>
inline void
MemoryPool<T, BlockSize>::deleteElement(pointer p)
{
if (p != nullptr) {
p->~value_type();
deallocate(p);
}
}
#endif // MEMORY_BLOCK_TCC

View File

@ -69,8 +69,7 @@ namespace sbgtc
void sbgSolutionModeSignal(int); void sbgSolutionModeSignal(int);
void sbgAccuracySignal(int); void sbgAccuracySignal(int, int);
}; };
} }

View File

@ -63,7 +63,7 @@ public slots:
void sendSerialPortStatus(int serialPortStatus); void sendSerialPortStatus(int serialPortStatus);
void sendSbgSolutionModeState(int SolutionMode); void sendSbgSolutionModeState(int SolutionMode);
void sendSbgAccuracyState(int Accuracy); void sendSbgAccuracyState(int Accuracy,int SatelliteCounter);
void sendXimeaImageStatus(int ximeaImageStatus); void sendXimeaImageStatus(int ximeaImageStatus);
void sendCopyFileStatus(int fileStatus); void sendCopyFileStatus(int fileStatus);

View File

@ -37,6 +37,11 @@
#include "math.h" #include "math.h"
#include "utility_tc.h" #include "utility_tc.h"
#include "MemoryPool.h"
#include <queue>
#include <QMutex>
//#ifdef WIN32 //#ifdef WIN32
//#include <xiApi.h> // Windows //#include <xiApi.h> // Windows
@ -44,6 +49,23 @@
//#include <m3api/xiApi.h> // Linux, OSX //#include <m3api/xiApi.h> // Linux, OSX
//#endif //#endif
//struct DataBuffer
//{
// unsigned short data[409200/2];
//};
class DataBuffer
{
public:
DataBuffer();
~DataBuffer();
unsigned short data[425600];//304*1400=425600为了兼容所有设置spectral bin和spatial bin
private:
};
class RecordXimeaTemperature : public QObject class RecordXimeaTemperature : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -64,6 +86,30 @@ signals:
}; };
//queue<DataBuffer *> q;
//static QMutex r_qtx{ QMutex::Recursive };
static std::mutex r_qtx;
class WriteData2Disk : public QObject
{
Q_OBJECT
public:
WriteData2Disk();
void setParm(queue<DataBuffer *> * q, QString baseFileName, int frameSizeInByte, MemoryPool<DataBuffer> * pool);
private:
queue<DataBuffer *> * m_q;
QString m_QbaseFileName;
int m_iFrameSizeInByte;
MemoryPool<DataBuffer> * m_pool;
public slots:
void write2Disk();
signals:
};
class XimeaImager : public QObject class XimeaImager : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -99,11 +145,17 @@ private:
QThread * m_recordTempThread; QThread * m_recordTempThread;
RecordXimeaTemperature * m_ximeaTemperature; RecordXimeaTemperature * m_ximeaTemperature;
QThread * writeData2DiskThread;
WriteData2Disk * writeData2Disk;
queue<DataBuffer *> * q;
MemoryPool<DataBuffer> * m_pool;
QString m_baseFileName; QString m_baseFileName;
QString m_ximeaTemperatureCSVPath; QString m_ximeaTemperatureCSVPath;
Iris::IrisXimeaImager m_imager; Iris::IrisXimeaImager m_imager;
unsigned short * m_buffer; unsigned short * m_buffer;
// MemoryPool<unsigned short> m_pool;
bool m_bRecordControl; bool m_bRecordControl;
int m_iFrameCounter; int m_iFrameCounter;
int m_iFrameSizeInByte; int m_iFrameSizeInByte;
@ -132,6 +184,8 @@ private:
Configfile m_configfile; Configfile m_configfile;
public slots: public slots:
void openImger(); void openImger();
void closeImger(); void closeImger();
@ -143,5 +197,6 @@ signals:
void ximeaImageStatus(int); void ximeaImageStatus(int);
void recordXimeaTemperatureSignal(QString); void recordXimeaTemperatureSignal(QString);
void startWriteDiskSignal();
}; };
#endif // XIMEAIMAGER_H #endif // XIMEAIMAGER_H

View File

@ -671,13 +671,11 @@ void sbgtc::SbgRecorder::parseSbgMessage(QByteArray * sbgMessage)
} }
else if(receivedMsgClass==SBG_ECOM_CLASS_LOG_ECOM_0 && receivedMsg==SBG_ECOM_LOG_GPS1_POS) else if(receivedMsgClass==SBG_ECOM_CLASS_LOG_ECOM_0 && receivedMsg==SBG_ECOM_LOG_GPS1_POS)
{ {
// std::cout<<"纬度精度为:"<<logData.gpsPosData.latitudeAccuracy<<std::endl;
float maximal=0; float maximal=0;
float latitudeAccuracy=logData.gpsPosData.latitudeAccuracy; float latitudeAccuracy=logData.gpsPosData.latitudeAccuracy;
float longitudeAccuracy=logData.gpsPosData.longitudeAccuracy; float longitudeAccuracy=logData.gpsPosData.longitudeAccuracy;
float altitudeAccuracy=logData.gpsPosData.altitudeAccuracy; float altitudeAccuracy=logData.gpsPosData.altitudeAccuracy;
int satelliteCounter=(int)logData.gpsPosData.numSvUsed;
if(latitudeAccuracy<longitudeAccuracy) if(latitudeAccuracy<longitudeAccuracy)
maximal = longitudeAccuracy; maximal = longitudeAccuracy;
@ -687,7 +685,10 @@ void sbgtc::SbgRecorder::parseSbgMessage(QByteArray * sbgMessage)
if(maximal<altitudeAccuracy) if(maximal<altitudeAccuracy)
maximal = altitudeAccuracy; maximal = altitudeAccuracy;
emit sbgAccuracySignal(static_cast<int>(maximal)); // std::cout<<"纬度精度为:"<<maximal<<std::endl;
// std::cout<<"numSvUsed"<<satelliteCounter<<std::endl;
emit sbgAccuracySignal(static_cast<int>(maximal), satelliteCounter);
if(maximal<7) if(maximal<7)
{ {
@ -710,15 +711,10 @@ void sbgtc::SbgRecorder::parseSbgMessage(QByteArray * sbgMessage)
char setGpsTimeCommand[256]; char setGpsTimeCommand[256];
sprintf(setGpsTimeCommand,"date --set=\"%d%02d%02d %02d:%02d:%02d\"",year,month,day,hour,minute,second);//02中的2代表2位数字0代表以0补全 sprintf(setGpsTimeCommand,"date --set=\"%d%02d%02d %02d:%02d:%02d\"",year,month,day,hour,minute,second);//02中的2代表2位数字0代表以0补全
system(setGpsTimeCommand);// // system(setGpsTimeCommand);
m_bIsSyncSystemTimeBaseGpstime=true; m_bIsSyncSystemTimeBaseGpstime=true;
} }
else if(receivedMsgClass==SBG_ECOM_CLASS_LOG_ECOM_0 && receivedMsg==SBG_ECOM_LOG_EKF_EULER)
{
// std::cout<<"1111111111111"<<"UTC time:"<<(int)logData.utcData.year<<","<<(int)logData.utcData.month<<","<<(int)logData.utcData.day<<","<<(int)logData.utcData.hour<<","<<(int)logData.utcData.minute<<","<<(int)(int)logData.utcData.second<<std::endl;
// std::cout<<"receivedMsg:"<<(int)receivedMsg<<std::endl;
}
else if(receivedMsgClass!=SBG_ECOM_CLASS_LOG_ECOM_0 && receivedMsg==SBG_ECOM_LOG_EKF_QUAT) else if(receivedMsgClass!=SBG_ECOM_CLASS_LOG_ECOM_0 && receivedMsg==SBG_ECOM_LOG_EKF_QUAT)
{ {
//std::cout<<"1111111111111------"<<"UTC time:"<<(int)logData.utcData.year<<","<<(int)logData.utcData.month<<","<<(int)logData.utcData.day<<","<<(int)logData.utcData.hour<<","<<(int)logData.utcData.minute<<","<<(int)(int)logData.utcData.second<<std::endl; //std::cout<<"1111111111111------"<<"UTC time:"<<(int)logData.utcData.year<<","<<(int)logData.utcData.month<<","<<(int)logData.utcData.day<<","<<(int)logData.utcData.hour<<","<<(int)logData.utcData.minute<<","<<(int)(int)logData.utcData.second<<std::endl;

View File

@ -16,7 +16,7 @@ UdpServer::UdpServer()
m_RecordThread=new QThread(); m_RecordThread=new QThread();
m_imager=new XimeaImager(); m_imager=new XimeaImager();
m_imager->moveToThread(m_RecordThread); m_imager->moveToThread(m_RecordThread);
m_RecordThread->start(); m_RecordThread->start(QThread::HighestPriority);
m_CopyFileThread=new QThread(); m_CopyFileThread=new QThread();
m_copyFile=new FileOperation(); m_copyFile=new FileOperation();
@ -47,7 +47,7 @@ UdpServer::UdpServer()
connect(m_sbgRecorder, SIGNAL(serialPortStatus(int)),this, SLOT(sendSerialPortStatus(int))); connect(m_sbgRecorder, SIGNAL(serialPortStatus(int)),this, SLOT(sendSerialPortStatus(int)));
connect(m_sbgRecorder, SIGNAL(sbgSolutionModeSignal(int)),this, SLOT(sendSbgSolutionModeState(int))); connect(m_sbgRecorder, SIGNAL(sbgSolutionModeSignal(int)),this, SLOT(sendSbgSolutionModeState(int)));
connect(m_sbgRecorder, SIGNAL(sbgAccuracySignal(int)),this, SLOT(sendSbgAccuracyState(int))); connect(m_sbgRecorder, SIGNAL(sbgAccuracySignal(int,int)),this, SLOT(sendSbgAccuracyState(int,int)));
connect(m_imager, SIGNAL(ximeaImageStatus(int)),this, SLOT(sendXimeaImageStatus(int))); connect(m_imager, SIGNAL(ximeaImageStatus(int)),this, SLOT(sendXimeaImageStatus(int)));
connect(m_copyFile, SIGNAL(copyFileStatus(int)),this, SLOT(sendCopyFileStatus(int))); connect(m_copyFile, SIGNAL(copyFileStatus(int)),this, SLOT(sendCopyFileStatus(int)));
@ -284,13 +284,13 @@ void UdpServer::sendSbgSolutionModeState(int SolutionMode)
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455); m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455);
} }
void UdpServer::sendSbgAccuracyState(int Accuracy) void UdpServer::sendSbgAccuracyState(int Accuracy,int SatelliteCounter)
{ {
// std::cout<<"UdpServer::sendSbgAccuracyState---------------------:"<< Accuracy <<std::endl; // std::cout<<"UdpServer::sendSbgAccuracyState---------------------:"<< Accuracy <<std::endl;
QByteArray datagram2send; QByteArray datagram2send;
QString status = "Accuracy," + QString::number(Accuracy); QString status = "Accuracy," + QString::number(Accuracy) + "," + QString::number(SatelliteCounter);
datagram2send.operator =(status.toStdString().c_str()); datagram2send.operator =(status.toStdString().c_str());
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455); m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455);

View File

@ -21,6 +21,15 @@ XimeaImager::XimeaImager()
m_recordTempThread->start(); m_recordTempThread->start();
connect(this, SIGNAL(recordXimeaTemperatureSignal(QString)),m_ximeaTemperature, SLOT(recordTemperature(QString))); 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() void XimeaImager::openImger()
@ -77,6 +86,7 @@ void XimeaImager::openImger()
int frameSizeAuto = m_imager.getBufferSizeOfOneFrame(); int frameSizeAuto = m_imager.getBufferSizeOfOneFrame();
m_iFrameSizeInByte = frameSizeAuto; m_iFrameSizeInByte = frameSizeAuto;
std::cout<<"每一帧的字节数:-------------------------------"<< m_iFrameSizeInByte <<std::endl;
m_buffer = new unsigned short[m_iFrameSizeInByte]; m_buffer = new unsigned short[m_iFrameSizeInByte];
@ -441,65 +451,66 @@ void XimeaImager::startRecord(double TimeDifferenceBetweensOSAndSbg,QString base
m_iFrameCounter=0; m_iFrameCounter=0;
m_bRecordControl=true; m_bRecordControl=true;
m_imager.start();
m_baseFileName=baseFileName; m_baseFileName=baseFileName;
QString imageFileName=m_baseFileName+".bil";
QString timesFileName=m_baseFileName+".times";
// QString timesFileName=m_baseFileName+".times";
FILE *hFile=fopen(imageFileName.toStdString().c_str(),"w+b");
FILE *hHimesFile=fopen(timesFileName.toStdString().c_str(),"w+"); FILE *hHimesFile=fopen(timesFileName.toStdString().c_str(),"w+");
using namespace std; 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; struct timeval timeStart, timeEnd;
double runTime=0; double runTime=0;
gettimeofday(&timeStart, NULL); gettimeofday(&timeStart, NULL);
while (m_bRecordControl) while (m_bRecordControl)
{ {
unsigned short *x=m_imager.get_frame(m_buffer); unsigned short *x=m_imager.get_frame(m_buffer);
//fwrite(m_buffer,2,getBandCount()*getSampleCount(),hFile); //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读操作能成功但系统什么时候写入磁盘由系统决定一般是达到一定量时系统他就写入磁盘。 //fflush(hFile);//只保证了将IO缓冲写入系统缓冲中使IO读操作能成功但系统什么时候写入磁盘由系统决定一般是达到一定量时系统他就写入磁盘。
//sync();//强制系统将系统文件缓冲的内容写入磁盘 //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); double sbgTime=getSbgTime(TimeDifferenceBetweensOSAndSbg);
fprintf(hHimesFile,"%f\n",sbgTime); fprintf(hHimesFile,"%f\n",sbgTime);
//fwrite(&sbgTime,sizeof(double),1,hHimesFile); //fwrite(&sbgTime,sizeof(double),1,hHimesFile);
timesFileHandle << sbgTime << "\n"; // timesFileHandle << sbgTime << "\n";
// std::cout<<"XimeaImager::startRecord---std::cout: "<<sbgTime<<std::endl; // 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 char pixel = *(unsigned char*)image.bp;//Default value: XI_MONO8
// unsigned short pixel =*(unsigned short*)image.bp;//XI_RAW16 // 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); // 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); gettimeofday(&timeEnd, NULL);
runTime = (timeEnd.tv_sec - timeStart.tv_sec ) + (double)(timeEnd.tv_usec -timeStart.tv_usec)/1000000; runTime = (timeEnd.tv_sec - timeStart.tv_sec ) + (double)(timeEnd.tv_usec -timeStart.tv_usec)/1000000;
m_imager.stop();
double frameInTheory=runTime * getFramerate(); double frameInTheory=runTime * getFramerate();
double frameLossed=frameInTheory - m_iFrameCounter; double frameLossed=frameInTheory - m_iFrameCounter;
@ -514,12 +525,10 @@ void XimeaImager::startRecord(double TimeDifferenceBetweensOSAndSbg,QString base
std::cout<<"丢失帧数为: "<<frameLossed<<std::endl; std::cout<<"丢失帧数为: "<<frameLossed<<std::endl;
std::cout<<"丢帧率为: "<<frameLossRate * 100<< "%" <<std::endl; std::cout<<"丢帧率为: "<<frameLossRate * 100<< "%" <<std::endl;
fclose(hFile);
fclose(hHimesFile); fclose(hHimesFile);
timesFileHandle.close(); // timesFileHandle.close();
printf("Stopping acquisition...\n"); printf("Stopping acquisition...\n");
m_imager.stop();
writeHdr(); writeHdr();
@ -704,6 +713,14 @@ int XimeaImager::getFrameCounter()
return m_iFrameCounter; return m_iFrameCounter;
} }
DataBuffer::DataBuffer()
{
}
DataBuffer::~DataBuffer()
{
}
RecordXimeaTemperature::RecordXimeaTemperature(Iris::IrisXimeaImager * imager) RecordXimeaTemperature::RecordXimeaTemperature(Iris::IrisXimeaImager * imager)
{ {
m_imager = imager; m_imager = imager;
@ -739,3 +756,61 @@ void RecordXimeaTemperature::recordTemperature(QString filePath= nullptr)
ximeaTemperatureFile.close(); 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;
}