Add Stream Reader Thread

This commit is contained in:
2019-11-10 14:25:35 -08:00
parent f567fb31c9
commit 49f1e3b19d
5 changed files with 329 additions and 15 deletions

View File

@@ -34,6 +34,7 @@ add_executable( FaultFinder
ImageManager.cpp
ConfigManager.cpp
FaultManager.cpp
StreamReader.cpp
${prog_SRCS}
)

View File

@@ -1,18 +1,213 @@
#include <QCoreApplication>
#include <QDebug>
#include <QTimer>
#include "StreamManager.hpp"
#include "ImageManager.hpp"
StreamManager::StreamManager(QObject *parent) : QObject(parent)
{
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, QOverload<>::of(&StreamManager::Process));
timer->start(1000);
// Listen for New Emissivity Signal
//connect(&config_mgr, &ConfigManager::NewEmissivity, this, &StreamManager::SetEmissivity);
PvResult res;
res = FindDevice();
if (res.IsFailure())
exit(res.GetCode());
res = ConnectToDevice();
if (res.IsFailure())
exit(res.GetCode());
res = OpenStream();
if (res.IsFailure())
exit(res.GetCode());
ConfigureStream();
CreatePipeline();
StartStream();
ImageThread = new StreamReader(Device, Stream, Pipeline);
ImageThread->start(QThread::TimeCriticalPriority);
}
void StreamManager::Process()
StreamManager::~StreamManager()
{
qInfo() << "TICK";
ImageThread->requestInterruption();
ImageThread->wait();
StopStream();
Disconnect();
}
void StreamManager::SetEmissivity(double emissivity)
{
if (lDeviceParams)
lDeviceParams->SetFloatValue("ObjectEmissivity", emissivity);
}
PvResult StreamManager::FindDevice()
{
PvResult lResult = PvResult();
const PvDeviceInfo *lSelectedDI = NULL;
PvSystem lSystem;
lSystem.Find();
// Detect, select device.
std::vector<const PvDeviceInfo *> lDIVector;
for (uint32_t i = 0; i < lSystem.GetInterfaceCount(); i++)
{
const PvInterface *lInterface = dynamic_cast<const PvInterface *>(lSystem.GetInterface(i));
if (lInterface != NULL)
{
for (uint32_t j = 0; j < lInterface->GetDeviceCount(); j++)
{
const PvDeviceInfo *lDI = dynamic_cast<const PvDeviceInfo *>(lInterface->GetDeviceInfo(j));
if (lDI != NULL)
{
lDIVector.push_back(lDI);
}
}
}
}
if (lDIVector.size() == 0)
{
qCritical() << "Device not found!";
lResult.SetCode(PV_NOT_FOUND);
return lResult;
}
lSelectedDI = lDIVector.front();
ConnectionID = lSelectedDI->GetConnectionID();
lResult.SetCode(PV_OK);
return lResult;
}
PvResult StreamManager::ConnectToDevice()
{
PvResult lResult;
// Connect to the GigE Vision or USB3 Vision device
qInfo() << "Connecting to device.";
Device = PvDevice::CreateAndConnect(ConnectionID, &lResult);
if (Device == NULL)
{
qCritical() << "Unable to connect to device.";
}
return lResult;
}
PvResult StreamManager::OpenStream()
{
PvResult lResult;
// Open stream to the GigE Vision or USB3 Vision device
qInfo() << "Opening stream from device.";
Stream = PvStream::CreateAndOpen(ConnectionID, &lResult);
if (Stream != NULL)
{
// If this is a GigE Vision device, configure GigE Vision specific streaming parameters
PvDeviceGEV* lDeviceGEV = dynamic_cast<PvDeviceGEV *>(Device);
if ( lDeviceGEV != NULL )
{
PvStreamGEV *lStreamGEV = static_cast<PvStreamGEV *>(Stream);
// Negotiate packet size
lDeviceGEV->NegotiatePacketSize();
// Configure device streaming destination
lDeviceGEV->SetStreamDestination( lStreamGEV->GetLocalIPAddress(), lStreamGEV->GetLocalPort() );
}
}
else
{
qCritical() << "Unable to stream from device.";
}
return lResult;
}
void StreamManager::ConfigureStream()
{
// Get device parameters need to control streaming
lDeviceParams = Device->GetParameters();
// Use Temperature Format Instead of Raw Counts
lDeviceParams->SetEnumValue("IRFormat", 1);
SetEmissivity(0.95);
}
void StreamManager::CreatePipeline()
{
// Create the PvPipeline object
Pipeline = new PvPipeline( Stream );
if ( Pipeline != NULL )
{
// Reading payload size from device
uint32_t lSize = Device->GetPayloadSize();
// Set the Buffer count and the Buffer size
Pipeline->SetBufferCount( BUFFER_COUNT );
Pipeline->SetBufferSize( lSize );
}
}
void StreamManager::StartStream()
{
// Map the GenICam AcquisitionStart and AcquisitionStop commands
PvGenCommand *lStart = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStart"));
qInfo() << "Starting pipeline";
Pipeline->Start();
// Get stream parameters
PvGenParameterArray *lStreamParams = Stream->GetParameters();
// Map a few GenICam stream stats counters
PvGenFloat *lFrameRate = dynamic_cast<PvGenFloat *>(lStreamParams->Get("AcquisitionRate"));
PvGenFloat *lBandwidth = dynamic_cast<PvGenFloat *>(lStreamParams->Get("Bandwidth"));
// Enable streaming and send the AcquisitionStart command
qInfo() << "Enabling streaming and sending AcquisitionStart command.";
Device->StreamEnable();
lStart->Execute();
}
void StreamManager::StopStream()
{
// Tell the device to stop sending images.
qInfo() << "Sending AcquisitionStop command to the device";
PvGenCommand *lStop = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStop"));
lStop->Execute();
// Disable streaming on the device
qInfo() << "Disable streaming on the controller.";;
Device->StreamDisable();
// Stop the pipeline
qInfo() << "Stop pipeline";
Pipeline->Stop();
}
void StreamManager::Disconnect()
{
if (Stream != NULL)
{
Stream->Close();
PvStream::Free(Stream);
}
if (Device != NULL)
{
Device->Disconnect();
PvDevice::Free(Device);
}
}

View File

@@ -2,17 +2,47 @@
#define STREAM_MANAGER_H
#include <QObject>
#include <QDebug>
#include <PvSystem.h>
#include <PvDevice.h>
#include <PvStream.h>
#include <PvPipeline.h>
#include <PvDeviceGEV.h>
#include <PvStreamGEV.h>
#include "StreamReader.hpp"
#define BUFFER_COUNT (32)
class StreamManager : public QObject
{
Q_OBJECT;
public:
StreamManager(QObject *parent);
void Process();
virtual ~StreamManager();
public slots:
void SetEmissivity(double emissivity);
private:
PvResult FindDevice();
PvResult ConnectToDevice();
PvResult OpenStream();
void ConfigureStream();
void StartStream();
void StopStream();
void CreatePipeline();
void AcquireImages();
void Disconnect();
PvString ConnectionID;
PvDevice *Device = NULL;
PvStream *Stream = NULL;
PvGenParameterArray *lDeviceParams = NULL;
PvPipeline *Pipeline = NULL;
StreamReader *ImageThread;
};
#endif

60
StreamReader.cpp Normal file
View File

@@ -0,0 +1,60 @@
#include "StreamReader.hpp"
StreamReader::StreamReader(PvDevice *Device, PvStream *Stream, PvPipeline *Pipeline)
{
this->Device = Device;
this->Stream = Stream;
this->Pipeline = Pipeline;
}
void StreamReader::run()
{
while (!isInterruptionRequested())
{
PvBuffer *lBuffer = NULL;
PvResult lOperationResult;
// wait for this to unblock before called in event loop
// Retrieve next buffer
PvResult lResult = Stream->RetrieveBuffer(&lBuffer, &lOperationResult, 1000);
if (lResult.IsOK())
{
if (lOperationResult.IsOK())
{
PvPayloadType lType;
// If the buffer contains an image, display width and height.
uint32_t lWidth = 0, lHeight = 0;
lType = lBuffer->GetPayloadType();
if (lType == PvPayloadTypeImage)
{
// Get image specific buffer interface.
PvImage *lImage = lBuffer->GetImage();
// Read width, height.
lWidth = lImage->GetWidth();
lHeight = lImage->GetHeight();
NewImage(lWidth, lHeight, lImage->GetDataPointer());
}
else
{
qWarning() << " (buffer does not contain image)";
}
}
else
{
qInfo() << lOperationResult.GetCodeString().GetAscii() << "\r";
}
// Re-queue the buffer in the stream object
Stream->QueueBuffer(lBuffer);
}
else
{
// Retrieve buffer failure
qCritical() << lResult.GetCodeString().GetAscii() << "\r";
}
}
}

28
StreamReader.hpp Normal file
View File

@@ -0,0 +1,28 @@
#ifndef STREAM_READER_H
#define STREAM_READER_H
#include <QThread>
#include <QDebug>
#include <PvDevice.h>
#include <PvStream.h>
#include <PvPipeline.h>
class StreamReader : public QThread
{
Q_OBJECT;
void run();
public:
StreamReader(PvDevice *Device, PvStream *Stream, PvPipeline *Pipeline);
signals:
void NewImage(uint32_t width, uint32_t height, uint8_t *imgPointer);
private:
PvDevice *Device = NULL;
PvStream *Stream = NULL;
PvPipeline *Pipeline = NULL;
};
#endif