Merge branch 'master' of https://git.physi.uni-heidelberg.de/HIT-PAT/HITDAQ
This commit is contained in:
commit
f82b5acd10
@ -4,9 +4,9 @@
|
||||
|
||||
DataReceiver::DataReceiver(QObject *parent) : QObject(parent), dataBuffer(RECEIVER_BUFFER_SIZE)
|
||||
{
|
||||
connect(this, DataReceiver::sigInit, this, DataReceiver::onInit);
|
||||
connect(this, DataReceiver::sigDeinit, this, DataReceiver::onDeinit);
|
||||
connect(this, DataReceiver::sigConfigureEthSettings, this, DataReceiver::onConfigureEthSettings);
|
||||
connect(this, &DataReceiver::sigInit, this, &DataReceiver::onInit);
|
||||
connect(this, &DataReceiver::sigDeinit, this, &DataReceiver::onDeinit);
|
||||
connect(this, &DataReceiver::sigConfigureEthSettings, this, &DataReceiver::onConfigureEthSettings);
|
||||
|
||||
moveToThread(&thread);
|
||||
thread.start();
|
||||
@ -97,13 +97,13 @@ void DataReceiver::onInit()
|
||||
if (dataSocket == NULL)
|
||||
{
|
||||
dataSocket = new QUdpSocket(this);
|
||||
connect(dataSocket, QUdpSocket::readyRead, this, DataReceiver::readData);
|
||||
connect(dataSocket, &QUdpSocket::readyRead, this, &DataReceiver::readData);
|
||||
}
|
||||
|
||||
if (timer == NULL)
|
||||
{
|
||||
timer = new QTimer(this);
|
||||
connect(timer, QTimer::timeout, this, onTimer);
|
||||
connect(timer, &QTimer::timeout, this, &DataReceiver::onTimer);
|
||||
timer->start(RECEIVER_TIMER_PERIOD_MS);
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ DialogBeta::DialogBeta(QWidget *parent) :
|
||||
DialogBeta::~DialogBeta()
|
||||
{
|
||||
timer.stop();
|
||||
disconnect(&timer, QTimer::timeout, this, &DialogBeta::onTimer);
|
||||
disconnect(&timer, &QTimer::timeout, this, &DialogBeta::onTimer);
|
||||
|
||||
delete ui;
|
||||
}
|
||||
@ -35,9 +35,9 @@ void DialogBeta::showEvent(QShowEvent * event)
|
||||
ui->lineRunsDone->setText(QString("%1").arg(nrRunsDone));
|
||||
//data logging possible only if global data logging is switched off
|
||||
if (theHW->eventBuilder.isLogging())
|
||||
ui->checkSaveRawData->setEnabled(FALSE);
|
||||
ui->checkSaveRawData->setEnabled(false);
|
||||
|
||||
connect(&timer, QTimer::timeout, this, &DialogBeta::onTimer);
|
||||
connect(&timer, &QTimer::timeout, this, &DialogBeta::onTimer);
|
||||
timer.start(250);
|
||||
}
|
||||
}
|
||||
|
@ -80,14 +80,14 @@ void DialogLinearity::run()
|
||||
|
||||
//Collect sensor data
|
||||
histoReady = 0;
|
||||
connect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogLinearity::onHistogramCompleted);
|
||||
connect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogLinearity::onHistogramCompleted);
|
||||
theHW->eventBuilder.startTakingHistos(nacqs);
|
||||
while (!histoReady)
|
||||
{
|
||||
QCoreApplication::processEvents();
|
||||
QThread::msleep(10);
|
||||
}
|
||||
disconnect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogLinearity::onHistogramCompleted);
|
||||
disconnect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogLinearity::onHistogramCompleted);
|
||||
QVector<Histogram> histos = theHW->eventBuilder.getHistos();
|
||||
|
||||
result.mean.fill(0, nr_devices*128);
|
||||
|
@ -99,7 +99,7 @@
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Display</string>
|
||||
<string>BPMDisplay</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -57,14 +57,14 @@ void DialogProfiler::run(int nr_loops)
|
||||
|
||||
//Collect sensor data
|
||||
histoReady = 0;
|
||||
connect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogProfiler::onHistogramCompleted);
|
||||
connect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogProfiler::onHistogramCompleted);
|
||||
theHW->eventBuilder.startTakingHistos(nacqs);
|
||||
while (!histoReady)
|
||||
{
|
||||
QCoreApplication::processEvents();
|
||||
QThread::msleep(10);
|
||||
}
|
||||
disconnect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogProfiler::onHistogramCompleted);
|
||||
disconnect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogProfiler::onHistogramCompleted);
|
||||
QVector<Histogram> histos = theHW->eventBuilder.getHistos();
|
||||
|
||||
result.mean.fill(0, nr_devices*128);
|
||||
|
@ -106,14 +106,14 @@ void DialogTiScan::run()
|
||||
|
||||
//Collect sensor data
|
||||
histoReady = 0;
|
||||
connect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogTiScan::onHistogramCompleted);
|
||||
connect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogTiScan::onHistogramCompleted);
|
||||
theHW->eventBuilder.startTakingHistos(nacqs);
|
||||
while (!histoReady)
|
||||
{
|
||||
QCoreApplication::processEvents();
|
||||
QThread::msleep(10);
|
||||
}
|
||||
disconnect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogTiScan::onHistogramCompleted);
|
||||
disconnect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogTiScan::onHistogramCompleted);
|
||||
QVector<Histogram> histos = theHW->eventBuilder.getHistos();
|
||||
|
||||
result.mean.fill(0, nr_devices*128);
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <QFileDialog>
|
||||
#include <QCheckBox>
|
||||
|
||||
Display::Display(QWidget *parent) :
|
||||
BPMDisplay::BPMDisplay(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::display)
|
||||
{
|
||||
@ -27,12 +27,12 @@ Display::Display(QWidget *parent) :
|
||||
// Connect the buttonClicked signal of the button group
|
||||
connect(buttonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(onButtonClicked(QAbstractButton*)));
|
||||
|
||||
connect(ui->pushButton_savebkg, &QPushButton::clicked, this, &Display::onSaveBackgroundClicked);
|
||||
connect(ui->pushButton_loadbkg, &QPushButton::clicked, this, &Display::onLoadBackgroundClicked);
|
||||
connect(ui->checkBox_subbkg, &QCheckBox::stateChanged, this, &Display::onCheckBoxStateChanged);
|
||||
connect(ui->pushButton_savecalib, &QPushButton::clicked, this, &Display::onSaveCalibrationClicked);
|
||||
connect(ui->pushButton_loadcalib, &QPushButton::clicked, this, &Display::onLoadCalibrationClicked);
|
||||
connect(ui->checkBox_expertmode, &QCheckBox::stateChanged, this, &Display::onExpertModeStateChanged);
|
||||
connect(ui->pushButton_savebkg, &QPushButton::clicked, this, &BPMDisplay::onSaveBackgroundClicked);
|
||||
connect(ui->pushButton_loadbkg, &QPushButton::clicked, this, &BPMDisplay::onLoadBackgroundClicked);
|
||||
connect(ui->checkBox_subbkg, &QCheckBox::stateChanged, this, &BPMDisplay::onCheckBoxStateChanged);
|
||||
connect(ui->pushButton_savecalib, &QPushButton::clicked, this, &BPMDisplay::onSaveCalibrationClicked);
|
||||
connect(ui->pushButton_loadcalib, &QPushButton::clicked, this, &BPMDisplay::onLoadCalibrationClicked);
|
||||
connect(ui->checkBox_expertmode, &QCheckBox::stateChanged, this, &BPMDisplay::onExpertModeStateChanged);
|
||||
|
||||
// Enable or disable the "Save Background" and "Save Calib" buttons accordingly
|
||||
ui->pushButton_savebkg->setEnabled(expertModeEnabled);
|
||||
@ -45,12 +45,12 @@ Display::Display(QWidget *parent) :
|
||||
|
||||
}
|
||||
|
||||
Display::~Display()
|
||||
BPMDisplay::~BPMDisplay()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void Display::showEvent(QShowEvent * event)
|
||||
void BPMDisplay::showEvent(QShowEvent * event)
|
||||
{
|
||||
if (!event->spontaneous())
|
||||
{
|
||||
@ -62,7 +62,7 @@ void Display::showEvent(QShowEvent * event)
|
||||
|
||||
//***********************************************
|
||||
|
||||
void Display::plot(const QVector<unsigned short> &data)
|
||||
void BPMDisplay::plot(const QVector<unsigned short> &data)
|
||||
{
|
||||
//resize data vectors and fill X values - only if needed
|
||||
if (data.length() != nrPoints)
|
||||
@ -138,18 +138,18 @@ void Display::plot(const QVector<unsigned short> &data)
|
||||
ui->plot->replot();
|
||||
}
|
||||
|
||||
void Display::plot()
|
||||
void BPMDisplay::plot()
|
||||
{
|
||||
plot(buffer);
|
||||
}
|
||||
|
||||
void Display::setTitle(QString title)
|
||||
void BPMDisplay::setTitle(QString title)
|
||||
{
|
||||
ui->lineTitle->setText(title);
|
||||
}
|
||||
|
||||
// Slot to handle button clicks
|
||||
void Display::onButtonClicked(QAbstractButton *button)
|
||||
void BPMDisplay::onButtonClicked(QAbstractButton *button)
|
||||
{
|
||||
// Handle button clicks here
|
||||
if (button == radioButtonFixedScale)
|
||||
@ -170,7 +170,7 @@ void Display::onButtonClicked(QAbstractButton *button)
|
||||
}
|
||||
}
|
||||
|
||||
void Display::onSaveBackgroundClicked()
|
||||
void BPMDisplay::onSaveBackgroundClicked()
|
||||
{
|
||||
// Check if there is data to save
|
||||
if (buffer.isEmpty()) {
|
||||
@ -208,7 +208,7 @@ void Display::onSaveBackgroundClicked()
|
||||
}
|
||||
}
|
||||
|
||||
void Display::onLoadBackgroundClicked()
|
||||
void BPMDisplay::onLoadBackgroundClicked()
|
||||
{
|
||||
// Get the plane's name (you might need to adjust how you retrieve it)
|
||||
QString planeName = ui->lineTitle->text();
|
||||
@ -246,13 +246,13 @@ void Display::onLoadBackgroundClicked()
|
||||
}
|
||||
}
|
||||
|
||||
void Display::onCheckBoxStateChanged(int state)
|
||||
void BPMDisplay::onCheckBoxStateChanged(int state)
|
||||
{
|
||||
// The state argument will be Qt::Unchecked (0) or Qt::Checked (2)
|
||||
subtractBackground = (state == Qt::Checked);
|
||||
}
|
||||
|
||||
void Display::onSaveCalibrationClicked()
|
||||
void BPMDisplay::onSaveCalibrationClicked()
|
||||
{
|
||||
|
||||
// Check if there is data to save
|
||||
@ -291,7 +291,7 @@ void Display::onSaveCalibrationClicked()
|
||||
}
|
||||
}
|
||||
|
||||
void Display::onLoadCalibrationClicked()
|
||||
void BPMDisplay::onLoadCalibrationClicked()
|
||||
{
|
||||
// Get the plane's name (you might need to adjust how you retrieve it)
|
||||
QString planeName = ui->lineTitle->text();
|
||||
@ -361,14 +361,14 @@ void Display::onLoadCalibrationClicked()
|
||||
}
|
||||
}
|
||||
|
||||
void Display::onCalibrationCheckBoxChanged(int state) {
|
||||
void BPMDisplay::onCalibrationCheckBoxChanged(int state) {
|
||||
// Check the state and update the subtractCalibration flag accordingly
|
||||
applyCalibration = (state == Qt::Checked);
|
||||
}
|
||||
|
||||
|
||||
// Slot to handle the state change of the "Expert Mode" checkbox
|
||||
void Display::onExpertModeStateChanged(int state)
|
||||
void BPMDisplay::onExpertModeStateChanged(int state)
|
||||
{
|
||||
// Check if the checkbox is checked (Expert Mode enabled)
|
||||
expertModeEnabled = (state == Qt::Checked);
|
||||
|
@ -13,13 +13,13 @@ namespace Ui {
|
||||
class display;
|
||||
}
|
||||
|
||||
class Display : public QDialog
|
||||
class BPMDisplay : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Display(QWidget *parent = 0);
|
||||
~Display();
|
||||
explicit BPMDisplay(QWidget *parent = 0);
|
||||
~BPMDisplay();
|
||||
|
||||
|
||||
void plot(const QVector<unsigned short> &data);
|
||||
|
@ -17,7 +17,7 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Online Display</string>
|
||||
<string>Online BPMDisplay</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<property name="geometry">
|
||||
|
@ -66,7 +66,7 @@ void DisplayServer::show()
|
||||
displays.clear();
|
||||
for (int plane = 0; plane < planeConfig.length(); plane++)
|
||||
{
|
||||
Display* newDisplay = new Display;
|
||||
BPMDisplay* newDisplay = new BPMDisplay;
|
||||
newDisplay->setTitle(planeConfig[plane]->name);
|
||||
newDisplay->show();
|
||||
displays.append(newDisplay);
|
||||
|
@ -38,7 +38,7 @@ protected:
|
||||
int active = 0;
|
||||
HW* theHW;
|
||||
QVector<PlaneConfig*> planeConfig;
|
||||
QVector<Display*> displays;
|
||||
QVector<BPMDisplay*> displays;
|
||||
|
||||
PlaneConfig *findPlane(int plane_nr);
|
||||
};
|
||||
|
@ -1,20 +1,19 @@
|
||||
#include "eventbuilder.h"
|
||||
#include "udpserver.h"
|
||||
#include "hit_analyse_v2.h"
|
||||
|
||||
#include <QTime>
|
||||
EventBuilder::EventBuilder( QObject *parent) : QObject(parent)
|
||||
{
|
||||
connect(this, EventBuilder::sigInit, this, EventBuilder::onInit);
|
||||
connect(this, EventBuilder::sigDeinit, this, EventBuilder::onDeinit);
|
||||
connect(this, EventBuilder::sigStartLogging, this, EventBuilder::onStartLogging);
|
||||
connect(this, EventBuilder::sigStopLogging, this, EventBuilder::onStopLogging);
|
||||
connect(this, EventBuilder::sigStartTakingHistos, this, EventBuilder::onStartTakingHistos);
|
||||
connect(this, EventBuilder::sigStopTakingHistos, this, EventBuilder::onStopTakingHistos);
|
||||
|
||||
connect(this, &EventBuilder::sigInit, this, &EventBuilder::onInit);
|
||||
connect(this, &EventBuilder::sigDeinit, this, &EventBuilder::onDeinit);
|
||||
connect(this, &EventBuilder::sigStartLogging, this, &EventBuilder::onStartLogging);
|
||||
connect(this, &EventBuilder::sigStopLogging, this, &EventBuilder::onStopLogging);
|
||||
connect(this, &EventBuilder::sigStartTakingHistos, this, &EventBuilder::onStartTakingHistos);
|
||||
connect(this, &EventBuilder::sigStopTakingHistos, this, &EventBuilder::onStopTakingHistos);
|
||||
|
||||
moveToThread(&thread);
|
||||
thread.start();
|
||||
init();
|
||||
//get the network thread
|
||||
}
|
||||
|
||||
EventBuilder::~EventBuilder()
|
||||
@ -23,6 +22,8 @@ EventBuilder::~EventBuilder()
|
||||
|
||||
thread.quit();
|
||||
thread.wait();
|
||||
// networkThread.stopThread();
|
||||
// networkThread.wait(); // Wait for the network thread to finish gracefully
|
||||
}
|
||||
|
||||
|
||||
@ -64,7 +65,7 @@ void EventBuilder::onNewData(DataReceiver* receiver)
|
||||
//1. Background subtraction.
|
||||
|
||||
frame_counter++;
|
||||
|
||||
/*
|
||||
while (frame_counter<10000){
|
||||
for (unsigned int dev_nr = 0; dev_nr < nrReceivers; dev_nr++){
|
||||
for (unsigned int ch = 0; ch < channelCounts[dev_nr]; ch++)
|
||||
@ -84,7 +85,7 @@ void EventBuilder::onNewData(DataReceiver* receiver)
|
||||
currentFrame[dev_nr].sensor_data[ch]-=backgroundFrame[dev_nr].sensor_data[ch] ;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
lastFrameMutex.lock();
|
||||
@ -92,7 +93,7 @@ void EventBuilder::onNewData(DataReceiver* receiver)
|
||||
newDataSemaphore.release(1);
|
||||
lastFrame = currentFrame;
|
||||
lastFrameMutex.unlock();
|
||||
|
||||
/*
|
||||
//histogram stuff
|
||||
if (histogramSamplesToTake)
|
||||
{
|
||||
@ -105,16 +106,25 @@ void EventBuilder::onNewData(DataReceiver* receiver)
|
||||
if (histogramSamplesToTake == 0)
|
||||
emit sigHistoCompleted();
|
||||
}
|
||||
|
||||
*/
|
||||
//log data
|
||||
if (loggingData) logDataToFile();
|
||||
//HIT_ANALYSE_V2 hit_analyse_v2;//create the object
|
||||
// QString dataString = hit_analyse_v2.analyseBeamData(currentFrame);
|
||||
|
||||
HIT_ANALYSE_V2 hit_analyse_v2;//create the object
|
||||
QString dataString;
|
||||
for (unsigned int dev_nr = 0; dev_nr < nrReceivers; dev_nr++){
|
||||
dataString += hit_analyse_v2.analyseBeamData(currentFrame);
|
||||
dataString +=',';
|
||||
}
|
||||
QTime currentTime = QTime::currentTime();
|
||||
//Calculate the time since midnight in milliseconds
|
||||
int millisecondsSinceMidnight = currentTime.msecsSinceStartOfDay();
|
||||
dataString += QString::number(millisecondsSinceMidnight);
|
||||
receiveData(dataString.toUtf8());
|
||||
// std::cerr << dataString.toStdString() << std::endl;
|
||||
// Call sendData method of the UDP server
|
||||
QString dataString = QString::number(intensity) + ',' + QString::number(position) + ',' + QString::number(focus);
|
||||
QByteArray data = dataString.toUtf8();
|
||||
udpServer.sendData(data);
|
||||
// QString dataString = QString::number(intensity) + ',' + QString::number(position) + ',' + QString::number(focus);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -282,13 +292,13 @@ void EventBuilder::addSource(DataReceiver* source)
|
||||
nrReceivers = receivers.length();
|
||||
currentFrame.resize(nrReceivers);
|
||||
backgroundFrame.resize(nrReceivers);
|
||||
connect(source, DataReceiver::sigDataReady, this, EventBuilder::onNewData);
|
||||
connect(source, &DataReceiver::sigDataReady, this, &EventBuilder::onNewData);
|
||||
}
|
||||
|
||||
void EventBuilder::deleteSources()
|
||||
{
|
||||
for (int i = 0; i < receivers.length(); i++)
|
||||
disconnect(receivers[i], DataReceiver::sigDataReady, this, EventBuilder::onNewData);
|
||||
disconnect(receivers[i], &DataReceiver::sigDataReady, this, &EventBuilder::onNewData);
|
||||
|
||||
receivers.clear();
|
||||
nrReceivers = receivers.length();
|
||||
@ -342,3 +352,21 @@ QVector<BufferData> EventBuilder::getNewFrame()
|
||||
//and return it
|
||||
return getLastFrame();
|
||||
}
|
||||
|
||||
void EventBuilder::receiveData(const QByteArray &data)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
dataQueue.enqueue(data);
|
||||
QString dataString = QString(data);
|
||||
// std::cerr << dataString.toStdString() << std::endl;
|
||||
|
||||
dataAvailable.wakeOne();
|
||||
}
|
||||
|
||||
QByteArray EventBuilder::getNextData()
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
if (dataQueue.isEmpty())
|
||||
return QByteArray(); // Return an empty QByteArray if no data is available
|
||||
return dataQueue.dequeue();
|
||||
}
|
||||
|
@ -8,8 +8,8 @@
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
#include "udpserver.h" // Include the UDP server header
|
||||
|
||||
#include <QQueue>
|
||||
#include <QWaitCondition>
|
||||
//#include "hw.h"
|
||||
#include "datareceiver.h"
|
||||
#include "histogram.h"
|
||||
@ -48,9 +48,18 @@ signals:
|
||||
void sigStopTakingHistos();
|
||||
|
||||
void sigHistoCompleted(); //this is a public signal which can be used to notify user that the histo is ready
|
||||
|
||||
// Define a signal to notify when postdata is updated
|
||||
void dataReady(const QByteArray& data); // Define a signal for data readiness
|
||||
public slots:
|
||||
void onNewData(DataReceiver *receiver);
|
||||
// Add a public slot to receive and store data
|
||||
void receiveData(const QByteArray &data);
|
||||
|
||||
|
||||
// Add a method to get data from the queue
|
||||
QByteArray getNextData();
|
||||
|
||||
|
||||
protected:
|
||||
int checkBufferOccupancies();
|
||||
int findLowestId();
|
||||
@ -94,6 +103,9 @@ private:
|
||||
double intensity = 0.0;
|
||||
double position = 0.0;
|
||||
double focus = 0.0;
|
||||
QQueue<QByteArray> dataQueue;
|
||||
QMutex mutex;
|
||||
QWaitCondition dataAvailable;
|
||||
|
||||
};
|
||||
|
||||
|
@ -5,8 +5,14 @@
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui network serialport
|
||||
QMAKE_CXXFLAGS += -Wa,-mbig-obj
|
||||
|
||||
unix {
|
||||
QMAKE_CXXFLAGS += -W -std=c++17
|
||||
}
|
||||
|
||||
win32 {
|
||||
QMAKE_CXXFLAGS += -Wa,-mbig-obj -std=c++17
|
||||
}
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 5): QT += widgets printsupport
|
||||
|
||||
@ -37,8 +43,7 @@ SOURCES += main.cpp\
|
||||
dialogtiscan.cpp \
|
||||
dialogprofiler.cpp \
|
||||
stepper.cpp \
|
||||
dialogbeta.cpp \
|
||||
udpserver.cpp
|
||||
dialogbeta.cpp
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
Q_DebugStream.h \
|
||||
@ -54,6 +59,7 @@ HEADERS += mainwindow.h \
|
||||
helpers.h \
|
||||
cbuffer.h \
|
||||
eventbuilder.h \
|
||||
networkthread.h \
|
||||
qcustomplot.h \
|
||||
display.h \
|
||||
displayserver.h \
|
||||
@ -65,7 +71,6 @@ HEADERS += mainwindow.h \
|
||||
dialogprofiler.h \
|
||||
stepper.h \
|
||||
dialogbeta.h \
|
||||
udpserver.h \
|
||||
hitreader.h
|
||||
|
||||
FORMS += mainwindow.ui \
|
||||
|
@ -8,11 +8,37 @@ HIT_ANALYSE_V2::HIT_ANALYSE_V2(QObject *parent) : QObject(parent)
|
||||
|
||||
}
|
||||
|
||||
// Define your own functions for matrix operations
|
||||
struct Matrix2x2 {
|
||||
double data[2][2];
|
||||
};
|
||||
|
||||
Matrix2x2 InvertMatrix2x2(const Matrix2x2& mat) {
|
||||
Matrix2x2 result;
|
||||
double det = mat.data[0][0] * mat.data[1][1] - mat.data[0][1] * mat.data[1][0];
|
||||
if (det != 0.0) {
|
||||
double invDet = 1.0 / det;
|
||||
result.data[0][0] = mat.data[1][1] * invDet;
|
||||
result.data[0][1] = -mat.data[0][1] * invDet;
|
||||
result.data[1][0] = -mat.data[1][0] * invDet;
|
||||
result.data[1][1] = mat.data[0][0] * invDet;
|
||||
} else {
|
||||
// Handle the case when the matrix is not invertible
|
||||
// You might want to implement error handling here.
|
||||
std::cerr << "Matrix not invertible! " << std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
struct Vector2 {
|
||||
double data[2];
|
||||
};
|
||||
|
||||
QString HIT_ANALYSE_V2::analyseBeamData(QVector<BufferData> dataframe){
|
||||
|
||||
double position=0.1;
|
||||
double focus=8;
|
||||
double intensity=10000.0;
|
||||
double intensity=1000.0;
|
||||
QString dataString;
|
||||
|
||||
|
||||
@ -20,7 +46,8 @@ QString HIT_ANALYSE_V2::analyseBeamData(QVector<BufferData> dataframe){
|
||||
|
||||
std::vector<double> signal_list(vector_length);
|
||||
std::vector<double> channel_list(vector_length);
|
||||
|
||||
std::vector<double> short_signal_list;
|
||||
std::vector<double> short_channel_list;
|
||||
|
||||
// Create a random number generator with a Gaussian distribution
|
||||
std::random_device rd;
|
||||
@ -30,21 +57,29 @@ QString HIT_ANALYSE_V2::analyseBeamData(QVector<BufferData> dataframe){
|
||||
// Create a vector to store the generated values
|
||||
std::vector<short int> result(vector_length);
|
||||
|
||||
// Fill the vector with random values
|
||||
for (int i = 0; i < vector_length; ++i) {
|
||||
result[i] = static_cast<short int>(dist(gen));
|
||||
signal_list.push_back(result[i]);
|
||||
channel_list.push_back(i);
|
||||
}
|
||||
// Fill the vector with random noise values
|
||||
//add a gaussian profile, focus is FWHM, position is random between 50 and 250
|
||||
bool fixeddata = true;
|
||||
if (!fixeddata){
|
||||
position = 50 + (rand() % (int)(250 - 50 + 1));
|
||||
for (int i = 0; i < vector_length; ++i) {
|
||||
signal_list[i] += intensity*exp(-4*log(2)*pow((channel_list[i]-position)/focus,2));
|
||||
|
||||
for (int i = 0; i < vector_length; i++) {
|
||||
double randomValue = dist(gen);
|
||||
signal_list[i] = static_cast<short int>(std::round(randomValue));
|
||||
channel_list[i] = i;
|
||||
signal_list[i] += static_cast<short int>(std::round(intensity*exp(-4*log(2)*pow((channel_list[i]-position)/focus,2))));
|
||||
|
||||
// std::cerr << channel_list[i] << ", ";
|
||||
}
|
||||
|
||||
// std::cerr <<std::endl;
|
||||
}
|
||||
else{
|
||||
signal_list = fixed_signal[0];
|
||||
channel_list = fixed_channel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
// Fill signal_list and channel_list with your data
|
||||
|
||||
double SumT = 0.0, SumS = 0.0, SumS2 = 0.0, SumST = 0.0, SumT2 = 0.0, SumY = 0.0, SumYS = 0.0, SumYT = 0.0;
|
||||
@ -138,6 +173,151 @@ QString HIT_ANALYSE_V2::analyseBeamData(QVector<BufferData> dataframe){
|
||||
//sigma = sqrt(1.0 / (2.0 * ABC_0));
|
||||
focus = 2.3548/sqrt(2*p);
|
||||
intensity = b;
|
||||
*/
|
||||
double SumArea = 0.0, SumY2 = 0.0, SumXY2 = 0.0, SumX2Y2 = 0.0, SumX3Y2 = 0.0;
|
||||
double SumY2LnY = 0.0, SumXY2LnY = 0.0, Ymax = 0.0, Pomax = 0.0;
|
||||
double fac_c = 0.0, Yn = 0.0, sigma = 0.0, amp = 0.0;
|
||||
double SumYYP = 0.0, SumYYM = 0.0, MeanY = 0.0, window_start = 0.0, window_end = 0.0;
|
||||
|
||||
// ...
|
||||
|
||||
Matrix2x2 M1, M1inv;
|
||||
Vector2 ABC, M2;
|
||||
|
||||
for (int i = 0; i < vector_length; i++) {
|
||||
if (signal_list[i] > Ymax) {
|
||||
Ymax = signal_list[i];
|
||||
Pomax = channel_list[i];
|
||||
}
|
||||
if (i > 0 && signal_list[i] > 34) {
|
||||
SumArea += signal_list[i] * (channel_list[i] - channel_list[i - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Estimate sigma
|
||||
sigma = SumArea / Ymax / 2.5066;
|
||||
|
||||
// Set a +-3 sigma window
|
||||
window_start = Pomax - 3 * sigma;
|
||||
window_end = Pomax + 3 * sigma;
|
||||
// std::cerr<< Pomax << " " << Ymax << " " << sigma << std::endl;
|
||||
|
||||
|
||||
for (int i = 0; i < vector_length; i++) {
|
||||
if (signal_list[i] > 34 && channel_list[i] > window_start && channel_list[i] < window_end) {
|
||||
short_signal_list.push_back(signal_list[i]);
|
||||
short_channel_list.push_back(channel_list[i]);
|
||||
}
|
||||
}
|
||||
signal_list.clear();
|
||||
channel_list.clear();
|
||||
// Recalculate SumArea using the sieved data
|
||||
SumArea = 0.0;
|
||||
for (int i = 1; i < short_signal_list.size(); i++) {
|
||||
SumArea += short_signal_list[i] * (short_channel_list[i] - short_channel_list[i - 1]);
|
||||
}
|
||||
|
||||
|
||||
const int shortlist_length = short_channel_list.size();
|
||||
|
||||
if (shortlist_length <= 3) {
|
||||
intensity = -1;
|
||||
focus = -1;
|
||||
position = -128;
|
||||
dataString += QString::number(intensity) + ',' + QString::number(position) + ',' + QString::number(focus)
|
||||
+ ',' + QString::number(0);
|
||||
|
||||
|
||||
return dataString;
|
||||
}
|
||||
|
||||
// Re-Estimate sigma
|
||||
sigma = SumArea / Ymax / 2.5066;
|
||||
fac_c = -1.0 / (2.0 * sigma * sigma);
|
||||
// std::cerr << sigma << std::endl;
|
||||
for(int k=0; k<shortlist_length;k++){
|
||||
|
||||
SumY2 += short_signal_list[k]*short_signal_list[k];
|
||||
SumXY2 += short_signal_list[k]*short_signal_list[k]*short_channel_list[k];
|
||||
SumX2Y2 += short_signal_list[k]*short_signal_list[k]*short_channel_list[k]*short_channel_list[k];
|
||||
SumX3Y2 += short_signal_list[k]*short_signal_list[k]*short_channel_list[k]*short_channel_list[k]*short_channel_list[k];
|
||||
|
||||
SumY2LnY += short_signal_list[k]*short_signal_list[k]*log(short_signal_list[k]);
|
||||
SumXY2LnY += short_channel_list[k]*short_signal_list[k]*short_signal_list[k]*log(short_signal_list[k]);
|
||||
// std::cerr<< shortlist_length << " " << short_channel_list[k] << " " << short_signal_list[k] << " " << short_signal_list[k] << " " << log(short_signal_list[k]) << std::endl;
|
||||
MeanY+=short_signal_list[k];
|
||||
}
|
||||
MeanY/=shortlist_length;
|
||||
|
||||
// Use custom matrix and vector functions for calculations
|
||||
M1.data[0][0] = SumY2;
|
||||
M1.data[0][1] = SumXY2;
|
||||
M1.data[1][0] = SumXY2;
|
||||
M1.data[1][1] = SumX2Y2;
|
||||
|
||||
// std::cerr << M1.data[0][0] << " " << M1.data[0][1] << " " << M1.data[1][0] << " " << M1.data[1][1] << std::endl;
|
||||
M2.data[0] = SumY2LnY - fac_c * SumX2Y2;
|
||||
M2.data[1] = SumXY2LnY - fac_c * SumX3Y2;
|
||||
// std::cerr << M2.data[0] << " " << M2.data[1] << std::endl;
|
||||
M1inv = InvertMatrix2x2(M1);
|
||||
ABC.data[0] = M1inv.data[0][0] * M2.data[0] + M1inv.data[0][1] * M2.data[1];
|
||||
ABC.data[1] = M1inv.data[1][0] * M2.data[0] + M1inv.data[1][1] * M2.data[1];
|
||||
|
||||
// std::cerr << ABC.data[0] << " " << ABC.data[1] << std::endl;
|
||||
|
||||
|
||||
//iterate to improve the fit.
|
||||
int N_iter = 1;
|
||||
for (int i = 0; i < N_iter; i++) {
|
||||
SumY2 = 0.0;
|
||||
SumXY2 = 0.0;
|
||||
SumX2Y2 = 0.0;
|
||||
SumX3Y2 = 0.0;
|
||||
SumY2LnY = 0.0;
|
||||
SumXY2LnY = 0.0;
|
||||
|
||||
for (int k = 0; k < shortlist_length; k++) {
|
||||
Yn = exp(ABC.data[0] + ABC.data[1] * short_channel_list[k] + fac_c * short_channel_list[k] * short_channel_list[k]);
|
||||
SumY2 += Yn * Yn;
|
||||
SumXY2 += Yn * Yn * short_channel_list[k];
|
||||
SumX2Y2 += Yn * Yn * short_channel_list[k] * short_channel_list[k];
|
||||
SumX3Y2 += Yn * Yn * short_channel_list[k] * short_channel_list[k] * short_channel_list[k];
|
||||
SumY2LnY += Yn * Yn * log(short_signal_list[k]);
|
||||
SumXY2LnY += short_channel_list[k] * Yn * Yn * log(short_signal_list[k]);
|
||||
}
|
||||
|
||||
M1.data[0][0] = SumY2;
|
||||
M1.data[0][1] = SumXY2;
|
||||
M1.data[1][0] = SumXY2;
|
||||
M1.data[1][1] = SumX2Y2;
|
||||
|
||||
M2.data[0] = SumY2LnY - fac_c * SumX2Y2;
|
||||
M2.data[1] = SumXY2LnY - fac_c * SumX3Y2;
|
||||
|
||||
M1inv = InvertMatrix2x2(M1);
|
||||
ABC.data[0] = M1inv.data[0][0] * M2.data[0] + M1inv.data[0][1] * M2.data[1];
|
||||
ABC.data[1] = M1inv.data[1][0] * M2.data[0] + M1inv.data[1][1] * M2.data[1];
|
||||
}
|
||||
|
||||
position = -ABC.data[1]/fac_c/2;
|
||||
|
||||
amp = exp(ABC.data[0]-ABC.data[1]*ABC.data[1]/4/fac_c);
|
||||
|
||||
sigma=SumArea/amp/2.5066;
|
||||
|
||||
// cout << sigma << " " << mean << " " << amp << endl;
|
||||
|
||||
|
||||
for(int k=0; k<shortlist_length;k++){
|
||||
SumYYM+= (short_signal_list[k]-MeanY)*(short_signal_list[k]-MeanY);
|
||||
SumYYP+= (amp*exp(-(short_channel_list[k]-position)*(short_channel_list[k]-position)/2/(sigma*sigma)) - MeanY )*(amp*exp(-(short_channel_list[k]-position)*(short_channel_list[k]-position)/2/(sigma*sigma)) - MeanY );
|
||||
}
|
||||
|
||||
|
||||
|
||||
focus = 2.3548*sigma;
|
||||
intensity = amp;
|
||||
double R_squared = SumYYP/SumYYM;
|
||||
|
||||
dataString += QString::number(intensity) + ',' + QString::number(position) + ',' + QString::number(focus)
|
||||
+ ',' + QString::number(R_squared);
|
||||
@ -148,6 +328,8 @@ QString HIT_ANALYSE_V2::analyseBeamData(QVector<BufferData> dataframe){
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
HIT_ANALYSE_V2::~HIT_ANALYSE_V2()
|
||||
{
|
||||
|
||||
|
@ -54,6 +54,14 @@ private:
|
||||
|
||||
};
|
||||
|
||||
const std::vector<std::vector<double>> fixed_signal =
|
||||
{
|
||||
{-13, -7, -12, 22, -6, 0, 22, 5, 8, 11, 25, -10, 11, 13, 32, -4, -2, -37, -21, 23, 13, 26, 11, -24, 1, -6, -6, 1, 22, 30, -21, -3, 11, -2, -11, 5, -2, 31, 24, 4, -17, 24, -24, 20, 31, -6, -1, -4, -10, -26, -12, -19, -7, -39, 1, 19, 3, -13, 37, 2, 11, -10, -14, 20, 14, -1, -13, 13, -18, -18, -15, -25, 14, 11, -32, 50, 18, -11, 26, 4, 4, -2, -10, 34, 6, 36, -9, 19, -3, 7, -10, -15, 4, 24, -3, 2, 13, -34, -28, -25, -4, -14, -11, 23, -19, -7, -6, 6, 23, 7, -21, 18, -8, 6, 21, -4, 3, -1, -11, 7, -38, -38, -12, -11, -11, 9, -11, -7, 2, -1, 19, 12, 0, -7, 15, 3, 28, -8, 1, 8, 2, -4, 4, 23, 31, -17, 8, 11, 34, 1, 7, 14, 14, 16, -1, -30, -2, 19, -20, -4, -9, 15, -6, -4, -4, 10, -27, -18, 24, 19, 20, 22, 68, 122, 234, 371, 496, 713, 840, 967, 1026, 957, 833, 674, 485, 317, 194, 98, 70, 45, 34, -15, 3, 10, 12, -19, 11, 27, -1, 2, -9, -1, -2, -15, -22, 7, 0, -20, -1, -7, 21, -4, -21, 21, -6, 23, -4, -2, -28, -17, -13, 1, 19, 20, 6, 10, -25, -4, 5, -14, -18, -4, 12, 7, -21, 7, -10, 10, 11, -21, 7, -6, -2, -3, 1, 16, 4, -23, 2, 14, 0, -5, -7, -12, -2, -8, -20, 11, 21, -5, -5, 20, -10, 3, -18, -5, 4, 6, 4, -21, -3, -26, -15, -7, -14, -10, -14, 7, -18, -2, -14, 36, -10, 11, 9, 3, -7, -51, -12, 2, 5, 9, 15, 20, -23, -6, -14, -4, 16, 4}
|
||||
,{-9, -1, -32, 19, 12, -13, 7, 7, -18, -5, 19, 15, 5, -5, -27, 4, -7, 7, -16, -9, -4, -6, -2, 27, 23, 15, -16, -23, 25, 4, 26, -17, -9, -1, 14, -9, -15, -29, -40, 5, 22, 14, 23, -25, 9, -16, -26, -4, -31, -6, -27, 1, 23, 24, 26, 61, 133, 222, 301, 501, 690, 822, 972, 980, 966, 852, 685, 486, 333, 239, 107, 54, 29, 19, 9, 1, 1, 6, 9, 14, -8, -5, 11, 21, -6, -17, -7, 11, 30, -3, 6, -4, 2, 18, -18, 4, -2, 18, 16, 17, 5, -15, -14, 24, -36, -19, 7, -22, -3, -15, -11, -4, -11, 13, -5, -6, 12, 8, 21, -24, -10, -10, -7, 5, 30, -16, -18, -3, -23, 3, -20, -3, 24, 8, -15, -1, -6, -1, -8, -25, 6, 1, -16, -11, 29, -21, 13, 11, -2, -10, 12, -13, 24, -31, 21, -7, 6, -13, 3, -6, -9, 20, -3, 2, -16, -14, 10, 6, 20, 6, 21, 9, 7, -27, 13, -17, 19, 20, -13, -11, -17, -4, 11, -24, 17, -7, -4, 26, 5, 13, 13, 4, -3, -17, -32, -14, 40, 1, -23, -28, 16, 1, 16, -4, -8, -9, 4, 2, -7, 7, -16, -23, -9, 10, 24, 0, -5, -24, -4, -22, -10, -29, 0, 2, 2, 4, -45, 4, -2, 12, 21, -22, -31, -15, 16, 2, 11, 35, 0, 3, 15, -15, -17, 20, -27, 24, 24, -6, 8, -15, 8, 26, -6, -14, 10, -20, 33, 6, -5, 1, 0, 9, 3, -33, -10, -3, 0, 11, -33, 0, 33, 25, -5, 1, 0, -32, -24, 17, 10, -2, 12, -26, 13, 7, -3, 36, 28, 10, 17, -26, 29, -15, 3, 14, -8, -9, -7, -15, -4, 0}
|
||||
,{14, -3, 2, 20, 3, -9, 15, -3, 26, 3, 8, -1, -5, 13, -10, -18, -9, 35, 3, 29, -12, 37, 12, -12, -9, -34, 9, -3, -19, -3, -10, -9, 3, -1, 5, 22, 10, -10, -27, 30, -19, -26, -23, -25, 16, 4, 4, 9, -23, 5, 0, -35, -5, -21, 0, 22, 18, -42, -4, 16, 17, 41, -15, -12, 13, -5, 35, 5, -4, 19, -12, 4, 4, -2, 2, -12, -23, 5, -2, 4, 7, 5, -10, 41, -20, -2, 4, 5, -34, -19, -6, 6, -3, -12, 39, 38, 72, 104, 194, 347, 484, 666, 808, 946, 1018, 978, 838, 690, 511, 317, 211, 112, 51, 22, 0, -14, 21, -2, 12, -24, 1, -6, 18, 5, -12, 6, -3, -9, -6, -29, -31, -6, -15, -2, -22, 14, -33, 1, 3, -7, -13, 14, 21, -11, -17, -1, -9, -12, 7, 5, -2, -2, -4, -2, -12, -33, 2, 5, -2, -8, 10, 26, 2, -28, 3, -20, 10, -8, 22, 8, -25, 3, -18, -18, 19, 15, -8, 8, 24, -13, 0, -5, -15, 1, -24, -2, 3, -28, 8, 5, -5, 0, 12, 10, -5, 12, 0, -10, -5, -7, -23, -32, -3, 9, 17, -14, -12, -3, -35, -12, -5, 8, 15, -10, 13, 4, 9, 23, -21, -31, 32, 6, -3, -7, 10, -5, 25, -32, 16, -22, 18, 0, 1, -16, -13, -10, -13, 2, -20, -2, 15, 7, 17, -17, 0, 8, 43, -23, -34, -7, 45, 8, 16, 26, -7, -7, -5, 4, -20, -8, -21, 13, 4, -23, 9, 29, 1, 13, -3, -23, 3, 20, 23, 29, -7, -8, 37, -4, -23, 1, -14, -11, 9, -4, -13, -20, -20, 16, -12, 23, 31, 5, 0, 27, 2, 5, 30, -12, -10, 3}
|
||||
,{-9, -15, -6, 24, -10, -12, 12, -9, -13, 1, -15, -2, -2, 0, 26, -19, -22, 7, 0, 26, 28, -13, -8, -24, 20, -1, -18, -1, -23, -21, -7, -10, 25, 29, 16, 23, -36, 9, 7, -28, -7, 1, 41, -1, -2, 14, -3, 26, -26, 20, -4, 22, 8, 50, 8, 0, -22, -8, 45, 1, -22, -24, -12, 6, 8, 26, 21, 22, -5, 1, -1, -10, -4, 22, 20, 40, -9, 11, -32, 9, -12, -3, -8, 13, 3, -4, -6, 2, 18, 6, 1, -16, 0, 33, 16, -18, -7, 27, 10, -3, 11, -10, -16, -3, 24, 1, -14, -4, 12, -11, -4, 22, 22, -21, -4, 24, 3, 12, 13, 28, -3, 27, 11, -6, 19, 8, -22, -1, 5, 0, 27, 2, -2, -12, -8, 6, 6, 9, 10, -8, 4, 40, 27, 38, 111, 200, 323, 492, 667, 834, 944, 990, 945, 861, 683, 466, 337, 205, 108, 53, 22, 0, 27, 9, -3, 37, 11, -8, -15, -16, 4, 23, 25, -14, -7, -7, -18, -7, 21, 6, 19, -12, 2, -13, -9, -8, -3, -7, -20, -27, 13, 4, -11, 16, 3, -24, 4, -23, 17, 17, -18, -25, 4, 5, -21, -10, -13, 43, 4, -1, -3, -1, -4, -4, 25, 47, 18, 21, 29, 4, -22, 16, -17, -37, -1, 12, -9, -7, 5, -4, 23, 21, -14, -17, 19, 11, 22, 39, -6, 3, 19, -25, 4, 1, -15, -8, 20, 13, -31, 5, 28, 10, 27, 9, -11, 2, 0, -20, -18, -9, 14, 9, 24, -16, -10, 29, 16, 13, 13, -22, 16, 18, 22, 20, 27, -20, 23, 6, 0, 14, -6, -6, -8, 15, -11, 23, -11, 23, -16, 16, -2, 10, 4, -22, -33, -17, -4, 4, 4, -8}
|
||||
};
|
||||
const std::vector<double> fixed_channel = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299};
|
||||
|
||||
public slots:
|
||||
QString analyseBeamData(QVector<BufferData> dataframe);
|
||||
|
@ -1,16 +1,21 @@
|
||||
#include "hw.h"
|
||||
|
||||
HW::HW(QObject *parent) : QObject(parent)
|
||||
HW::HW(QObject *parent) : QObject(parent), eventBuilder(), networkThread(eventBuilder)
|
||||
{
|
||||
|
||||
/*eventBuilder.moveToThread(&eventBuilderThread);
|
||||
eventBuilderThread.start();
|
||||
eventBuilder.init();*/
|
||||
|
||||
// Create and start the network thread
|
||||
networkThread.start();
|
||||
}
|
||||
|
||||
HW::~HW()
|
||||
{
|
||||
if (networkThread.isRunning()){
|
||||
networkThread.stopThread();
|
||||
networkThread.wait(); // Wait for the network thread to finish gracefully
|
||||
}
|
||||
eventBuilder.stopLogging();
|
||||
removeDevices();
|
||||
|
||||
@ -64,7 +69,7 @@ void HW::disconnectDevices()
|
||||
void HW::run()
|
||||
{
|
||||
//No need to start EVB. It's running all the time.
|
||||
|
||||
// Start the UDP server when an instance of HW is created
|
||||
//run slave(s)
|
||||
for (int i = 0; i < devices.length(); i++)
|
||||
if (devices[i]->deviceConfig.master == 0)
|
||||
@ -78,6 +83,11 @@ void HW::run()
|
||||
|
||||
void HW::stop()
|
||||
{
|
||||
// Application cleanup
|
||||
if (networkThread.isRunning()){
|
||||
networkThread.stopThread();
|
||||
networkThread.wait(); // Wait for the network thread to finish gracefully
|
||||
}
|
||||
//stop master(s)
|
||||
for (int i = 0; i < devices.length(); i++)
|
||||
if (devices[i]->deviceConfig.master != 0)
|
||||
|
@ -6,17 +6,19 @@
|
||||
#include <QThread>
|
||||
#include "device.h"
|
||||
#include "eventbuilder.h"
|
||||
|
||||
#include "networkthread.h"
|
||||
class HW : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
public:
|
||||
explicit HW(QObject *parent = 0);
|
||||
~HW();
|
||||
|
||||
QVector<Device*> devices;
|
||||
EventBuilder eventBuilder;
|
||||
|
||||
NetworkThread networkThread;
|
||||
|
||||
Device &operator [](int nr);
|
||||
void addDevices(int nr_devices);
|
||||
@ -33,9 +35,12 @@ signals:
|
||||
public slots:
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // HW_H
|
||||
|
@ -64,11 +64,11 @@ keithley_thr::keithley_thr()
|
||||
|
||||
keithleyWorker *worker = new keithleyWorker;
|
||||
//worker->theKeithley = &theKeithley;
|
||||
worker->moveToThread(&workerThread);
|
||||
worker->timer.moveToThread(&workerThread);
|
||||
worker->theKeithley.serialPort.moveToThread(&workerThread);
|
||||
worker->moveToThread(&udpThread);
|
||||
worker->timer.moveToThread(&udpThread);
|
||||
worker->theKeithley.serialPort.moveToThread(&udpThread);
|
||||
//controller -> worker
|
||||
QObject::connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
|
||||
QObject::connect(&udpThread, &QThread::finished, worker, &QObject::deleteLater);
|
||||
QObject::connect(this, &keithley_thr::sig_connect, worker, &keithleyWorker::connect);
|
||||
QObject::connect(this, &keithley_thr::sig_disconnect, worker, &keithleyWorker::disconnect);
|
||||
QObject::connect(this, &keithley_thr::sig_on, worker, &keithleyWorker::on);
|
||||
@ -78,13 +78,13 @@ keithley_thr::keithley_thr()
|
||||
//worker -> controller
|
||||
QObject::connect(worker, &keithleyWorker::sig_currentReadout, this, &keithley_thr::on_currentReadout);
|
||||
QObject::connect(worker, &keithleyWorker::sig_isOpen, this, &keithley_thr::on_isOpen);
|
||||
workerThread.start();
|
||||
udpThread.start();
|
||||
}
|
||||
|
||||
keithley_thr::~keithley_thr()
|
||||
{
|
||||
workerThread.quit();
|
||||
workerThread.wait();
|
||||
udpThread.quit();
|
||||
udpThread.wait();
|
||||
}
|
||||
|
||||
|
||||
@ -92,7 +92,7 @@ keithley_thr::~keithley_thr()
|
||||
//************************** slots for communication with worker thread ******************
|
||||
|
||||
//called on each current readout
|
||||
keithley_thr::on_currentReadout(const double value)
|
||||
void keithley_thr::on_currentReadout(const double value)
|
||||
{
|
||||
lastCurrentReadout = value;
|
||||
emit esig_newCurrentReadout(lastCurrentReadout);
|
||||
|
@ -58,14 +58,14 @@ public:
|
||||
double getCurrent();
|
||||
void ps_flush();
|
||||
|
||||
QThread workerThread;
|
||||
QThread udpThread;
|
||||
|
||||
double lastCurrentReadout;
|
||||
QString portName;
|
||||
|
||||
int recognizeSpillState(double current);
|
||||
public slots:
|
||||
on_currentReadout(const double value);
|
||||
void on_currentReadout(const double value);
|
||||
int on_isOpen(const int state, const QString givenPortName);
|
||||
signals:
|
||||
void sig_connect();
|
||||
|
@ -1,16 +1,10 @@
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
#include "udpserver.h" // Include udpserver header
|
||||
|
||||
// Define the global UdpServer object
|
||||
UdpServer udpServer; // This allocates memory for udpServer
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
|
||||
// Create the UdpServer object on the heap and store a pointer to it
|
||||
udpServer.startServer();
|
||||
|
||||
// Apply the stylesheet to each display
|
||||
qDebug() << "App path : " << qApp->applicationDirPath();
|
||||
|
@ -29,8 +29,13 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
theKeithley = new keithley_thr;
|
||||
theStepper = new Stepper;
|
||||
|
||||
connect(&timer, QTimer::timeout, this, on_timer);
|
||||
connect(theKeithley, keithley_thr::esig_newCurrentReadout, this, MainWindow::on_newCurrentReadout);
|
||||
// connect(&timer, QTimer::timeout, this, on_timer);
|
||||
connect(&timer, &QTimer::timeout, this, &MainWindow::on_timer);
|
||||
|
||||
// connect(theKeithley, keithley_thr::esig_newCurrentReadout, this, MainWindow::on_newCurrentReadout);
|
||||
connect(theKeithley, &keithley_thr::esig_newCurrentReadout, this, &MainWindow::on_newCurrentReadout);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -41,6 +46,7 @@ MainWindow::~MainWindow()
|
||||
delete theHW;
|
||||
delete theDisplay;
|
||||
delete theKeithley;
|
||||
|
||||
}
|
||||
|
||||
//***************** Initialization ******************
|
||||
@ -479,3 +485,14 @@ void MainWindow::on_actionDisconnect_Stepper_triggered()
|
||||
qInfo("Stepper controller disconnected.");
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_pushButton_exit_clicked()
|
||||
{
|
||||
if(running) stop();
|
||||
theHW->stop();
|
||||
|
||||
theHW->disconnectDevices();
|
||||
|
||||
QApplication::exit(); //close the application;
|
||||
}
|
||||
|
||||
|
@ -63,30 +63,19 @@ private slots:
|
||||
void on_actionDisconnect_triggered();
|
||||
void on_actionHost_IP_triggered();
|
||||
void on_actionTrigger_config_triggered();
|
||||
|
||||
void on_actionDevices_triggered();
|
||||
|
||||
void on_pushRun_pressed();
|
||||
|
||||
void on_pushLogging_pressed();
|
||||
|
||||
void on_pushDisplay_pressed();
|
||||
|
||||
void on_actionConnect_Keithley_triggered();
|
||||
|
||||
void on_actionDisconnect_Keithley_triggered();
|
||||
|
||||
void on_actionLinearity_test_triggered();
|
||||
|
||||
void on_actionIntegration_time_scan_triggered();
|
||||
|
||||
void on_actionProfile_viewer_triggered();
|
||||
|
||||
void on_actionConnect_Stepper_triggered();
|
||||
|
||||
void on_actionDisconnect_Stepper_triggered();
|
||||
|
||||
void on_actionBeta_Scanner_triggered();
|
||||
void on_pushButton_exit_clicked();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
|
@ -80,6 +80,19 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_exit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>760</x>
|
||||
<y>510</y>
|
||||
<width>80</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Quit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
|
198
hit2023v2/networkthread.h
Normal file
198
hit2023v2/networkthread.h
Normal file
@ -0,0 +1,198 @@
|
||||
#ifndef NETWORKTHREAD_H
|
||||
#define NETWORKTHREAD_H
|
||||
|
||||
|
||||
#include <QThread>
|
||||
#include <QUdpSocket>
|
||||
#include "iostream"
|
||||
#include <QTime>
|
||||
#include <QThread>
|
||||
#include <QUdpSocket>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include "eventbuilder.h"
|
||||
|
||||
class NetworkThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
quint16 serverPort = 1901; // Port number for the UDP server
|
||||
double intensity = 0.0, position = 0.0, focus = 0.0;
|
||||
|
||||
QMutex mutex; // Mutex for data synchronization
|
||||
QWaitCondition dataReady; // Condition variable to signal data readiness
|
||||
|
||||
EventBuilder &eventBuilder;
|
||||
|
||||
public:
|
||||
NetworkThread(EventBuilder &builder, QObject *parent = nullptr) : QThread(parent), eventBuilder(builder), stopped(false) {}
|
||||
|
||||
void run() override
|
||||
{
|
||||
QUdpSocket udpSocket;
|
||||
//udpSocket.bind(QHostAddress::Any, 12345); // Set your desired port
|
||||
// Bind the socket to a specific IP address and port
|
||||
if ( udpSocket.bind(QHostAddress("127.0.0.1"), serverPort) )
|
||||
{
|
||||
// connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
|
||||
qInfo() << "UDP server started on port" << serverPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
stopped = true;
|
||||
qWarning() << "Failed to bind UDP socket on port" << serverPort;
|
||||
}
|
||||
|
||||
while (!stopped)
|
||||
{
|
||||
// Your data serialization and broadcasting logic here
|
||||
|
||||
|
||||
QByteArray data = eventBuilder.getNextData(); // Get data from the EventBuilder
|
||||
if (!data.isEmpty())
|
||||
{
|
||||
QString dataString = QString(data);
|
||||
udpSocket.writeDatagram(data.data(), data.size(), QHostAddress::Broadcast, serverPort);
|
||||
// std::cerr << dataString.toStdString() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::cerr << "data is empty" << std::endl;
|
||||
|
||||
}
|
||||
// QByteArray data = serializeYourData();
|
||||
|
||||
|
||||
// QTime currentTime = QTime::currentTime();
|
||||
// Calculate the time since midnight in milliseconds
|
||||
// int millisecondsSinceMidnight = currentTime.msecsSinceStartOfDay();
|
||||
|
||||
// QByteArray data; // Create a QByteArray for your data
|
||||
// Populate data with your custom data
|
||||
// data.append(QByteArray::number(millisecondsSinceMidnight));
|
||||
|
||||
// udpSocket.writeDatagram(data.data(),data.size(), QHostAddress::Broadcast, serverPort); // Broadcast to all reachable devices
|
||||
// emit dataReady(data); // Emit the signal when data is ready
|
||||
// std::cerr << " running" << std::endl;
|
||||
// QThread::msleep(1); // Sleep for microseconds usleep / millisecond msleep //!!!!! on windows the minimum is about 15ms from OS reasons. ~ 30 microseconds between loops without thread sleep.
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void stopThread()
|
||||
{
|
||||
stopped = true;
|
||||
emit terminationRequested();
|
||||
}
|
||||
// Add this public slot to receive data from the main thread
|
||||
public slots:
|
||||
|
||||
signals:
|
||||
void terminationRequested();
|
||||
|
||||
private:
|
||||
bool stopped;
|
||||
|
||||
QByteArray serializeYourData()
|
||||
{
|
||||
// Implement your data serialization here
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
#include <QThread>
|
||||
#include <QUdpSocket>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include <QTime>
|
||||
|
||||
class NetworkThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
quint16 serverPort = 1901; // Port number for the UDP server
|
||||
double intensity = 0.0, position = 0.0, focus = 0.0;
|
||||
|
||||
QMutex mutex; // Mutex for data synchronization
|
||||
QWaitCondition dataReady; // Condition variable to signal data readiness
|
||||
|
||||
public:
|
||||
NetworkThread(QObject *parent = nullptr) : QThread(parent), stopped(false) {}
|
||||
|
||||
void run() override
|
||||
{
|
||||
QUdpSocket udpSocket;
|
||||
|
||||
if (udpSocket.bind(QHostAddress("10.0.7.1"), serverPort))
|
||||
{
|
||||
qInfo() << "UDP server started on port" << serverPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
stopped = true;
|
||||
qWarning() << "Failed to bind UDP socket on port" << serverPort;
|
||||
}
|
||||
|
||||
while (!stopped)
|
||||
{
|
||||
// Wait for data to be ready
|
||||
mutex.lock();
|
||||
dataReady.wait(&mutex);
|
||||
// Data is now ready, unlock the mutex
|
||||
|
||||
QTime currentTime = QTime::currentTime();
|
||||
int millisecondsSinceMidnight = currentTime.msecsSinceStartOfDay();
|
||||
|
||||
QByteArray data;
|
||||
data.append(QByteArray::number(millisecondsSinceMidnight));
|
||||
|
||||
// Append the updated parameters to the data
|
||||
data.append(",");
|
||||
data.append(QByteArray::number(intensity));
|
||||
data.append(",");
|
||||
data.append(QByteArray::number(position));
|
||||
data.append(",");
|
||||
data.append(QByteArray::number(focus));
|
||||
|
||||
udpSocket.writeDatagram(data.data(), data.size(), QHostAddress::Broadcast, serverPort);
|
||||
mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void stopThread()
|
||||
{
|
||||
stopped = true;
|
||||
emit terminationRequested();
|
||||
}
|
||||
|
||||
public slots:
|
||||
// This slot is called from another thread to update the parameters
|
||||
void updateParameters(double newIntensity, double newPosition, double newFocus)
|
||||
{
|
||||
// Lock the mutex before updating the parameters
|
||||
mutex.lock();
|
||||
|
||||
// Update the parameters
|
||||
intensity = newIntensity;
|
||||
position = newPosition;
|
||||
focus = newFocus;
|
||||
|
||||
// Signal that data is ready to be sent
|
||||
dataReady.wakeAll();
|
||||
|
||||
// Unlock the mutex
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
signals:
|
||||
void terminationRequested();
|
||||
|
||||
private:
|
||||
bool stopped;
|
||||
};
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#endif // NETWORKTHREAD_H
|
Binary file not shown.
@ -1,37 +0,0 @@
|
||||
#include "udpserver.h"
|
||||
|
||||
UdpServer::UdpServer(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
// Configure the timer for data updates
|
||||
// connect(&timer, &QTimer::timeout, this, &UdpServer::sendData);
|
||||
// timer.setInterval(1); // 1 milliseconds (1 kHz)
|
||||
startServer();
|
||||
}
|
||||
|
||||
void UdpServer::startServer()
|
||||
{
|
||||
// Bind the UDP socket to a specific port (replace with your desired port)
|
||||
// udpSocket.bind(QHostAddress::Any, 12345); // Replace 12345 with your desired port
|
||||
udpSocket.bind(QHostAddress("10.0.7.1"), 12345); // Use the desired host address and port
|
||||
// udpSocket.bind(QHostAddress::LocalHost, 12345); // Use "localhost" (127.0.0.1) and port 12345
|
||||
// Start the timer for data updates
|
||||
// timer.start();
|
||||
}
|
||||
|
||||
void UdpServer::stopServer()
|
||||
{
|
||||
// Stop the timer and close the UDP socket
|
||||
// timer.stop();
|
||||
udpSocket.close();
|
||||
}
|
||||
|
||||
|
||||
void UdpServer::sendData(QByteArray data)
|
||||
{
|
||||
// Prepare the data to be sent
|
||||
// QString dataString = QString::number(intensity) + ',' + QString::number(position) + ',' + QString::number(focus);
|
||||
// QByteArray data = dataString.toUtf8();
|
||||
// Send the data to all connected clients (broadcast to all on the same network)
|
||||
udpSocket.writeDatagram(data, QHostAddress::Broadcast, 12345); // Replace 12345 with your desired port
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
#ifndef UDPSERVER_H
|
||||
#define UDPSERVER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUdpSocket>
|
||||
#include <QTimer> // Add this line to include QTimer
|
||||
|
||||
|
||||
|
||||
class UdpServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit UdpServer(QObject *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void startServer();
|
||||
void stopServer();
|
||||
void sendData(QByteArray data); // New slot to send data with custom values
|
||||
|
||||
private:
|
||||
QUdpSocket udpSocket;
|
||||
QTimer timer;
|
||||
|
||||
};
|
||||
|
||||
// Declare the global UdpServer object as an external variable
|
||||
extern UdpServer udpServer;
|
||||
|
||||
#endif // UDPSERVER_H
|
@ -1,20 +1,25 @@
|
||||
// udpclient.cpp
|
||||
|
||||
#include "udpclient.h"
|
||||
#include <iostream>
|
||||
|
||||
quint16 serverPort = 1901; // Port number for the UDP server
|
||||
|
||||
UdpClient::UdpClient(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
// Create a QHostAddress for the server's IP address
|
||||
QHostAddress serverAddress("10.0.7.1");
|
||||
QHostAddress serverAddress("127.0.0.1");
|
||||
|
||||
// Bind the UDP socket to a specific port for receiving data (replace with your desired port)
|
||||
udpSocket.bind(QHostAddress::Any, 12345); // Replace 12345 with your desired port
|
||||
udpSocket.bind(QHostAddress::Any, serverPort); // Replace 12345 with your desired port
|
||||
|
||||
// Connect the UDP socket's readyRead signal to the receiveData slot
|
||||
connect(&udpSocket, &QUdpSocket::readyRead, this, &UdpClient::receiveData);
|
||||
|
||||
// Set the server's address and port for sending data
|
||||
udpSocket.connectToHost(serverAddress, 12345); // Replace 12345 with the server's port
|
||||
udpSocket.connectToHost(serverAddress, serverPort); // Replace 12345 with the server's port
|
||||
|
||||
}
|
||||
|
||||
void UdpClient::startClient()
|
||||
@ -22,6 +27,7 @@ void UdpClient::startClient()
|
||||
// Start any client functionality here
|
||||
// This method can be used to initialize the client if needed.
|
||||
qDebug() << "UDP Client is listening for data...";
|
||||
messageCount = 0;
|
||||
}
|
||||
|
||||
void UdpClient::receiveData()
|
||||
@ -39,18 +45,53 @@ void UdpClient::processPendingDatagrams()
|
||||
datagram.resize(udpSocket.pendingDatagramSize());
|
||||
QHostAddress sender;
|
||||
quint16 senderPort;
|
||||
QTime currentTime = QTime::currentTime();
|
||||
|
||||
udpSocket.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
|
||||
|
||||
if(udpSocket.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort)){
|
||||
// std::cerr << "found data" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
// Parse and display the received data
|
||||
QString receivedData = QString::fromUtf8(datagram);
|
||||
// std::cout << "Received Data: " << receivedData.toStdString() << std::endl;
|
||||
QStringList dataList = receivedData.split(',');
|
||||
if (dataList.size() == 3) {
|
||||
|
||||
if (dataList.size() == 9) {
|
||||
|
||||
double intensity = dataList[0].toDouble();
|
||||
double position = dataList[1].toDouble();
|
||||
double focus = dataList[2].toDouble();
|
||||
double rSquare = dataList[3].toDouble();
|
||||
int msecTime = dataList[4].toInt();
|
||||
|
||||
qDebug() << "Received data - Intensity:" << intensity << "Position:" << position << "Focus:" << focus;
|
||||
// qDebug() << "Received data - Intensity: " << intensity << " Position:" << position << " Focus:" << focus << " rsquare:" << rSquare << " msec:" << msecTime ;
|
||||
}
|
||||
else{
|
||||
qDebug() << "Data of unexpected size" << dataList.size() ;
|
||||
}
|
||||
messageCount++;
|
||||
if (messageCount==1) {
|
||||
startTime = currentTime.msecsSinceStartOfDay();
|
||||
}
|
||||
|
||||
// Check if 1000 messages have been received
|
||||
if (messageCount % 1000 == 0 && messageCount >1) {
|
||||
QTime currentTime = QTime::currentTime();
|
||||
elapsedTimeInmSeconds = currentTime.msecsSinceStartOfDay();
|
||||
elapsedTimeInmSeconds-= startTime;
|
||||
|
||||
// Calculate the rate in messages per second
|
||||
// double messageRate = static_cast<double>(messageCount) / elapsedTimeInmSeconds;
|
||||
|
||||
// qInfo() << "Messages received: " << messageCount;
|
||||
qInfo() << "Message rate (msec/1k): " << elapsedTimeInmSeconds;;// << 1000/(elapsedTimeInmSeconds/1000) << "kHz" ;
|
||||
|
||||
|
||||
// Reset the counters
|
||||
messageCount = 0;
|
||||
startTime = currentTime.msecsSinceStartOfDay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QUdpSocket>
|
||||
#include <QTime>
|
||||
|
||||
class UdpClient : public QObject
|
||||
{
|
||||
@ -15,7 +16,9 @@ public:
|
||||
|
||||
private:
|
||||
QUdpSocket udpSocket;
|
||||
|
||||
int messageCount = 0;
|
||||
int startTime=0;
|
||||
int elapsedTimeInmSeconds=0;
|
||||
public slots:
|
||||
void receiveData();
|
||||
void processPendingDatagrams();
|
||||
|
Loading…
Reference in New Issue
Block a user