From 016d79347d429c291ea65eb95663e200e1e601f2 Mon Sep 17 00:00:00 2001 From: Wim Vriend Date: Sat, 25 Dec 2010 13:57:40 +0000 Subject: Finished removing QThread from Protocol-server code. Seems to work fine... git-svn-id: svn+ssh://svn.code.sf.net/p/facetracknoir/code@33 19e81ba0-9b1a-49c3-bd6c-561e1906d5fb --- FaceTrackNoIR/FGServer.cpp | 94 ++++--- FaceTrackNoIR/FGServer.h | 7 +- FaceTrackNoIR/FTIRServer.h | 1 - FaceTrackNoIR/FaceTrackNoIR.cpp | 2 +- FaceTrackNoIR/FaceTrackNoIR.ui | 600 +++++++++++++++++++--------------------- FaceTrackNoIR/PPJoyServer.cpp | 68 ++--- FaceTrackNoIR/SCServer.cpp | 161 +++++------ FaceTrackNoIR/SCServer.h | 8 + 8 files changed, 432 insertions(+), 509 deletions(-) (limited to 'FaceTrackNoIR') diff --git a/FaceTrackNoIR/FGServer.cpp b/FaceTrackNoIR/FGServer.cpp index 47ca31ba..9f362e52 100644 --- a/FaceTrackNoIR/FGServer.cpp +++ b/FaceTrackNoIR/FGServer.cpp @@ -25,6 +25,11 @@ * to FlightGear, using UDP. * * It is based on the (Linux) example made by Melchior FRANZ. * ********************************************************************************/ +/* + Modifications (last one on top): + 20101224 - WVR: Base class is no longer inheriting QThread. sendHeadposeToGame + is called from run() of Tracker.cpp +*/ #include #include #include "FGServer.h" @@ -36,43 +41,26 @@ FGServer::FGServer( Tracker *parent ) { // Save the parent headTracker = parent; + loadSettings(); +} - // Create events - //m_StopThread = CreateEvent(0, TRUE, FALSE, 0); - //m_WaitThread = CreateEvent(0, TRUE, FALSE, 0); +/** destructor **/ +FGServer::~FGServer() { + inSocket->disconnectFromHost(); + inSocket->waitForDisconnected(); + outSocket->disconnectFromHost(); + outSocket->waitForDisconnected(); - loadSettings(); + delete inSocket; + delete outSocket; } // -// Callback function registered in the run() method. -// Retrieve all pending Datagrams (typically 1) and send a reply, containing the headpose-data. +// Update Headpose in Game. // -void FGServer::readPendingDatagrams() -{ -QHostAddress sender; -quint16 senderPort; -qint32 cmd; +void FGServer::sendHeadposeToGame() { int no_bytes; - // - // Read data from FlightGear - // - while (inSocket->hasPendingDatagrams()) { - QByteArray datagram; - datagram.resize(inSocket->pendingDatagramSize()); - -// qDebug() << "FGServer::readPendingDatagrams says: size =" << inSocket->pendingDatagramSize(); - - inSocket->readDatagram( (char * ) &cmd, sizeof(cmd), &sender, &senderPort); -// qDebug() << "FGServer::readPendingDatagrams says: data =" << cmd; - - fg_cmd = cmd; // Let's just accept that command for now... - if ( cmd > 0 ) { - headTracker->handleGameCommand ( cmd ); // Send it upstream, for the Tracker to handle - } - } - // // Copy the Raw measurements directly to the client. // @@ -100,9 +88,40 @@ int no_bytes; } -/** QThread run @override **/ -void FGServer::run() { +// +// Callback function registered in the run() method. +// Retrieve all pending Datagrams (typically 1) and send a reply, containing the headpose-data. +// +void FGServer::readPendingDatagrams() +{ +QHostAddress sender; +quint16 senderPort; + + // + // Read data from FlightGear + // + while (inSocket->hasPendingDatagrams()) { + QByteArray datagram; + datagram.resize(inSocket->pendingDatagramSize()); + +// qDebug() << "FGServer::readPendingDatagrams says: size =" << inSocket->pendingDatagramSize(); + inSocket->readDatagram( (char * ) &cmd, sizeof(cmd), &sender, &senderPort); +// qDebug() << "FGServer::readPendingDatagrams says: data =" << cmd; + + fg_cmd = cmd; // Let's just accept that command for now... + if ( cmd > 0 ) { + headTracker->handleGameCommand ( cmd ); // Send it upstream, for the Tracker to handle + } + } +} + +// +// Check if the Client DLL exists and load it (to test it), if so. +// Returns 'true' if all seems OK. +// +bool FGServer::checkServerInstallationOK( HANDLE handle ) +{ // Init. the data TestData.x = 0.0f; TestData.y = 0.0f; @@ -123,19 +142,8 @@ void FGServer::run() { // Connect the inSocket to the member-function, to read FlightGear commands connect(inSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()), Qt::DirectConnection); -// exec(); // Exec only returns, when the thread terminates... -} -/** QThread terminate @override **/ -void FGServer::terminate() { - - inSocket->disconnectFromHost(); - inSocket->waitForDisconnected(); - outSocket->disconnectFromHost(); - outSocket->waitForDisconnected(); - - delete inSocket; - delete outSocket; + return true; } // diff --git a/FaceTrackNoIR/FGServer.h b/FaceTrackNoIR/FGServer.h index 8b61f920..9fd52eb3 100644 --- a/FaceTrackNoIR/FGServer.h +++ b/FaceTrackNoIR/FGServer.h @@ -56,12 +56,12 @@ public: // public member methods FGServer( Tracker *parent ); - virtual ~FGServer() {}; + ~FGServer(); // protected member methods protected: - void run(); - void terminate(); + bool checkServerInstallationOK( HANDLE handle ); + void sendHeadposeToGame(); private slots: void readPendingDatagrams(); @@ -71,6 +71,7 @@ private: TFlightGearData TestData; QUdpSocket *inSocket; // Receive from FligthGear QUdpSocket *outSocket; // Send to FligthGear + qint32 cmd; qint32 fg_cmd; // Command from FlightGear QHostAddress destIP; // Destination IP-address int destPort; // Destination port-number diff --git a/FaceTrackNoIR/FTIRServer.h b/FaceTrackNoIR/FTIRServer.h index c27a1ab5..bdf31cc6 100644 --- a/FaceTrackNoIR/FTIRServer.h +++ b/FaceTrackNoIR/FTIRServer.h @@ -56,7 +56,6 @@ public: // protected member methods protected: -// void run(); bool checkServerInstallationOK( HANDLE handle ); void sendHeadposeToGame(); diff --git a/FaceTrackNoIR/FaceTrackNoIR.cpp b/FaceTrackNoIR/FaceTrackNoIR.cpp index 7298a207..4c63d93b 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.cpp +++ b/FaceTrackNoIR/FaceTrackNoIR.cpp @@ -72,7 +72,7 @@ void FaceTrackNoIR::setupFaceTrackNoIR() { ui.setupUi(this); - ui.headPoseWidget->hide(); + ui.headPoseWidget->show(); ui.video_frame->hide(); // menu objects will be connected with the functions in FaceTrackNoIR class diff --git a/FaceTrackNoIR/FaceTrackNoIR.ui b/FaceTrackNoIR/FaceTrackNoIR.ui index d24308bd..2d7aad69 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.ui +++ b/FaceTrackNoIR/FaceTrackNoIR.ui @@ -11,7 +11,7 @@ 0 0 970 - 521 + 421 @@ -49,11 +49,18 @@ QWidget { /* Specials for individual widget(s) */ QWidget#widget { background-color: #484848; + border-left: 1px solid #000; } -QWidget#Leftwidget { +/* Specials for individual widget(s) */ +QWidget#widget4video { background-color: #595959; - border-right: 1px solid #000; + border-top: 1px solid #000; + border-bottom: 1px solid #000; +} + +QWidget#Leftwidget { + background-color: ; } QWidget#widgetTop { @@ -115,7 +122,7 @@ QGroupBox { 800 - 500 + 400 @@ -128,347 +135,313 @@ QGroupBox { 0 - - - - - 0 - 0 - - - - - 166 - 90 - - - - - - - - 6 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - 177 - 20 - - - - - - - - - 0 - 0 - - - - - 90 - 90 - - - - QFrame#logoInstitute { - background:#595959 url(UIElements/logoFaceTrackNoIR.png) no-repeat; -border:none; -} - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - 0 - - - - 1000 - 16777215 - + + + 6 - - - - - - 0 - - - 0 - - - - - - 250 - 300 - + + + + + 0 + 100 + + + + + 16777215 + 100 + + + + + + + + + 151 + 40 + 80 + 20 + - + border:1px solid #ccc; +background:white; +color:#000; - - - - - - - 0 - 100 - + + N/A - - - 16777215 - 100 - + + + + + 151 + 10 + 81 + 20 + - - - - - - 151 - 40 - 80 - 20 - - - - border:1px solid #ccc; + border:1px solid #ccc; background:white; color:#000; - - - N/A - - - - - - 151 - 10 - 81 - 20 - - - - border:1px solid #ccc; -background:white; -color:#000; - - - N/A - - - - - - 150 - 70 - 81 - 20 - - - - border:1px solid #ccc; + + + N/A + + + + + + 150 + 70 + 81 + 20 + + + + border:1px solid #ccc; background:white; color:#000; - - - N/A - - - - - - 10 - 10 - 21 - 16 - - - - border:none; + + + N/A + + + + + + 10 + 10 + 21 + 16 + + + + border:none; color:white - - - X - - - - - - 10 - 40 - 21 - 16 - - - - border:none; + + + X + + + + + + 10 + 40 + 21 + 16 + + + + border:none; color:white; - - - Y - - - - - - 10 - 70 - 21 - 16 - - - - color:white; + + + Y + + + + + + 10 + 70 + 21 + 16 + + + + color:white; border:none; - - - Z - - - - - - 120 - 70 - 21 - 16 - - - - border:none; + + + Z + + + + + + 120 + 70 + 21 + 16 + + + + border:none; color:white; - - - rotZ - - - - - - 120 - 40 - 21 - 16 - - - - color:white; + + + rotZ + + + + + + 120 + 40 + 21 + 16 + + + + color:white; border:none; - - - rotY - - - - - - 120 - 10 - 21 - 16 - - - - border:none; + + + rotY + + + + + + 120 + 10 + 21 + 16 + + + + border:none; color:white; - - - rotX - - - - - - 30 - 70 - 81 - 20 - - - - border:1px solid #ccc; + + + rotX + + + + + + 30 + 70 + 81 + 20 + + + + border:1px solid #ccc; background:white; color:#000; - - - N/A - - - - - - 30 - 40 - 81 - 20 - - - - border:1px solid #ccc; + + + N/A + + + + + + 30 + 40 + 81 + 20 + + + + border:1px solid #ccc; background:white; color:#000; + + + N/A + + + + + + 30 + 10 + 81 + 20 + + + + border:1px solid #ccc; +background:white; +color:#000; + + + N/A + + + + + + + + + + + 0 + 0 + - - N/A + + + 90 + 90 + - - - - - 30 - 10 - 81 - 20 - + + + 16777215 + 90 + - border:1px solid #ccc; -background:white; -color:#000; + QFrame#logoInstitute { + background:#595959 url(UIElements/logoFaceTrackNoIR.png) no-repeat; +border:none; +} + + + QFrame::StyledPanel - - N/A + + QFrame::Raised - - - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 250 + 180 + + + + + 0 + 0 + 250 + 180 + + 250 @@ -491,9 +464,9 @@ color:#000; QFrame::Raised - - - + + + @@ -1984,7 +1957,6 @@ background:none; View - diff --git a/FaceTrackNoIR/PPJoyServer.cpp b/FaceTrackNoIR/PPJoyServer.cpp index 9a2301fd..cf0773c2 100644 --- a/FaceTrackNoIR/PPJoyServer.cpp +++ b/FaceTrackNoIR/PPJoyServer.cpp @@ -41,10 +41,6 @@ char strDevName[100]; // Save the parent headTracker = parent; - // Create events - //m_StopThread = CreateEvent(0, TRUE, FALSE, 0); - //m_WaitThread = CreateEvent(0, TRUE, FALSE, 0); - // Initialize arrays for (int i = 0;i < 3;i++) { centerPos[i] = 0; @@ -72,28 +68,13 @@ PPJoyServer::~PPJoyServer() { /* Make sure we could open the device! */ if (h == INVALID_HANDLE_VALUE) { - //terminate(); - //wait(); return; } - //// Trigger thread to stop - //::SetEvent(m_StopThread); - - //// Wait until thread finished - //::WaitForSingleObject(m_WaitThread, INFINITE); - - //// Close handles - //::CloseHandle(m_StopThread); - //::CloseHandle(m_WaitThread); - // // Free the Virtual Joystick // CloseHandle(h); - //terminates the QThread and waits for finishing the QThread - //terminate(); - //wait(); } /** QThread run @override **/ @@ -112,38 +93,25 @@ void PPJoyServer::sendHeadposeToGame() { return; } - forever + // The effective angle for faceTracking will be < 90 degrees, so we assume a smaller range here + Analog[0] = scale2AnalogLimits( virtRotX, -50.0f, 50.0f ); // Pitch + Analog[1] = scale2AnalogLimits( virtRotY, -50.0f, 50.0f ); // Yaw + Analog[2] = scale2AnalogLimits( virtRotZ, -50.0f, 50.0f ); // Roll + + // The effective movement for faceTracking will be < 50 cm, so we assume a smaller range here + Analog[3] = scale2AnalogLimits( virtPosX, -40.0f, 40.0f ); // X + + Analog[4] = scale2AnalogLimits( virtPosY, -40.0f, 40.0f ); // Y + Analog[5] = scale2AnalogLimits( virtPosZ, -40.0f, 40.0f ); // Z + + checkAnalogLimits(); + + /* Send request to PPJoy for processing. */ + /* Currently there is no Return Code from PPJoy, this may be added at a */ + /* later stage. So we pass a 0 byte output buffer. */ + if (!DeviceIoControl( h, IOCTL_PPORTJOY_SET_STATE, &JoyState, sizeof(JoyState), NULL, 0, &RetSize, NULL)) { - // Check event for stop thread - //if(::WaitForSingleObject(m_StopThread, 0) == WAIT_OBJECT_0) { - // // Set event - // ::SetEvent(m_WaitThread); - // return; - //} - - // The effective angle for faceTracking will be < 90 degrees, so we assume a smaller range here - Analog[0] = scale2AnalogLimits( virtRotX, -50.0f, 50.0f ); // Pitch - Analog[1] = scale2AnalogLimits( virtRotY, -50.0f, 50.0f ); // Yaw - Analog[2] = scale2AnalogLimits( virtRotZ, -50.0f, 50.0f ); // Roll - - // The effective movement for faceTracking will be < 50 cm, so we assume a smaller range here - Analog[3] = scale2AnalogLimits( virtPosX, -40.0f, 40.0f ); // X - - Analog[4] = scale2AnalogLimits( virtPosY, -40.0f, 40.0f ); // Y - Analog[5] = scale2AnalogLimits( virtPosZ, -40.0f, 40.0f ); // Z - - checkAnalogLimits(); - - /* Send request to PPJoy for processing. */ - /* Currently there is no Return Code from PPJoy, this may be added at a */ - /* later stage. So we pass a 0 byte output buffer. */ - if (!DeviceIoControl( h, IOCTL_PPORTJOY_SET_STATE, &JoyState, sizeof(JoyState), NULL, 0, &RetSize, NULL)) - { - return; - } - // just for lower cpu load - //msleep(15); - //yieldCurrentThread(); + return; } } diff --git a/FaceTrackNoIR/SCServer.cpp b/FaceTrackNoIR/SCServer.cpp index 9ee52f8d..d55d11c3 100644 --- a/FaceTrackNoIR/SCServer.cpp +++ b/FaceTrackNoIR/SCServer.cpp @@ -1,6 +1,6 @@ /******************************************************************************** -* SCServer SCServer is the Class, that communicates headpose-data * -* to games, using the SimConnect.dll. * +* SCServer SCServer is the Class, that communicates headpose-data * +* to games, using the SimConnect.dll. * * * * Copyright (C) 2010 Wim Vriend (Developing) * * Ron Hendriks (Testing and Research) * @@ -21,132 +21,77 @@ ********************************************************************************/ /* Modifications (last one on top): + 20101224 - WVR: Base class is no longer inheriting QThread. sendHeadposeToGame + is called from run() of Tracker.cpp */ #include "SCServer.h" /** constructor **/ SCServer::SCServer() { + ProgramName = "Microsoft FSX"; + blnSimConnectActive = false; + hSimConnect = NULL; - // Create events - //m_StopThread = CreateEvent(0, TRUE, FALSE, 0); - //m_WaitThread = CreateEvent(0, TRUE, FALSE, 0); + prevPosX = 0.0f; + prevPosY = 0.0f; + prevPosZ = 0.0f; + prevRotX = 0.0f; + prevRotY = 0.0f; + prevRotZ = 0.0f; - ProgramName = ""; } /** destructor **/ SCServer::~SCServer() { - // 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); - // // Free the DLL // + simconnect_close( hSimConnect ); SCClientLib.unload(); - - //terminates the QThread and waits for finishing the QThread - //terminate(); - //wait(); } -/** QThread run @override **/ +// +// Update Headpose in Game. +// void SCServer::sendHeadposeToGame() { -bool blnSimConnectActive = false; -HANDLE hSimConnect = NULL; // Handle to SimConnect -importSimConnect_Open simconnect_open; // SimConnect function(s) in DLL -importSimConnect_Close simconnect_close; -importSimConnect_CameraSetRelative6DOF simconnect_set6DOF; - -float prevPosX, prevPosY, prevPosZ, prevRotX, prevRotY, prevRotZ; // - // Get the SimConnect_Open function from the DLL and use it! + // It's only usefull to send data, if the connection was made. // - simconnect_open = (importSimConnect_Open) SCClientLib.resolve("SimConnect_Open"); - if (simconnect_open == NULL) { - qDebug() << "SCServer::run() says: SimConnect_Open function not found in DLL!"; - return; - } - simconnect_set6DOF = (importSimConnect_CameraSetRelative6DOF) SCClientLib.resolve("SimConnect_CameraSetRelative6DOF"); - if (simconnect_set6DOF == NULL) { - qDebug() << "SCServer::run() says: SimConnect_CameraSetRelative6DOF function not found in DLL!"; - return; - } - simconnect_close = (importSimConnect_Close) SCClientLib.resolve("SimConnect_Close"); - if (simconnect_close == NULL) { - qDebug() << "SCServer::run() says: SimConnect_Close function not found in DLL!"; - return; - } - - qDebug() << "SCServer::run() says: SimConnect functions resolved in DLL!"; - - prevPosX = 0.0f; - prevPosY = 0.0f; - prevPosZ = 0.0f; - prevRotX = 0.0f; - prevRotY = 0.0f; - prevRotZ = 0.0f; - - forever - { - // Check event for stop thread - //if(::WaitForSingleObject(m_StopThread, 0) == WAIT_OBJECT_0) - //{ - // // Set event -// simconnect_close( hSimConnect ); - // ::SetEvent(m_WaitThread); - // return; - //} - - if (!blnSimConnectActive) { - if (SUCCEEDED(simconnect_open(&hSimConnect, "FaceTrackNoIR", NULL, 0, 0, 0))) { - qDebug() << "SCServer::run() says: SimConnect active!"; - blnSimConnectActive = true; - } - //else { - // msleep(5000); - // yieldCurrentThread(); - //} + if (!blnSimConnectActive) { + if (SUCCEEDED(simconnect_open(&hSimConnect, "FaceTrackNoIR", NULL, 0, 0, 0))) { + qDebug() << "SCServer::run() says: SimConnect active!"; + blnSimConnectActive = true; } - else { - // - // Write the 6DOF-data to FSX - // - // Only do this when the data has changed. This way, the HAT-switch can be used when tracking is OFF. - // - if ((prevPosX != virtPosX) || (prevPosY != virtPosY) || (prevPosZ != virtPosZ) || - (prevRotX != virtRotX) || (prevRotY != virtRotY) || (prevRotZ != virtRotZ)) { - if (S_OK == simconnect_set6DOF(hSimConnect, virtPosX, virtPosY, virtPosZ, virtRotX, virtRotZ, virtRotY)) { + } + else { + // + // Write the 6DOF-data to FSX + // + // Only do this when the data has changed. This way, the HAT-switch can be used when tracking is OFF. + // + if ((prevPosX != virtPosX) || (prevPosY != virtPosY) || (prevPosZ != virtPosZ) || + (prevRotX != virtRotX) || (prevRotY != virtRotY) || (prevRotZ != virtRotZ)) { + if (S_OK == simconnect_set6DOF(hSimConnect, virtPosX, virtPosY, virtPosZ, virtRotX, virtRotZ, virtRotY)) { // qDebug() << "SCServer::run() says: SimConnect data written!"; - } } - - prevPosX = virtPosX; - prevPosY = virtPosY; - prevPosZ = virtPosZ; - prevRotX = virtRotX; - prevRotY = virtRotY; - prevRotZ = virtRotZ; - - // just for lower cpu load - //msleep(15); - //yieldCurrentThread(); } + + prevPosX = virtPosX; + prevPosY = virtPosY; + prevPosZ = virtPosZ; + prevRotX = virtRotX; + prevRotY = virtRotY; + prevRotZ = virtRotZ; } } // // Check if the Client DLL exists and load it (to test it), if so. +// SimConnect uses a 'side-by-side' installation. The manifest is loaded and (if that's OK) the +// right DLL will be loaded automatically... +// // Returns 'true' if all seems OK. // bool SCServer::checkServerInstallationOK( HANDLE handle ) @@ -209,6 +154,28 @@ bool SCServer::checkServerInstallationOK( HANDLE handle ) } catch(...) { return false; } + + // + // Get the functions from the DLL. + // + simconnect_open = (importSimConnect_Open) SCClientLib.resolve("SimConnect_Open"); + if (simconnect_open == NULL) { + qDebug() << "SCServer::run() says: SimConnect_Open function not found in DLL!"; + return false; + } + simconnect_set6DOF = (importSimConnect_CameraSetRelative6DOF) SCClientLib.resolve("SimConnect_CameraSetRelative6DOF"); + if (simconnect_set6DOF == NULL) { + qDebug() << "SCServer::run() says: SimConnect_CameraSetRelative6DOF function not found in DLL!"; + return false; + } + simconnect_close = (importSimConnect_Close) SCClientLib.resolve("SimConnect_Close"); + if (simconnect_close == NULL) { + qDebug() << "SCServer::run() says: SimConnect_Close function not found in DLL!"; + return false; + } + + qDebug() << "SCServer::run() says: SimConnect functions resolved in DLL!"; + return true; } diff --git a/FaceTrackNoIR/SCServer.h b/FaceTrackNoIR/SCServer.h index f107de55..eea55376 100644 --- a/FaceTrackNoIR/SCServer.h +++ b/FaceTrackNoIR/SCServer.h @@ -71,6 +71,14 @@ private: QString ProgramName; QLibrary SCClientLib; + bool blnSimConnectActive; + HANDLE hSimConnect; // Handle to SimConnect + importSimConnect_Open simconnect_open; // SimConnect function(s) in DLL + importSimConnect_Close simconnect_close; + importSimConnect_CameraSetRelative6DOF simconnect_set6DOF; + +float prevPosX, prevPosY, prevPosZ, prevRotX, prevRotY, prevRotZ; + public: void setVirtRotX(float rot) { virtRotX = -1.0f * rot; } // degrees void setVirtRotY(float rot) { virtRotY = -1.0f * rot; } -- cgit v1.2.3