From 445ebbfa3edc12bd79469a61c25257fe853c3768 Mon Sep 17 00:00:00 2001 From: Wim Vriend Date: Sat, 22 Jan 2011 15:21:34 +0000 Subject: Work on DLL-FTNoir-Tracker. git-svn-id: svn+ssh://svn.code.sf.net/p/facetracknoir/code@41 19e81ba0-9b1a-49c3-bd6c-561e1906d5fb --- FTNoIR_Tracker_UDP/FTNoIR_Tracker_UDP.vcproj | 236 ++++++++++++++++++++++++ FTNoIR_Tracker_UDP/ftnoir_tracker_base.h | 48 +++++ FTNoIR_Tracker_UDP/ftnoir_tracker_base_global.h | 12 ++ FTNoIR_Tracker_UDP/ftnoir_tracker_udp.cpp | 181 ++++++++++++++++++ FaceTrackNoIR.suo | Bin 314880 -> 317440 bytes FaceTrackNoIR/tracker.cpp | 43 ++++- FaceTrackNoIR/tracker.h | 1 + bin/FaceTrackNoIR.exe | Bin 737280 -> 741376 bytes 8 files changed, 519 insertions(+), 2 deletions(-) create mode 100644 FTNoIR_Tracker_UDP/FTNoIR_Tracker_UDP.vcproj create mode 100644 FTNoIR_Tracker_UDP/ftnoir_tracker_base.h create mode 100644 FTNoIR_Tracker_UDP/ftnoir_tracker_base_global.h create mode 100644 FTNoIR_Tracker_UDP/ftnoir_tracker_udp.cpp diff --git a/FTNoIR_Tracker_UDP/FTNoIR_Tracker_UDP.vcproj b/FTNoIR_Tracker_UDP/FTNoIR_Tracker_UDP.vcproj new file mode 100644 index 00000000..d5df6fc0 --- /dev/null +++ b/FTNoIR_Tracker_UDP/FTNoIR_Tracker_UDP.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FTNoIR_Tracker_UDP/ftnoir_tracker_base.h b/FTNoIR_Tracker_UDP/ftnoir_tracker_base.h new file mode 100644 index 00000000..60c26ee1 --- /dev/null +++ b/FTNoIR_Tracker_UDP/ftnoir_tracker_base.h @@ -0,0 +1,48 @@ +#ifndef FTNOIR_TRACKER_BASE_H +#define FTNOIR_TRACKER_BASE_H + +#include "ftnoir_tracker_base_global.h" + +// +// x,y,z position in centimetres, yaw, pitch and roll in degrees... +// +#pragma pack(push, 2) +struct THeadPoseData { + double x, y, z, yaw, pitch, roll; +}; +#pragma pack(pop) + +// COM-Like abstract interface. +// This interface doesn't require __declspec(dllexport/dllimport) specifier. +// Method calls are dispatched via virtual table. +// Any C++ compiler can use it. +// Instances are obtained via factory function. +struct ITracker +{ + virtual int Foo(int n) = 0; + virtual void Release() = 0; + virtual void Initialize() = 0; + virtual void StartTracker() = 0; + virtual void GiveHeadPoseData(THeadPoseData *data) = 0; +}; + +// Handle type. In C++ language the iterface type is used. +typedef ITracker* TRACKERHANDLE; + +//////////////////////////////////////////////////////////////////////////////// +// +#ifdef __cplusplus +# define EXTERN_C extern "C" +#else +# define EXTERN_C +#endif // __cplusplus + +// Factory function that creates instances of the Xyz object. +EXTERN_C +FTNOIR_TRACKER_BASE_EXPORT +TRACKERHANDLE +__stdcall +GetTracker( + void); + +#endif // FTNOIR_TRACKER_BASE_H diff --git a/FTNoIR_Tracker_UDP/ftnoir_tracker_base_global.h b/FTNoIR_Tracker_UDP/ftnoir_tracker_base_global.h new file mode 100644 index 00000000..9f4a6118 --- /dev/null +++ b/FTNoIR_Tracker_UDP/ftnoir_tracker_base_global.h @@ -0,0 +1,12 @@ +#ifndef FTNOIR_TRACKER_BASE_GLOBAL_H +#define FTNOIR_TRACKER_BASE_GLOBAL_H + +#include + +#ifdef FTNOIR_TRACKER_BASE_LIB +# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_EXPORT +#else +# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT +#endif + +#endif // FTNOIR_TRACKER_BASE_GLOBAL_H diff --git a/FTNoIR_Tracker_UDP/ftnoir_tracker_udp.cpp b/FTNoIR_Tracker_UDP/ftnoir_tracker_udp.cpp new file mode 100644 index 00000000..005671cb --- /dev/null +++ b/FTNoIR_Tracker_UDP/ftnoir_tracker_udp.cpp @@ -0,0 +1,181 @@ +#include "ftnoir_tracker_base.h" +#include +#include +#include "Windows.h" + +class FTNoIR_Tracker_UDP : public ITracker, QThread +{ +public: + FTNoIR_Tracker_UDP(); + ~FTNoIR_Tracker_UDP(); + + int Foo(int n); + void Release(); + void Initialize(); + void StartTracker(); + void GiveHeadPoseData(THeadPoseData *data); + +protected: + void run(); // qthread override run method + +private: + // Handles to neatly terminate thread... + HANDLE m_StopThread; + HANDLE m_WaitThread; + + // UDP socket-variables + QUdpSocket *inSocket; // Receive from ... + QUdpSocket *outSocket; // Send to ... + QHostAddress destIP; // Destination IP-address + int destPort; // Destination port-number + QHostAddress srcIP; // Source IP-address + int srcPort; // Source port-number + + THeadPoseData newHeadPose; // Structure with new headpose +}; + +FTNoIR_Tracker_UDP::FTNoIR_Tracker_UDP() +{ + inSocket = 0; + outSocket = 0; + + // Create events + m_StopThread = CreateEvent(0, TRUE, FALSE, 0); + m_WaitThread = CreateEvent(0, TRUE, FALSE, 0); + + newHeadPose.x = 1.0f; + newHeadPose.y = 2.0f; + newHeadPose.z = 3.0f; + newHeadPose.yaw = 4.0f; + newHeadPose.pitch = 5.0f; + newHeadPose.roll = 6.0f; +} + +FTNoIR_Tracker_UDP::~FTNoIR_Tracker_UDP() +{ + // 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 (inSocket) { + inSocket->disconnectFromHost(); + inSocket->waitForDisconnected(); + delete inSocket; + } + + if (outSocket) { + outSocket->disconnectFromHost(); + outSocket->waitForDisconnected(); + delete outSocket; + } +} + +/** QThread run @override **/ +void FTNoIR_Tracker_UDP::run() { + +int no_bytes; +QHostAddress sender; +quint16 senderPort; + + // + // Create UDP-sockets if they don't exist already. + // They must be created here, because they must be in the new thread (FTNoIR_Tracker_UDP::run()) + // + if (inSocket == 0) { + qDebug() << "FTNoIR_Tracker_UDP::run() creating insocket"; + inSocket = new QUdpSocket(); + // Connect the inSocket to the port, to receive messages + inSocket->bind(QHostAddress::Any, destPort+1); + } + + // + // 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_UDP::run() terminated run()"; + return; + } + + while (inSocket->hasPendingDatagrams()) { + + QByteArray datagram; + datagram.resize(inSocket->pendingDatagramSize()); + + inSocket->readDatagram( (char * ) &newHeadPose, sizeof(newHeadPose), &sender, &senderPort); + } + + //for lower cpu load + usleep(5000); + yieldCurrentThread(); + + } +} + +int FTNoIR_Tracker_UDP::Foo(int n) +{ + return n * n; +} + +void FTNoIR_Tracker_UDP::Release() +{ + delete this; +} + +void FTNoIR_Tracker_UDP::Initialize() +{ + return; +} + +void FTNoIR_Tracker_UDP::StartTracker() +{ + start( QThread::TimeCriticalPriority ); + return; +} + +void FTNoIR_Tracker_UDP::GiveHeadPoseData(THeadPoseData *data) +{ + + newHeadPose.x += 1.0f; + newHeadPose.y += 2.0f; + newHeadPose.z += 3.0f; + newHeadPose.yaw += 4.0f; + newHeadPose.pitch += 5.0f; + newHeadPose.roll += 6.0f; + + data->x = newHeadPose.x; + data->y = newHeadPose.y; + data->z = newHeadPose.z; + data->yaw = newHeadPose.yaw; + data->pitch = newHeadPose.pitch; + data->roll = newHeadPose.roll; + return; +} + +//////////////////////////////////////////////////////////////////////////////// +// 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 TRACKERHANDLE __stdcall GetTracker() +{ + return new FTNoIR_Tracker_UDP; +} + diff --git a/FaceTrackNoIR.suo b/FaceTrackNoIR.suo index d64f82f7..48e0d28e 100644 Binary files a/FaceTrackNoIR.suo and b/FaceTrackNoIR.suo differ diff --git a/FaceTrackNoIR/tracker.cpp b/FaceTrackNoIR/tracker.cpp index 974b1251..73023b2f 100644 --- a/FaceTrackNoIR/tracker.cpp +++ b/FaceTrackNoIR/tracker.cpp @@ -194,7 +194,9 @@ Tracker::~Tracker() { ::SetEvent(m_StopThread); // Wait until thread finished - ::WaitForSingleObject(m_WaitThread, INFINITE); + if (isRunning()) { + ::WaitForSingleObject(m_WaitThread, INFINITE); + } // Close handles ::CloseHandle(m_StopThread); @@ -245,6 +247,7 @@ void Tracker::setup(QWidget *head, FaceTrackNoIR *parent) { if (selectedTracker == FT_FTNOIR) { int fooResult = pTracker->Foo(42); qDebug() << "Tracker::setup Foo gives: " << fooResult; + pTracker->StartTracker(); } // set up the line edits for calling @@ -438,6 +441,13 @@ void Tracker::run() { } # endif + if (selectedTracker == FT_FTNOIR) { + THeadPoseData newpose; + pTracker->GiveHeadPoseData(&newpose); + addHeadPose(newpose); + Tracker::confid = true; + } + // // Get the System-time and substract the time from the previous call. // dT will be used for the EWMA-filter. @@ -653,7 +663,6 @@ void Tracker::run() { ReleaseMutex(Tracker::hTrackMutex); server_Game->sendHeadposeToGame(); - //for lower cpu load usleep(10000); yieldCurrentThread(); @@ -720,6 +729,36 @@ void Tracker::addHeadPose( smEngineHeadPoseData head_pose ) addRaw2List ( &Z.rawList, Z.maxItems, Tracker::Z.headPos ); } +/** Add the headpose-data to the Lists **/ +void Tracker::addHeadPose( THeadPoseData head_pose ) +{ + // Pitch + Tracker::Pitch.headPos = head_pose.pitch; // degrees + addRaw2List ( &Pitch.rawList, Pitch.maxItems, Tracker::Pitch.headPos ); +// Tracker::Pitch.confidence = head_pose.confidence; // Just this one ... + Tracker::Pitch.newSample = true; + + // Yaw + Tracker::Yaw.headPos = head_pose.yaw; // degrees + addRaw2List ( &Yaw.rawList, Yaw.maxItems, Tracker::Yaw.headPos ); + + // Roll + Tracker::Roll.headPos = head_pose.roll; // degrees + addRaw2List ( &Roll.rawList, Roll.maxItems, Tracker::Roll.headPos ); + + // X-position + Tracker::X.headPos = head_pose.x; // centimeters + addRaw2List ( &X.rawList, X.maxItems, Tracker::X.headPos ); + + // Y-position + Tracker::Y.headPos = head_pose.y; // centimeters + addRaw2List ( &Y.rawList, Y.maxItems, Tracker::Y.headPos ); + + // Z-position (distance to camera, absolute!) + Tracker::Z.headPos = head_pose.z; // centimeters + addRaw2List ( &Z.rawList, Z.maxItems, Tracker::Z.headPos ); +} + // // Get the ProgramName from the Game and return it. // diff --git a/FaceTrackNoIR/tracker.h b/FaceTrackNoIR/tracker.h index 20fd60d8..ab14e06a 100644 --- a/FaceTrackNoIR/tracker.h +++ b/FaceTrackNoIR/tracker.h @@ -143,6 +143,7 @@ private: /** static callback method for the head pose tracking **/ static void STDCALL receiveHeadPose(void *,smEngineHeadPoseData head_pose, smCameraVideoFrame video_frame); static void addHeadPose( smEngineHeadPoseData head_pose ); + static void addHeadPose( THeadPoseData head_pose ); static void addRaw2List ( QList *rawList, float maxIndex, float raw ); static float lowPassFilter ( float newvalue, float *oldvalue, float dt, float coeff); static float rateLimiter ( float newvalue, float *oldvalue, float dt, float max_rate); diff --git a/bin/FaceTrackNoIR.exe b/bin/FaceTrackNoIR.exe index f15da144..438e6f3c 100644 Binary files a/bin/FaceTrackNoIR.exe and b/bin/FaceTrackNoIR.exe differ -- cgit v1.2.3