优化:
1. 通过内存池解决丢帧问题; 2. 解析惯导卫星个数,并通过socket发送给psdk; 3. 取消通过sbg卫星时间设置linux系统时间,此功能交给psdk做;
This commit is contained in:
@ -41,7 +41,9 @@ add_executable(${CMAKE_PROJECT_NAME}
|
||||
Source_Files/ximeaimager.cpp
|
||||
Header_Files/ximeaimager.h
|
||||
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})
|
||||
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||
|
98
Header_Files/MemoryPool.h
Normal file
98
Header_Files/MemoryPool.h
Normal 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
235
Header_Files/MemoryPool.tcc
Normal 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
|
@ -69,8 +69,7 @@ namespace sbgtc
|
||||
|
||||
void sbgSolutionModeSignal(int);
|
||||
|
||||
void sbgAccuracySignal(int);
|
||||
|
||||
void sbgAccuracySignal(int, int);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public slots:
|
||||
void sendSerialPortStatus(int serialPortStatus);
|
||||
|
||||
void sendSbgSolutionModeState(int SolutionMode);
|
||||
void sendSbgAccuracyState(int Accuracy);
|
||||
void sendSbgAccuracyState(int Accuracy,int SatelliteCounter);
|
||||
|
||||
void sendXimeaImageStatus(int ximeaImageStatus);
|
||||
void sendCopyFileStatus(int fileStatus);
|
||||
|
@ -37,6 +37,11 @@
|
||||
#include "math.h"
|
||||
#include "utility_tc.h"
|
||||
|
||||
#include "MemoryPool.h"
|
||||
#include <queue>
|
||||
#include <QMutex>
|
||||
|
||||
|
||||
|
||||
//#ifdef WIN32
|
||||
//#include <xiApi.h> // Windows
|
||||
@ -44,6 +49,23 @@
|
||||
//#include <m3api/xiApi.h> // Linux, OSX
|
||||
//#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
|
||||
{
|
||||
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
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -99,11 +145,17 @@ private:
|
||||
QThread * m_recordTempThread;
|
||||
RecordXimeaTemperature * m_ximeaTemperature;
|
||||
|
||||
QThread * writeData2DiskThread;
|
||||
WriteData2Disk * writeData2Disk;
|
||||
queue<DataBuffer *> * q;
|
||||
MemoryPool<DataBuffer> * m_pool;
|
||||
|
||||
QString m_baseFileName;
|
||||
QString m_ximeaTemperatureCSVPath;
|
||||
|
||||
Iris::IrisXimeaImager m_imager;
|
||||
unsigned short * m_buffer;
|
||||
// MemoryPool<unsigned short> m_pool;
|
||||
bool m_bRecordControl;
|
||||
int m_iFrameCounter;
|
||||
int m_iFrameSizeInByte;
|
||||
@ -132,6 +184,8 @@ private:
|
||||
|
||||
Configfile m_configfile;
|
||||
|
||||
|
||||
|
||||
public slots:
|
||||
void openImger();
|
||||
void closeImger();
|
||||
@ -143,5 +197,6 @@ signals:
|
||||
void ximeaImageStatus(int);
|
||||
|
||||
void recordXimeaTemperatureSignal(QString);
|
||||
void startWriteDiskSignal();
|
||||
};
|
||||
#endif // XIMEAIMAGER_H
|
||||
|
@ -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)
|
||||
{
|
||||
// std::cout<<"纬度精度为:"<<logData.gpsPosData.latitudeAccuracy<<std::endl;
|
||||
|
||||
float maximal=0;
|
||||
float latitudeAccuracy=logData.gpsPosData.latitudeAccuracy;
|
||||
float longitudeAccuracy=logData.gpsPosData.longitudeAccuracy;
|
||||
float altitudeAccuracy=logData.gpsPosData.altitudeAccuracy;
|
||||
|
||||
int satelliteCounter=(int)logData.gpsPosData.numSvUsed;
|
||||
|
||||
if(latitudeAccuracy<longitudeAccuracy)
|
||||
maximal = longitudeAccuracy;
|
||||
@ -687,7 +685,10 @@ void sbgtc::SbgRecorder::parseSbgMessage(QByteArray * sbgMessage)
|
||||
if(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)
|
||||
{
|
||||
@ -710,15 +711,10 @@ void sbgtc::SbgRecorder::parseSbgMessage(QByteArray * sbgMessage)
|
||||
char setGpsTimeCommand[256];
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
//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;
|
||||
|
@ -16,7 +16,7 @@ UdpServer::UdpServer()
|
||||
m_RecordThread=new QThread();
|
||||
m_imager=new XimeaImager();
|
||||
m_imager->moveToThread(m_RecordThread);
|
||||
m_RecordThread->start();
|
||||
m_RecordThread->start(QThread::HighestPriority);
|
||||
|
||||
m_CopyFileThread=new QThread();
|
||||
m_copyFile=new FileOperation();
|
||||
@ -47,7 +47,7 @@ UdpServer::UdpServer()
|
||||
connect(m_sbgRecorder, SIGNAL(serialPortStatus(int)),this, SLOT(sendSerialPortStatus(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_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);
|
||||
}
|
||||
|
||||
void UdpServer::sendSbgAccuracyState(int Accuracy)
|
||||
void UdpServer::sendSbgAccuracyState(int Accuracy,int SatelliteCounter)
|
||||
{
|
||||
// std::cout<<"UdpServer::sendSbgAccuracyState---------------------:"<< Accuracy <<std::endl;
|
||||
|
||||
QByteArray datagram2send;
|
||||
|
||||
QString status = "Accuracy," + QString::number(Accuracy);
|
||||
QString status = "Accuracy," + QString::number(Accuracy) + "," + QString::number(SatelliteCounter);
|
||||
|
||||
datagram2send.operator =(status.toStdString().c_str());
|
||||
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user