Files
ximeaAirborneSystem/Source_Files/udpserver.cpp

603 lines
20 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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)));
QString ximeaParamCfgFile = "/media/nvme/300TC/config/StateOf300tc.cfg";
stateOf300tc.setConfigfilePath(ximeaParamCfgFile.toStdString());
if(!stateOf300tc.isConfigfileExist())
stateOf300tc.createConfigFile();
stateOf300tc.parseConfigfile();
stateOf300tc.setSbgState(0);
stateOf300tc.setSbgSolutionMode(0);
stateOf300tc.setXimeaState(100);
stateOf300tc.setFrameRate(0);
stateOf300tc.setExposeTime(0);
stateOf300tc.setExposeMaxValueOfOneFrame(0);
//当软件不正常关闭并且重启后通知其他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();//μs
m_imager->wrapSetExposureTime(time);
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;
}
case 10:
{
std::cout<<"10代表!"<<std::endl;
int sbgState,sbgSolutionMode,ximeaState,frameRate,exposeMaxValueOfOneFrame;
float exposeTime;
stateOf300tc.getSbgState(sbgState);
stateOf300tc.getSbgSolutionMode(sbgSolutionMode);
stateOf300tc.getXimeaState(ximeaState);
stateOf300tc.getFrameRate(frameRate);
stateOf300tc.getExposeTime(exposeTime);
stateOf300tc.getExposeMaxValueOfOneFrame(exposeMaxValueOfOneFrame);
sendSerialPortStatus(sbgState);
sendSbgSolutionModeState(sbgSolutionMode);
sendXimeaImageStatus(ximeaState);
sendXimeaAutoExposeMaxValueOfOneFrame(exposeMaxValueOfOneFrame, exposeTime);
sendXimeaImageFrameRate(frameRate);
break;
}
default:
std::cout<<">=11没有意义!"<<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);
stateOf300tc.setSbgState(serialPortStatus);
}
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);
stateOf300tc.setSbgSolutionMode(SolutionMode);
}
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);
stateOf300tc.setXimeaState(ximeaImageStatus);
}
void UdpServer::sendXimeaAutoExposeMaxValueOfOneFrame(int autoExposeMaxValueOfOneFrame, double exposeTime)
{
// std::cout<<"UdpServer::sendXimeaAutoExposeMaxValueOfOneFrame---------------------:"<< exposeTime << " " << autoExposeMaxValueOfOneFrame <<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);
stateOf300tc.setExposeTime(exposeTime);
stateOf300tc.setExposeMaxValueOfOneFrame(autoExposeMaxValueOfOneFrame);
}
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);
stateOf300tc.setFrameRate(frameRate);
}
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;
}
}