diff options
Diffstat (limited to 'tracker-hatire')
-rw-r--r-- | tracker-hatire/ftnoir_arduino_type.h | 8 | ||||
-rw-r--r-- | tracker-hatire/ftnoir_tracker_hat.cpp | 535 | ||||
-rw-r--r-- | tracker-hatire/ftnoir_tracker_hat.h | 122 | ||||
-rw-r--r-- | tracker-hatire/ftnoir_tracker_hat_dialog.cpp | 41 | ||||
-rw-r--r-- | tracker-hatire/ftnoir_tracker_hat_dialog.h | 26 | ||||
-rw-r--r-- | tracker-hatire/ftnoir_tracker_hat_settings.cpp | 22 | ||||
-rw-r--r-- | tracker-hatire/ftnoir_tracker_hat_settings.h | 10 | ||||
-rw-r--r-- | tracker-hatire/thread.cpp | 300 | ||||
-rw-r--r-- | tracker-hatire/thread.hpp | 167 |
9 files changed, 590 insertions, 641 deletions
diff --git a/tracker-hatire/ftnoir_arduino_type.h b/tracker-hatire/ftnoir_arduino_type.h index 57afed63..481e137b 100644 --- a/tracker-hatire/ftnoir_arduino_type.h +++ b/tracker-hatire/ftnoir_arduino_type.h @@ -1,5 +1,4 @@ -#ifndef FTNOIR_TARDUINO_TYPE_H -#define FTNOIR_TARDUINO_TYPE_H +#pragma once #include <QDataStream> @@ -15,7 +14,6 @@ struct TArduinoData } ; #pragma pack(pop) - inline QDataStream & operator >> ( QDataStream& in, TArduinoData& out ) { in.setFloatingPointPrecision(QDataStream::SinglePrecision ); @@ -27,6 +25,4 @@ inline QDataStream & operator >> ( QDataStream& in, TArduinoData& out ) return in; } - - -#endif +static_assert(sizeof(TArduinoData) == 30, "sizeof packet != 30"); diff --git a/tracker-hatire/ftnoir_tracker_hat.cpp b/tracker-hatire/ftnoir_tracker_hat.cpp index eea1cbca..6b76ddba 100644 --- a/tracker-hatire/ftnoir_tracker_hat.cpp +++ b/tracker-hatire/ftnoir_tracker_hat.cpp @@ -11,12 +11,8 @@ #include <QDebug> #include "ftnoir_tracker_hat.h" -FTNoIR_Tracker::FTNoIR_Tracker() +hatire::hatire() { - qDebug()<<"Tracker::HAT"; - - ComPort = NULL; - HAT.Rot[0]=0; HAT.Rot[1]=0; HAT.Rot[2]=0; @@ -24,415 +20,126 @@ FTNoIR_Tracker::FTNoIR_Tracker() HAT.Trans[1]=0; HAT.Trans[2]=0; - - // prepare & reserve QByteArray - dataRead.resize(4096); - dataRead.clear(); Begin.append((char) 0xAA); Begin.append((char) 0xAA); End.append((char) 0x55); End.append((char) 0x55); - flDiagnostics.setFileName(QCoreApplication::applicationDirPath() + "/HATDiagnostics.txt"); - settings.load_ini(); } -FTNoIR_Tracker::~FTNoIR_Tracker() +hatire::~hatire() { - qDebug()<<"Tracker::~HAT"; - if (ComPort!=NULL) { - if (ComPort->isOpen() ) { - -#ifdef OPENTRACK_API - QByteArray Msg; - Log("Tracker shut down"); - ComPort->write(sCmdStop); - if (!ComPort->waitForBytesWritten(1000)) { - emit sendMsgInfo("TimeOut in writing CMD"); - } else - { - Msg.append("\r\n"); - Msg.append("SEND '"); - Msg.append(sCmdStop); - Msg.append("'\r\n"); - } - emit sendMsgInfo(Msg); -#endif - ComPort->close(); - disconnect(ComPort,SIGNAL(readyRead()),0,0); - - } - delete ComPort; - ComPort=NULL; - } -} - - -//send ZERO to Arduino -bool FTNoIR_Tracker::notifyZeroed() { - qDebug() << " HAT send ZEROed "; - sendcmd(sCmdZero); - return true; } - - //send RESET to Arduino -void FTNoIR_Tracker::reset() { - qDebug() << " HAT send RESET "; - sendcmd(sCmdReset); -} - - -// Info SerialPort -void FTNoIR_Tracker::SerialInfo() { - QByteArray Msg; - if (ComPort!=NULL) { - if (ComPort->isOpen() ) { - Msg.append("\r\n"); - Msg.append(ComPort->portName()); - Msg.append("\r\n"); - Msg.append("BAUDRATE :"); - Msg.append(QString::number(ComPort->baudRate())); - Msg.append("\r\n"); - Msg.append("DataBits :"); - Msg.append(QString::number(ComPort->dataBits())); - Msg.append("\r\n"); - Msg.append("Parity :"); - switch (ComPort->parity()) { - case 0: Msg.append("No parity"); - break; - case 2: Msg.append("Even parity"); - break; - case 3: Msg.append("Odd parity"); - break; - case 4: Msg.append("Space parity"); - break; - case 5: Msg.append("Mark parity"); - break; - default: Msg.append("Unknown parity"); - break; - } - Msg.append("\r\n"); - Msg.append("Stop Bits :"); - switch (ComPort->stopBits()) { - Msg.append(QString::number(ComPort->stopBits())); - case 1: Msg.append("1 stop bit."); - break; - case 2: Msg.append("2 stop bits."); - break; - case 3: Msg.append("1.5 stop bits."); - break; - default: Msg.append("Unknown number of stop bit."); - break; - } - Msg.append("\r\n"); - Msg.append("Flow Control :"); - switch (ComPort->flowControl()) { - case 0: Msg.append("No flow control"); - break; - case 1: Msg.append("Hardware flow control (RTS/CTS)"); - break; - case 2: Msg.append("Software flow control (XON/XOFF)"); - break; - default: Msg.append("Unknown flow control"); - break; - } - emit sendMsgInfo(Msg); - - } - } -} - - -//send command to Arduino -void FTNoIR_Tracker::sendcmd(const QByteArray &cmd) { - QByteArray Msg; - if (cmd.length()>0) { - if (ComPort->isOpen() ) - { - QString logMess; - logMess.append("SEND '"); - logMess.append(cmd); - logMess.append("'"); - Log(logMess); - ComPort->write(cmd); - if (!ComPort->waitForBytesWritten(1000)) { - emit sendMsgInfo("TimeOut in writing CMD"); - } else - { - Msg.append("\r\n"); - Msg.append("SEND '"); - Msg.append(cmd); - Msg.append("'\r\n"); - } - #if 0 // WaitForReadyRead isn't working well and there are some reports of it being a win32 issue. We can live without it anyway - if ( !ComPort->waitForReadyRead(1000)) { - emit sendMsgInfo("TimeOut in response to CMD") ; - } else { - emit sendMsgInfo(Msg); - } - #else - emit sendMsgInfo(Msg); - #endif - } else { - emit sendMsgInfo("ComPort not open") ; - } - } +void hatire::reset() +{ + t.sendcmd(ts.sCmdReset); } - // return FPS -void FTNoIR_Tracker::get_info( int *tps ){ +void hatire::get_info( int *tps ) +{ *tps=frame_cnt; frame_cnt=0; } - -void FTNoIR_Tracker::SerialRead() -{ - QMutexLocker lck(&mutex); - dataRead+=ComPort->readAll(); -} - -#ifndef OPENTRACK_API -void FTNoIR_Tracker::Initialize( QFrame *videoframe ) +void hatire::start_tracker(QFrame*) { CptError=0; - dataRead.clear(); frame_cnt=0; - - Log("INITIALISING HATIRE"); - + new_frame=false; settings.load_ini(); applysettings(settings); - ComPort = new QSerialPort(this); - ComPort->setPortName(sSerialPortName); - if (ComPort->open(QIODevice::ReadWrite ) == true) { - connect(ComPort, SIGNAL(readyRead()), this, SLOT(SerialRead())); - if ( - ComPort->setBaudRate((QSerialPort::BaudRate)iBaudRate) - && ComPort->setDataBits((QSerialPort::DataBits)iDataBits) - && ComPort->setParity((QSerialPort::Parity)iParity) - && ComPort->setStopBits((QSerialPort::StopBits)iStopBits) - && ComPort->setFlowControl((QSerialPort::FlowControl)iFlowControl) - && ComPort->clear(QSerialPort::AllDirections) - && ComPort->setDataErrorPolicy(QSerialPort::IgnorePolicy) - ) { - // Wait init arduino sequence - for (int i = 1; i <=iDelayInit; i+=50) { - if (ComPort->waitForReadyRead(50)) break; - } - sendcmd(sCmdInit); - // Wait init MPU sequence - for (int i = 1; i <=iDelayStart; i+=50) { - if (ComPort->waitForReadyRead(50)) break; - } - - } else { - QMessageBox::warning(0,"Error", ComPort->errorString(),QMessageBox::Ok,QMessageBox::NoButton); - } - } - else { - QMessageBox::warning(0,"Error", "Unable to open ComPort",QMessageBox::Ok,QMessageBox::NoButton); - delete ComPort; - ComPort = NULL; - } - return; -} - - + t.Log("Starting Tracker"); + + serial_result ret = t.init_serial_port(); + + switch (ret.code) + { + case result_ok: + break; + case result_error: + QMessageBox::warning(0,"Error", ret.error, QMessageBox::Ok,QMessageBox::NoButton); + break; + case result_open_error: + QMessageBox::warning(0,"Error", "Unable to open ComPort: " + ret.error, QMessageBox::Ok,QMessageBox::NoButton); + break; + } -void FTNoIR_Tracker::StartTracker(HWND parent_window) -{ - // Send START cmd to IMU - sendcmd(sCmdStart); - Log("Starting Tracker"); - // Wait start MPU sequence - for (int i = 1; i <=iDelaySeq; i+=50) { - if (ComPort->waitForReadyRead(50)) break; - } - return; + t.start(ts); } - -void FTNoIR_Tracker::StopTracker( bool exit ) +void hatire::serial_info() { - QByteArray Msg; - - Log("Stopping tracker"); - if (sCmdStop.length()>0) { - if (ComPort->isOpen() ) - { - ComPort->write(sCmdStop); - if (!ComPort->waitForBytesWritten(1000)) { - emit sendMsgInfo("TimeOut in writing CMD"); - } else - { - Msg.append("\r\n"); - Msg.append("SEND '"); - Msg.append(sCmdStop); - Msg.append("'\r\n"); - } - emit sendMsgInfo(Msg); - } - } - // OK, the thread is not stopped, doing this. That might be dangerous anyway... - // - if (exit || !exit) return; - return; -} -//send CENTER to Arduino -void FTNoIR_Tracker::notifyCenter() { - sendcmd(sCmdCenter); + t.serial_info(); } - -#else -void FTNoIR_Tracker::start_tracker(QFrame*) +void hatire::send_serial_command(const QByteArray& x) { - CptError=0; - dataRead.clear(); - frame_cnt=0; - new_frame=false; - settings.load_ini(); - applysettings(settings); - ComPort = new QSerialPort(this); - ComPort->setPortName(sSerialPortName); - Log("Starting Tracker"); - - if (ComPort->open(QIODevice::ReadWrite ) == true) { - connect(ComPort, SIGNAL(readyRead()), this, SLOT(SerialRead())); - Log("Port Open"); - if ( - ComPort->setBaudRate((QSerialPort::BaudRate)iBaudRate) - && ComPort->setDataBits((QSerialPort::DataBits)iDataBits) - && ComPort->setParity((QSerialPort::Parity)iParity) - && ComPort->setStopBits((QSerialPort::StopBits)iStopBits) - && ComPort->setFlowControl((QSerialPort::FlowControl)iFlowControl) - && ComPort->clear(QSerialPort::AllDirections) - && ComPort->setDataErrorPolicy(QSerialPort::IgnorePolicy) - ) { - Log("Port Parameters set"); - qDebug() << QTime::currentTime() << " HAT OPEN on " << ComPort->portName() << ComPort->baudRate() << ComPort->dataBits() << ComPort->parity() << ComPort->stopBits() << ComPort->flowControl(); - - if (ComPort->flowControl() == QSerialPort::HardwareControl) - { - // Raise DTR - Log("Raising DTR"); - if (!ComPort->setDataTerminalReady(true)) - Log("Couldn't set DTR"); - - // Raise RTS/CTS - Log("Raising RTS"); - if (!ComPort->setRequestToSend(true)) - Log("Couldn't set RTS"); - - } - // Wait init arduino sequence - for (int i = 1; i <=iDelayInit; i+=50) { - if (ComPort->waitForReadyRead(50)) break; - } - Log("Waiting on init"); - qDebug() << QTime::currentTime() << " HAT send INIT "; - sendcmd(sCmdInit); - // Wait init MPU sequence - for (int i = 1; i <=iDelayStart; i+=50) { - if (ComPort->waitForReadyRead(50)) break; - } - // Send START cmd to IMU - qDebug() << QTime::currentTime() << " HAT send START "; - sendcmd(sCmdStart); - - // Wait start MPU sequence - for (int i = 1; i <=iDelaySeq; i+=50) { - if (ComPort->waitForReadyRead(50)) break; - } - Log("Port setup, waiting for HAT frames to process"); - qDebug() << QTime::currentTime() << " HAT wait MPU "; - } else { - QMessageBox::warning(0,"Error", ComPort->errorString(),QMessageBox::Ok,QMessageBox::NoButton); - } - } - else { - QMessageBox::warning(0,"Error", "Unable to open ComPort: " + ComPort->errorString(), QMessageBox::Ok,QMessageBox::NoButton); - delete ComPort; - ComPort = NULL; - } - return; - + t.sendcmd(x); } -//send CENTER to Arduino -void FTNoIR_Tracker::center() { - qDebug() << " HAT send CENTER "; - Log("Sending Centre Command"); - - sendcmd(sCmdCenter); -} - -//Return speed FPS sketch Arduino -int FTNoIR_Tracker::preferredHz() { - qDebug() << " HAT return Preferred FPS " << iFpsArduino; - return iFpsArduino; -} - -#endif - - // // Return 6DOF info // -#ifdef OPENTRACK_API -void FTNoIR_Tracker::data(double *data) -#else -bool FTNoIR_Tracker::GiveHeadPoseData(THeadPoseData *data) -#endif +void hatire::data(double *data) { - QMutexLocker lck(&mutex); - while (dataRead.length()>=30) { - Log(dataRead.toHex()); - if ((dataRead.startsWith(Begin) && ( dataRead.mid(28,2)==End )) ) { // .Begin==0xAAAA .End==0x5555 - QDataStream datastream(dataRead.left(30)); - if (bBigEndian) datastream.setByteOrder(QDataStream::BigEndian ); - else datastream.setByteOrder(QDataStream::LittleEndian ); + QByteArray dataRead(t.flush_data_read()); + + while (dataRead.length() >= 30) + { + t.Log(dataRead.toHex()); + if (dataRead.startsWith(Begin) && dataRead.mid(28,2) == End) + { // .Begin==0xAAAA .End==0x5555 + QDataStream datastream(dataRead.left(30)); + if (ts.bBigEndian) datastream.setByteOrder(QDataStream::BigEndian ); + else datastream.setByteOrder(QDataStream::LittleEndian); datastream>>ArduinoData; frame_cnt++; - if (ArduinoData.Code <= 1000) { + if (ArduinoData.Code <= 1000) + { HAT=ArduinoData; new_frame=true; - } else { - emit sendMsgInfo(dataRead.mid(4,24)) ; + } + else + { + emit t.serial_debug_info(dataRead.mid(4,24)) ; } dataRead.remove(0,30); - } else { + } + else + { + bool ok = true; // resynchro trame int index = dataRead.indexOf(Begin); if (index==-1) { + ok = false; index=dataRead.length(); } - emit sendMsgInfo(dataRead.mid(0,index)) ; + emit t.serial_debug_info(dataRead.mid(0,index)) ; dataRead.remove(0,index); CptError++; - qDebug() << QTime::currentTime() << " HAT Resync-Frame, counter " << CptError; + qDebug() << QTime::currentTime() << "hatire resync stream" << "index" << index << "ok" << ok; } } - if (CptError>50) { - emit sendMsgInfo("Can't find HAT frame") ; + t.prepend_unread_data(dataRead); + + if (CptError > 50) + { + emit t.serial_debug_info("Can't find HAT frame"); CptError=0; -#ifndef OPENTRACK_API - return false; -#endif } + + // XXX fix copy-pasted code -sh 20160410 + // Need to handle this differently in opentrack as opposed to tracknoir //if (new_frame) { -#ifdef OPENTRACK_API // in open track always populate the data, it seems opentrack always gives us a zeroed data structure to populate with pose data. // if we have no new data, we don't populate it and so 0 pose gets handed back which is wrong. By always running the code below, if we // have no new data, we will just give it the previous pose data which is the best thing we can do really. - if(1){ - + if (bEnableYaw) { if (bInvertYaw ) data[Yaw] = HAT.Rot[iYawAxe] * -1.0f; else data[Yaw] = HAT.Rot[iYawAxe]; @@ -463,54 +170,20 @@ bool FTNoIR_Tracker::GiveHeadPoseData(THeadPoseData *data) if (bInvertZ) data[TZ] = HAT.Trans[iZAxe]* -1.0f; else data[TZ] = HAT.Trans[iZAxe]; } else data[TZ] =0; -#else - if (new_frame) { // treat frame handling as it was for TrackNoIR. - if (bEnableYaw) { - if (bInvertYaw ) data->yaw = (double) HAT.Rot[iYawAxe] * -1.0f; - else data->yaw = (double) HAT.Rot[iYawAxe]; - } - - if (bEnablePitch) { - if (bInvertPitch)data->pitch = (double) HAT.Rot[iPitchAxe] * -1.0f; - else data->pitch = (double) HAT.Rot[iPitchAxe]; - } - if (bEnableRoll) { - if (bInvertRoll) data->roll = (double) HAT.Rot[iRollAxe] * -1.0f; - else data->roll = (double) HAT.Rot[iRollAxe]; - } - - if (bEnableX) { - if (bInvertX) data->x = (double) HAT.Trans[iXAxe]* -1.0f; - else data->x = (double) HAT.Trans[iXAxe]; - } - - if (bEnableY) { - if (bInvertY) data->y = (double) HAT.Trans[iYAxe]* -1.0f; - else data->y = (double) HAT.Trans[iYAxe]; - } + new_frame=false; - if (bEnableZ) { - if (bInvertZ) data->z = (double) HAT.Trans[iZAxe]* -1.0f; - else data->z = (double) HAT.Trans[iZAxe]; - } - return true; -#endif - new_frame=false; // For debug //data->x=dataRead.length(); //data->y=CptError; - } } - - // // Apply modification Settings // -void FTNoIR_Tracker::applysettings(const TrackerSettings& settings){ - QMutexLocker lck(&mutex); - sSerialPortName= settings.SerialPortName; +void hatire::applysettings(const TrackerSettings& settings) +{ + ts.sSerialPortName = settings.SerialPortName; bEnableRoll = settings.EnableRoll; bEnablePitch = settings.EnablePitch; @@ -525,7 +198,7 @@ void FTNoIR_Tracker::applysettings(const TrackerSettings& settings){ bInvertX = settings.InvertX; bInvertY = settings.InvertY; bInvertZ = settings.InvertZ; - bEnableLogging = settings.EnableLogging; + ts.bEnableLogging = settings.EnableLogging; iRollAxe= settings.RollAxe; iPitchAxe= settings.PitchAxe; @@ -534,64 +207,26 @@ void FTNoIR_Tracker::applysettings(const TrackerSettings& settings){ iYAxe= settings.YAxe; iZAxe= settings.ZAxe; - iBaudRate=settings.pBaudRate; - iDataBits=settings.pDataBits; - iParity=settings.pParity; - iStopBits=settings.pStopBits; - iFlowControl=settings.pFlowControl; - - sCmdStart= settings.CmdStart.toLatin1(); - sCmdStop= settings.CmdStop.toLatin1(); - sCmdInit= settings.CmdInit.toLatin1(); - sCmdReset= settings.CmdReset.toLatin1(); - sCmdCenter= settings.CmdCenter.toLatin1(); - sCmdZero= settings.CmdZero.toLatin1(); - - iDelayInit=settings.DelayInit; - iDelayStart=settings.DelayStart; - iDelaySeq=settings.DelaySeq; - - bBigEndian=settings.BigEndian; -#ifdef OPENTRACK_API - iFpsArduino=settings.FPSArduino; -#endif -} - -void FTNoIR_Tracker::Log(QString message) -{ - // Drop out immediately if logging is off. Yes, there is still some overhead because of passing strings around for no reason. - // that's unfortunate and I'll monitor the impact and see if it needs a more involved fix. - if (!bEnableLogging) return; - QString logMessage; - - if (flDiagnostics.open(QIODevice::ReadWrite | QIODevice::Append)) - { - QTextStream out(&flDiagnostics); - QString milliSeconds; - milliSeconds = QString("%1").arg(QTime::currentTime().msec(), 3, 10, QChar('0')); - // We have a file - out << QTime::currentTime().toString() << "." << milliSeconds << ": " << message << "\r\n"; - flDiagnostics.close(); - } -} + ts.iBaudRate=settings.pBaudRate; + ts.iDataBits=settings.pDataBits; + ts.iParity=settings.pParity; + ts.iStopBits=settings.pStopBits; + ts.iFlowControl=settings.pFlowControl; + ts.sCmdStart= settings.CmdStart.toLatin1(); + ts.sCmdStop= settings.CmdStop.toLatin1(); + ts.sCmdInit= settings.CmdInit.toLatin1(); + ts.sCmdReset= settings.CmdReset.toLatin1(); + ts.sCmdCenter= settings.CmdCenter.toLatin1(); + ts.sCmdZero= settings.CmdZero.toLatin1(); + ts.iDelayInit=settings.DelayInit; + ts.iDelayStart=settings.DelayStart; + ts.iDelaySeq=settings.DelaySeq; + ts.bBigEndian=settings.BigEndian; -//////////////////////////////////////////////////////////////////////////////// -// Factory function that creates instances if the Tracker object. + t.update_serial_settings(ts); +} -// Export both decorated and undecorated names. -// GetTracker - Undecorated name, which can be easily used with GetProcAddress -// Win32 API function. -// _GetTracker@0 - Common name decoration for __stdcall functions in C language. -//////////////////////////////////////////////////////////////////////////////// -#ifdef OPENTRACK_API #include "ftnoir_tracker_hat_dialog.h" -OPENTRACK_DECLARE_TRACKER(FTNoIR_Tracker, TrackerControls, TrackerDll) -#else -#pragma comment(linker, "/export:GetTracker=_GetTracker@0") -FTNOIR_TRACKER_BASE_EXPORT ITrackerPtr __stdcall GetTracker() -{ - return new FTNoIR_Tracker; -} -#endif +OPENTRACK_DECLARE_TRACKER(hatire, TrackerControls, TrackerDll) diff --git a/tracker-hatire/ftnoir_tracker_hat.h b/tracker-hatire/ftnoir_tracker_hat.h index 2472428b..4767d291 100644 --- a/tracker-hatire/ftnoir_tracker_hat.h +++ b/tracker-hatire/ftnoir_tracker_hat.h @@ -1,13 +1,10 @@ -#ifndef FTNOIR_TRACKER_HAT_H -#define FTNOIR_TRACKER_HAT_H +#pragma once -#ifdef OPENTRACK_API -# include "opentrack/plugin-support.hpp" -#else -# include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" -#endif +#include "thread.hpp" +#include "opentrack/plugin-support.hpp" #include "ftnoir_tracker_hat_settings.h" #include "ftnoir_arduino_type.h" + #include <QObject> #include <QPalette> #include <QtGui> @@ -15,59 +12,42 @@ #include <QMessageBox> #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> -#include <QMutex> -#include <QMutexLocker> #include <QSettings> -#define VER_FILEVERSION_STR "Version 2.1.1\0" +#define VER_FILEVERSION_STR "Version 2.1.1" -class FTNoIR_Tracker : public QObject, public ITracker +class hatire : public QObject, public ITracker { Q_OBJECT + public: - FTNoIR_Tracker(); - ~FTNoIR_Tracker(); + hatire(); + ~hatire(); -#ifdef OPENTRACK_API void start_tracker(QFrame*); void data(double *data); - int preferredHz(); // unused - void center(); // unused -#else - void Initialize( QFrame *videoframe ); - void StartTracker(HWND parent_window); - void StopTracker(bool exit); - bool GiveHeadPoseData(THeadPoseData *data); - void notifyCenter(); -#endif + //void center(); void applysettings(const TrackerSettings& settings); - bool notifyZeroed(); + //bool notifyZeroed(); void reset(); - void SerialInfo(); - void sendcmd(const QByteArray &cmd); void get_info( int *tps ); - -private Q_SLOTS: - void SerialRead(); - void Log(QString message); - -signals: - void sendMsgInfo(const QByteArray &MsgInfo); - + void serial_info(); + void send_serial_command(const QByteArray& x); private: - QSerialPort *ComPort; - TArduinoData ArduinoData, HAT ; // Trame from Arduino - QByteArray dataRead; - QByteArray dataToSend; + TArduinoData ArduinoData, HAT; QByteArray Begin; QByteArray End; - QMutex mutex; - int frame_cnt; - bool new_frame; + hatire_thread t; + thread_settings ts; + + // XXX move to settings api -sh 20160410 TrackerSettings settings; + int frame_cnt; + bool new_frame; + bool bEnableRoll; bool bEnablePitch; bool bEnableYaw; @@ -81,7 +61,6 @@ private: bool bInvertX; bool bInvertY; bool bInvertZ; - bool bEnableLogging; int iRollAxe; int iPitchAxe; @@ -90,68 +69,11 @@ private: int iYAxe; int iZAxe; - QByteArray sCmdStart; - QByteArray sCmdStop; - QByteArray sCmdInit; - QByteArray sCmdReset; - QByteArray sCmdCenter; - QByteArray sCmdZero; - - int iDelayInit; - int iDelayStart; - int iDelaySeq; - - bool bBigEndian; - - QString sSerialPortName; - QSerialPort::BaudRate iBaudRate; - QSerialPort::DataBits iDataBits; - QSerialPort::Parity iParity; - QSerialPort::StopBits iStopBits; - QSerialPort::FlowControl iFlowControl; - - QFile flDiagnostics; -#ifdef OPENTRACK_API - int iFpsArduino; -#endif - int CptError; - - + volatile int CptError; }; - -//******************************************************************************************************* -// FaceTrackNoIR Tracker DLL. Functions used to get general info on the Tracker -//******************************************************************************************************* -#if defined(OPENTRACK_API) class TrackerDll : public Metadata { QString name() { return QString("Hatire Arduino"); } QIcon icon() { return QIcon(":/images/hat.png"); } }; -#else -class TrackerDll : -public Metadata -public ITrackerDll -{ -public: - TrackerDll(); - ~TrackerDll(); - - void Initialize(); - - QString name(); - QIcon icon(); - void getFullName(QString *strToBeFilled); - void getShortName(QString *strToBeFilled); - void getDescription(QString *strToBeFilled); - void getIcon(QIcon *icon); - -private: - QString trackerFullName; // Trackers' name and description - QString trackerShortName; - QString trackerDescription; -}; -#endif - -#endif // FTNOIR_TRACKER_HAT_H diff --git a/tracker-hatire/ftnoir_tracker_hat_dialog.cpp b/tracker-hatire/ftnoir_tracker_hat_dialog.cpp index 3ef1a764..4ef83fb5 100644 --- a/tracker-hatire/ftnoir_tracker_hat_dialog.cpp +++ b/tracker-hatire/ftnoir_tracker_hat_dialog.cpp @@ -13,13 +13,6 @@ #include <QScrollBar> -//******************************************************************************************************* -// FaceTrackNoIR Client Settings-dialog. -//******************************************************************************************************* - -// -// Constructor for server-settings-dialog -// TrackerControls::TrackerControls() : theTracker(NULL), settingsDirty(false), timer(this) { @@ -180,7 +173,7 @@ TrackerControls::TrackerControls() : theTracker(NULL), settingsDirty(false), tim connect(ui.QCB_Serial_flowControl, SIGNAL(currentIndexChanged(int)), this,SLOT(set_mod_flowControl(int)) ); connect(ui.btnReset, SIGNAL(clicked()), this, SLOT(doReset())); - connect(ui.btnCenter, SIGNAL(clicked()), this, SLOT(doCenter())); + //connect(ui.btnCenter, SIGNAL(clicked()), this, SLOT(doCenter())); connect(ui.btnZero, SIGNAL(clicked()), this, SLOT(doZero())); connect(ui.btnSend, SIGNAL(clicked()), this, SLOT(doSend())); @@ -209,8 +202,6 @@ void TrackerControls::Initialize(QWidget *parent) { show(); } - - // // Apply online settings to tracker // @@ -220,27 +211,13 @@ void TrackerControls::settings_changed() if (theTracker) theTracker->applysettings(settings); } - -// -// Center asked to ARDUINO -// -void TrackerControls::doCenter() { -#ifdef OPENTRACK_API - if (theTracker) theTracker->center(); -#else - if (theTracker) theTracker->notifyCenter(); -#endif -} - - // // Zero asked to ARDUINO // void TrackerControls::doZero() { - if (theTracker) theTracker->notifyZeroed(); + //if (theTracker) theTracker->notifyZeroed(); } - // // Reset asked to ARDUINO // @@ -253,32 +230,28 @@ void TrackerControls::doReset() { // Serial Info debug // void TrackerControls::doSerialInfo() { - if (theTracker) theTracker->SerialInfo(); + if (theTracker) theTracker->serial_info(); } - // // Send command to ARDUINO // void TrackerControls::doSend() { if (theTracker) { if (!ui.lineSend->text().isEmpty()) { - theTracker->sendcmd(ui.lineSend->text().toLatin1()); + theTracker->send_serial_command(ui.lineSend->text().toLatin1()); } } } - // // Enter on lineSend for send to ARDUINO // void TrackerControls::on_lineSend_returnPressed() { this->doSend(); - } - // // Display FPS of Arduino. // @@ -295,7 +268,6 @@ void TrackerControls::poll_tracker_info() } - void TrackerControls::WriteMsgInfo(const QByteArray &MsgInfo) { QApplication::beep(); @@ -305,14 +277,11 @@ void TrackerControls::WriteMsgInfo(const QByteArray &MsgInfo) bar->setValue(bar->maximum()); } - - void TrackerControls::doSave() { settingsDirty=false; settings.save_ini(); } - // // OK clicked on server-dialog // @@ -358,7 +327,7 @@ void TrackerControls::register_tracker(ITracker *tracker) void TrackerControls::registerTracker(ITracker *tracker) #endif { - theTracker = static_cast<FTNoIR_Tracker*>(tracker); + theTracker = static_cast<hatire*>(tracker); connect(theTracker, SIGNAL(sendMsgInfo(QByteArray)),this , SLOT(WriteMsgInfo(QByteArray))); if (isVisible() && settingsDirty) theTracker->applysettings(settings); diff --git a/tracker-hatire/ftnoir_tracker_hat_dialog.h b/tracker-hatire/ftnoir_tracker_hat_dialog.h index bd225b3e..7be31e37 100644 --- a/tracker-hatire/ftnoir_tracker_hat_dialog.h +++ b/tracker-hatire/ftnoir_tracker_hat_dialog.h @@ -1,11 +1,4 @@ -#ifndef FTNOIR_TRACKER_HAT_DIALOG_H -#define FTNOIR_TRACKER_HAT_DIALOG_H - -#ifdef OPENTRACK_API #include "opentrack/plugin-api.hpp" -#else -#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" -#endif #include "ftnoir_tracker_hat_settings.h" #include "ftnoir_tracker_hat.h" #include "ui_ftnoir_hatcontrols.h" @@ -17,29 +10,19 @@ #include <QMetaType> // Widget that has controls for FTNoIR protocol client-settings. -#ifdef OPENTRACK_API class TrackerControls: public ITrackerDialog - #else -class TrackerControls: public QWidget, public ITrackerDialog - #endif { Q_OBJECT public: explicit TrackerControls(); ~TrackerControls() override; -#ifdef OPENTRACK_API void Initialize(QWidget *parent) ; // unused void register_tracker(ITracker *tracker) override; void unregister_tracker() override; -#else - void Initialize(QWidget *parent) ; - void registerTracker(ITracker *tracker) ; - void unRegisterTracker() ; -#endif private: Ui::UIHATControls ui; - FTNoIR_Tracker *theTracker; + hatire *theTracker; QTime last_time; public slots: @@ -83,9 +66,8 @@ protected slots: void set_DelaySeq(int val) { settings.DelaySeq = val; settings_changed(); } void set_endian(bool val) { settings.BigEndian = val; settings_changed(); } -#ifdef OPENTRACK_API + void set_Fps(int val) { settings.FPSArduino = val; settings_changed(); } -#endif void set_mod_baud(int val) { settings.pBaudRate = static_cast<QSerialPort::BaudRate>(ui.QCB_Serial_baudRate->itemData(val).toInt()) ; settings_changed(); } void set_mod_dataBits(int val) { settings.pDataBits = static_cast<QSerialPort::DataBits>(ui.QCB_Serial_dataBits->itemData(val).toInt()) ; settings_changed(); } @@ -97,7 +79,7 @@ protected slots: void doCancel(); void doSave(); void doReset(); - void doCenter(); + //void doCenter(); void doZero(); void doSend(); void poll_tracker_info(); @@ -112,5 +94,3 @@ protected: private slots: void on_lineSend_returnPressed(); }; - -#endif //FTNOIR_TRACKER_HAT_DIALOG_H diff --git a/tracker-hatire/ftnoir_tracker_hat_settings.cpp b/tracker-hatire/ftnoir_tracker_hat_settings.cpp index df0480a1..02c99e75 100644 --- a/tracker-hatire/ftnoir_tracker_hat_settings.cpp +++ b/tracker-hatire/ftnoir_tracker_hat_settings.cpp @@ -13,18 +13,13 @@ #include <QVariant> #include "ftnoir_tracker_hat_settings.h" -#ifdef OPENTRACK_API #include "opentrack-compat/options.hpp" -#endif + +// XXX TODO move to opentrack settings api -sh 20160410 void TrackerSettings::load_ini() { -#ifndef OPENTRACK_API - QSettings settings(OPENTRACK_ORG); // Registry settings (in HK_USER) - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); -#else QString currentFile = options::group::ini_pathname(); -#endif QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup( "HAT" ); @@ -66,9 +61,8 @@ void TrackerSettings::load_ini() DelayStart=iniFile.value("DelayStart",0).toInt(); DelaySeq=iniFile.value("DelaySeq",0).toInt(); -#ifdef OPENTRACK_API FPSArduino=iniFile.value("FPSArduino",30).toInt(); -#endif + BigEndian=iniFile.value("BigEndian",0).toBool(); @@ -84,12 +78,8 @@ void TrackerSettings::load_ini() void TrackerSettings::save_ini() const { -#ifndef OPENTRACK_API - QSettings settings(OPENTRACK_ORG); // Registry settings (in HK_USER) - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); -#else QString currentFile = options::group::ini_pathname(); -#endif + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "HAT" ); @@ -129,9 +119,8 @@ void TrackerSettings::save_ini() const iniFile.setValue ( "DelayStart",DelayStart); iniFile.setValue ( "DelaySeq",DelaySeq); -#ifdef OPENTRACK_API iniFile.setValue ( "FPSArduino", FPSArduino ); -#endif + iniFile.setValue("BigEndian",BigEndian); iniFile.setValue("BaudRate",pBaudRate); @@ -143,4 +132,3 @@ void TrackerSettings::save_ini() const iniFile.endGroup(); } - diff --git a/tracker-hatire/ftnoir_tracker_hat_settings.h b/tracker-hatire/ftnoir_tracker_hat_settings.h index ade46d54..bed33200 100644 --- a/tracker-hatire/ftnoir_tracker_hat_settings.h +++ b/tracker-hatire/ftnoir_tracker_hat_settings.h @@ -5,12 +5,10 @@ * copyright notice and this permission notice appear in all copies. */ -#ifndef FTNOIR_TRACKER_HAT_SETTINGS_H -#define FTNOIR_TRACKER_HAT_SETTINGS_H +#pragma once #include <QtSerialPort/QSerialPort> -//----------------------------------------------------------------------------- struct TrackerSettings { void load_ini(); @@ -30,7 +28,6 @@ struct TrackerSettings bool InvertY; bool InvertZ; - int RollAxe; int PitchAxe; int YawAxe; @@ -59,10 +56,5 @@ struct TrackerSettings QSerialPort::StopBits pStopBits; QSerialPort::FlowControl pFlowControl; -#ifdef OPENTRACK_API int FPSArduino; -#endif }; - - -#endif //FTNOIR_TRACKER_HAT_SETTINGS_H diff --git a/tracker-hatire/thread.cpp b/tracker-hatire/thread.cpp new file mode 100644 index 00000000..26bdc14d --- /dev/null +++ b/tracker-hatire/thread.cpp @@ -0,0 +1,300 @@ +#include "thread.hpp" +#include "opentrack-compat/sleep.hpp" +#include <utility> + +#include <QTextStream> +#include <QTime> +#include <QDebug> + +#include <cstring> + +void hatire_thread::Log(const QString& message) +{ + // Drop out immediately if logging is off. Yes, there is still some overhead because of passing strings around for no reason. + // that's unfortunate and I'll monitor the impact and see if it needs a more involved fix. + if (!s.bEnableLogging) return; + + Diag flDiagnostics; + + if (flDiagnostics.open(QIODevice::ReadWrite | QIODevice::Append)) + { + QTextStream out(&flDiagnostics); + QString milliSeconds; + milliSeconds = QString("%1").arg(QTime::currentTime().msec(), 3, 10, QChar('0')); + // We have a file + out << QTime::currentTime().toString() << "." << milliSeconds << ": " << message << "\r\n"; + flDiagnostics.close(); + } +} + +void hatire_thread::start(const thread_settings& s_) +{ + s = s_; + com_port.moveToThread(this); +#ifdef HATIRE_DEBUG_LOGFILE + read_timer.moveToThread(this); +#endif + QThread::start(); +} + +hatire_thread::~hatire_thread() +{ + quit(); + wait(); +} + +thread_settings hatire_thread::serial_settings_impl() +{ + return s; +} + +hatire_thread::hatire_thread() +{ + data_read.reserve(65536); + + connect(this, &QThread::finished, this, &hatire_thread::teardown_serial); + connect(this, &hatire_thread::update_serial_settings, this, &hatire_thread::update_serial_settings_impl, Qt::QueuedConnection); + connect(this, &hatire_thread::init_serial_port, this, &hatire_thread::init_serial_port_impl, Qt::QueuedConnection); + connect(this, &hatire_thread::serial_info, this, &hatire_thread::serial_info_impl, Qt::QueuedConnection); + connect(this, &hatire_thread::sendcmd, this, &hatire_thread::sendcmd_impl, Qt::QueuedConnection); + connect(this, &hatire_thread::serial_settings, this, &hatire_thread::serial_settings_impl, Qt::QueuedConnection); +} + +void hatire_thread::teardown_serial() +{ + if (isRunning() && com_port.isOpen()) + { + QByteArray msg; + Log("Tracker shut down"); + com_port.write(s.sCmdStop); + if (!com_port.waitForBytesWritten(1000)) + { + emit serial_debug_info("TimeOut in writing CMD"); + } + else + { + msg.append("\r\n"); + msg.append("SEND '"); + msg.append(s.sCmdStop); + msg.append("'\r\n"); + } + emit serial_debug_info(msg); + + disconnect(&com_port, SIGNAL(readyRead()), nullptr, nullptr); + com_port.close(); + } +} + +void hatire_thread::run() +{ +#ifdef HATIRE_DEBUG_LOGFILE + com_port.setFileName(HATIRE_DEBUG_LOGFILE); + com_port.open(QIODevice::ReadOnly); + + connect(&read_timer, &QTimer::timeout, this, &hatire_thread::on_serial_read, Qt::DirectConnection); + read_timer.start(16); +#else + connect(&com_port, &serial_t::readyRead, this, &hatire_thread::on_serial_read, Qt::DirectConnection); +#endif + (void) exec(); +} + +void hatire_thread::update_serial_settings_impl(const thread_settings &s_) +{ + s = s_; +} + +serial_result hatire_thread::init_serial_port_impl() +{ +#ifndef HATIRE_DEBUG_LOGFILE + com_port.setPortName(s.sSerialPortName); + + if (com_port.open(QIODevice::ReadWrite)) + { + Log("Port Open"); + if ( + com_port.setBaudRate((QSerialPort::BaudRate)s.iBaudRate) + && com_port.setDataBits((QSerialPort::DataBits)s.iDataBits) + && com_port.setParity((QSerialPort::Parity)s.iParity) + && com_port.setStopBits((QSerialPort::StopBits)s.iStopBits) + && com_port.setFlowControl((QSerialPort::FlowControl)s.iFlowControl) + && com_port.clear(QSerialPort::AllDirections) + && com_port.setDataErrorPolicy(QSerialPort::IgnorePolicy) + ) + { + Log("Port Parameters set"); + qDebug() << QTime::currentTime() << " HAT OPEN on " << com_port.portName() << com_port.baudRate() << com_port.dataBits() << com_port.parity() << com_port.stopBits() << com_port.flowControl(); + + if (com_port.flowControl() == QSerialPort::HardwareControl) + { + // Raise DTR + Log("Raising DTR"); + if (!com_port.setDataTerminalReady(true)) + Log("Couldn't set DTR"); + + // Raise RTS/CTS + Log("Raising RTS"); + if (!com_port.setRequestToSend(true)) + Log("Couldn't set RTS"); + } + // Wait init arduino sequence + for (int i = 1; i <=s.iDelayInit; i+=50) { + if (com_port.waitForReadyRead(50)) break; + } + Log("Waiting on init"); + qDebug() << QTime::currentTime() << " HAT send INIT "; + sendcmd(s.sCmdInit); + // Wait init MPU sequence + for (int i = 1; i <=s.iDelayStart; i+=50) { + if (com_port.waitForReadyRead(50)) break; + } + // Send START cmd to IMU + qDebug() << QTime::currentTime() << " HAT send START "; + sendcmd(s.sCmdStart); + + // Wait start MPU sequence + for (int i = 1; i <=s.iDelaySeq; i+=50) { + if (com_port.waitForReadyRead(50)) break; + } + Log("Port setup, waiting for HAT frames to process"); + qDebug() << QTime::currentTime() << " HAT wait MPU "; + + return serial_result(); + } + else + { + return serial_result(result_error, com_port.errorString()); + } + } + else + return serial_result(result_open_error, com_port.errorString()); +#else + return serial_result(); +#endif +} + +// Info SerialPort +void hatire_thread::serial_info_impl() +{ +#ifndef HATIRE_DEBUG_LOGFILE + QByteArray msg; + + if (com_port.isOpen()) + { + msg.append("\r\n"); + msg.append(com_port.portName()); + msg.append("\r\n"); + msg.append("BAUDRATE :"); + msg.append(QString::number(com_port.baudRate())); + msg.append("\r\n"); + msg.append("DataBits :"); + msg.append(QString::number(com_port.dataBits())); + msg.append("\r\n"); + msg.append("Parity :"); + + switch (com_port.parity()) + { + case 0: msg.append("No parity"); + break; + case 2: msg.append("Even parity"); + break; + case 3: msg.append("Odd parity"); + break; + case 4: msg.append("Space parity"); + break; + case 5: msg.append("Mark parity"); + break; + default: msg.append("Unknown parity"); + break; + } + + msg.append("\r\n"); + msg.append("Stop Bits :"); + + switch (com_port.stopBits()) + { + msg.append(QString::number(com_port.stopBits())); + case 1: msg.append("1 stop bit."); + break; + case 2: msg.append("2 stop bits."); + break; + case 3: msg.append("1.5 stop bits."); + break; + default: msg.append("Unknown number of stop bit."); + break; + } + + msg.append("\r\n"); + msg.append("Flow Control :"); + switch (com_port.flowControl()) + { + case 0: msg.append("No flow control"); + break; + case 1: msg.append("Hardware flow control (RTS/CTS)"); + break; + case 2: msg.append("Software flow control (XON/XOFF)"); + break; + default: msg.append("Unknown flow control"); + break; + } + + emit serial_debug_info(msg); + } +#endif +} + +#ifdef __GNUC__ +# define unused(t, i) t __attribute__((unused)) i +#else +# define unused(t, i) t i +#endif + +//send command to Arduino + + +void hatire_thread::on_serial_read() +{ + static constexpr int ms = 1000/60; + + { + QMutexLocker lck(&data_mtx); +#ifndef HATIRE_DEBUG_LOGFILE + data_read += com_port.readAll(); +#else + QByteArray tmp = com_port.read(30); + data_read += tmp; + if (tmp.length() == 0) + { + qDebug() << "eof"; + read_timer.stop(); + } +#endif + } + // qt can fire QSerialPort::readyRead() needlessly, causing a busy loop. + // see https://github.com/opentrack/opentrack/issues/327#issuecomment-207941003 + portable::sleep(ms); +} + +void hatire_thread::prepend_unread_data(const QByteArray &data) +{ + QMutexLocker lck(&data_mtx); + data_read.prepend(data); +} + +QByteArray hatire_thread::flush_data_read() +{ + QMutexLocker lck(&data_mtx); + + constexpr int packet_len = 30; + + if (data_read.length() < 4 * packet_len) + { + // we're requesting more than packet length to help resync the stream if needed + return QByteArray(); + } + + QByteArray ret = data_read.left(90); + data_read = data_read.mid(90); + + return ret; +} diff --git a/tracker-hatire/thread.hpp b/tracker-hatire/thread.hpp new file mode 100644 index 00000000..dd0d8c14 --- /dev/null +++ b/tracker-hatire/thread.hpp @@ -0,0 +1,167 @@ +#pragma once + +#include <QSerialPort> +#include <QByteArray> +#include <QThread> +#include <QMutex> + +#include <QFile> +#include <QCoreApplication> + +enum results +{ + result_ok, + result_open_error, + result_error, +}; + +//#define HATIRE_DEBUG_LOGFILE "d:/putty-hatire.log" + +#ifdef HATIRE_DEBUG_LOGFILE +# include <QFile> +# include <QTimer> +#endif + +struct thread_settings +{ + QByteArray sCmdStart; + QByteArray sCmdStop; + QByteArray sCmdInit; + QByteArray sCmdReset; + QByteArray sCmdCenter; + QByteArray sCmdZero; + + QString sSerialPortName; + QSerialPort::BaudRate iBaudRate; + QSerialPort::DataBits iDataBits; + QSerialPort::Parity iParity; + QSerialPort::StopBits iStopBits; + QSerialPort::FlowControl iFlowControl; + + int iDelayInit; + int iDelayStart; + int iDelaySeq; + bool bBigEndian; + volatile bool bEnableLogging; + + thread_settings() : + iBaudRate(QSerialPort::UnknownBaud), + iDataBits(QSerialPort::UnknownDataBits), + iParity(QSerialPort::UnknownParity), + iStopBits(QSerialPort::UnknownStopBits), + iFlowControl(QSerialPort::UnknownFlowControl), + iDelayInit(0), + iDelayStart(0), + iDelaySeq(0), + bBigEndian(false), + bEnableLogging(false) + { + } +}; + +#include <QMetaType> + +Q_DECLARE_METATYPE(thread_settings) + +struct serial_result +{ + serial_result() : code(result_ok) {} + serial_result(results code, const QString& error) : error(error), code(code) {} + + QString error; + results code; +}; + +struct Diag : public QFile +{ + Diag() + { + setFileName(QCoreApplication::applicationDirPath() + "/HATDiagnostics.txt"); + } +}; + +class hatire_thread : public QThread +{ + Q_OBJECT + +#ifdef HATIRE_DEBUG_LOGFILE + using serial_t = QFile; + QTimer read_timer; +#else + using serial_t = QSerialPort; +#endif + + QByteArray data_read; + serial_t com_port; + thread_settings s; + QMutex data_mtx; + + void run() override; + +private slots: + void on_serial_read(); + void teardown_serial(); + + void sendcmd_impl(const QByteArray& cmd) + { +#ifndef HATIRE_DEBUG_LOGFILE + QByteArray Msg; + + if (cmd.length() > 0) + { + if (com_port.isOpen()) + { + QString logMess; + logMess.append("SEND '"); + logMess.append(cmd); + logMess.append("'"); + Log(logMess); + com_port.write(cmd); + if (!com_port.waitForBytesWritten(1000)) { + emit serial_debug_info("TimeOut in writing CMD"); + } else + { + Msg.append("\r\n"); + Msg.append("SEND '"); + Msg.append(cmd); + Msg.append("'\r\n"); + } +#if 0 // WaitForReadyRead isn't working well and there are some reports of it being a win32 issue. We can live without it anyway + if ( !com_port.waitForReadyRead(1000)) { + emit serial_debug_info("TimeOut in response to CMD") ; + } else { + emit serial_debug_info(Msg); + } +#else + emit serial_debug_info(Msg); +#endif + } else { + emit serial_debug_info("ComPort not open") ; + } + } +#endif + } + void serial_info_impl(); + serial_result init_serial_port_impl(); + void update_serial_settings_impl(const thread_settings& s); + thread_settings serial_settings_impl(); + +signals: + void serial_debug_info(const QByteArray &MsgInfo); + + void sendcmd(const QByteArray& cmd); + void serial_info(); + serial_result init_serial_port(); + void update_serial_settings(const thread_settings& s); + thread_settings serial_settings(); + +public: + void start(const thread_settings &s_); + ~hatire_thread() override; + hatire_thread(); + + void prepend_unread_data(const QByteArray& data); + + QByteArray flush_data_read(); + void Log(const QString& message); +}; |