23 Commits
Author SHA1 Message Date
agterris e4ad57e3e4 Add Config JSONs to Config Manager 2020-02-08 16:44:49 -08:00
agterris 8ad4fa9012 Change default frame rate for testing 2020-02-08 15:45:51 -08:00
agterris f985e50cbe Set FrameRate to Camera 2020-02-08 15:45:51 -08:00
agterris bcaa8e5b2e Fix File Format 2020-01-19 14:13:43 -08:00
agterris d1188afc47 Save Fault Info to Database 2020-01-15 19:11:06 -08:00
agterris 6251ce673a Get Emissivity from Config Manager Before Setting 2020-01-14 17:51:23 -08:00
agterris ef91a9281f Add Ready State Function 2020-01-14 17:49:59 -08:00
agterris 56dfe9366d Add Data Copy Reminder 2020-01-12 15:22:11 -08:00
agterris eef985ecfc Add Frame Reading 2020-01-12 15:17:01 -08:00
agterris 628e9e4adf Use Pipeline to Retrieve Buffer 2020-01-12 15:17:01 -08:00
agterris d0cbfacef8 Activate Debugging on CMake 2020-01-11 22:43:22 -08:00
agterris 0720c9bb28 Link New Image Connection 2019-11-20 21:50:40 -08:00
agterris 997b3c5db0 Correct Event Loop Connections 2019-11-20 21:42:12 -08:00
agterris e928234c14 Casted Reference from Parent Method 2019-11-20 19:06:24 -08:00
agterris 1b85bb40e4 Add GPS Parsing 2019-11-19 19:27:58 -08:00
agterris 005f6241f5 Add Database Connection 2019-11-13 23:16:02 -08:00
agterris 39cd2fb24f Add Image Manager Code 2019-11-10 17:20:26 -08:00
agterris 72005400e5 Split FaultFinder into Own Object 2019-11-10 17:20:11 -08:00
agterris 49f1e3b19d Add Stream Reader Thread 2019-11-10 14:25:35 -08:00
agterris f567fb31c9 Fix Formatting 2019-11-10 13:26:03 -08:00
agterris 2c7fcac115 Add Interrupt Signal Handling 2019-11-10 12:57:41 -08:00
agterris aac70c87c1 Add FrameRate Config 2019-11-10 12:57:25 -08:00
Grant Terris c49c8f6e33 Initial Commit 2019-11-09 15:44:38 -08:00
20 changed files with 636 additions and 293 deletions
+5
View File
@@ -38,6 +38,11 @@ install_manifest.txt
compile_commands.json compile_commands.json
CTestTestfile.cmake CTestTestfile.cmake
_deps _deps
*_autogen
# Qt
*.xml
*adaptor*
# Executables # Executables
FaultFinder FaultFinder
+1 -1
View File
@@ -5,7 +5,7 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Build and Debug", "name": "Debug",
"type": "cppdbg", "type": "cppdbg",
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/FaultFinder", "program": "${workspaceFolder}/FaultFinder",
+2 -1
View File
@@ -55,6 +55,7 @@
"streambuf": "cpp", "streambuf": "cpp",
"thread": "cpp", "thread": "cpp",
"cinttypes": "cpp", "cinttypes": "cpp",
"typeinfo": "cpp" "typeinfo": "cpp",
"qdbusconnection": "cpp"
} }
} }
+1
View File
@@ -6,6 +6,7 @@
"type": "shell", "type": "shell",
"command": "cmake", "command": "cmake",
"args": [ "args": [
"-DCMAKE_BUILD_TYPE=Debug",
"." "."
], ],
"group": { "group": {
+26 -2
View File
@@ -5,20 +5,41 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
find_package( OpenCV REQUIRED ) find_package( OpenCV REQUIRED )
find_package( Ebus REQUIRED ) find_package( Ebus REQUIRED )
find_package( Qt5 COMPONENTS Widgets Network REQUIRED ) find_package( Qt5 COMPONENTS Widgets Network DBus Sql Positioning SerialPort REQUIRED )
set(CMAKE_AUTOMOC ON)
set(prog_SRCS DBus.xml)
qt5_generate_dbus_interface(ConfigManager.hpp
DBus.xml
OPTIONS -A
)
qt5_add_dbus_adaptor(prog_SRCS
${CMAKE_CURRENT_BINARY_DIR}/DBus.xml
ConfigManager.hpp
ConfigManager
)
include_directories( include_directories(
${OpenCV_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS}
${Ebus_INCLUDE_DIRS} ${Ebus_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS}
${Qt5Network_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS}
${Qt5DBus_INCLUDE_DIRS}
${Qt5Sql_INCLUDE_DIRS}
${Qt5Positioning_INCLUDE_DIRS}
${Qt5SerialPort_INCLUDE_DIRS}
) )
add_executable( FaultFinder add_executable( FaultFinder
FaultFinder.cpp FaultFinder.cpp
StreamManager.cpp StreamManager.cpp
ImageManager.cpp ImageManager.cpp
ConfigManager.cpp
FaultManager.cpp FaultManager.cpp
StreamReader.cpp
main.cpp
${prog_SRCS}
) )
target_link_libraries( FaultFinder target_link_libraries( FaultFinder
@@ -26,5 +47,8 @@ target_link_libraries( FaultFinder
${Ebus_LIBRARIES} ${Ebus_LIBRARIES}
${Qt5Widgets_LIBRARIES} ${Qt5Widgets_LIBRARIES}
${Qt5Network_LIBRARIES} ${Qt5Network_LIBRARIES}
${Qt5DBus_LIBRARIES}
${Qt5Sql_LIBRARIES}
${Qt5Positioning_LIBRARIES}
${Qt5SerialPort_LIBRARIES}
) )
message( ${Qt5Network_INCLUDE_DIRS} )
+93
View File
@@ -0,0 +1,93 @@
#include <QDBusConnection>
#include <QDebug>
#include "ConfigManager.hpp"
#include "dbusadaptor.h"
ConfigManager::ConfigManager(QObject *parent) : QObject(parent)
{
new ConfigManagerAdaptor(this);
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerObject("/configuration", this);
dbus.registerService("com.infraredinspectionsystems.FaultFinder");
}
ConfigManager::~ConfigManager()
{
}
bool ConfigManager::GetRecordingState()
{
qDebug() << "ConfigManager::GetRecordingState";
return this->recording;
}
void ConfigManager::SetRecordingState(bool enable)
{
// if sensor is cold
qDebug() << "ConfigManager::SetRecordingState";
if (this->recording != enable) {
this->recording = enable;
emit NewRecordingState(this->recording);
}
}
int ConfigManager::GetFrameRate()
{
qDebug() << "ConfigManager::GetFrameRate";
return this->frame_rate;
}
void ConfigManager::SetFrameRate(int frame_rate)
{
qDebug() << "ConfigManager::SetFrameRate";
if (this->frame_rate != frame_rate) {
this->frame_rate = frame_rate;
emit NewFrameRate(this->frame_rate);
}
}
double ConfigManager::GetEmissivity()
{
qDebug() << "ConfigManager::GetEmissivity";
return this->emissivity;
}
void ConfigManager::SetEmissivity(double emissivity)
{
qDebug() << "ConfigManager::SetEmissivity";
if (this->emissivity != emissivity) {
this->emissivity = emissivity;
emit NewEmissivity(this->emissivity);
}
}
QString ConfigManager::GetViewfinderConfig()
{
qDebug() << "ConfigManager::GetViewfinderConfig";
QJsonDocument doc(this->viewfinder_config);
return doc.toJson();
}
void ConfigManager::SetViewfinderConfig(QString config)
{
qDebug() << "ConfigManager::SetViewfinderConfig";
QJsonDocument doc = QJsonDocument::fromJson(config.toUtf8());
this->viewfinder_config = doc.object();
}
QString ConfigManager::GetTriggerConfig()
{
qDebug() << "ConfigManager::GetTriggerConfig";
QJsonDocument doc(this->trigger_config);
return doc.toJson();
}
void ConfigManager::SetTriggerConfig(QString config)
{
qDebug() << "ConfigManager::SetTriggerConfig";
QJsonDocument doc = QJsonDocument::fromJson(config.toUtf8());
this->trigger_config = doc.object();
}
+55
View File
@@ -0,0 +1,55 @@
#ifndef CONFIG_MANAGER_H
#define CONFIG_MANAGER_H
#include <QObject>
#include <QJsonObject>
class ConfigManager: public QObject
{
Q_OBJECT;
Q_PROPERTY(bool recording READ GetRecordingState WRITE SetRecordingState)
Q_PROPERTY(int frame_rate READ GetFrameRate WRITE SetFrameRate)
Q_PROPERTY(double emissivity READ GetEmissivity WRITE SetEmissivity)
Q_PROPERTY(QString viewfinder_config READ GetViewfinderConfig WRITE SetViewfinderConfig)
Q_PROPERTY(QString trigger_config READ GetTriggerConfig WRITE SetTriggerConfig)
public:
ConfigManager(QObject *parent);
virtual ~ConfigManager();
public slots:
bool GetRecordingState();
void SetRecordingState(bool enable);
int GetFrameRate();
void SetFrameRate(int frame_rate);
double GetEmissivity();
void SetEmissivity(double emissivity);
QString GetViewfinderConfig();
void SetViewfinderConfig(QString config);
QString GetTriggerConfig();
void SetTriggerConfig(QString config);
signals:
void NewRecordingState(bool enable);
void NewFrameRate(int frame_rate);
void NewEmissivity(double emissivity);
private:
bool recording = false;
int frame_rate = 5;
double emissivity = 0.95;
QJsonObject viewfinder_config = QJsonObject(
{
qMakePair(QString("palette"), QJsonValue("rainbow")),
qMakePair(QString("low_temp"), QJsonValue(0)),
qMakePair(QString("high_temp"), QJsonValue(100))
});
QJsonObject trigger_config = QJsonObject(
{
qMakePair(QString("method"), QJsonValue("threshold")),
qMakePair(QString("min"), QJsonValue(50)),
qMakePair(QString("max"), QJsonValue(100))
});
};
#endif
+7 -38
View File
@@ -1,45 +1,14 @@
#include <iostream> #include "FaultFinder.hpp"
#include "StreamManager.hpp" FaultFinder::FaultFinder(QObject *parent) : QObject(parent)
#include "ImageManager.hpp"
#include "FaultManager.hpp"
using namespace std;
int main(int argc, char **argv)
{ {
StreamManager stream_mgr; fault_mgr = new FaultManager(this);
ImageManager image_mgr; image_mgr = new ImageManager(this);
FaultManager fault_mgr; config_mgr = new ConfigManager(this);
PvString lConnectionID; stream_mgr = new StreamManager(this);
// If running in test mode
if (argc > 1 && !strcmp(argv[1], "test"))
{
while(1)
{
if (!image_mgr.ProcessImage(0, 0, 0, fault_mgr, true))
break;
}
return 0;
} }
// If no devies are found, exit. FaultFinder::~FaultFinder()
if (stream_mgr.FindDevice(&lConnectionID).IsFailure())
{ {
return -1;
}
if (stream_mgr.ConnectToDevice(lConnectionID).IsFailure())
{
return -1;
}
stream_mgr.OpenStream(lConnectionID);
stream_mgr.AcquireImages(image_mgr, fault_mgr);
stream_mgr.Disconnect();
return 0;
} }
+27
View File
@@ -0,0 +1,27 @@
#ifndef FAULT_FINDER_H
#define FAULT_FINDER_H
#include <QObject>
#include "StreamManager.hpp"
#include "ImageManager.hpp"
#include "FaultManager.hpp"
#include "ConfigManager.hpp"
class FaultFinder : public QObject
{
Q_OBJECT;
public:
FaultFinder(QObject *parent);
virtual ~FaultFinder();
FaultManager *fault_mgr;
ImageManager *image_mgr;
ConfigManager *config_mgr;
StreamManager *stream_mgr;
bool test_mode = false;
};
#endif
+77 -7
View File
@@ -1,11 +1,81 @@
#include <opencv2/opencv.hpp>
#include "FaultManager.hpp" #include "FaultManager.hpp"
using namespace cv; FaultManager::FaultManager(QObject *parent) : QObject(parent)
void FaultManager::SaveImage(Mat image)
{ {
// Tag date, time, gps in file meta data bool res;
//imwrite( "/tmp/uniquetime.png", image);
res = OpenDatabase();
if (!res) {
qCritical() << "Failed to open database connection.";
exit(15);
}
res = OpenSerial();
if (!res) {
qCritical() << "Failure to open GPS serial device.";
exit(16);
}
StartGPS();
}
FaultManager::~FaultManager()
{
db.close();
gps->stopUpdates();
serial->close();
}
bool FaultManager::OpenDatabase()
{
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("FaultDatabase");
db.setUserName("user");
db.setPassword("faultfinder");
return db.open();
}
bool FaultManager::OpenSerial()
{
serial = new QSerialPort();
serial->setPortName("ttyUSB0");
serial->setBaudRate(QSerialPort::Baud4800);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
return serial->open(QIODevice::ReadOnly);
}
void FaultManager::StartGPS()
{
gps = new QNmeaPositionInfoSource(QNmeaPositionInfoSource::RealTimeMode);
gps->setDevice((QIODevice *)serial);
gps->startUpdates();
}
void FaultManager::SaveImage(QByteArray *imageBuffer)
{
QSqlQuery query;
// Get GPS Location
QGeoPositionInfo position = gps->lastKnownPosition(true);
QGeoCoordinate coorinate = position.coordinate();
query.prepare("INSERT INTO Faults (latitude, longitude, altitude, image) "
"VALUES (:latitude, :longitude, :altitude, :image)");
if (coorinate.isValid())
{
// This probably wont work without proper converstions
query.bindValue(":latitude", coorinate.latitude());
query.bindValue(":longitude", coorinate.longitude());
query.bindValue(":altitude", coorinate.altitude());
}
query.bindValue(":image", *imageBuffer);
// Save to Database
query.exec();
} }
+21 -5
View File
@@ -1,14 +1,30 @@
#ifndef FAULTMANAGER_H #ifndef FAULT_MANAGER_H
#define FAULTMANAGER_H #define FAULT_MANAGER_H
#include <opencv2/core.hpp> #include <QObject>
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSaveFile>
#include <QNmeaPositionInfoSource>
#include <QSerialPort>
class FaultManager class FaultManager: public QObject
{ {
Q_OBJECT;
public: public:
FaultManager(QObject *parent);
virtual ~FaultManager();
void SaveImage(QByteArray *imageBuffer);
void SaveImage(cv::Mat image); private:
bool OpenDatabase();
bool OpenSerial();
void StartGPS();
QSqlDatabase db;
QSerialPort *serial;
QNmeaPositionInfoSource *gps;
}; };
+26 -25
View File
@@ -3,8 +3,8 @@
#include <opencv2/imgcodecs.hpp> #include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp> #include <opencv2/imgproc.hpp>
#include "FaultFinder.hpp"
#include "ImageManager.hpp" #include "ImageManager.hpp"
#include "FaultManager.hpp"
#define ZERO 0 #define ZERO 0
#define BITS8 0xff #define BITS8 0xff
@@ -13,9 +13,20 @@
using namespace cv; using namespace cv;
Mat testFrame = imread("/home/midstate/Documents/flirTest.tif", CV_16UC1); //Mat testFrame = imread("/home/midstate/Documents/flirTest.tif", CV_16UC1);
bool ImageManager::ProcessImage(uint32_t width, uint32_t height, uint8_t *imgPointer, FaultManager fault_mgr, bool test = false) ImageManager::ImageManager(QObject *parent) : QObject(parent)
{
socket = new QUdpSocket();
socket->connectToHost(QHostAddress::LocalHost, 40000, QIODevice::ReadWrite);
}
ImageManager::~ImageManager()
{
}
void ImageManager::ProcessImage(int width, int height, uint8_t *imgPointer)
{ {
Mat frame, mask, viewfinder; Mat frame, mask, viewfinder;
std::vector<std::vector<Point>> contours; std::vector<std::vector<Point>> contours;
@@ -32,14 +43,16 @@ bool ImageManager::ProcessImage(uint32_t width, uint32_t height, uint8_t *imgPoi
else else
{ {
throttle_count++; throttle_count++;
return true; return;
} }
// Read in frame // Read in frame
if (!test) //if (!test)
// frame = Mat(height, width, CV_16UC1, imgPointer, Mat::AUTO_STEP);
//else
// frame = testFrame;
frame = Mat(height, width, CV_16UC1, imgPointer, Mat::AUTO_STEP); frame = Mat(height, width, CV_16UC1, imgPointer, Mat::AUTO_STEP);
else
frame = testFrame;
// Create mask and then flatten // Create mask and then flatten
GaussianBlur(frame, mask, cv::Size(0, 0), 1); GaussianBlur(frame, mask, cv::Size(0, 0), 1);
@@ -63,31 +76,19 @@ bool ImageManager::ProcessImage(uint32_t width, uint32_t height, uint8_t *imgPoi
if (area > fault_area) if (area > fault_area)
{ {
// Fault Detected, Draw on Screen and Save to Database
drawContours(viewfinder, contours, i, Scalar(ZERO, BITS8, ZERO), 2); drawContours(viewfinder, contours, i, Scalar(ZERO, BITS8, ZERO), 2);
fault_mgr.SaveImage(viewfinder);
}
}
// Create Viewfinder Window std::vector<uchar> imageBuffer;
createTrackbar("Lower Bound", "FLIR Viewfinder", &lower_bound, BITS14, NULL); imencode(".pgm", frame, imageBuffer);
createTrackbar("Upper Bound", "FLIR Viewfinder", &upper_bound, BITS14, NULL); QByteArray* imageBytes = new QByteArray(reinterpret_cast<const char*>(imageBuffer.data()), imageBuffer.size());
createTrackbar("Temperature Threshold", "FLIR Viewfinder", &temp_threshold, BITS14, NULL);
createTrackbar("Fault Area", "FLIR Viewfinder", &fault_area, 0x50280, NULL);
// Make clicking a pixel display the temp value
//setMouseCallback("FLIR Viewfinder", NULL);
namedWindow("FLIR Viewfinder", WINDOW_AUTOSIZE);
imshow("FLIR Viewfinder", viewfinder);
if (waitKey(1) == 27 || getWindowProperty("FLIR Viewfinder", WND_PROP_FULLSCREEN) == -1) ((FaultFinder*)(parent()))->fault_mgr->SaveImage(imageBytes);
{ }
destroyAllWindows();
return false;
} }
// Send image to other servers // Send image to other servers
SendImage(viewfinder); SendImage(viewfinder);
return true;
} }
void ImageManager::SendImage(Mat image) void ImageManager::SendImage(Mat image)
+9 -12
View File
@@ -1,29 +1,26 @@
#ifndef ImageManager_H #ifndef IMAGE_MANAGER_H
#define ImageManager_H #define IMAGE_MANAGER_H
#include <opencv2/core.hpp> #include <QObject>
#include <QUdpSocket> #include <QUdpSocket>
#include "FaultManager.hpp" #include <opencv2/core.hpp>
#define THROTTLE_AMOUNT 1 #define THROTTLE_AMOUNT 1
class ImageManager class ImageManager: public QObject
{ {
Q_OBJECT;
public: public:
ImageManager(QObject *parent);
virtual ~ImageManager();
bool ProcessImage(uint32_t width, uint32_t height, uint8_t *imgPointer, FaultManager fault_mgr, bool test); void ProcessImage(int width, int height, uint8_t *imgPointer);
void SendImage(cv::Mat image); void SendImage(cv::Mat image);
QUdpSocket *socket; QUdpSocket *socket;
ImageManager() {
socket = new QUdpSocket();
socket->connectToHost(QHostAddress::LocalHost, 40000, QIODevice::ReadWrite);
}
private: private:
int throttle_count = 1; int throttle_count = 1;
}; };
+126 -169
View File
@@ -1,15 +1,74 @@
#include <iostream>
#include <PvSystem.h>
#include <PvDevice.h>
#include <PvDeviceGEV.h>
#include <PvStream.h>
#include <PvStreamGEV.h>
#include "StreamManager.hpp" #include "StreamManager.hpp"
#include "FaultManager.hpp" #include "FaultFinder.hpp"
PvResult StreamManager::FindDevice(PvString *aConnectionID) StreamManager::StreamManager(QObject *parent) : QObject(parent)
{
// Connect Signals
connect(((FaultFinder *)parent)->config_mgr, &ConfigManager::NewEmissivity, this, &StreamManager::SetEmissivity);
connect(((FaultFinder *)parent)->config_mgr, &ConfigManager::NewFrameRate, this, &StreamManager::SetFrameRate);
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);
connect(ImageThread, &StreamReader::NewImage, this, &StreamManager::SendForProcessing, Qt::QueuedConnection);
ImageThread->start(QThread::TimeCriticalPriority);
}
StreamManager::~StreamManager()
{
ImageThread->requestInterruption();
ImageThread->wait();
StopStream();
Disconnect();
}
void StreamManager::SendForProcessing(int width, int height, uint8_t *imgPointer)
{
((FaultFinder *)parent())->image_mgr->ProcessImage(width, height, imgPointer);
}
void StreamManager::SetEmissivity(double emissivity)
{
if (lDeviceParams)
lDeviceParams->SetFloatValue("ObjectEmissivity", emissivity);
}
void StreamManager::SetFrameRate(int frame_rate)
{
if (lDeviceParams)
lDeviceParams->SetFloatValue("PS0FrameRate", frame_rate);
}
bool StreamManager::GetReadyState()
{
bool cold = false;
if (lDeviceParams)
lDeviceParams->GetBooleanValue("FPACold", cold);
return cold;
}
PvResult StreamManager::FindDevice()
{ {
PvResult lResult = PvResult(); PvResult lResult = PvResult();
const PvDeviceInfo *lSelectedDI = NULL; const PvDeviceInfo *lSelectedDI = NULL;
@@ -37,55 +96,50 @@ PvResult StreamManager::FindDevice(PvString *aConnectionID)
if (lDIVector.size() == 0) if (lDIVector.size() == 0)
{ {
std::cout << "Device not found!" << std::endl; qCritical() << "Device not found!";
lResult.SetCode(PV_NOT_FOUND); lResult.SetCode(PV_NOT_FOUND);
return lResult; return lResult;
} }
lSelectedDI = lDIVector.front(); lSelectedDI = lDIVector.front();
*aConnectionID = lSelectedDI->GetConnectionID(); ConnectionID = lSelectedDI->GetConnectionID();
lResult.SetCode(PV_OK); lResult.SetCode(PV_OK);
return lResult; return lResult;
} }
PvResult StreamManager::ConnectToDevice(const PvString &aConnectionID) PvResult StreamManager::ConnectToDevice()
{ {
PvResult lResult; PvResult lResult;
// Connect to the GigE Vision or USB3 Vision device // Connect to the GigE Vision or USB3 Vision device
std::cout << "Connecting to device." << std::endl; qInfo() << "Connecting to device.";
lDevice = PvDevice::CreateAndConnect(aConnectionID, &lResult); Device = PvDevice::CreateAndConnect(ConnectionID, &lResult);
if (lDevice == NULL) if (Device == NULL)
{ {
std::cout << "Unable to connect to device." << std::endl; qCritical() << "Unable to connect to device.";
} }
return lResult; return lResult;
} }
PvResult StreamManager::OpenStream(const PvString &aConnectionID) PvResult StreamManager::OpenStream()
{ {
PvResult lResult; PvResult lResult;
if (lDevice == NULL)
{
return lResult;
}
// Open stream to the GigE Vision or USB3 Vision device // Open stream to the GigE Vision or USB3 Vision device
std::cout << "Opening stream from device." << std::endl; qInfo() << "Opening stream from device.";
lStream = PvStream::CreateAndOpen(aConnectionID, &lResult); Stream = PvStream::CreateAndOpen(ConnectionID, &lResult);
if (lStream != NULL) if (Stream != NULL)
{ {
// If this is a GigE Vision device, configure GigE Vision specific streaming parameters // If this is a GigE Vision device, configure GigE Vision specific streaming parameters
PvDeviceGEV* lDeviceGEV = dynamic_cast<PvDeviceGEV *>(lDevice); PvDeviceGEV* lDeviceGEV = dynamic_cast<PvDeviceGEV *>(Device);
if ( lDeviceGEV != NULL ) if ( lDeviceGEV != NULL )
{ {
PvStreamGEV *lStreamGEV = static_cast<PvStreamGEV *>(lStream); PvStreamGEV *lStreamGEV = static_cast<PvStreamGEV *>(Stream);
// Negotiate packet size // Negotiate packet size
lDeviceGEV->NegotiatePacketSize(); lDeviceGEV->NegotiatePacketSize();
@@ -96,184 +150,87 @@ PvResult StreamManager::OpenStream(const PvString &aConnectionID)
} }
else else
{ {
std::cout << "Unable to stream from device." << std::endl; qCritical() << "Unable to stream from device.";
} }
return lResult; return lResult;
} }
void StreamManager::CreateStreamBuffers() void StreamManager::ConfigureStream()
{ {
// Reading payload size from device
uint32_t lSize = lDevice->GetPayloadSize();
// Use BUFFER_COUNT or the maximum number of buffers, whichever is smaller
uint32_t lBufferCount = (lStream->GetQueuedBufferMaximum() < BUFFER_COUNT) ?
lStream->GetQueuedBufferMaximum() :
BUFFER_COUNT;
// Allocate buffers
for (uint32_t i = 0; i < lBufferCount; i++)
{
// Create new buffer object
PvBuffer *lBuffer = new PvBuffer;
// Have the new buffer object allocate payload memory
lBuffer->Alloc(static_cast<uint32_t>(lSize));
// Add to external list - used to eventually release the buffers
lBufferList.push_back(lBuffer);
}
// Queue all buffers in the stream
BufferList::iterator lIt = lBufferList.begin();
while (lIt != lBufferList.end())
{
lStream->QueueBuffer( *lIt );
lIt++;
}
}
void StreamManager::AcquireImages(ImageManager image_mgr, FaultManager fault_mgr)
{
if (lDevice == NULL || lStream == NULL)
{
return;
}
CreateStreamBuffers();
// Get device parameters need to control streaming // Get device parameters need to control streaming
PvGenParameterArray *lDeviceParams = lDevice->GetParameters(); lDeviceParams = Device->GetParameters();
// Use Temperature Format Instead of Raw Counts // Use Temperature Format Instead of Raw Counts
lDeviceParams->SetEnumValue("IRFormat", 1); lDeviceParams->SetEnumValue("IRFormat", 1);
// Set Emissivity SetEmissivity(((FaultFinder *)parent())->config_mgr->GetEmissivity());
//lDeviceParams->SetFloatValue("ObjectEmissivity", 0.95); SetFrameRate(((FaultFinder *)parent())->config_mgr->GetFrameRate());
}
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 // Map the GenICam AcquisitionStart and AcquisitionStop commands
PvGenCommand *lStart = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStart")); PvGenCommand *lStart = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStart"));
PvGenCommand *lStop = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStop"));
qInfo() << "Starting pipeline";
Pipeline->Start();
// Get stream parameters // Get stream parameters
PvGenParameterArray *lStreamParams = lStream->GetParameters(); PvGenParameterArray *lStreamParams = Stream->GetParameters();
// Map a few GenICam stream stats counters // Map a few GenICam stream stats counters
PvGenFloat *lFrameRate = dynamic_cast<PvGenFloat *>(lStreamParams->Get("AcquisitionRate")); PvGenFloat *lFrameRate = dynamic_cast<PvGenFloat *>(lStreamParams->Get("AcquisitionRate"));
PvGenFloat *lBandwidth = dynamic_cast<PvGenFloat *>(lStreamParams->Get("Bandwidth")); PvGenFloat *lBandwidth = dynamic_cast<PvGenFloat *>(lStreamParams->Get("Bandwidth"));
// Enable streaming and send the AcquisitionStart command // Enable streaming and send the AcquisitionStart command
std::cout << "Enabling streaming and sending AcquisitionStart command." << std::endl; qInfo() << "Enabling streaming and sending AcquisitionStart command.";
lDevice->StreamEnable(); Device->StreamEnable();
lStart->Execute(); lStart->Execute();
double lFrameRateVal = 0.0;
double lBandwidthVal = 0.0;
// Acquire images until the user instructs us to stop.
while (true)
{
PvBuffer *lBuffer = NULL;
PvResult lOperationResult;
// Retrieve next buffer
PvResult lResult = lStream->RetrieveBuffer(&lBuffer, &lOperationResult, 1000);
if (lResult.IsOK())
{
if (lOperationResult.IsOK())
{
PvPayloadType lType;
lFrameRate->GetValue(lFrameRateVal);
lBandwidth->GetValue(lBandwidthVal);
// 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();
// Process Image
if (!image_mgr.ProcessImage(lWidth, lHeight, lImage->GetDataPointer(), fault_mgr, false))
break;
std::cout << " W: " << std::dec << lWidth << " H: " << lHeight;
}
else
{
std::cout << " (buffer does not contain image)";
}
std::cout << " " << lFrameRateVal << " FPS " << ( lBandwidthVal / 1000000.0 ) << " Mb/s \r";
}
else
{
std::cout << lOperationResult.GetCodeString().GetAscii() << "\r";
} }
// Re-queue the buffer in the stream object void StreamManager::StopStream()
lStream->QueueBuffer(lBuffer);
}
else
{ {
// Retrieve buffer failure
std::cout << lResult.GetCodeString().GetAscii() << "\r";
}
}
// Tell the device to stop sending images. // Tell the device to stop sending images.
std::cout << "Sending AcquisitionStop command to the device" << std::endl; qInfo() << "Sending AcquisitionStop command to the device";
PvGenCommand *lStop = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStop"));
lStop->Execute(); lStop->Execute();
// Disable streaming on the device // Disable streaming on the device
std::cout << "Disable streaming on the controller." << std::endl; qInfo() << "Disable streaming on the controller.";;
lDevice->StreamDisable(); Device->StreamDisable();
// Abort all buffers from the stream and dequeue // Stop the pipeline
std::cout << "Aborting buffers still in stream" << std::endl; qInfo() << "Stop pipeline";
lStream->AbortQueuedBuffers(); Pipeline->Stop();
while (lStream->GetQueuedBufferCount() > 0)
{
PvBuffer *lBuffer = NULL;
PvResult lOperationResult;
lStream->RetrieveBuffer(&lBuffer, &lOperationResult);
}
FreeStreamBuffers();
}
void StreamManager::FreeStreamBuffers()
{
// Go through the buffer list
BufferList::iterator lIt = lBufferList.begin();
while (lIt != lBufferList.end())
{
delete *lIt;
lIt++;
}
// Clear the buffer list
lBufferList.clear();
} }
void StreamManager::Disconnect() void StreamManager::Disconnect()
{ {
if (lStream != NULL) if (Stream != NULL)
{ {
lStream->Close(); Stream->Close();
PvStream::Free( lStream ); PvStream::Free(Stream);
} }
if (lDevice != NULL) if (Device != NULL)
{ {
lDevice->Disconnect(); Device->Disconnect();
PvDevice::Free(lDevice); PvDevice::Free(Device);
} }
} }
+37 -18
View File
@@ -1,32 +1,51 @@
#include <list> #ifndef STREAM_MANAGER_H
#define STREAM_MANAGER_H
#include <QObject>
#include <QDebug>
#include <PvSystem.h>
#include <PvDevice.h> #include <PvDevice.h>
#include <PvStream.h> #include <PvStream.h>
#include <PvBuffer.h> #include <PvPipeline.h>
#include <PvDeviceGEV.h>
#include "ImageManager.hpp" #include <PvStreamGEV.h>
#include "FaultManager.hpp" #include "StreamReader.hpp"
#define BUFFER_COUNT (32) #define BUFFER_COUNT (32)
typedef std::list<PvBuffer *> BufferList;
class StreamManager class StreamManager : public QObject
{ {
Q_OBJECT;
public: public:
StreamManager(QObject *parent);
virtual ~StreamManager();
PvResult FindDevice(PvString *aConnectionID); bool GetReadyState();
PvResult ConnectToDevice(const PvString &aConnectionID);
PvResult OpenStream(const PvString &aConnectionID); public slots:
void AcquireImages(ImageManager image_mgr, FaultManager fault_mgr); void SetEmissivity(double emissivity);
void Disconnect(); void SetFrameRate(int frame_rate);
void SendForProcessing(int width, int height, uint8_t *imgPointer);
private: private:
PvResult FindDevice();
PvResult ConnectToDevice();
PvResult OpenStream();
void ConfigureStream();
void StartStream();
void StopStream();
void CreatePipeline();
void AcquireImages();
void Disconnect();
PvDevice *lDevice = NULL; PvString ConnectionID;
PvStream *lStream = NULL; PvDevice *Device = NULL;
BufferList lBufferList; PvStream *Stream = NULL;
PvGenParameterArray *lDeviceParams = NULL;
void CreateStreamBuffers(); PvPipeline *Pipeline = NULL;
void FreeStreamBuffers(); StreamReader *ImageThread;
}; };
#endif
+61
View File
@@ -0,0 +1,61 @@
#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 = Pipeline->RetrieveNextBuffer(&lBuffer, 1000, &lOperationResult);
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();
// May need to push copy of data, not pointer to buffer in case it deallocs
emit 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
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(int width, int height, uint8_t *imgPointer);
private:
PvDevice *Device = NULL;
PvStream *Stream = NULL;
PvPipeline *Pipeline = NULL;
};
#endif
-2
View File
@@ -1,2 +0,0 @@
- Switch BufferList to Pipeline
- Signal Break From While Loop
+1 -1
View File
@@ -89,7 +89,7 @@ if(NOT Ebus_INCLUDE_DIR OR NOT EXISTS ${Ebus_INCLUDE_DIR})
"path to ebus include directory," "path to ebus include directory,"
"e.g. /opt/pleora/ebus_sdk/Ubuntu-x86_64/include.") "e.g. /opt/pleora/ebus_sdk/Ubuntu-x86_64/include.")
else() else()
message(STATUS "ebus include dir found: " ${Ebus_INCLUDE_DIR}) #message(STATUS "ebus include dir found: " ${Ebus_INCLUDE_DIR})
endif() endif()
# Find library directory for ebus # Find library directory for ebus
+21
View File
@@ -0,0 +1,21 @@
#include <csignal>
#include <QCoreApplication>
#include "FaultFinder.hpp"
using namespace std;
void handleClose(int signal)
{
qApp->exit(14);
}
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
FaultFinder ff(&app);
signal(SIGINT, &handleClose);
return app.exec();
}