560 lines
18 KiB
C++
560 lines
18 KiB
C++
#include "Header_Files/udpserver.h"
|
||
|
||
//using namespace sbgtc;
|
||
|
||
UdpServer::UdpServer()
|
||
{
|
||
m_udpSocket = new QUdpSocket(this);
|
||
m_udpSocket->bind(45454, QUdpSocket::ShareAddress);
|
||
connect(m_udpSocket, SIGNAL(readyRead()),this, SLOT(processPendingDatagrams()));
|
||
|
||
m_RecordThread=new QThread();
|
||
m_imager=new XimeaImager();
|
||
m_imager->moveToThread(m_RecordThread);
|
||
m_RecordThread->start(QThread::HighestPriority);
|
||
|
||
m_RecordSbgThread=new QThread();
|
||
m_sbgRecorder=new sbgtc::SbgRecorder();
|
||
m_sbgRecorder->moveToThread(m_RecordSbgThread);
|
||
m_RecordSbgThread->start();
|
||
|
||
m_CopyFileThread=new QThread();
|
||
m_copyFile=new FileOperation();
|
||
m_copyFile->moveToThread(m_CopyFileThread);
|
||
m_CopyFileThread->start();
|
||
|
||
//系统采集步骤1:打开sbg串口并采集数据,打开光谱仪
|
||
connect(this, SIGNAL(systemStart()),m_sbgRecorder, SLOT(startRecordSbg()));
|
||
connect(this, SIGNAL(systemStart()),m_imager, SLOT(openImger()));
|
||
|
||
connect(this, SIGNAL(systemStop()),m_sbgRecorder, SLOT(closeSerialPort()));//
|
||
connect(this, SIGNAL(systemStop()),m_imager, SLOT(closeImger()));
|
||
|
||
|
||
//系统采集步骤2:开始采集高光谱影像
|
||
connect(this, SIGNAL(startRecordHyperspectralSignal()),m_sbgRecorder, SLOT(startRecordHyperspectral()));
|
||
connect(m_sbgRecorder, SIGNAL(sbgReady(double,QString)),m_imager, SLOT(startRecord(double,QString)));
|
||
connect(this, SIGNAL(recordXimeaOnlySignal(double,QString)),m_imager, SLOT(startRecord(double,QString)));
|
||
|
||
//系统采集步骤3:停止采集
|
||
connect(m_imager, SIGNAL(recordFinished()),this, SLOT(onRecordFinished()));
|
||
|
||
//系统采集步骤4:拷贝文件
|
||
connect(this, SIGNAL(startCopyFileSignal()),m_copyFile, SLOT(copyFile()));
|
||
connect(this, SIGNAL(startDeleteFileSignal()),m_copyFile, SLOT(deleteFile()));
|
||
|
||
//系统采集步骤5:进程间通讯
|
||
connect(m_sbgRecorder, SIGNAL(serialPortStatus(int)),this, SLOT(sendSerialPortStatus(int)));
|
||
|
||
connect(m_sbgRecorder, SIGNAL(sbgSolutionModeSignal(int)),this, SLOT(sendSbgSolutionModeState(int)));
|
||
connect(m_sbgRecorder, SIGNAL(sbgAccuracySignal(int,int)),this, SLOT(sendSbgAccuracyState(int,int)));
|
||
|
||
connect(m_imager, SIGNAL(ximeaImageStatus(int)),this, SLOT(sendXimeaImageStatus(int)));
|
||
connect(m_imager, SIGNAL(autoExposeMaxValueOfOneFrame(int, double)),this, SLOT(sendXimeaAutoExposeMaxValueOfOneFrame(int, double)));
|
||
connect(m_imager, SIGNAL(binSignal(int, int)),this, SLOT(sendXimeaBinState(int, int)));
|
||
connect(m_imager, SIGNAL(frameRateSignal(double)),this, SLOT(sendXimeaImageFrameRate(double)));
|
||
connect(m_copyFile, SIGNAL(copyFileStatus(int)),this, SLOT(sendCopyFileStatus(int)));
|
||
|
||
|
||
|
||
//当软件不正常关闭并且重启后,通知其他psdk程序
|
||
m_clientIpAddress=QHostAddress(QHostAddress::LocalHost);
|
||
sendSerialPortStatus(0);
|
||
sendXimeaImageStatus(100);
|
||
sendCopyFileStatus(0);
|
||
|
||
system("sudo gpio write 10 0");
|
||
|
||
m_recordTempThread=new QThread();
|
||
m_300tcTemperature = new Record300TcTemperature();
|
||
m_300tcTemperature->moveToThread(m_recordTempThread);
|
||
m_recordTempThread->start();
|
||
connect(this, SIGNAL(record300tcTemperatureSignal(QString)),m_300tcTemperature, SLOT(recordTemperature(QString)));
|
||
|
||
QDateTime curDateTime = QDateTime::currentDateTime();
|
||
QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss");
|
||
QString Temperature300tcCSVPath = QDir::cleanPath(QString::fromStdString("/media/nvme/300TC/programRunLog/300tcTemperature") + QDir::separator() + "300tcTemperature_" + currentTime + ".csv");
|
||
emit record300tcTemperatureSignal(Temperature300tcCSVPath);
|
||
|
||
|
||
std::cout<<"UdpServer::UdpServer--------:System ready!"<<std::endl;
|
||
}
|
||
|
||
void UdpServer::processPendingDatagrams()
|
||
{
|
||
using namespace std;
|
||
while (m_udpSocket->hasPendingDatagrams())
|
||
{
|
||
QByteArray datagram;
|
||
|
||
datagram.resize(m_udpSocket->pendingDatagramSize());
|
||
m_udpSocket->readDatagram(datagram.data(), datagram.size(),&m_clientIpAddress, &m_clientPort);
|
||
|
||
|
||
printf("接收数据字节数: %d.\n",datagram.size());
|
||
|
||
QList<QByteArray> datagramList=datagram.split(',');
|
||
printf("有多少个list: %d.\n",datagramList.size());
|
||
|
||
QString instruction=datagramList[0].data();// QByteArray转QString方法1
|
||
switch (instruction.toInt())
|
||
{
|
||
case 1://启动系统: 打开sbg串口并采集数据,打开光谱仪
|
||
{
|
||
std::cout<<"1代表启动系统!"<<std::endl;
|
||
|
||
system("sudo gpio write 10 1");
|
||
sleep(4);//睡眠4秒,等待电脑打开usb电源,以便给相机供电
|
||
|
||
emit systemStart();
|
||
|
||
break;
|
||
}
|
||
case 2://关闭系统:关闭相机和sbg串口,关闭软件
|
||
{
|
||
std::cout<<"2代表关闭系统!"<<std::endl;
|
||
m_300tcTemperature->stopRecordTemperature();
|
||
|
||
if(m_sbgRecorder->getSbgState()>=1)
|
||
{
|
||
m_sbgRecorder->stopRecordSbg();
|
||
}
|
||
|
||
|
||
if(m_imager->getImagerState()>=101)
|
||
{
|
||
m_imager->stopRecord();
|
||
}
|
||
|
||
emit systemStop();
|
||
|
||
sleep(4);//睡眠4秒,等待
|
||
system("sudo gpio write 10 0");
|
||
|
||
//QCoreApplication::quit();
|
||
break;
|
||
}
|
||
case 3://系统开始采集高光谱影像
|
||
{
|
||
if(m_imager->getImagerState()>=101 && m_imager->getImagerState()<=103)
|
||
{
|
||
std::cout<<"3代表系统开始采集高光谱影像!"<<std::endl;
|
||
m_sbgRecorder->startRecordHyperspectral();
|
||
}
|
||
|
||
break;
|
||
}
|
||
case 4://系统停止采集高光谱影像
|
||
{
|
||
if(m_imager->getImagerState()>=101 && m_imager->getImagerState()<=104)
|
||
{
|
||
std::cout<<"4代表系统停止采集高光谱影像!"<<std::endl;
|
||
m_imager->stopRecord();
|
||
}
|
||
|
||
break;
|
||
}
|
||
case 5://
|
||
{
|
||
if(m_imager->getImagerState()>=101 && m_imager->getImagerState()<=103)
|
||
{
|
||
std::cout<<"5代表设置帧率!"<<std::endl;
|
||
m_imager->setFramerate(datagramList[1].toFloat());
|
||
}
|
||
|
||
break;
|
||
}
|
||
case 6://
|
||
{
|
||
if(m_imager->getImagerState()>=101 && m_imager->getImagerState()<=103)
|
||
{
|
||
std::cout<<"6代表自动曝光!"<<std::endl;
|
||
m_imager->autoExposure();
|
||
}
|
||
|
||
break;
|
||
}
|
||
case 7:
|
||
{
|
||
if(m_imager->getImagerState()>=101 && m_imager->getImagerState()<=103)
|
||
{
|
||
float time = datagramList[1].toFloat();//ms
|
||
m_imager->wrapSetExposureTime(time*1000);
|
||
std::cout<<"7,手动设置曝光时间为:" << time <<std::endl;
|
||
}
|
||
|
||
break;
|
||
}
|
||
case 8:
|
||
{
|
||
;
|
||
}
|
||
case 9:
|
||
{
|
||
std::cout<<"9代表仅采集影像!"<<std::endl;
|
||
|
||
if(datagramList[1].toInt()==1)
|
||
{
|
||
QString xx = getFileNameBaseOnTime();
|
||
xx = xx + "testImage";
|
||
emit recordXimeaOnlySignal(1000.0,xx);
|
||
|
||
// emit recordXimeaOnlySignal(1000.0,"testImage");
|
||
}
|
||
else if(datagramList[1].toInt()==0)
|
||
{
|
||
m_imager->stopRecord();
|
||
}
|
||
|
||
break;
|
||
}
|
||
default:
|
||
std::cout<<">=9没有意义!"<<std::endl;
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
double UdpServer::getTimeDifferenceBetweenSystemAndSbg(double secondSbg)
|
||
{
|
||
// time_t timer;//time_t就是long int 类型
|
||
// struct tm *tblock;
|
||
// timer = time(NULL);//返回秒数(精度为秒),从1970-1-1,00:00:00 可以当成整型输出或用于其它函数
|
||
// tblock = localtime(&timer);
|
||
// printf("Local time is: %s\n", asctime(tblock));
|
||
|
||
|
||
|
||
//https://blog.csdn.net/FUN6367/article/details/89787566
|
||
struct timespec systemTime;
|
||
clock_gettime(CLOCK_REALTIME,&systemTime);
|
||
tm systemTime_rili;
|
||
localtime_r(&systemTime.tv_sec, &systemTime_rili);
|
||
|
||
// std::cout<<"systemTime_rili--年: "<<systemTime_rili.tm_year+1900<<std::endl;
|
||
// std::cout<<"systemTime_rili--月: "<<systemTime_rili.tm_mon+1<<std::endl;
|
||
// std::cout<<"systemTime_rili--日: "<<systemTime_rili.tm_mday<<std::endl;
|
||
// std::cout<<"systemTime_rili--时: "<<systemTime_rili.tm_hour<<std::endl;
|
||
// std::cout<<"systemTime_rili--分: "<<systemTime_rili.tm_min<<std::endl;
|
||
// std::cout<<"systemTime_rili--秒: "<<systemTime_rili.tm_sec<<std::endl;
|
||
|
||
// printf("Local time is: %s\n", asctime(&systemTime_rili));
|
||
|
||
|
||
|
||
double secondSystem=(systemTime_rili.tm_mday-1)*24*60*60+systemTime_rili.tm_hour*60*60+systemTime_rili.tm_min*60+systemTime_rili.tm_sec;
|
||
double nanosecondSystem=secondSystem+static_cast<double>(systemTime.tv_nsec)/1000000000;
|
||
|
||
printf("UdpServer::getTimeDifferenceBetweenSystemAndSbg------%f\n", nanosecondSystem-secondSbg);
|
||
|
||
return nanosecondSystem-secondSbg;
|
||
}
|
||
|
||
void UdpServer::sender(int status)
|
||
{
|
||
QByteArray datagram2send;
|
||
|
||
datagram2send.operator =(QString::number(status).toStdString().c_str());
|
||
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, m_clientPort+1);
|
||
}
|
||
|
||
void UdpServer::sendSerialPortStatus(int serialPortStatus)
|
||
{
|
||
// std::cout<<"UdpServer::sendSerialPortStatus---------------------:"<< serialPortStatus <<std::endl;
|
||
|
||
// std::cout<<"UdpServer::sendSerialPortStatus---------------------:"<< m_clientIpAddress.AnyIPv4 <<std::endl;
|
||
|
||
QByteArray datagram2send;
|
||
|
||
QString status = "sbg," + QString::number(serialPortStatus);
|
||
|
||
datagram2send.operator =(status.toStdString().c_str());
|
||
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455);
|
||
}
|
||
|
||
void UdpServer::sendSbgSolutionModeState(int SolutionMode)
|
||
{
|
||
// std::cout<<"UdpServer::sendSbgSolutionModeState---------------------:"<< SolutionMode <<std::endl;
|
||
|
||
QByteArray datagram2send;
|
||
|
||
QString status = "SolutionMode," + QString::number(SolutionMode);
|
||
|
||
datagram2send.operator =(status.toStdString().c_str());
|
||
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455);
|
||
}
|
||
|
||
void UdpServer::sendSbgAccuracyState(int Accuracy,int SatelliteCounter)
|
||
{
|
||
// std::cout<<"UdpServer::sendSbgAccuracyState---------------------:"<< Accuracy <<std::endl;
|
||
|
||
QByteArray datagram2send;
|
||
|
||
QString status = "Accuracy," + QString::number(Accuracy) + "," + QString::number(SatelliteCounter);
|
||
|
||
datagram2send.operator =(status.toStdString().c_str());
|
||
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455);
|
||
}
|
||
|
||
void UdpServer::sendXimeaImageStatus(int ximeaImageStatus)
|
||
{
|
||
// std::cout<<"UdpServer::sendXimeaImageStatus---------------------:"<< ximeaImageStatus <<std::endl;
|
||
|
||
QByteArray datagram2send;
|
||
|
||
QString status = "ximea," + QString::number(ximeaImageStatus);
|
||
|
||
datagram2send.operator =(status.toStdString().c_str());
|
||
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455);
|
||
}
|
||
|
||
void UdpServer::sendXimeaAutoExposeMaxValueOfOneFrame(int autoExposeMaxValueOfOneFrame, double exposeTime)
|
||
{
|
||
// std::cout<<"UdpServer::sendXimeaAutoExposeMaxValueOfOneFrame---------------------:"<< ximeaImageStatus <<std::endl;
|
||
|
||
QByteArray datagram2send;
|
||
|
||
QString status = "XimeaAutoExpose," + QString::number(autoExposeMaxValueOfOneFrame) + "," + QString::number(exposeTime, 'f', 2);
|
||
|
||
datagram2send.operator =(status.toStdString().c_str());
|
||
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455);
|
||
}
|
||
|
||
void UdpServer::sendXimeaBinState(int spatialBin, int spectralBin)
|
||
{
|
||
// std::cout<<"UdpServer::sendXimeaAutoExposeMaxValueOfOneFrame---------------------:"<< ximeaImageStatus <<std::endl;
|
||
|
||
QByteArray datagram2send;
|
||
|
||
QString status = "bin," + QString::number(spatialBin) + "," + QString::number(spectralBin);
|
||
|
||
datagram2send.operator =(status.toStdString().c_str());
|
||
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455);
|
||
}
|
||
|
||
void UdpServer::sendXimeaImageFrameRate(double frameRate)
|
||
{
|
||
// std::cout<<"UdpServer::sendXimeaImageFrameRate---------------------:"<< ximeaImageStatus <<std::endl;
|
||
|
||
QByteArray datagram2send;
|
||
|
||
QString status = "XimeaFrameRate," + QString::number(frameRate, 'f', 2);
|
||
|
||
datagram2send.operator =(status.toStdString().c_str());
|
||
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455);
|
||
}
|
||
|
||
void UdpServer::sendCopyFileStatus(int fileStatus)
|
||
{
|
||
// std::cout<<"UdpServer::sendCopyFileStatus---------------------:"<< fileStatus <<std::endl;
|
||
|
||
QByteArray datagram2send;
|
||
|
||
QString status = "file," + QString::number(fileStatus);
|
||
|
||
datagram2send.operator =(status.toStdString().c_str());
|
||
m_udpSocket->writeDatagram(datagram2send.data(),datagram2send.size(),m_clientIpAddress, 45455);
|
||
}
|
||
|
||
void UdpServer::onRecordFinished()
|
||
{
|
||
std::cout<<"UdpServer::onRecordFinished----------------:影像停止采集"<<std::endl;
|
||
}
|
||
|
||
Record300TcTemperature::Record300TcTemperature()
|
||
{
|
||
m_bIsRecord = true;
|
||
}
|
||
|
||
void Record300TcTemperature::stopRecordTemperature()
|
||
{
|
||
m_bIsRecord = false;
|
||
}
|
||
|
||
void Record300TcTemperature::recordTemperature(QString filePath= nullptr)
|
||
{
|
||
if(filePath== nullptr)
|
||
filePath="300tcTemperature.csv";
|
||
QList<QString> fileInfo = getFileInfo(filePath);
|
||
bool ret = createDir(fileInfo[0]);
|
||
|
||
ofstream temperatureFile300Tc(filePath.toStdString().c_str(),ios::app);
|
||
int counter = 0;
|
||
|
||
m_serial=new QSerialPort();
|
||
|
||
if(m_serial->isOpen())//如果串口已经打开了 先给他关闭了
|
||
{
|
||
m_serial->clear();
|
||
m_serial->close();
|
||
}
|
||
|
||
QString portname = "ttyUSB2";
|
||
|
||
m_serial->setPortName(portname);
|
||
m_serial->open(QIODevice::ReadWrite);
|
||
|
||
bool x=m_serial->setBaudRate(9600);
|
||
|
||
QByteArray requestData;
|
||
while (m_bIsRecord)
|
||
{
|
||
counter++;
|
||
if(m_serial->waitForReadyRead(30000))
|
||
{
|
||
requestData = m_serial->readAll();
|
||
|
||
float temp = parseMessage(&requestData);
|
||
if (temp == -10000)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
QDateTime curDateTime = QDateTime::currentDateTime();
|
||
QString currentTime = curDateTime.toString("yyyy/MM/dd hh:mm:ss");
|
||
|
||
temperatureFile300Tc << currentTime.toStdString() << "," << temp << "\n";
|
||
|
||
// if(temp > 80)
|
||
// {
|
||
// system("/home/300tc/projects/udpClient/udpClient 127.0.0.1 9,0");
|
||
// }
|
||
// if(temp > 90)
|
||
// {
|
||
// system("/home/300tc/projects/udpClient/udpClient 127.0.0.1 2");
|
||
// }
|
||
//
|
||
if (counter % 60 == 0)
|
||
{
|
||
temperatureFile300Tc.flush();
|
||
}
|
||
sleep(1);
|
||
}
|
||
else
|
||
{
|
||
// std::cout<<"Record300TcTemperature::recordTemperature--Wait response timeout."<<std::endl;
|
||
}
|
||
}
|
||
m_bIsRecord = true;
|
||
|
||
temperatureFile300Tc.close();
|
||
}
|
||
|
||
float Record300TcTemperature::parseMessage(QByteArray * data)
|
||
{
|
||
float Lux;
|
||
float T;
|
||
float P;
|
||
float Hum;
|
||
float H;
|
||
bool hasTemperature = false;
|
||
|
||
// qDebug() << "Received data(hex): " << data->toHex();
|
||
|
||
// for (int i = 0; i < data->length(); ++i)
|
||
// {
|
||
// qDebug() << i << ":" << (int)data->at(i);
|
||
// }
|
||
|
||
QByteArray target = QByteArray::fromHex("5a5a"); // The pattern to search for
|
||
|
||
int offset_tmp = data->indexOf(target);
|
||
QList<int> offsets;
|
||
|
||
while (offset_tmp != -1)
|
||
{
|
||
offsets.append(offset_tmp);
|
||
offset_tmp = data->indexOf(target, offset_tmp + target.size());
|
||
}
|
||
|
||
if (offsets.isEmpty())
|
||
{
|
||
// qDebug() << "5A5A not found in the data.";
|
||
return -10000;
|
||
}
|
||
// qDebug() << "5A5A found at offsets:" << offsets;
|
||
|
||
for (int i = 0; i < offsets.length(); ++i)
|
||
{
|
||
int offset = offsets.at(i);
|
||
|
||
int messageClass = data->at(offset + 2);
|
||
int messageCount = data->at(offset + 3) + 5;
|
||
// qDebug() << "messageCount:" << messageCount;
|
||
if (offset + messageCount - 1 > data->length() - 1)
|
||
{
|
||
qDebug() << i << ": Some data of this frame is missing! Discarding the frame.";
|
||
continue;
|
||
}
|
||
|
||
|
||
int checksum = 0;
|
||
QList<int> numbers;
|
||
for (int j = 0; j < messageCount - 1; ++j)
|
||
{
|
||
if (i==offsets.length()-1 && j== messageCount-1)
|
||
{
|
||
int sdf=1;
|
||
}
|
||
|
||
int index = offset + j;
|
||
|
||
if (index >= data->length())//Some data of this frame is missing! Discarding the frame.
|
||
{
|
||
checksum = -1;
|
||
break;
|
||
}
|
||
int tmp = static_cast<int>(data->at(index));
|
||
numbers.append(tmp);
|
||
checksum += tmp;
|
||
}
|
||
// qDebug() << "jiaqilai:" << numbers;
|
||
|
||
if (checksum == -1)
|
||
{
|
||
qDebug() << "Some data of this frame is missing! Discarding the frame.";
|
||
continue;
|
||
}
|
||
|
||
if ((checksum & 0xFF) != data->at(offset + messageCount - 1))
|
||
{
|
||
qDebug() << "Checksum mismatch! Discarding the frame.";
|
||
continue;
|
||
}
|
||
|
||
//parse data
|
||
switch (messageClass)
|
||
{
|
||
case 0x15:
|
||
Lux = (float)((data->at(offset + 4)<<24)|(data->at(offset + 5)<<16)|(data->at(offset + 6)<<8)|data->at(offset + 7)) / 100;
|
||
// qDebug() << "lux: " << Lux;
|
||
break;
|
||
case 0x45:
|
||
T = (float)((data->at(offset + 4)<<8)|data->at(offset + 5)) / 100;
|
||
P = (float)((data->at(offset + 6)<<24)|(data->at(offset + 7)<<16)|(data->at(offset + 8)<<8)|data->at(offset + 9)) / 100;
|
||
Hum = (float)((data->at(offset + 10)<<8) | data->at(offset + 11)) / 100;
|
||
H = (float)((data->at(offset + 12)<<8)|data->at(offset + 13));
|
||
|
||
hasTemperature = true;
|
||
|
||
// qDebug() << "T: " << T;
|
||
// qDebug() << "P: " << P;
|
||
// qDebug() << "Hum: " << Hum;
|
||
// qDebug() << "H: " << H;
|
||
break;
|
||
default : // 可选的
|
||
;
|
||
|
||
}
|
||
}
|
||
if (hasTemperature)
|
||
{
|
||
return T;
|
||
}
|
||
else
|
||
{
|
||
return -10000;
|
||
}
|
||
}
|