From 5f17327c0d9d5bd2da69139a324434d461519403 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 27 Nov 2013 01:33:53 +0100 Subject: initial import of hatire by Furax49 Signed-off-by: Stanislaw Halik --- CMakeLists.txt | 16 +- facetracknoir/clientfiles/HAT_100/HAT_100.ino | 389 +++++++ facetracknoir/clientfiles/HAT_100/README | 35 + ftnoir_tracker_hatire/ftnoir_arduino_type.h | 31 + ftnoir_tracker_hatire/ftnoir_hat.qrc | 6 + ftnoir_tracker_hatire/ftnoir_hatcontrols.ui | 1066 ++++++++++++++++++++ ftnoir_tracker_hatire/ftnoir_tracker_hat.cpp | 304 ++++++ ftnoir_tracker_hatire/ftnoir_tracker_hat.h | 102 ++ ftnoir_tracker_hatire/ftnoir_tracker_hat.rc | 61 ++ .../ftnoir_tracker_hat_dialog.cpp | 299 ++++++ ftnoir_tracker_hatire/ftnoir_tracker_hat_dialog.h | 78 ++ ftnoir_tracker_hatire/ftnoir_tracker_hat_dll.cpp | 79 ++ .../ftnoir_tracker_hat_settings.cpp | 102 ++ .../ftnoir_tracker_hat_settings.h | 44 + ftnoir_tracker_hatire/images/hat.ico | Bin 0 -> 1150 bytes ftnoir_tracker_hatire/images/hat_logo.png | Bin 0 -> 15210 bytes 16 files changed, 2611 insertions(+), 1 deletion(-) create mode 100644 facetracknoir/clientfiles/HAT_100/HAT_100.ino create mode 100644 facetracknoir/clientfiles/HAT_100/README create mode 100644 ftnoir_tracker_hatire/ftnoir_arduino_type.h create mode 100644 ftnoir_tracker_hatire/ftnoir_hat.qrc create mode 100644 ftnoir_tracker_hatire/ftnoir_hatcontrols.ui create mode 100644 ftnoir_tracker_hatire/ftnoir_tracker_hat.cpp create mode 100644 ftnoir_tracker_hatire/ftnoir_tracker_hat.h create mode 100644 ftnoir_tracker_hatire/ftnoir_tracker_hat.rc create mode 100644 ftnoir_tracker_hatire/ftnoir_tracker_hat_dialog.cpp create mode 100644 ftnoir_tracker_hatire/ftnoir_tracker_hat_dialog.h create mode 100644 ftnoir_tracker_hatire/ftnoir_tracker_hat_dll.cpp create mode 100644 ftnoir_tracker_hatire/ftnoir_tracker_hat_settings.cpp create mode 100644 ftnoir_tracker_hatire/ftnoir_tracker_hat_settings.h create mode 100644 ftnoir_tracker_hatire/images/hat.ico create mode 100644 ftnoir_tracker_hatire/images/hat_logo.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 12c4cee0..307aeac4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ if(MINGW) endif() find_package(OpenCV REQUIRED) - find_package(Qt5 REQUIRED COMPONENTS Core Xml Network Widgets Gui QUIET) + find_package(Qt5 REQUIRED COMPONENTS Core Xml Network Widgets Gui SerialPort QUIET) cmake_policy(SET CMP0020 NEW) include_directories(${Qt5Core_INCLUDE_DIRS} ${Qt5Xml_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS}) add_definitions(${Qt5Core_DEFINITIONS} ${Qt5Xml_DEFINITIONS} ${Qt5Gui_DEFINITIONS} ${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS}) @@ -308,6 +308,13 @@ file(GLOB opentrack-tracker-hydra-rc "ftnoir_tracker_hydra/*.qrc") QT5_WRAP_UI(opentrack-tracker-hydra-uih ${opentrack-tracker-hydra-ui}) QT5_ADD_RESOURCES(opentrack-tracker-hydra-rcc ${opentrack-tracker-hydra-rc}) +file(GLOB opentrack-tracker-hatire-c "ftnoir_tracker_hatire/*.cpp") +file(GLOB opentrack-tracker-hatire-h "ftnoir_tracker_hatire/*.h") +file(GLOB opentrack-tracker-hatire-ui "ftnoir_tracker_hatire/*.ui") +file(GLOB opentrack-tracker-hatire-rc "ftnoir_tracker_hatire/*.qrc") +QT5_WRAP_UI(opentrack-tracker-hatire-uih ${opentrack-tracker-hatire-ui}) +QT5_ADD_RESOURCES(opentrack-tracker-hatire-rcc ${opentrack-tracker-hatire-rc}) + file(GLOB opentrack-csv-c "ftnoir_csv/*.cpp") # compat lib for POSIX/win32 @@ -524,6 +531,13 @@ if(SDK_ARUCO_LIBPATH) endif() endif() +add_library(opentrack-tracker-hatire SHARED ${opentrack-tracker-hatire-c} ${opentrack-tracker-hatire-h} ${opentrack-tracker-hatire-moc} ${opentrack-tracker-hatire-uih} ${opentrack-tracker-hatire-rcc}) +target_link_libraries(opentrack-tracker-hatire ${MY_QT_LIBS} Qt5SerialPort) +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC) + SET_TARGET_PROPERTIES(opentrack-tracker-hatire + PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_SOURCE_DIR}/facetracknoir/posix-version-script.txt") +endif() + if(WIN32) target_link_libraries(opentrack-tracker-ht "${CMAKE_SOURCE_DIR}/dinput/dxguid.lib" diff --git a/facetracknoir/clientfiles/HAT_100/HAT_100.ino b/facetracknoir/clientfiles/HAT_100/HAT_100.ino new file mode 100644 index 00000000..f8644ffe --- /dev/null +++ b/facetracknoir/clientfiles/HAT_100/HAT_100.ino @@ -0,0 +1,389 @@ +// Arduino sketch for MPU6050 on NanoWII using DMP MotionApps v4.1 +// HAT 14/04/2013 by FuraX49 +// +// Head Arduino Tracker for FaceTrackNoIR +// http://facetracknoir.sourceforge.net/home/default.htm +// I2C device class (I2Cdev) +// https://github.com/jrowberg/i2cdevlib + + +#include +#include +#include "I2Cdev.h" +#include "MPU6050_9Axis_MotionApps41.h" + + +MPU6050 mpu; + + +typedef struct { + int16_t Begin ; // 2 Debut + uint16_t Cpt ; // 2 Compteur trame or Code info or error + float gyro[3]; // 12 [Y, P, R] gyro + float acc[3]; // 12 [x, y, z] Acc + int16_t End ; // 2 Fin +} _hatire; + +typedef struct { + int16_t Begin ; // 2 Debut + uint16_t Code ; // 2 Code info + char Msg[24]; // 24 Message + int16_t End ; // 2 Fin +} _msginfo; + +typedef struct +{ + byte rate; + double gyro_offset[3] ; + double acc_offset[3] ; +} _eprom_save; + + +// MPU control/status vars +bool dmpReady = false; // set true if DMP init was successful +bool dmpLoaded = false; // set true if DMP loaded successfuly +uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU +uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) +uint16_t packetSize; // expected DMP packet size (default is 42 bytes) +uint16_t fifoCount; // count of all bytes currently in FIFO +uint8_t fifoBuffer[64]; // FIFO storage buffer + +char Commande; +char Version[] = "HAT V 1.00"; + +// orientation/motion vars +Quaternion q; // [w, x, y, z] quaternion container +VectorInt16 aa; // [x, y, z] accel sensor measurements +VectorFloat gravity; // [x, y, z] gravity vector + +float Rad2Deg = (180/M_PI) ; + +// trame for message +_hatire hatire; +_msginfo msginfo; +_eprom_save eprom_save; + + +bool AskCalibrate = false; // set true when calibrating is ask +int CptCal = 0; +const int NbCal = 5; + + + + +// ================================================================ +// === INTERRUPT DETECTION ROUTINE === +// ================================================================ +volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high + +void dmpDataReady() { + mpuInterrupt = true; +} + +// ================================================================ +// === PRINT SERIAL FORMATTE === +// ================================================================ +void PrintCodeSerial(uint16_t code,char Msg[24],bool EOL ) { + msginfo.Code=code; + memset(msginfo.Msg,0x00,24); + strcpy(msginfo.Msg,Msg); + if (EOL) msginfo.Msg[23]=0x0A; + // Send HATIRE message to PC + Serial.write((byte*)&msginfo,30); +} + + +// ================================================================ +// === INITIAL SETUP === +// ================================================================ + +void setup() { + // join I2C bus (I2Cdev library doesn't do this automatically) + Wire.begin(); + + // initialize serial communication + while (!Serial); // wait for Leonardo enumeration, others continue immediately + + Serial.begin(115200); + PrintCodeSerial(2000,Version,true); + + hatire.Begin=0xAAAA; + hatire.Cpt=0; + hatire.End=0x5555; + + msginfo.Begin=0xAAAA; + msginfo.Code=0; + msginfo.End=0x5555; + + // initialize device + PrintCodeSerial(3001,"Initializing I2C",true); + mpu.initialize(); + + // verify connection + PrintCodeSerial(3002,"Testing connections",true); + + if (mpu.testConnection()){ + PrintCodeSerial(3003,"MPU6050 connection OK",true); + } else { + PrintCodeSerial(9007,"MPU6050 ERRROR CNX",true); + } + + while (Serial.available() && Serial.read()); // empty buffer + + // load and configure the DMP + PrintCodeSerial(3004,"Initializing DMP...",true); + devStatus = mpu.dmpInitialize(); + + // make sure it worked (returns 0 if so) + if (devStatus == 0) { + dmpLoaded=true; + + // Read Epprom saved params + PrintCodeSerial(3005,"Reading saved params...",true); + ReadParams(); + + // turn on the DMP, now that it's ready + PrintCodeSerial(3006,"Enabling DMP...",true); + mpu.setDMPEnabled(true); + + // enable Arduino interrupt detection + PrintCodeSerial(3007,"Enabling interrupt",true); + attachInterrupt(0, dmpDataReady, RISING); + mpuIntStatus = mpu.getIntStatus(); + + // set our DMP Ready flag so the main loop() function knows it's okay to use it + PrintCodeSerial(5000,"HAT BEGIN",true); + dmpReady = true; + // get expected DMP packet size for later comparison + packetSize = mpu.dmpGetFIFOPacketSize(); + // Empty FIFO + fifoCount = mpu.getFIFOCount(); + while (fifoCount > packetSize) { + fifoCount = mpu.getFIFOCount(); + mpu.getFIFOBytes(fifoBuffer, fifoCount); + } + } + else { + // ERROR! + // 1 = initial memory load failed + // 2 = DMP configuration updates failed + // (if it's going to break, usually the code will be 1) + dmpLoaded=false; + PrintCodeSerial(9000+devStatus,"DMP Initialization failed",true); + } +} + + +// ================================================================ +// === RAZ OFFSET === +// ================================================================ +void razoffset() { + eprom_save.gyro_offset[0] = 0; + eprom_save.gyro_offset[1] = 0; + eprom_save.gyro_offset[2] = 0; + eprom_save.acc_offset[0] = 0; + eprom_save.acc_offset[1] = 0; + eprom_save.acc_offset[2] = 0; +} + + +// ================================================================ +// === SAVE PARAMS === +// ================================================================ +void SaveParams() { + eeprom_write_block((const void*)&eprom_save, (void*) 0, sizeof(eprom_save)); +} + + + +// ================================================================ +// === READ PARAMS === +// ================================================================ +void ReadParams() { + eeprom_read_block( (void*)&eprom_save, (void*) 0, sizeof(eprom_save)); +} + + +// ================================================================ +// === Serial Command === +// ================================================================ +void serialEvent(){ + Commande = (char)Serial.read(); + switch (Commande) { + case 'S': + PrintCodeSerial(5001,"HAT START",true); + if (dmpLoaded==true) { + mpu.resetFIFO(); + hatire.Cpt=0; + attachInterrupt(0, dmpDataReady, RISING); + mpu.setDMPEnabled(true); + dmpReady = true; + } + else { + PrintCodeSerial(9011,"Error DMP not loaded",true); + } + break; + + case 's': + PrintCodeSerial(5002,"HAT STOP",true); + if (dmpReady==true) { + mpu.setDMPEnabled(false); + detachInterrupt(0); + dmpReady = false; + } + break; + + case 'R': + PrintCodeSerial(5003,"HAT RESET",true); + if (dmpLoaded==true) { + mpu.setDMPEnabled(false); + detachInterrupt(0); + mpu.resetFIFO(); + hatire.Cpt=0; + dmpReady = false; + setup(); + } + else { + PrintCodeSerial(9011,"Error DMP not loaded",true); + } + break; + + + case 'C': + CptCal=0; + razoffset(); + AskCalibrate=true; + break; + + case 'V': + PrintCodeSerial(2000,Version,true); + break; + + case 'I': + Serial.println(); + Serial.print("Version : \t"); + Serial.println(Version); + Serial.println("Gyroscopes offsets"); + for (int i=0; i <= 2; i++) { + Serial.print(i); + Serial.print(" : "); + Serial.print(eprom_save.gyro_offset[i]); + Serial.println(); + } + Serial.println("Accelerometers offsets"); + for (int i=0; i <= 2; i++) { + Serial.print(i); + Serial.print(" : "); + Serial.print(eprom_save.acc_offset[i]); + Serial.println(); + } + break; + + + default: + break; + } +} + + +// ================================================================ +// === MAIN PROGRAM LOOP === +// ================================================================ +void loop() { + // Leonardo BUG (simul Serial Event) + if(Serial.available() > 0) serialEvent(); + + + // if programming failed, don't try to do anything + if (dmpReady) { + + + while (!mpuInterrupt && fifoCount < packetSize) ; + + // reset interrupt flag and get INT_STATUS byte + mpuInterrupt = false; + mpuIntStatus = mpu.getIntStatus(); + + // get current FIFO count + fifoCount = mpu.getFIFOCount(); + + // check for overflow (this should never happen unless our code is too inefficient) + if ((mpuIntStatus & 0x10) || fifoCount == 1024) { + // reset so we can continue cleanly + mpu.resetFIFO(); + PrintCodeSerial(9010,"Overflow FIFO DMP",true); + hatire.Cpt=0; + + // otherwise, check for DMP data ready interrupt (this should happen frequently) + } + else if (mpuIntStatus & 0x02) { + // wait for correct available data length, should be a VERY short wait + while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); + + // read a packet from FIFO + mpu.getFIFOBytes(fifoBuffer, packetSize); + + // track FIFO count here in case there is > 1 packet available + // (this lets us immediately read more without waiting for an interrupt) + fifoCount -= packetSize; + + // Get Euler angles in degrees + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetYawPitchRoll(hatire.gyro, &q, &gravity); + + // Get real acceleration, adjusted to remove gravity + // not used in this script + // mpu.dmpGetAccel(&aa, fifoBuffer); + // mpu.dmpGetLinearAccel(&hatire.acc, &aa, &gravity); + + // Calibration sur X mesures + if (AskCalibrate) { + if ( CptCal>=NbCal) { + CptCal=0; + eprom_save.gyro_offset[0] = eprom_save.gyro_offset[0] / NbCal ; + eprom_save.gyro_offset[1] = eprom_save.gyro_offset[1] / NbCal ; + eprom_save.gyro_offset[2] = eprom_save.gyro_offset[2] / NbCal ; + AskCalibrate=false; + SaveParams(); + } + else { + eprom_save.gyro_offset[0] += (float) hatire.gyro[0]; + eprom_save.gyro_offset[1] += (float) hatire.gyro[1]; + eprom_save.gyro_offset[2] += (float) hatire.gyro[2]; + + CptCal++; + } + } + + + // Conversion angles Euler en +-180 Degr�es + for (int i=0; i <= 2; i++) { + hatire.gyro[i]= (hatire.gyro[i] - eprom_save.gyro_offset[i] ) * Rad2Deg; + if (hatire.gyro[i]>180) { + hatire.gyro[i] = hatire.gyro[i] - 360; + } + } + + if (AskCalibrate) { + hatire.gyro[0] = 0; + hatire.gyro[1] = 0; + hatire.gyro[2] = 0; + hatire.acc[0]= 0; + hatire.acc[1] = 0; + hatire.acc[2] = 0; + } + + // Send Trame to HATIRE PC + Serial.write((byte*)&hatire,30); + + hatire.Cpt++; + if (hatire.Cpt>999) { + hatire.Cpt=0; + } + } + } + delay(1); +} + + diff --git a/facetracknoir/clientfiles/HAT_100/README b/facetracknoir/clientfiles/HAT_100/README new file mode 100644 index 00000000..1e4f2926 --- /dev/null +++ b/facetracknoir/clientfiles/HAT_100/README @@ -0,0 +1,35 @@ + Frame exchange protocol fixed size of 30 bytes like this : + + typedef struct { + int16_t Begin ; // 2 Debut + uint16_t Cpt ; // 2 Compteur trame or Code + float gyro[3]; // 12 [Y, P, R] gyro + float acc[3]; // 12 [x, y, z] Acc + int16_t End ; // 2 Fin +} _hatire; +_hat hat; + + +void setup() { + Serial.begin(115200); + // header frame + hatire.Begin=0xAAAA; + // Frame Number or Error code + hat.Cpt=0; + // footer frame + hat.End=0x5555; +} + + + void loop() { + mpu.dmpGetYawPitchRoll(hatire.gyro); + mpu.dmpAccXYZ(hatire.acc); + // Send Trame to HATIRE PC + Serial.write((byte*)&hatire,30); + hatire.Cpt++; + if (hatire.Cpt>999) { + hatire.Cpt=0; + } + delay(1); +} + diff --git a/ftnoir_tracker_hatire/ftnoir_arduino_type.h b/ftnoir_tracker_hatire/ftnoir_arduino_type.h new file mode 100644 index 00000000..4d19043b --- /dev/null +++ b/ftnoir_tracker_hatire/ftnoir_arduino_type.h @@ -0,0 +1,31 @@ +#ifndef FTNOIR_TARDUINO_TYPE_H +#define FTNOIR_TARDUINO_TYPE_H + +// 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 Gyro[3]; + float Acc[3]; + quint16 End; // End trame 0x5555; +} ; +#pragma pack(pop) + + +inline QDataStream & operator >> ( QDataStream& in, TArduinoData& out ) +{ + in.setByteOrder(QDataStream::LittleEndian ); + in.setFloatingPointPrecision(QDataStream::SinglePrecision ); + + in >> (quint16)out.Begin >> (quint16)out.Code + >> (float)out.Gyro[0] >> (float)out.Gyro[1] >> (float)out.Gyro[2] + >> (float)out.Acc[0] >> (float)out.Acc[1] >> (float)out.Acc[2] + >> (quint16)out.End; + return in; +} + + + +#endif \ No newline at end of file diff --git a/ftnoir_tracker_hatire/ftnoir_hat.qrc b/ftnoir_tracker_hatire/ftnoir_hat.qrc new file mode 100644 index 00000000..4c606f92 --- /dev/null +++ b/ftnoir_tracker_hatire/ftnoir_hat.qrc @@ -0,0 +1,6 @@ + + + images/hat.ico + images/hat_logo.png + + diff --git a/ftnoir_tracker_hatire/ftnoir_hatcontrols.ui b/ftnoir_tracker_hatire/ftnoir_hatcontrols.ui new file mode 100644 index 00000000..86f9e48a --- /dev/null +++ b/ftnoir_tracker_hatire/ftnoir_hatcontrols.ui @@ -0,0 +1,1066 @@ + + + UIHATControls + + + + 0 + 0 + 370 + 520 + + + + + 370 + 520 + + + + + 370 + 520 + + + + Qt::NoContextMenu + + + Head Arduino Tracker settings FaceTrackNoIR + + + + images/hat.icoimages/hat.ico + + + 1.000000000000000 + + + Qt::LeftToRight + + + false + + + + + 0 + 480 + 361 + 27 + + + + + + + + 0 + 0 + + + + + 80 + 25 + + + + + 80 + 25 + + + + OK + + + + + + + + 80 + 25 + + + + + 80 + 25 + + + + Save + + + + + + + + 0 + 0 + + + + + 80 + 25 + + + + + 80 + 25 + + + + Cancel + + + + + + + + + 0 + 0 + 360 + 470 + + + + + 360 + 470 + + + + + 360 + 470 + + + + 0 + + + true + + + + + :/images/hat.ico:/images/hat.ico + + + General + + + + + 10 + 350 + 331 + 91 + + + + Information + + + + + 10 + 20 + 311 + 51 + + + + + QFormLayout::AllNonFixedFieldsGrow + + + 10 + + + 10 + + + 0 + + + 0 + + + 0 + + + + + + 31 + 0 + + + + + 60 + 13 + + + + Trame per seconde + + + tps : + + + + + + + + 60 + 16777215 + + + + Status : + + + + + + + + 170 + 0 + + + + + 60 + 16777215 + + + + + + + + + + + + 31 + 0 + + + + + 60 + 13 + + + + 00 + + + + + + + + + + 10 + 130 + 331 + 211 + + + + + 0 + 106 + + + + Axis Configuration + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + 10 + 20 + 311 + 181 + + + + + QLayout::SetMinAndMaxSize + + + 0 + + + 0 + + + 6 + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + + + + Associate Axis + + + + RotX + + + + + RotY + + + + + RotZ + + + + + + + + Yaw: + + + + + + + Associate Axis + + + + RotX + + + + + RotY + + + + + RotZ + + + + + + + + Associate Axis + + + + RotX + + + + + RotY + + + + + RotZ + + + + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + Pitch: + + + + + + + Roll: + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + Enable + + + + + + + Axis + + + + + + + Invert + + + + + + + X: + + + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + Associate Axis + + + + X + + + + + Y + + + + + Z + + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + Y: + + + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + Associate Axis + + + + X + + + + + Y + + + + + Z + + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + Z: + + + + + + + + 20 + 16777215 + + + + Enable Axis + + + Qt::LeftToRight + + + + + + + + + + Associate Axis + + + + X + + + + + Y + + + + + Z + + + + + + + + + 20 + 16777215 + + + + Invert Axis + + + Qt::LeftToRight + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 16 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 16 + + + + + + + + + + + 10 + 90 + 331 + 31 + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 13 + 16 + + + + + + + + + 80 + 20 + + + + Center + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 13 + 16 + + + + + + + + + 80 + 20 + + + + Reset + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 13 + 16 + + + + + + + + + + 10 + 10 + 331 + 31 + + + + + + + + 60 + 16777215 + + + + Serial Port : + + + + + + + + 100 + 16777215 + + + + false + + + QComboBox::AdjustToMinimumContentsLength + + + 0 + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 40 + 20 + + + + + + + + + + 10 + 50 + 331 + 31 + + + + + 7 + + + + + Choose the Serial Com port where is connected ARDUINO. + + + true + + + + + + + + + About + + + + + 10 + 20 + 111 + 111 + + + + <!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-weight:600;">FTNoIR HAT Plugin<br />Version 1.0</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">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-weight:600; text-decoration: underline; color:#0000ff;">Manual (external)</span></a></p></body></html> + + + true + + + + + + 200 + 20 + 128 + 128 + + + + + + + :/images/hat_logo.png + + + + + + 10 + 190 + 331 + 251 + + + + true + + + 800 + + + + + + 10 + 160 + 241 + 20 + + + + + + + 260 + 160 + 75 + 23 + + + + Send + + + + + + + btnCancel + + + + + + + startEngineClicked() + stopEngineClicked() + cameraSettingsClicked() + + diff --git a/ftnoir_tracker_hatire/ftnoir_tracker_hat.cpp b/ftnoir_tracker_hatire/ftnoir_tracker_hat.cpp new file mode 100644 index 00000000..e961a10f --- /dev/null +++ b/ftnoir_tracker_hatire/ftnoir_tracker_hat.cpp @@ -0,0 +1,304 @@ +/******************************************************************************** +* FaceTrackNoIR This program is a private project of some enthusiastic * +* gamers from Holland, who don't like to pay much for * +* head-tracking. * +* * +* Copyright (C) 2012 Wim Vriend (Developing) * +* Ron Hendriks (Researching and Testing) * +* * +* Homepage: http://facetracknoir.sourceforge.net/home/default.htm * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the * +* Free Software Foundation; either version 3 of the License, or (at your * +* option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, see . * +* * +********************************************************************************/ + + +#include "ftnoir_tracker_hat.h" +#include +#include +#include + +FTNoIR_Tracker::FTNoIR_Tracker() +{ + SerialPort = NULL; + waitTimeout = 1000; + TrackerSettings settings; + settings.load_ini(); + applysettings(settings); + + + // Create events + m_StopThread = CreateEvent(0, TRUE, FALSE, 0); + m_WaitThread = CreateEvent(0, TRUE, FALSE, 0); + + ListErrInf = new QList(); + + // prepare & reserve QByteArray + datagram.reserve(30); +} + +FTNoIR_Tracker::~FTNoIR_Tracker() +{ + // Trigger thread to stop + ::SetEvent(m_StopThread); + + // Wait until thread finished + if (isRunning()) { + ::WaitForSingleObject(m_WaitThread, INFINITE); + } + + // Close handles + ::CloseHandle(m_StopThread); + ::CloseHandle(m_WaitThread); + + if (SerialPort!=NULL) { + if (SerialPort->isOpen() ) { + SerialPort->putChar('s'); //Send STOP to Arduino + SerialPort->close(); + } + delete SerialPort; + SerialPort=NULL; + } + +} + +//send CENTER to Arduino +void FTNoIR_Tracker::notifyCenter() { + if (SerialPort!=NULL) { + if (SerialPort->isOpen() ) { + SerialPort->putChar('C'); + } + } +} + + + +//send CENTER to Arduino +void FTNoIR_Tracker::center() { + if (SerialPort!=NULL) { + if (SerialPort->isOpen() ) { + SerialPort->putChar('C'); + } + } +} + +//send RESET to Arduino +void FTNoIR_Tracker::reset() { + if (SerialPort!=NULL) { + if (SerialPort->isOpen() ) { + SerialPort->putChar('R'); + } + } +} + +//send command to Arduino +void FTNoIR_Tracker::sendcmd(QString* cmd) { + QReadLocker locker(&rwlock); + QByteArray bytes; + if (SerialPort!=NULL) { + if (SerialPort->isOpen() ) { + bytes.append(cmd->toAscii()); + SerialPort->write(bytes); + } + } +} + +// return FPS and last status +void FTNoIR_Tracker::get_info(QString* info, int* tps ){ + QReadLocker locker(&rwlock); + *tps=HAT.Code; + if (ListErrInf->size()>0) { + *info=ListErrInf->takeFirst(); + } else { + *info= QString(); + } +} + + +/** QThread run @override **/ +void FTNoIR_Tracker::run() { + // + // Read the data that was received. + // + forever { + + // Check event for stop thread + if(::WaitForSingleObject(m_StopThread, 0) == WAIT_OBJECT_0) + { + // Set event + ::SetEvent(m_WaitThread); + qDebug() << "FTNoIR_Tracker::run() terminated run()"; + return; + } + if (SerialPort->bytesAvailable()>=30) { + QWriteLocker locker(&rwlock); + datagram.clear(); + datagram=SerialPort->read(30); + QDataStream datastream(datagram); + datastream>>ArduinoData; + + if (ArduinoData.Begin==0xAAAA && ArduinoData.End==0x5555 ) { + if (ArduinoData.Code <= 1000) { + HAT=ArduinoData; + } else { + ListErrInf->push_back(QString::fromAscii(datagram.mid(4,24),24)) ; + } + } else { + SerialPort->read(1); + } + } + //for lower cpu load + usleep(10000); + } +} + +void FTNoIR_Tracker::Initialize( QFrame *videoframe ) +{ + qDebug() << "FTNoIR_Tracker::Initialize says: Starting "; + + // + // Create SerialPort if they don't exist already. + // They must be created here, because they must be in the new thread (FTNoIR_Tracker::run()) + // + + if (SerialPort == NULL) { + qDebug() << "FTNoIR_Tracker::Initialize() Open SerialPort"; + SerialPort = new QextSerialPort(sSerialPortName); + if (SerialPort->open(QIODevice::ReadWrite | QIODevice::Unbuffered ) == true) { + SerialPort->flush(); + SerialPort->setBaudRate(BAUD115200); + SerialPort->setParity(PAR_NONE); + SerialPort->setDataBits(DATA_8); + SerialPort->setStopBits(STOP_1); + SerialPort->setFlowControl(FLOW_OFF); + SerialPort->setTimeout(waitTimeout); + SerialPort->setQueryMode(QextSerialPort::EventDriven); //Polling + // Send START to arduino + SerialPort->putChar('S'); + } + else { + QMessageBox::warning(0,"FaceTrackNoIR Error", "Unable to open SerialPort",QMessageBox::Ok,QMessageBox::NoButton); + delete SerialPort; + SerialPort = NULL; + } + } + return; +} + +void FTNoIR_Tracker::StartTracker( HWND parent_window ) +{ + start( QThread::TimeCriticalPriority ); + return; +} + +void FTNoIR_Tracker::StopTracker( bool exit ) +{ + // + // OK, the thread is not stopped, doing this. That might be dangerous anyway... + // + if (exit || !exit) return; + return; +} + +// +// Return 6DOF info +// +bool FTNoIR_Tracker::GiveHeadPoseData(THeadPoseData *data) +{ + QReadLocker locker(&rwlock); + data->frame_number = HAT.Code; + + if (bEnableYaw) { + if (bInvertYaw ) data->yaw = HAT.Gyro[iYawAxe] * -1.0f; + else data->yaw = HAT.Gyro[iYawAxe]; + } + + if (bEnablePitch) { + if (bInvertPitch)data->pitch = HAT.Gyro[iPitchAxe] * -1.0f; + else data->pitch = HAT.Gyro[iPitchAxe]; + } + + if (bEnableRoll) { + if (bInvertRoll) data->roll = HAT.Gyro[iRollAxe] * -1.0f; + else data->roll = HAT.Gyro[iRollAxe]; + } + + if (bEnableX) { + if (bInvertX) data->x = HAT.Acc[iXAxe]* -1.0f; + else data->x = HAT.Acc[iXAxe]; + } + + if (bEnableY) { + if (bInvertY) data->y = HAT.Acc[iYAxe]* -1.0f; + else data->y = HAT.Acc[iYAxe]; + } + + if (bEnableZ) { + if (bInvertZ) data->z = HAT.Acc[iZAxe]* -1.0f; + else data->z = HAT.Acc[iZAxe]; + } + + return true; +} + + + +// +// Apply modification Settings +// +void FTNoIR_Tracker::applysettings(const TrackerSettings& settings){ + qDebug()<<"Tracker:: Applying settings"; + + QReadLocker locker(&rwlock); + 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; + + + iRollAxe= settings.RollAxe; + iPitchAxe= settings.PitchAxe; + iYawAxe= settings.YawAxe; + iXAxe= settings.XAxe; + iYAxe= settings.YAxe; + iZAxe= settings.ZAxe; +} + + + + +//////////////////////////////////////////////////////////////////////////////// +// 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. +#pragma comment(linker, "/export:GetTracker=_GetTracker@0") + +FTNOIR_TRACKER_BASE_EXPORT ITrackerPtr __stdcall GetTracker() +{ + return new FTNoIR_Tracker; +} diff --git a/ftnoir_tracker_hatire/ftnoir_tracker_hat.h b/ftnoir_tracker_hatire/ftnoir_tracker_hat.h new file mode 100644 index 00000000..54e67f48 --- /dev/null +++ b/ftnoir_tracker_hatire/ftnoir_tracker_hat.h @@ -0,0 +1,102 @@ +#ifndef FTNOIR_TRACKER_HAT_H +#define FTNOIR_TRACKER_HAT_H + +#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" +#include "ftnoir_tracker_hat_settings.h" +#include "ftnoir_arduino_type.h" + +#include +#include +#include +#include +#include +#include +#include "Windows.h" +#include "math.h" + +class QextSerialPort; +class QExtSerialEnumerator; + +class FTNoIR_Tracker : public ITracker, QThread +{ + +public: + FTNoIR_Tracker(); + ~FTNoIR_Tracker(); + + void Initialize( QFrame *videoframe ); + void StartTracker( HWND parent_window ); + void StopTracker( bool exit ); + bool GiveHeadPoseData(THeadPoseData *data); + + void applysettings(const TrackerSettings& settings); + void notifyCenter(); + void center(); + void reset(); + void sendcmd(QString* cmd); + void get_info(QString* info , int* tps ); + +protected: + void run(); // qthread override run method + + +private: + // Handles to neatly terminate thread... + HANDLE m_StopThread; + HANDLE m_WaitThread; + + TArduinoData ArduinoData, HAT ; // Trame from Arduino + QByteArray datagram; + QextSerialPort *SerialPort; + QReadWriteLock rwlock; + QList* ListErrInf ; + int waitTimeout; + QString sSerialPortName; // Port serial name + bool bEnableRoll; + bool bEnablePitch; + bool bEnableYaw; + bool bEnableX; + bool bEnableY; + bool bEnableZ; + + bool bInvertRoll; + bool bInvertPitch; + bool bInvertYaw; + bool bInvertX; + bool bInvertY; + bool bInvertZ; + + + int iRollAxe; + int iPitchAxe; + int iYawAxe; + int iXAxe; + int iYAxe; + int iZAxe; + +}; + + +//******************************************************************************************************* +// FaceTrackNoIR Tracker DLL. Functions used to get general info on the Tracker +//******************************************************************************************************* +class FTNoIR_TrackerDll : public ITrackerDll +{ +public: + FTNoIR_TrackerDll(); + ~FTNoIR_TrackerDll(); + + void Initialize(); + + 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 // FTNOIR_TRACKER_HAT_H \ No newline at end of file diff --git a/ftnoir_tracker_hatire/ftnoir_tracker_hat.rc b/ftnoir_tracker_hatire/ftnoir_tracker_hat.rc new file mode 100644 index 00000000..62e0a613 --- /dev/null +++ b/ftnoir_tracker_hatire/ftnoir_tracker_hat.rc @@ -0,0 +1,61 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +//#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE 9, 1 +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/ftnoir_tracker_hatire/ftnoir_tracker_hat_dialog.cpp b/ftnoir_tracker_hatire/ftnoir_tracker_hat_dialog.cpp new file mode 100644 index 00000000..b889341f --- /dev/null +++ b/ftnoir_tracker_hatire/ftnoir_tracker_hat_dialog.cpp @@ -0,0 +1,299 @@ +/******************************************************************************** +* FaceTrackNoIR This program is a private project of some enthusiastic * +* gamers from Holland, who don't like to pay much for * +* head-tracking. * +* * +* Copyright (C) 2012 Wim Vriend (Developing) * +* Ron Hendriks (Researching and Testing) * +* * +* Homepage: http://facetracknoir.sourceforge.net/home/default.htm * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the * +* Free Software Foundation; either version 3 of the License, or (at your * +* option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, see . * +* * +********************************************************************************/ +#include "ftnoir_tracker_hat.h" +#include "ftnoir_tracker_hat_dialog.h" + +#include +#include + +//******************************************************************************************************* +// FaceTrackNoIR Client Settings-dialog. +//******************************************************************************************************* + +// +// Constructor for server-settings-dialog +// +TrackerControls::TrackerControls() : settingsDirty(false), theTracker(NULL), timer(this), +QWidget() +{ + + settingsDirty= false; + theTracker = NULL; + ui.setupUi( this ); + pre_trame = 0; + settings.load_ini(); + + // make SerialPort list + foreach (QextPortInfo PortInfo , QextSerialEnumerator::getPorts() ) { + ui.cbSerialPort->addItem(PortInfo.portName); + } + // Stop if no SerialPort dispo + if (ui.cbSerialPort->count()<1) { + QMessageBox::critical(this,"FaceTrackNoIR Error", "No SerialPort avaible"); + } else { + + int indxport =ui.cbSerialPort->findText(settings.SerialPortName,Qt::MatchExactly ); + if (indxport!=-1) { + ui.cbSerialPort->setCurrentIndex(indxport); + } else { + QMessageBox::warning(this,"FaceTrackNoIR Error", "Selected SerialPort modified"); + ui.cbSerialPort-> setCurrentIndex(indxport); + } + } + + 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.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); + + + // 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.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.btnReset, SIGNAL(clicked()), this, SLOT(doReset())); + connect(ui.btnCenter, SIGNAL(clicked()), this, SLOT(doCenter())); + connect(ui.btnSend, SIGNAL(clicked()), this, SLOT(doSend())); + + connect(&timer,SIGNAL(timeout()), this,SLOT(poll_tracker_info())); +} + +// +// Destructor for server-dialog +// +TrackerControls::~TrackerControls() { + delete this; +} + + +// +// 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() { + if (theTracker) theTracker->center(); +} + +// +// Reset asked to ARDUINO +// +void TrackerControls::doReset() { + if (theTracker) theTracker->reset(); +} + + +// +// Send command to ARDUINO +// +void TrackerControls::doSend() { + if (theTracker) { + if (!ui.lineSend->text().isEmpty()) { + QString cmd; + cmd=ui.lineSend->text(); + theTracker->sendcmd(&cmd); + ui.lineSend->clear(); + } + } +} + + +// +// Display FPS and Status of Arduino. +// +void TrackerControls::poll_tracker_info() +{ + if (theTracker) + { + QString info; + int num_trame; + int nb_trame; + + theTracker->get_info(&info,&num_trame); + if ( !info.isNull()) { + ui.lab_vstatus->setText(info); + ui.pteINFO->moveCursor(QTextCursor::End); + ui.pteINFO->insertPlainText(info); + } + + + if (pre_tramesetText(QString::number(nb_trame*(1000/timer.interval()))); + + pre_trame=num_trame; + } + +} + + +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 ); + + // qDebug() << "doCancel says: answer =" << ret; + + 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(); + } +} + + +void TrackerControls::registerTracker(ITracker *tracker) { +// theTracker = (FTNoIR_Tracker *) tracker; + theTracker = static_cast(tracker); + if (isVisible() && settingsDirty) theTracker->applysettings(settings); + ui.cbSerialPort->setEnabled(false); + timer.start(250); + ui.lab_vstatus->setText("HAT START"); +} + + +void TrackerControls::unRegisterTracker() { + theTracker = NULL; + ui.cbSerialPort->setEnabled(true); + timer.stop(); + 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. +#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0") + +FTNOIR_TRACKER_BASE_EXPORT ITrackerDialogPtr __stdcall GetTrackerDialog( ) +{ + return new TrackerControls; +} diff --git a/ftnoir_tracker_hatire/ftnoir_tracker_hat_dialog.h b/ftnoir_tracker_hatire/ftnoir_tracker_hat_dialog.h new file mode 100644 index 00000000..c463f361 --- /dev/null +++ b/ftnoir_tracker_hatire/ftnoir_tracker_hat_dialog.h @@ -0,0 +1,78 @@ +#ifndef FTNOIR_TRACKER_HAT_DIALOG_H +#define FTNOIR_TRACKER_HAT_DIALOG_H + +#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" +#include "ftnoir_tracker_hat_settings.h" +#include "ftnoir_tracker_hat.h" +#include "ui_ftnoir_hatcontrols.h" + +#include +#include + +// Widget that has controls for FTNoIR protocol client-settings. +class TrackerControls: public QWidget, Ui::UIHATControls, public ITrackerDialog +{ + Q_OBJECT + +public: + explicit TrackerControls(); + virtual ~TrackerControls(); + + void Initialize(QWidget *parent); + void registerTracker(ITracker *tracker); + void unRegisterTracker() ; + +private: + Ui::UIHATControls ui; + int pre_trame; + FTNoIR_Tracker *theTracker; + +protected slots: + + /* + void set_mod_port(int val) { settings.SerialPortName = ui.cbSerialPort->itemText(val); + QMessageBox::warning(this,"FaceTrackNoIR Error", settings.SerialPortName); + settings_changed(); } +*/ + void set_mod_port(const QString & val) { settings.SerialPortName =val; + QMessageBox::warning(this,"FaceTrackNoIR Error", settings.SerialPortName); + 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_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 doOK(); + void doCancel(); + void doSave(); + void doReset(); + void doCenter(); + void doSend(); + void poll_tracker_info(); + +protected: + bool settingsDirty; + void settings_changed(); + TrackerSettings settings; + QTimer timer; +}; + + +#endif //FTNOIR_TRACKER_HAT_DIALOG_H \ No newline at end of file diff --git a/ftnoir_tracker_hatire/ftnoir_tracker_hat_dll.cpp b/ftnoir_tracker_hatire/ftnoir_tracker_hat_dll.cpp new file mode 100644 index 00000000..246eb397 --- /dev/null +++ b/ftnoir_tracker_hatire/ftnoir_tracker_hat_dll.cpp @@ -0,0 +1,79 @@ +/******************************************************************************** +* FaceTrackNoIR This program is a private project of some enthusiastic * +* gamers from Holland, who don't like to pay much for * +* head-tracking. * +* * +* Copyright (C) 2012 Wim Vriend (Developing) * +* Ron Hendriks (Researching and Testing) * +* * +* Homepage: http://facetracknoir.sourceforge.net/home/default.htm * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the * +* Free Software Foundation; either version 3 of the License, or (at your * +* option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, see . * +* * +********************************************************************************/ + +#include "ftnoir_tracker_hat.h" +#include +#include + +FTNoIR_TrackerDll::FTNoIR_TrackerDll() { + //populate the description strings + trackerFullName = "Head Arduino Tracker"; + trackerShortName = "HAT"; + trackerDescription = "FaceTrackNoIR HAT"; +} + +FTNoIR_TrackerDll::~FTNoIR_TrackerDll() +{ + +} + +void FTNoIR_TrackerDll::Initialize() +{ + return; +} + +void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled) +{ + *strToBeFilled = trackerFullName; +}; + +void FTNoIR_TrackerDll::getShortName(QString *strToBeFilled) +{ + *strToBeFilled = trackerShortName; +}; + +void FTNoIR_TrackerDll::getDescription(QString *strToBeFilled) +{ + *strToBeFilled = trackerDescription; +}; + +void FTNoIR_TrackerDll::getIcon(QIcon *icon) +{ + *icon = QIcon(":/images/hat.ico"); +}; + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Tracker object. + +// Export both decorated and undecorated names. +// GetTrackerDll - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetTrackerDll@0 - Common name decoration for __stdcall functions in C language. +#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0") + +FTNOIR_TRACKER_BASE_EXPORT ITrackerDllPtr __stdcall GetTrackerDll() +{ + return new FTNoIR_TrackerDll; +} diff --git a/ftnoir_tracker_hatire/ftnoir_tracker_hat_settings.cpp b/ftnoir_tracker_hatire/ftnoir_tracker_hat_settings.cpp new file mode 100644 index 00000000..f8b342cc --- /dev/null +++ b/ftnoir_tracker_hatire/ftnoir_tracker_hat_settings.cpp @@ -0,0 +1,102 @@ +/******************************************************************************** +* FaceTrackNoIR This program is a private project of some enthusiastic * +* gamers from Holland, who don't like to pay much for * +* head-tracking. * +* * +* Copyright (C) 2012 Wim Vriend (Developing) * +* Ron Hendriks (Researching and Testing) * +* * +* Homepage: http://facetracknoir.sourceforge.net/home/default.htm * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the * +* Free Software Foundation; either version 3 of the License, or (at your * +* option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, see . * +* * +********************************************************************************/ +#include +#include + +#include "ftnoir_tracker_hat_settings.h" + +void TrackerSettings::load_ini() +{ + qDebug("TrackerSettings::load_ini()"); + QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + 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(); + + + 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(); + + iniFile.endGroup(); +} + + +void TrackerSettings::save_ini() const +{ + qDebug("TrackerSettings::save_ini()"); + + QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) + QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); + 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( "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.endGroup(); +} diff --git a/ftnoir_tracker_hatire/ftnoir_tracker_hat_settings.h b/ftnoir_tracker_hatire/ftnoir_tracker_hat_settings.h new file mode 100644 index 00000000..a29fed6b --- /dev/null +++ b/ftnoir_tracker_hatire/ftnoir_tracker_hat_settings.h @@ -0,0 +1,44 @@ +/* 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 + + +//----------------------------------------------------------------------------- +struct TrackerSettings +{ + + QString SerialPortName; + 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; + + void load_ini(); + void save_ini() const; +}; + + +#endif //FTNOIR_TRACKER_HAT_SETTINGS_H \ No newline at end of file diff --git a/ftnoir_tracker_hatire/images/hat.ico b/ftnoir_tracker_hatire/images/hat.ico new file mode 100644 index 00000000..d8f5aac4 Binary files /dev/null and b/ftnoir_tracker_hatire/images/hat.ico differ diff --git a/ftnoir_tracker_hatire/images/hat_logo.png b/ftnoir_tracker_hatire/images/hat_logo.png new file mode 100644 index 00000000..c3a92b1b Binary files /dev/null and b/ftnoir_tracker_hatire/images/hat_logo.png differ -- cgit v1.2.3