From aa066bdd4622d4f6824fee864f6be6806813f04d Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Fri, 30 Oct 2015 07:37:41 +0100 Subject: move to subdirectory-based build system Closes #224 --- tracker-hatire/CMakeLists.txt | 5 + tracker-hatire/ftnoir_arduino_type.h | 32 + tracker-hatire/ftnoir_hat.qrc | 7 + tracker-hatire/ftnoir_hatcontrols.ui | 1253 ++++++++++++++++++++++++ tracker-hatire/ftnoir_tracker_hat.cpp | 597 +++++++++++ tracker-hatire/ftnoir_tracker_hat.h | 157 +++ tracker-hatire/ftnoir_tracker_hat_dialog.cpp | 411 ++++++++ tracker-hatire/ftnoir_tracker_hat_dialog.h | 116 +++ tracker-hatire/ftnoir_tracker_hat_settings.cpp | 146 +++ tracker-hatire/ftnoir_tracker_hat_settings.h | 68 ++ tracker-hatire/images/hat.ico | Bin 0 -> 1150 bytes tracker-hatire/images/hat.png | Bin 0 -> 249 bytes tracker-hatire/images/hat_logo.png | Bin 0 -> 15210 bytes 13 files changed, 2792 insertions(+) create mode 100644 tracker-hatire/CMakeLists.txt create mode 100644 tracker-hatire/ftnoir_arduino_type.h create mode 100644 tracker-hatire/ftnoir_hat.qrc create mode 100644 tracker-hatire/ftnoir_hatcontrols.ui create mode 100644 tracker-hatire/ftnoir_tracker_hat.cpp create mode 100644 tracker-hatire/ftnoir_tracker_hat.h create mode 100644 tracker-hatire/ftnoir_tracker_hat_dialog.cpp create mode 100644 tracker-hatire/ftnoir_tracker_hat_dialog.h create mode 100644 tracker-hatire/ftnoir_tracker_hat_settings.cpp create mode 100644 tracker-hatire/ftnoir_tracker_hat_settings.h create mode 100644 tracker-hatire/images/hat.ico create mode 100644 tracker-hatire/images/hat.png create mode 100644 tracker-hatire/images/hat_logo.png (limited to 'tracker-hatire') diff --git a/tracker-hatire/CMakeLists.txt b/tracker-hatire/CMakeLists.txt new file mode 100644 index 00000000..e4c7b9d1 --- /dev/null +++ b/tracker-hatire/CMakeLists.txt @@ -0,0 +1,5 @@ +if(Qt5SerialPort_FOUND) + opentrack_boilerplate(opentrack-tracker-hatire) + target_link_libraries(opentrack-tracker-hatire ${Qt5SerialPort_LIBRARIES}) + target_include_directories(opentrack-tracker-hatire SYSTEM PUBLIC ${Qt5SerialPort_INCLUDE_DIRS}) +endif() diff --git a/tracker-hatire/ftnoir_arduino_type.h b/tracker-hatire/ftnoir_arduino_type.h new file mode 100644 index 00000000..57afed63 --- /dev/null +++ b/tracker-hatire/ftnoir_arduino_type.h @@ -0,0 +1,32 @@ +#ifndef FTNOIR_TARDUINO_TYPE_H +#define FTNOIR_TARDUINO_TYPE_H + +#include + +// Arduino trame structure +#pragma pack(push,2) +struct TArduinoData +{ + quint16 Begin; // Header trame 0xAAAA; + quint16 Code; // 0->999 Num Trame >=2000 Info >=3000 Init >=5000 Start Command >=9000 Error + float Rot[3]; + float Trans[3]; + quint16 End; // End trame 0x5555; +} ; +#pragma pack(pop) + + +inline QDataStream & operator >> ( QDataStream& in, TArduinoData& out ) +{ + in.setFloatingPointPrecision(QDataStream::SinglePrecision ); + + in >> out.Begin >> out.Code + >> out.Rot[0] >> out.Rot[1] >> out.Rot[2] + >> out.Trans[0] >> out.Trans[1] >> out.Trans[2] + >> out.End; + return in; +} + + + +#endif diff --git a/tracker-hatire/ftnoir_hat.qrc b/tracker-hatire/ftnoir_hat.qrc new file mode 100644 index 00000000..41d43617 --- /dev/null +++ b/tracker-hatire/ftnoir_hat.qrc @@ -0,0 +1,7 @@ + + + images/hat_logo.png + images/hat.ico + images/hat.png + + diff --git a/tracker-hatire/ftnoir_hatcontrols.ui b/tracker-hatire/ftnoir_hatcontrols.ui new file mode 100644 index 00000000..2d347f08 --- /dev/null +++ b/tracker-hatire/ftnoir_hatcontrols.ui @@ -0,0 +1,1253 @@ + + + UIHATControls + + + + 0 + 0 + 370 + 740 + + + + + 0 + 0 + + + + + 65536 + 65536 + + + + Qt::NoContextMenu + + + Head Arduino Tracker settings FaceTrackNoIR + + + + :/images/hat.png:/images/hat.png + + + 1.000000000000000 + + + Qt::LeftToRight + + + false + + + + + + + 0 + 0 + + + + + 80 + 25 + + + + + 80 + 25 + + + + Cancel + + + + + + + + 0 + 0 + + + + + 80 + 25 + + + + + 80 + 25 + + + + OK + + + + + + + + 0 + 0 + + + + + 65535 + 65535 + + + + 0 + + + + General + + + + + + + + + true + + + + 4 + + + + + + 0 + 0 + + + + + 65536 + 16777215 + + + + Serial port + + + + + + + + 0 + 0 + + + + + 65535 + 16777215 + + + + false + + + QComboBox::AdjustToMinimumContentsLength + + + 0 + + + + + + + + + + false + + + + 80 + 20 + + + + Zero + + + + + + + false + + + + 80 + 20 + + + + Center + + + + + + + false + + + + 80 + 20 + + + + Reset + + + + + + + Axis Configuration + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + Associate Axis + + + + RotX + + + + + RotY + + + + + RotZ + + + + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + Pitch: + + + + + + + Enable + + + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + Yaw: + + + + + + + Invert + + + + + + + Y: + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + X: + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + Associate Axis + + + + X + + + + + Y + + + + + Z + + + + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + Associate Axis + + + + X + + + + + Y + + + + + Z + + + + + + + + Roll: + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + Associate Axis + + + + X + + + + + Y + + + + + Z + + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + Z: + + + + + + + Associate Axis + + + + RotX + + + + + RotY + + + + + RotZ + + + + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + Associate Axis + + + + RotX + + + + + RotY + + + + + RotZ + + + + + + + + Axis + + + + + + + + + + + 0 + 0 + + + + Status + + + false + + + + + + + 31 + 20 + + + + + 60 + 20 + + + + Trame per seconde + + + tps : + + + + + + + + 31 + 20 + + + + + 60 + 20 + + + + 0 + + + Qt::PlainText + + + + + + + + 0 + 20 + + + + + 60 + 20 + + + + Info : + + + + + + + + 170 + 20 + + + + + 60 + 20 + + + + HAT STOPPED + + + Qt::PlainText + + + + + + + + + + + Command + + + + + + Serial Parameters + + + + + + + + + + + + Flow control: + + + + + + + + + + + + + Stop bits: + + + + + + + Parity: + + + + + + + BaudRate: + + + + + + + + + + Data bits: + + + + + + + + + + Arduino Commands + + + + + + Delay Init + + + + + + + Init + + + + + + + Command for Initialising Arduino + + + + + + + Delay Start + + + + + + + Start: + + + + + + + Command for Start send sequence + + + + + + + Delay Sequence + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Delay after Start Command in ms</span></p></body></html> + + + 5000 + + + 50 + + + + + + + Stop: + + + + + + + Command for Stop send sequence + + + + + + + Center: + + + + + + + Command for read Center Gyro arduino + + + + + + + Zero: + + + + + + + Command for reset Center Gyro arduino + + + + + + + Reset: + + + + + + + Command for Reset Arduino + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Little or Big Endian for <span style=" font-family:'Arial,Geneva,Helvetica,sans-serif'; font-size:medium; color:#000000;">the serialization of byte order</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial,Geneva,Helvetica,sans-serif'; font-size:medium; color:#000000;">Arduino is LittleEndian ( unchecked)</span></p></body></html> + + + Endian + + + + + + + + 60 + 16777215 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Delay before Init command in ms</span></p></body></html> + + + 5000 + + + 50 + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Delay after Init command in ms</span></p></body></html> + + + 5000 + + + 50 + + + + + + + + 51 + 19 + + + + <html><head/><body><p>Indicate at OpenTrack speed sketch FPS to adjust CPU </p></body></html> + + + 10 + + + 200 + + + + + + + + + + + About + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">FTNoIR HAT Plugin<br />by FuraX49</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://hatire.sourceforge.net/"><span style=" font-size:8pt; font-weight:600; text-decoration: underline; color:#0000ff;">Manual (external)</span></a></p></body></html> + + + true + + + + + + + false + + + + + + + :/images/hat_logo.png + + + + + 128 + 128 + + + + true + + + + + + + + Arial Black + 10 + 75 + true + true + + + + Version 1.0.0 + + + Qt::PlainText + + + true + + + + + + + + + + + + + + + + + Send + + + + + + + Qt::ActionsContextMenu + + + true + + + + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + 800 + + + false + + + + + + + Disable when not in use, will have a performance impact + + + Enable logging to diagnostic file + + + + + + + + + + + + 80 + 25 + + + + + 80 + 25 + + + + Save + + + + + + + btnOK + btnSave + btnCancel + cbSerialPort + btnZero + btnCenter + btnReset + chkEnableYaw + cb_yaw + chkInvertYaw + chkEnablePitch + cb_pitch + chkInvertPitch + chkEnableRoll + cb_roll + chkInvertRoll + chkEnableX + cb_x + chkInvertX + chkEnableY + cb_y + chkInvertY + chkEnableZ + cb_z + chkInvertZ + spb_BeforeInit + le_cmd_init + spb_BeforeStart + le_cmd_start + spb_AfterStart + le_cmd_stop + le_cmd_center + le_cmd_zero + le_cmd_reset + spb_Fps + cb_Endian + QCB_Serial_baudRate + QCB_Serial_dataBits + QCB_Serial_parity + QCB_Serial_stopBits + QCB_Serial_flowControl + lineSend + btnSend + pteINFO + tabWidget + btn_icone + + + + + + + startEngineClicked() + stopEngineClicked() + cameraSettingsClicked() + + diff --git a/tracker-hatire/ftnoir_tracker_hat.cpp b/tracker-hatire/ftnoir_tracker_hat.cpp new file mode 100644 index 00000000..eea1cbca --- /dev/null +++ b/tracker-hatire/ftnoir_tracker_hat.cpp @@ -0,0 +1,597 @@ +/* Homepage http://facetracknoir.sourceforge.net/home/default.htm * + * * + * ISC License (ISC) * + * * + * Copyright (c) 2015, Wim Vriend * + * * + * Permission to use, copy, modify, and/or distribute this software for any * + * purpose with or without fee is hereby granted, provided that the above * + * copyright notice and this permission notice appear in all copies. * + */ +#include +#include "ftnoir_tracker_hat.h" + +FTNoIR_Tracker::FTNoIR_Tracker() +{ + qDebug()<<"Tracker::HAT"; + + ComPort = NULL; + + HAT.Rot[0]=0; + HAT.Rot[1]=0; + HAT.Rot[2]=0; + HAT.Trans[0]=0; + 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() +{ + 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") ; + } + } +} + + +// return FPS +void FTNoIR_Tracker::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 ) +{ + CptError=0; + dataRead.clear(); + frame_cnt=0; + + Log("INITIALISING HATIRE"); + + 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; +} + + + +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; +} + + +void FTNoIR_Tracker::StopTracker( bool exit ) +{ + 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); +} + + +#else +void FTNoIR_Tracker::start_tracker(QFrame*) +{ + 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; + +} + +//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 +{ + 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 ); + datastream>>ArduinoData; + frame_cnt++; + if (ArduinoData.Code <= 1000) { + HAT=ArduinoData; + new_frame=true; + } else { + emit sendMsgInfo(dataRead.mid(4,24)) ; + } + dataRead.remove(0,30); + } else { + // resynchro trame + int index = dataRead.indexOf(Begin); + if (index==-1) { + index=dataRead.length(); + } + emit sendMsgInfo(dataRead.mid(0,index)) ; + dataRead.remove(0,index); + CptError++; + qDebug() << QTime::currentTime() << " HAT Resync-Frame, counter " << CptError; + } + } + + if (CptError>50) { + emit sendMsgInfo("Can't find HAT frame") ; + CptError=0; +#ifndef OPENTRACK_API + return false; +#endif + } + // 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]; + + } else data[Yaw] =0; + + if (bEnablePitch) { + if (bInvertPitch) data[Pitch] = HAT.Rot[iPitchAxe] * -1.0f; + else data[Pitch] = HAT.Rot[iPitchAxe]; + } else data[Pitch] = 0; + + if (bEnableRoll) { + if (bInvertRoll) data[Roll] = HAT.Rot[iRollAxe] * -1.0f; + else data[Roll] = HAT.Rot[iRollAxe]; + } else data[Roll] =0; + + if (bEnableX) { + if (bInvertX) data[TX] = HAT.Trans[iXAxe]* -1.0f; + else data[TX] = HAT.Trans[iXAxe]; + } else data[TX] =0; + + if (bEnableY) { + if (bInvertY) data[TY] = HAT.Trans[iYAxe]* -1.0f; + else data[TY] = HAT.Trans[iYAxe]; + } else data[TY] =0; + + if (bEnableZ) { + 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]; + } + + 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; + + bEnableRoll = settings.EnableRoll; + bEnablePitch = settings.EnablePitch; + bEnableYaw = settings.EnableYaw; + bEnableX = settings.EnableX; + bEnableY = settings.EnableY; + bEnableZ = settings.EnableZ; + + bInvertRoll = settings.InvertRoll; + bInvertPitch = settings.InvertPitch; + bInvertYaw = settings.InvertYaw; + bInvertX = settings.InvertX; + bInvertY = settings.InvertY; + bInvertZ = settings.InvertZ; + bEnableLogging = settings.EnableLogging; + + iRollAxe= settings.RollAxe; + iPitchAxe= settings.PitchAxe; + iYawAxe= settings.YawAxe; + iXAxe= settings.XAxe; + 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(); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Tracker object. + +// 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 + diff --git a/tracker-hatire/ftnoir_tracker_hat.h b/tracker-hatire/ftnoir_tracker_hat.h new file mode 100644 index 00000000..2472428b --- /dev/null +++ b/tracker-hatire/ftnoir_tracker_hat.h @@ -0,0 +1,157 @@ +#ifndef FTNOIR_TRACKER_HAT_H +#define FTNOIR_TRACKER_HAT_H + +#ifdef OPENTRACK_API +# include "opentrack/plugin-support.hpp" +#else +# include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" +#endif +#include "ftnoir_tracker_hat_settings.h" +#include "ftnoir_arduino_type.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VER_FILEVERSION_STR "Version 2.1.1\0" + +class FTNoIR_Tracker : public QObject, public ITracker +{ + Q_OBJECT +public: + FTNoIR_Tracker(); + ~FTNoIR_Tracker(); + +#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 applysettings(const TrackerSettings& settings); + 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); + + +private: + QSerialPort *ComPort; + TArduinoData ArduinoData, HAT ; // Trame from Arduino + QByteArray dataRead; + QByteArray dataToSend; + QByteArray Begin; + QByteArray End; + QMutex mutex; + int frame_cnt; + bool new_frame; + + TrackerSettings settings; + + bool bEnableRoll; + bool bEnablePitch; + bool bEnableYaw; + bool bEnableX; + bool bEnableY; + bool bEnableZ; + + bool bInvertRoll; + bool bInvertPitch; + bool bInvertYaw; + bool bInvertX; + bool bInvertY; + bool bInvertZ; + bool bEnableLogging; + + int iRollAxe; + int iPitchAxe; + int iYawAxe; + int iXAxe; + 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; + + +}; + + +//******************************************************************************************************* +// 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 new file mode 100644 index 00000000..3ef1a764 --- /dev/null +++ b/tracker-hatire/ftnoir_tracker_hat_dialog.cpp @@ -0,0 +1,411 @@ +/* Homepage http://facetracknoir.sourceforge.net/home/default.htm * + * * + * ISC License (ISC) * + * * + * Copyright (c) 2015, Wim Vriend * + * * + * Permission to use, copy, modify, and/or distribute this software for any * + * purpose with or without fee is hereby granted, provided that the above * + * copyright notice and this permission notice appear in all copies. * + */ +#include "ftnoir_tracker_hat.h" +#include "ftnoir_tracker_hat_dialog.h" + +#include + +//******************************************************************************************************* +// FaceTrackNoIR Client Settings-dialog. +//******************************************************************************************************* + +// +// Constructor for server-settings-dialog +// +TrackerControls::TrackerControls() : theTracker(NULL), settingsDirty(false), timer(this) +{ + + ui.setupUi( this ); + settings.load_ini(); + + ui.label_version->setText(VER_FILEVERSION_STR); + + // make SerialPort list + ui.cbSerialPort->clear(); + foreach (QSerialPortInfo PortInfo , QSerialPortInfo::availablePorts() ) { + ui.cbSerialPort->addItem(PortInfo.portName()); + } + + + // Stop if no SerialPort dispo + if (ui.cbSerialPort->count()<1) { + QMessageBox::critical(this,"Error", "No SerialPort avaible"); + } else { + + int indxport =ui.cbSerialPort->findText(settings.SerialPortName,Qt::MatchExactly ); + if (indxport!=-1) { + ui.cbSerialPort->setCurrentIndex(indxport); + } else { + if (settings.SerialPortName != "") + QMessageBox::warning(this,"Error", "Selected SerialPort modified"); + ui.cbSerialPort-> setCurrentIndex(indxport); + } + } + // Serial config + ui.QCB_Serial_baudRate->clear(); + ui.QCB_Serial_baudRate->addItem(QLatin1String("9600"),QSerialPort::Baud9600); + ui.QCB_Serial_baudRate->addItem(QLatin1String("19200"),QSerialPort::Baud19200); + ui.QCB_Serial_baudRate->addItem(QLatin1String("38400"),QSerialPort::Baud38400); + ui.QCB_Serial_baudRate->addItem(QLatin1String("57600"),QSerialPort:: Baud57600); + ui.QCB_Serial_baudRate->addItem(QLatin1String("115200"),QSerialPort::Baud115200); + ui.QCB_Serial_baudRate->setCurrentIndex(ui.QCB_Serial_baudRate->findData(settings.pBaudRate)); + + ui.QCB_Serial_dataBits->clear(); + ui.QCB_Serial_dataBits->addItem(QLatin1String("5"), QSerialPort::Data5); + ui.QCB_Serial_dataBits->addItem(QLatin1String("6"), QSerialPort::Data6); + ui.QCB_Serial_dataBits->addItem(QLatin1String("7"), QSerialPort::Data7); + ui.QCB_Serial_dataBits->addItem(QLatin1String("8"), QSerialPort::Data8); + ui.QCB_Serial_dataBits->setCurrentIndex(ui.QCB_Serial_dataBits->findData(settings.pDataBits)); + + ui.QCB_Serial_parity->clear(); + ui.QCB_Serial_parity->addItem(QLatin1String("None"), QSerialPort::NoParity); + ui.QCB_Serial_parity->addItem(QLatin1String("Even"), QSerialPort::EvenParity); + ui.QCB_Serial_parity->addItem(QLatin1String("Odd"), QSerialPort::OddParity); + ui.QCB_Serial_parity->addItem(QLatin1String("Space"), QSerialPort::SpaceParity); + ui.QCB_Serial_parity->addItem(QLatin1String("Mark"), QSerialPort::MarkParity); + ui.QCB_Serial_parity->setCurrentIndex(ui.QCB_Serial_parity->findData(settings.pParity)); + + ui.QCB_Serial_stopBits->clear(); + ui.QCB_Serial_stopBits->addItem(QLatin1String("1"), QSerialPort::OneStop); + ui.QCB_Serial_stopBits->addItem(QLatin1String("1.5"), QSerialPort::OneAndHalfStop); + ui.QCB_Serial_stopBits->addItem(QLatin1String("2"), QSerialPort::TwoStop); + ui.QCB_Serial_stopBits->setCurrentIndex(ui.QCB_Serial_stopBits->findData(settings.pStopBits)); + + + ui.QCB_Serial_flowControl->clear(); + ui.QCB_Serial_flowControl->addItem(QLatin1String("None"), QSerialPort::NoFlowControl); + ui.QCB_Serial_flowControl->addItem(QLatin1String("RTS/CTS"), QSerialPort::HardwareControl); + ui.QCB_Serial_flowControl->addItem(QLatin1String("XON/XOFF"), QSerialPort::SoftwareControl); + ui.QCB_Serial_flowControl->setCurrentIndex(ui.QCB_Serial_flowControl->findData(settings.pFlowControl)); + + + ui.chkEnableRoll->setChecked(settings.EnableRoll); + ui.chkEnablePitch->setChecked(settings.EnablePitch); + ui.chkEnableYaw->setChecked(settings.EnableYaw); + ui.chkEnableX->setChecked(settings.EnableX); + ui.chkEnableY->setChecked(settings.EnableY); + ui.chkEnableZ->setChecked(settings.EnableZ); + + ui.chkInvertRoll->setChecked(settings.InvertRoll); + ui.chkInvertPitch->setChecked(settings.InvertPitch); + ui.chkInvertYaw->setChecked(settings.InvertYaw); + ui.chkInvertX->setChecked(settings.InvertX); + ui.chkInvertY->setChecked(settings.InvertY); + ui.chkInvertZ->setChecked(settings.InvertZ); + + ui.chkEnableLogging->setChecked(settings.EnableLogging); + + + ui.cb_roll->setCurrentIndex(settings.RollAxe); + ui.cb_pitch->setCurrentIndex(settings.PitchAxe); + ui.cb_yaw->setCurrentIndex(settings.YawAxe); + ui.cb_x->setCurrentIndex(settings.XAxe); + ui.cb_y->setCurrentIndex(settings.YAxe); + ui.cb_z->setCurrentIndex(settings.ZAxe); + + ui.le_cmd_start->setText(settings.CmdStart); + ui.le_cmd_stop->setText(settings.CmdStop); + ui.le_cmd_init->setText(settings.CmdInit); + ui.le_cmd_reset->setText(settings.CmdReset); + ui.le_cmd_center->setText(settings.CmdCenter); + ui.le_cmd_zero->setText(settings.CmdZero); + + ui.spb_BeforeInit->setValue(settings.DelayInit); + ui.spb_BeforeStart->setValue(settings.DelayStart); + ui.spb_AfterStart->setValue(settings.DelaySeq); + + ui.cb_Endian->setChecked(settings.BigEndian); + +#ifdef OPENTRACK_API + ui.spb_Fps->setValue(settings.FPSArduino); + connect(ui.spb_Fps, SIGNAL(valueChanged ( int )), this,SLOT(set_Fps(int))); +#endif + + // Connect Qt signals to member-functions + connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); + connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + connect(ui.btnSave, SIGNAL(clicked()), this, SLOT(doSave())); + + + connect(ui.cbSerialPort, SIGNAL(currentIndexChanged(QString)), this,SLOT(set_mod_port(QString)) ); + + connect( ui.chkEnableRoll,SIGNAL(toggled(bool)), this,SLOT(set_ena_roll(bool)) ); + connect( ui.chkEnablePitch,SIGNAL(toggled(bool)), this,SLOT(set_ena_pitch(bool)) ); + connect( ui.chkEnableYaw,SIGNAL(toggled(bool)), this,SLOT(set_ena_yaw(bool)) ); + connect( ui.chkEnableX,SIGNAL(toggled(bool)), this,SLOT(set_ena_x(bool)) ); + connect( ui.chkEnableY,SIGNAL(toggled(bool)), this,SLOT(set_ena_y(bool)) ); + connect( ui.chkEnableZ,SIGNAL(toggled(bool)), this,SLOT(set_ena_z(bool)) ); + + connect( ui.chkInvertRoll,SIGNAL(toggled(bool)), this,SLOT(set_inv_roll(bool)) ); + connect( ui.chkInvertPitch,SIGNAL(toggled(bool)), this,SLOT(set_inv_pitch(bool)) ); + connect( ui.chkInvertYaw,SIGNAL(toggled(bool)), this,SLOT(set_inv_yaw(bool)) ); + connect( ui.chkInvertX,SIGNAL(toggled(bool)), this,SLOT(set_inv_x(bool)) ); + connect( ui.chkInvertY,SIGNAL(toggled(bool)), this,SLOT(set_inv_y(bool)) ); + connect( ui.chkInvertZ,SIGNAL(toggled(bool)), this,SLOT(set_inv_z(bool)) ); + connect( ui.chkEnableLogging,SIGNAL(toggled(bool)), this,SLOT(set_diag_logging(bool)) ); + + connect(ui.cb_roll, SIGNAL(currentIndexChanged(int)), this,SLOT(set_rot_roll(int))); + connect(ui.cb_pitch, SIGNAL(currentIndexChanged(int)),this,SLOT(set_rot_pitch(int))); + connect(ui.cb_yaw, SIGNAL(currentIndexChanged(int)), this,SLOT(set_rot_yaw(int))); + connect(ui.cb_x, SIGNAL(currentIndexChanged(int)), this,SLOT(set_acc_x(int))); + connect(ui.cb_y, SIGNAL(currentIndexChanged(int)), this,SLOT(set_acc_y(int))); + connect(ui.cb_z, SIGNAL(currentIndexChanged(int)), this,SLOT(set_acc_z(int))); + + connect(ui.le_cmd_start, SIGNAL(textEdited (QString )), this,SLOT(set_cmd_start(QString))); + connect(ui.le_cmd_stop, SIGNAL(textEdited ( QString )), this,SLOT(set_cmd_stop(QString))); + connect(ui.le_cmd_init, SIGNAL(textChanged ( QString )), this,SLOT(set_cmd_init(QString))); + connect(ui.le_cmd_reset, SIGNAL(textChanged ( QString )), this,SLOT(set_cmd_reset(QString))); + connect(ui.le_cmd_center, SIGNAL(textChanged ( QString )),this,SLOT(set_cmd_center(QString))); + connect(ui.le_cmd_zero, SIGNAL(textChanged ( QString )),this,SLOT(set_cmd_zero(QString))); + + connect(ui.spb_BeforeInit, SIGNAL(valueChanged ( int )), this,SLOT(set_DelayInit(int))); + connect(ui.spb_BeforeStart, SIGNAL(valueChanged ( int )), this,SLOT(set_DelayStart(int))); + connect(ui.spb_AfterStart, SIGNAL(valueChanged ( int )), this,SLOT(set_DelaySeq(int))); + + connect( ui.cb_Endian,SIGNAL(toggled(bool)), this,SLOT(set_endian(bool)) ); + + + connect(ui.QCB_Serial_baudRate, SIGNAL(currentIndexChanged(int)), this,SLOT(set_mod_baud(int)) ); + connect(ui.QCB_Serial_dataBits, SIGNAL(currentIndexChanged(int)), this,SLOT(set_mod_dataBits(int)) ); + connect(ui.QCB_Serial_parity, SIGNAL(currentIndexChanged(int)), this,SLOT(set_mod_parity(int)) ); + connect(ui.QCB_Serial_stopBits, SIGNAL(currentIndexChanged(int)), this,SLOT(set_mod_stopBits(int)) ); + 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.btnZero, SIGNAL(clicked()), this, SLOT(doZero())); + connect(ui.btnSend, SIGNAL(clicked()), this, SLOT(doSend())); + + connect(ui.btn_icone, SIGNAL(clicked()), this, SLOT(doSerialInfo())); + + connect(&timer,SIGNAL(timeout()), this,SLOT(poll_tracker_info())); + + // can't connect slot, keyPressEvent takes QKeyPressEvent as argument + //connect(ui.lineSend,SIGNAL(keyPressEvent),this,SLOT(on_lineSend_returnPressed()) ); +} + +// +// Destructor for server-dialog +// +TrackerControls::~TrackerControls() { +} + +// +// Initialize tracker-client-dialog +// +void TrackerControls::Initialize(QWidget *parent) { + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + + + +// +// Apply online settings to tracker +// +void TrackerControls::settings_changed() +{ + settingsDirty = true; + 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(); +} + + +// +// Reset asked to ARDUINO +// +void TrackerControls::doReset() { + if (theTracker) theTracker->reset(); +} + + +// +// Serial Info debug +// +void TrackerControls::doSerialInfo() { + if (theTracker) theTracker->SerialInfo(); +} + + +// +// Send command to ARDUINO +// +void TrackerControls::doSend() { + if (theTracker) { + if (!ui.lineSend->text().isEmpty()) { + theTracker->sendcmd(ui.lineSend->text().toLatin1()); + } + } +} + + +// +// Enter on lineSend for send to ARDUINO +// +void TrackerControls::on_lineSend_returnPressed() +{ + this->doSend(); + +} + + +// +// Display FPS of Arduino. +// +void TrackerControls::poll_tracker_info() +{ + if (theTracker) + { + int nb_trame; + + theTracker->get_info(&nb_trame); + ui.lab_vtps->setText(QString::number(nb_trame*(1000/last_time.elapsed()))); + last_time.restart(); + } + +} + + +void TrackerControls::WriteMsgInfo(const QByteArray &MsgInfo) +{ + QApplication::beep(); + ui.pteINFO->moveCursor(QTextCursor::End); + ui.pteINFO->insertPlainText(QString(MsgInfo)); + QScrollBar *bar = ui.pteINFO->verticalScrollBar(); + bar->setValue(bar->maximum()); +} + + + +void TrackerControls::doSave() { + settingsDirty=false; + settings.save_ini(); +} + + +// +// OK clicked on server-dialog +// +void TrackerControls::doOK() { + settingsDirty=false; + settings.save_ini(); + this->close(); +} + +// +// Cancel clicked on server-dialog +// +void TrackerControls::doCancel() { + // + // Ask if changed Settings should be saved + // + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + switch (ret) { + case QMessageBox::Save: + settings.save_ini(); + close(); + break; + case QMessageBox::Discard: + close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + close(); + } +} + +#ifdef OPENTRACK_API +void TrackerControls::register_tracker(ITracker *tracker) +#else +void TrackerControls::registerTracker(ITracker *tracker) +#endif +{ + theTracker = static_cast(tracker); + connect(theTracker, SIGNAL(sendMsgInfo(QByteArray)),this , SLOT(WriteMsgInfo(QByteArray))); + + if (isVisible() && settingsDirty) theTracker->applysettings(settings); + + ui.cbSerialPort->setEnabled(false); + ui.btnZero->setEnabled(true); + ui.btnCenter->setEnabled(true); + ui.btnReset->setEnabled(true); + ui.pteINFO->clear(); + ui.lab_vstatus->setText("HAT START"); + last_time.start(); + timer.start(250); + +} + +#ifdef OPENTRACK_API +void TrackerControls::unregister_tracker() +#else +void TrackerControls::unRegisterTracker() +#endif +{ + timer.stop(); + theTracker=NULL; + ui.cbSerialPort->setEnabled(true); + ui.btnZero->setEnabled(false); + ui.btnCenter->setEnabled(false); + ui.btnReset->setEnabled(false); + ui.lab_vstatus->setText("HAT STOPPED"); + ui.lab_vtps->setText(""); +} + + + + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Tracker-settings dialog object. + +// Export both decorated and undecorated names. +// GetTrackerDialog - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetTrackerDialog@0 - Common name decoration for __stdcall functions in C language. +#ifdef OPENTRACK_API +#else +#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0") +FTNOIR_TRACKER_BASE_EXPORT ITrackerDialogPtr __stdcall GetTrackerDialog( ) +{ + return new TrackerControls; +} +#endif + diff --git a/tracker-hatire/ftnoir_tracker_hat_dialog.h b/tracker-hatire/ftnoir_tracker_hat_dialog.h new file mode 100644 index 00000000..ebaffc6d --- /dev/null +++ b/tracker-hatire/ftnoir_tracker_hat_dialog.h @@ -0,0 +1,116 @@ +#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" +#include +#include +#include +#include +#include +#include + +// 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); + void unregister_tracker(); +#else + void Initialize(QWidget *parent) ; + void registerTracker(ITracker *tracker) ; + void unRegisterTracker() ; +#endif + +private: + Ui::UIHATControls ui; + FTNoIR_Tracker *theTracker; + QTime last_time; + +public slots: + void WriteMsgInfo(const QByteArray &MsgInfo); + +protected slots: + void set_mod_port(const QString & val) { settings.SerialPortName =val; settings_changed(); } + void set_ena_roll(bool val) { settings.EnableRoll = val; settings_changed(); } + void set_ena_pitch(bool val) { settings.EnablePitch = val; settings_changed(); } + void set_ena_yaw(bool val) { settings.EnableYaw = val; settings_changed(); } + void set_ena_x(bool val) { settings.EnableX = val; settings_changed(); } + void set_ena_y(bool val) { settings.EnableY = val; settings_changed(); } + void set_ena_z(bool val) { settings.EnableZ = val; settings_changed(); } + + void set_inv_roll(bool val) { settings.InvertRoll = val; settings_changed(); } + void set_inv_pitch(bool val) { settings.InvertPitch = val; settings_changed(); } + void set_inv_yaw(bool val) { settings.InvertYaw = val; settings_changed(); } + void set_inv_x(bool val) { settings.InvertX = val; settings_changed(); } + void set_inv_y(bool val) { settings.InvertY = val; settings_changed(); } + void set_inv_z(bool val) { settings.InvertZ = val; settings_changed(); } + + void set_diag_logging(bool val) { settings.EnableLogging = val; settings_changed(); } + + + void set_rot_roll(int val) { settings.RollAxe = val; settings_changed(); } + void set_rot_pitch(int val) { settings.PitchAxe = val; settings_changed(); } + void set_rot_yaw(int val) { settings.YawAxe = val; settings_changed(); } + void set_acc_x(int val) { settings.XAxe = val; settings_changed(); } + void set_acc_y(int val) { settings.YAxe = val; settings_changed(); } + void set_acc_z(int val) { settings.ZAxe = val; settings_changed(); } + + void set_cmd_start(const QString &val) { settings.CmdStart = val; settings_changed(); } + void set_cmd_stop(const QString &val) { settings.CmdStop = val; settings_changed(); } + void set_cmd_init(const QString &val) { settings.CmdInit = val; settings_changed(); } + void set_cmd_reset(const QString &val) { settings.CmdReset = val; settings_changed(); } + void set_cmd_center(const QString &val) { settings.CmdCenter = val; settings_changed(); } + void set_cmd_zero(const QString &val) { settings.CmdZero = val; settings_changed(); } + + void set_DelayInit(int val) { settings.DelayInit = val; settings_changed(); } + void set_DelayStart(int val) { settings.DelayStart = val; settings_changed(); } + 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(ui.QCB_Serial_baudRate->itemData(val).toInt()) ; settings_changed(); } + void set_mod_dataBits(int val) { settings.pDataBits = static_cast(ui.QCB_Serial_dataBits->itemData(val).toInt()) ; settings_changed(); } + void set_mod_parity(int val) { settings.pParity = static_cast(ui.QCB_Serial_parity->itemData(val).toInt()) ; settings_changed(); } + void set_mod_stopBits(int val) { settings.pStopBits = static_cast(ui.QCB_Serial_stopBits->itemData(val).toInt()); settings_changed(); } + void set_mod_flowControl(int val) { settings.pFlowControl = static_cast(ui.QCB_Serial_flowControl->itemData(val).toInt()) ; settings_changed(); } + + void doOK(); + void doCancel(); + void doSave(); + void doReset(); + void doCenter(); + void doZero(); + void doSend(); + void poll_tracker_info(); + void doSerialInfo(); + +protected: + bool settingsDirty; + void settings_changed(); + TrackerSettings settings; + QTimer timer; + +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 new file mode 100644 index 00000000..e6b32047 --- /dev/null +++ b/tracker-hatire/ftnoir_tracker_hat_settings.cpp @@ -0,0 +1,146 @@ +/* Homepage http://facetracknoir.sourceforge.net/home/default.htm * + * * + * ISC License (ISC) * + * * + * Copyright (c) 2015, Wim Vriend * + * * + * Permission to use, copy, modify, and/or distribute this software for any * + * purpose with or without fee is hereby granted, provided that the above * + * copyright notice and this permission notice appear in all copies. * + */ +#include +#include +#include + +#include "ftnoir_tracker_hat_settings.h" +#ifdef OPENTRACK_API +#include "opentrack/options.hpp" +#endif + +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" ); + + SerialPortName=iniFile.value ( "PortName" ).toString(); + + EnableRoll = iniFile.value( "EnableRoll", 1 ).toBool(); + EnablePitch = iniFile.value( "EnablePitch", 1 ).toBool(); + EnableYaw = iniFile.value( "EnableYaw", 1 ).toBool(); + EnableX = iniFile.value( "EnableX", 0 ).toBool(); + EnableY = iniFile.value( "EnableY", 0 ).toBool(); + EnableZ = iniFile.value( "EnableZ", 0 ).toBool(); + EnableLogging = iniFile.value( "EnableLogging", 0).toBool(); + + InvertRoll = iniFile.value( "InvertRoll", 1 ).toBool(); + InvertPitch = iniFile.value( "InvertPitch", 1 ).toBool(); + InvertYaw = iniFile.value( "InvertYaw", 1 ).toBool(); + InvertX = iniFile.value( "InvertX", 0 ).toBool(); + InvertY = iniFile.value( "InvertY", 0 ).toBool(); + InvertZ = iniFile.value( "InvertZ", 0 ).toBool(); + + + RollAxe=iniFile.value("RollAxe",1).toInt(); + PitchAxe=iniFile.value("PitchAxe",2).toInt(); + YawAxe=iniFile.value("YawAxe",0).toInt(); + XAxe=iniFile.value("XAxe",1).toInt(); + YAxe=iniFile.value("YAxe",2).toInt(); + ZAxe=iniFile.value("ZAxe",0).toInt(); + + + CmdStart=iniFile.value ( "CmdStart").toString(); + CmdStop=iniFile.value ( "CmdStop" ).toString(); + CmdInit=iniFile.value ( "CmdInit" ).toString(); + CmdReset=iniFile.value ( "CmdReset" ).toString(); + CmdCenter=iniFile.value ( "CmdCenter" ).toString(); + CmdZero=iniFile.value ( "CmdZero" ).toString(); + + DelayInit=iniFile.value("DelayInit",0).toInt(); + 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(); + + + pBaudRate=static_cast(iniFile.value("BaudRate",QSerialPort::Baud115200).toInt()); + pDataBits=static_cast(iniFile.value("DataBits",QSerialPort::Data8).toInt()); + pParity=static_cast(iniFile.value("Parity",QSerialPort::NoParity).toInt()); + pStopBits=static_cast(iniFile.value("StopBits",QSerialPort::OneStop).toInt()); + pFlowControl=static_cast(iniFile.value("FlowControl",QSerialPort::HardwareControl).toInt()); + + iniFile.endGroup(); +} + +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" ); + + iniFile.setValue ( "PortName",SerialPortName ); + + iniFile.setValue( "EnableRoll", EnableRoll ); + iniFile.setValue( "EnablePitch", EnablePitch ); + iniFile.setValue( "EnableYaw", EnableYaw ); + iniFile.setValue( "EnableX", EnableX ); + iniFile.setValue( "EnableY", EnableY ); + iniFile.setValue( "EnableZ", EnableZ ); + iniFile.setValue( "EnableLogging", EnableLogging ); + + iniFile.setValue( "InvertRoll", InvertRoll ); + iniFile.setValue( "InvertPitch", InvertPitch ); + iniFile.setValue( "InvertYaw", InvertYaw ); + iniFile.setValue( "InvertX", InvertX ); + iniFile.setValue( "InvertY", InvertY ); + iniFile.setValue( "InvertZ", InvertZ ); + + iniFile.setValue ( "RollAxe", RollAxe ); + iniFile.setValue ( "PitchAxe", PitchAxe ); + iniFile.setValue ( "YawAxe",YawAxe ); + iniFile.setValue ( "XAxe", XAxe ); + iniFile.setValue ( "YAxe", YAxe ); + iniFile.setValue ( "ZAxe", ZAxe ); + + iniFile.setValue ( "CmdStart",CmdStart.toLatin1()); + iniFile.setValue ( "CmdStop",CmdStop.toLatin1()); + iniFile.setValue ( "CmdInit",CmdInit.toLatin1()); + iniFile.setValue ( "CmdReset",CmdReset.toLatin1()); + iniFile.setValue ( "CmdCenter",CmdCenter.toLatin1() ); + iniFile.setValue ( "CmdZero",CmdZero.toLatin1() ); + + iniFile.setValue ( "DelayInit",DelayInit); + iniFile.setValue ( "DelayStart",DelayStart); + iniFile.setValue ( "DelaySeq",DelaySeq); + +#ifdef OPENTRACK_API + iniFile.setValue ( "FPSArduino", FPSArduino ); +#endif + iniFile.setValue("BigEndian",BigEndian); + + iniFile.setValue("BaudRate",pBaudRate); + iniFile.setValue("DataBits",pDataBits); + iniFile.setValue("Parity",pParity); + iniFile.setValue("StopBits",pStopBits); + iniFile.setValue("FlowControl",pFlowControl); + + + iniFile.endGroup(); +} + diff --git a/tracker-hatire/ftnoir_tracker_hat_settings.h b/tracker-hatire/ftnoir_tracker_hat_settings.h new file mode 100644 index 00000000..ade46d54 --- /dev/null +++ b/tracker-hatire/ftnoir_tracker_hat_settings.h @@ -0,0 +1,68 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef FTNOIR_TRACKER_HAT_SETTINGS_H +#define FTNOIR_TRACKER_HAT_SETTINGS_H + +#include + +//----------------------------------------------------------------------------- +struct TrackerSettings +{ + void load_ini(); + void save_ini() const; + + bool EnableRoll; + bool EnablePitch; + bool EnableYaw; + bool EnableX; + bool EnableY; + bool EnableZ; + + bool InvertRoll; + bool InvertPitch; + bool InvertYaw; + bool InvertX; + bool InvertY; + bool InvertZ; + + + int RollAxe; + int PitchAxe; + int YawAxe; + int XAxe; + int YAxe; + int ZAxe; + + QString CmdStart; + QString CmdStop; + QString CmdInit; + QString CmdReset; + QString CmdCenter; + QString CmdZero; + + int DelayInit; + int DelayStart; + int DelaySeq; + + bool BigEndian; + bool EnableLogging; + + QString SerialPortName; + QSerialPort::BaudRate pBaudRate; + QSerialPort::DataBits pDataBits; + QSerialPort::Parity pParity; + QSerialPort::StopBits pStopBits; + QSerialPort::FlowControl pFlowControl; + +#ifdef OPENTRACK_API + int FPSArduino; +#endif +}; + + +#endif //FTNOIR_TRACKER_HAT_SETTINGS_H diff --git a/tracker-hatire/images/hat.ico b/tracker-hatire/images/hat.ico new file mode 100644 index 00000000..d8f5aac4 Binary files /dev/null and b/tracker-hatire/images/hat.ico differ diff --git a/tracker-hatire/images/hat.png b/tracker-hatire/images/hat.png new file mode 100644 index 00000000..a5f7852f Binary files /dev/null and b/tracker-hatire/images/hat.png differ diff --git a/tracker-hatire/images/hat_logo.png b/tracker-hatire/images/hat_logo.png new file mode 100644 index 00000000..c3a92b1b Binary files /dev/null and b/tracker-hatire/images/hat_logo.png differ -- cgit v1.2.3