diff --git a/ECTrainer2/ECTrainer.cpp b/ECTrainer2/ECTrainer.cpp index 9489332..6189b5c 100644 --- a/ECTrainer2/ECTrainer.cpp +++ b/ECTrainer2/ECTrainer.cpp @@ -9,11 +9,11 @@ #include "TobiiREST.h" #include "BitalMonitor.h" #include "Worker.h" +#include "KeepAlive.h" // �R���X�g���N�^ ECTrainer::ECTrainer(HINSTANCE hInstance) : _AppRunning(true) - //, _HomographyOK(false) , _CalibResult(0) , _hInstance(hInstance) { @@ -22,7 +22,8 @@ _pProcs[IMGPROC] = new ImageProc(this); _pProcs[SCNCAM] = new SceneCamera(this); _pProcs[STIM] = new Stimulus(this, _pMarker); - _pProcs[EYETR] = new EyeTrack(this, _pMarker); + _pProcs[ALIVE] = new KeepAlive(this); + _pProcs[EYETR] = new EyeTrack(this); _pProcs[REST] = new TobiiREST(this); _pProcs[BITAL] = new BitalMonitor(this); _pProcs[WORKER] = new Worker(this); @@ -40,16 +41,15 @@ bool ECTrainer::Process() { // �v���Z�X������ if (!((ECTrainerGUI*)_pProcs[GUI])->Init(_hInstance)) return false; - for (int i = 1; i < PROC::NUM; i++) { + for (int i = 0; i < PROC::NUM - 1; i++) { if (!_pProcs[i]->Init()) return false; } // �X���b�h�J�n - const int N_THREADS = PROC::NUM; // GUI��������KeepAlive��������̂œ��� + const int N_THREADS = PROC::NUM - 1; // GUI�̓��C���X���b�h�Ŏ��s����̂� -1 DWORD thIds[N_THREADS]; HANDLE thHandles[N_THREADS]; - thHandles[0] = CreateThread(NULL, 0, KeepAliveThreadEntry, this, 0, &thIds[0]); - for (int i = 1; i < N_THREADS; i++) { + for (int i = 0; i < N_THREADS; i++) { thHandles[i] = CreateThread(NULL, 0, ThreadEntry, _pProcs[i], 0, &thIds[i]); } _pProcs[GUI]->MainLoop(); @@ -115,10 +115,10 @@ } // KeepAlive�X���b�h�J�n�_ -DWORD WINAPI ECTrainer::KeepAliveThreadEntry(LPVOID lpParameter) { - ((EyeTrack*)((ECTrainer*)lpParameter)->_pProcs[EYETR])->KeepAliveLoop(); - return 0; -} +//DWORD WINAPI ECTrainer::KeepAliveThreadEntry(LPVOID lpParameter) { +// ((EyeTrack*)((ECTrainer*)lpParameter)->_pProcs[EYETR])->KeepAliveLoop(); +// return 0; +//} // ����摜���̒����_�ݒ� void ECTrainer::SetGazeV(cv::Point gazeV) { @@ -131,9 +131,9 @@ } // �h���摜���̒����_�擾 -cv::Point2f ECTrainer::GetGazeI() { - return ((EyeTrack*)_pProcs[EYETR])->GetGazeI(); -} +//cv::Point2f ECTrainer::GetGazeI() { +// return ((EyeTrack*)_pProcs[EYETR])->GetGazeI(); +//} // �E�ڂ̈ʒu�擾 cv::Point2f ECTrainer::GetEyeR() { diff --git a/ECTrainer2/ECTrainer.h b/ECTrainer2/ECTrainer.h index b233889..c9b9b9b 100644 --- a/ECTrainer2/ECTrainer.h +++ b/ECTrainer2/ECTrainer.h @@ -14,24 +14,24 @@ class TobiiREST; class BitalMonitor; class Worker; +class KeepAlive; class Marker; class ECTrainer { private: - enum PROC { GUI, IMGPROC, SCNCAM, STIM, EYETR, REST, BITAL, WORKER, NUM }; + // �v���Z�X�ꗗ KeepAlive -> EyeTrack �̏��K�{ + enum PROC { IMGPROC, SCNCAM, STIM, ALIVE, EYETR, REST, BITAL, WORKER, GUI, NUM }; BaseProcess* _pProcs[PROC::NUM]; HINSTANCE _hInstance; Marker* _pMarker; bool _AppRunning; // ���s���t���O - //bool _HomographyOK; // �ϊ��s��̊l���L�� int _CalibResult; // �L�����u���[�V�������� 0:�����{ 1:���� -1:���s - //cv::Size _SceneSize; // ���E�J�����̉摜�T�C�Y std::wstring _MovieToShow; // �Đ����铮��t�@�C�� // �X���b�h�J�n�_ static DWORD WINAPI ThreadEntry(LPVOID lpParameter); - static DWORD WINAPI KeepAliveThreadEntry(LPVOID lpParameter); + //static DWORD WINAPI KeepAliveThreadEntry(LPVOID lpParameter); public: static const int RINGBUFSIZE = 4; @@ -41,6 +41,7 @@ ImageProc* PImageProc() { return (ImageProc*)_pProcs[IMGPROC]; } SceneCamera* PSceneCamera() { return (SceneCamera*)_pProcs[SCNCAM]; } Stimulus* PStimulus() { return (Stimulus*)_pProcs[STIM]; } + KeepAlive* PKeepAlive() { return (KeepAlive*)_pProcs[ALIVE]; } EyeTrack* PEyeTrack() { return (EyeTrack*)_pProcs[EYETR]; } TobiiREST* PTobiiREST() { return (TobiiREST*)_pProcs[REST]; } BitalMonitor* PBitalMonitor() { return (BitalMonitor*)_pProcs[BITAL]; } @@ -57,7 +58,7 @@ void SetGazeV(cv::Point gazeV); int BatteryLevel(); cv::Point GetGazeV(); - cv::Point2f GetGazeI(); + //cv::Point2f GetGazeI(); cv::Point2f GetEyeR(); cv::Point2f GetEyeL(); diff --git a/ECTrainer2/ECTrainer2.vcxproj b/ECTrainer2/ECTrainer2.vcxproj index 60f43b2..fafaa24 100644 --- a/ECTrainer2/ECTrainer2.vcxproj +++ b/ECTrainer2/ECTrainer2.vcxproj @@ -149,6 +149,7 @@ + @@ -166,6 +167,7 @@ + diff --git a/ECTrainer2/ECTrainer2.vcxproj.filters b/ECTrainer2/ECTrainer2.vcxproj.filters index def3c08..314b9f3 100644 --- a/ECTrainer2/ECTrainer2.vcxproj.filters +++ b/ECTrainer2/ECTrainer2.vcxproj.filters @@ -57,6 +57,9 @@ ソース ファイル + + ソース ファイル + @@ -116,6 +119,9 @@ ヘッダー ファイル + + ヘッダー ファイル + diff --git a/ECTrainer2/ECTrainerGUI.cpp b/ECTrainer2/ECTrainerGUI.cpp index cbd5241..09850d7 100644 --- a/ECTrainer2/ECTrainerGUI.cpp +++ b/ECTrainer2/ECTrainerGUI.cpp @@ -184,10 +184,10 @@ if (_pEct->GetGazeV().x >= 0) { cv::circle(sceneBuf, _pEct->GetGazeV(), 10, CV_RGB(0, 0, 255), 2); } - if (_pEct->GetGazeI().x >= 0) { - cv::circle(CurDisplay, cv::Point((int)_pEct->GetGazeI().x/2, - (int)_pEct->GetGazeI().y/2), 10, CV_RGB(0, 0, 255), 2); - } + //if (_pEct->GetGazeI().x >= 0) { + // cv::circle(CurDisplay, cv::Point((int)_pEct->GetGazeI().x/2, + // (int)_pEct->GetGazeI().y/2), 10, CV_RGB(0, 0, 255), 2); + //} // �h���摜 //fContact = false; @@ -290,7 +290,7 @@ cvui::printf("Mouse W %d, %d", mp.x, mp.y); cvui::printf("Mouse L %.2f, %.2f", imagePos.x, imagePos.y); cvui::printf("View Gaze %d, %d", _pEct->GetGazeV().x, _pEct->GetGazeV().y); - cvui::printf("Img Gaze %.2f, %.2f", _pEct->GetGazeI().x, _pEct->GetGazeI().y); + //cvui::printf("Img Gaze %.2f, %.2f", _pEct->GetGazeI().x, _pEct->GetGazeI().y); cvui::text(_pEct->PMarker()->IsDetected() ? "AR Markers OK" : "AR Markers NG"); cvui::printf("Battery %d %%", _pEct->BatteryLevel()); if (IsPlaying()) { diff --git a/ECTrainer2/ECTrainerGUI.h b/ECTrainer2/ECTrainerGUI.h index a40140b..f38dceb 100644 --- a/ECTrainer2/ECTrainerGUI.h +++ b/ECTrainer2/ECTrainerGUI.h @@ -29,8 +29,8 @@ //std::vector _MovieFiles; std::vector _Displays; cv::Mat _MainFrame; // ���C���E�C���h�E�t���[�� - cv::Mat _DispImage; // �h���摜 - cv::Mat _DispBuffer; // �h����� + cv::Mat _DispImage; // �h���摜�i����җp�j + cv::Mat _DispBuffer; // �h����ʁi�팱�җp�j //cv::Mat _SceneBuffer; // ����摜 cv::Mat _Logo; // ���S cv::Mat _blank; // �u�����N diff --git a/ECTrainer2/EyeTrack.cpp b/ECTrainer2/EyeTrack.cpp index 31b0877..507cecf 100644 --- a/ECTrainer2/EyeTrack.cpp +++ b/ECTrainer2/EyeTrack.cpp @@ -3,69 +3,39 @@ #include #include "EyeTrack.h" #include "ECTrainer.h" +#include "KeepAlive.h" #include "SceneCamera.h" -#include "Marker.h" #include "MeanBuffer.h" #pragma comment(lib, "ws2_32.lib") #include // �R���X�g���N�^ -EyeTrack::EyeTrack(ECTrainer* pEct, Marker* pMarker) +EyeTrack::EyeTrack(ECTrainer* pEct) : BaseProcess(pEct) - , _pMarker(pMarker) - //, _GazeV(-1, -1) - , _GazeI(-1.F, -1.F) - , _KeepAliveSignal(false) - , _GazeV(4) + , _GazeV(ECTrainer::RINGBUFSIZE) { } -// ������ -bool EyeTrack::Init() { - //Initialize winsock - WSADATA wsa; - - if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) - { - std::cerr << "Initialising Winsock Failed with error Code : " << WSAGetLastError() << std::endl; - return false; - } - if ((_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR) - { - std::cerr << "Creating socket failed with error code : " << WSAGetLastError() << std::endl; - return false; - } - - //setup address structure - memset((char*)&_socketAddr, 0, sizeof(_socketAddr)); - _socketAddr.sin_family = AF_INET; - _socketAddr.sin_port = htons(PORT); - InetPton(_socketAddr.sin_family, _T(ADDR), &_socketAddr.sin_addr.S_un.S_addr); - - return true; -} - -// �f�[�^�X���b�h���[�v +// ���C�����[�v bool EyeTrack::MainLoop() { - int slen = sizeof(_socketAddr); - char buf[BUFLEN]; + int slen = _pEct->PKeepAlive()->GetSocketAddrLen(); + char buf[KeepAlive::SOCKET_BUF_LEN]; int lastGidx = 0; - cv::Point2f gp; + cv::Point2f gazePoint; cv::Size sceneSize = _pEct->PSceneCamera()->GetSize(); - std::cout << "sceneSize: " << sceneSize.width << "," << sceneSize.height << std::endl; - MeanBuffer gpCx(DATA_MEAN_SIZE), gpCy(DATA_MEAN_SIZE); - //std::ofstream ofs; - //ofs.open("datalog.txt"); + //std::cout << "sceneSize: " << sceneSize.width << "," << sceneSize.height << std::endl; + MeanBuffer gpCx(MEAN_BUF_SIZE), gpCy(MEAN_BUF_SIZE); - while (!_KeepAliveSignal) Sleep(1); // �ŏ���KeepAlive���M�҂� + while (!_pEct->PKeepAlive()->IsSent()) Sleep(1); // �ŏ���KeepAlive���M�҂� while (_pEct->IsAppRun()) { // �f�[�^��M - memset(buf, '\0', BUFLEN); - if (recvfrom(_socket, buf, BUFLEN, 0, (struct sockaddr*)&_socketAddr, &slen) == SOCKET_ERROR) + memset(buf, '\0', KeepAlive::SOCKET_BUF_LEN); + if (recvfrom(_pEct->PKeepAlive()->GetSocket(), buf, KeepAlive::SOCKET_BUF_LEN, + 0, _pEct->PKeepAlive()->GetSocketAddr(), &slen) == SOCKET_ERROR) { std::cerr << "Data Receive Error" << std::endl; Sleep(10); @@ -75,59 +45,23 @@ // ��M�f�[�^��� GazeData gd(buf); - //ofs << buf; if (gd.gidx > lastGidx) { - //printf("gp %f,%f ", gp.x, gp.y); - if (gp.x > 0 && gp.y > 0) { - gpCx.Push(gp.x * sceneSize.width); - gpCy.Push(gp.y * sceneSize.height); + if (gazePoint.x > 0 && gazePoint.y > 0) { + gpCx.Push(gazePoint.x * sceneSize.width); + gpCy.Push(gazePoint.y * sceneSize.height); _GazeV.Put(cv::Point2f(gpCx.Mean(), gpCy.Mean())); - //_GazeI = _pMarker->ConvV2I(_GazeV.Get()); - //printf("_GazeV %d,%d ", _GazeV.x, _GazeV.y); - //printf("_GazeI %f,%f ", _GazeI.x, _GazeI.y); } else { - _GazeV.Put(gp); + _GazeV.Put(gazePoint); } - //printf("\n"); - gp = cv::Point2f(-1.F, -1.F); + gazePoint = cv::Point2f(-1.F, -1.F); lastGidx = gd.gidx; } if (gd.isGP && gd.s == 0) { - gp = gd.gp; - //_gp = gp; - //TRACE("%d, %f, %f\n", gd.gidx, gd.gpx, gd.gpy); + gazePoint = gd.gp; } - - // ���W�ϊ� - //if (_GazeV.x >= 0 && _GazeV.y >= 0) { - // _GazeI = _pMarker->ConvV2I(_GazeV); - //} else { - // _GazeI = cv::Point2f(-1.F, -1.F); - //} - //Sleep(1); - } - //if (ofs) ofs.close(); - - return true; -} - -// KeepAlive�X���b�h���[�v -bool EyeTrack::KeepAliveLoop() { - const std::string KA_DATA_MSG = "{\"type\": \"live.data.unicast\", \"key\": \"some_GUID\", \"op\": \"start\"}"; - const int KEEP_ALIVE_WAIT_COUNT = 20; // x 100ms - char message[BUFLEN]; - strcpy_s(message, BUFLEN, KA_DATA_MSG.c_str()); - int slen = sizeof(_socketAddr); - - while (_pEct->IsAppRun()) { - if (sendto(_socket, message, (int)strlen(message), 0, (struct sockaddr*)&_socketAddr, slen) == SOCKET_ERROR) { - std::cerr << "Keep Alive Data Sent Error" << std::endl; - } else { - _KeepAliveSignal = true; - } - for (int i = 0; i < KEEP_ALIVE_WAIT_COUNT && _pEct->IsAppRun(); i++) Sleep(100); + if (gd.isPDR && gd.s == 0) _pupilD.r = gd.pdr; } return true; diff --git a/ECTrainer2/EyeTrack.h b/ECTrainer2/EyeTrack.h index e1695cf..0257751 100644 --- a/ECTrainer2/EyeTrack.h +++ b/ECTrainer2/EyeTrack.h @@ -4,45 +4,47 @@ #include "myOpenCV.h" #include "RingBuffer.h" -class Marker; +// LR�e���v���[�g +template +class LR { +public: + T l; + T r; +}; class EyeTrack : public BaseProcess { - static const int PORT = 49152; // The port on which to listen for incoming data - static const int BUFLEN = 512; // Socket�ʐM�o�b�t�@�T�C�Y - static const int DATA_MEAN_SIZE = 20; // �����_�f�[�^�ړ����σT�C�Y + static const int MEAN_BUF_SIZE = 20; // �����_�f�[�^�ړ����σT�C�Y - Marker* _pMarker; RingBuffer _GazeV; // ����摜���̒����_���W - //cv::Point _GazeV; // ����摜���̒����_���W - cv::Point2f _GazeI; // �h���摜���̒����_���W�i���K�����W�n�j - SOCKET _socket; - struct sockaddr_in _socketAddr; - bool _KeepAliveSignal; + LR _pupilD; public: - EyeTrack(ECTrainer* pEct, Marker* pMarker); - bool Init(); + // �R���X�g���N�^ + EyeTrack(ECTrainer* pEct); + // ���C�����[�v bool MainLoop(); - bool KeepAliveLoop(); - //void SetGazeV(cv::Point gazeV) { _GazeV = gazeV; } + // �����_�̍X�V�� bool IsNewGazeV() { return _GazeV.IsNew(); } + // �����_���擾 cv::Point2f GetGazeV() { return _GazeV.Get(); } - cv::Point2f GetGazeI() { return _GazeI; } }; + // �g���b�J�[�f�[�^��̓N���X struct GazeData { long ts = 0; int s = 0; int gidx = 0; int l = 0; - cv::Point2f gp; - cv::Point3f gdr; - cv::Point3f gdl; + cv::Point2f gp; // �����_ + cv::Point3f gdr, gdl; // �����x�N�g�� L,R + float pdr, pdl; // ���E�a L,R bool isGP = false; bool isGDR = false; bool isGDL = false; + bool isPDR = false; + bool isPDL = false; GazeData(char* str) { char* pts = strstr(str, "\"ts\""); @@ -89,5 +91,16 @@ if (pgd) gdl.z = (float)atof(pgd + 1); } } + + char* ppd = strstr(pgidx, "\"pd\""); + if (ppd) { + if (strstr(ppd, "right") != NULL) { + isPDR = true; + pdr = (float)atof(ppd + 5); + } else { + isPDL = true; + pdl = (float)atof(ppd + 5); + } + } } }; diff --git a/ECTrainer2/KeepAlive.cpp b/ECTrainer2/KeepAlive.cpp new file mode 100644 index 0000000..6045559 --- /dev/null +++ b/ECTrainer2/KeepAlive.cpp @@ -0,0 +1,59 @@ +#include +#include +#include +#include "KeepAlive.h" +#include "ECTrainer.h" + +// �R���X�g���N�^ +KeepAlive::KeepAlive(ECTrainer* pEct) + : BaseProcess(pEct) + , _sent(false) + , _socket(NULL) { + _socketAddrLen = sizeof(_socketAddr); + memset((char*)&_socketAddr, 0, _socketAddrLen); +} + +// ������ +bool KeepAlive::Init() { + // Initialize winsock + WSADATA wsa; + if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { + std::cerr << "Initialising Winsock Failed with error Code : " << WSAGetLastError() << std::endl; + return false; + } + + // Create socket + if ((_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR) { + std::cerr << "Creating socket failed with error code : " << WSAGetLastError() << std::endl; + return false; + } + + // setup address structure + _socketAddr.sin_family = AF_INET; + _socketAddr.sin_port = htons(PORT); + InetPton(_socketAddr.sin_family, _T(ADDR), &_socketAddr.sin_addr.S_un.S_addr); + + return true; +} + +// ���C�����[�v +bool KeepAlive::MainLoop() { + const std::string KA_DATA_MSG = "{\"type\": \"live.data.unicast\", \"key\": \"some_GUID\", \"op\": \"start\"}"; + char message[SOCKET_BUF_LEN]; + strcpy_s(message, SOCKET_BUF_LEN, KA_DATA_MSG.c_str()); + + int count = 0; + while (_pEct->IsAppRun()) { + Sleep(100); + if (++count < KEEP_ALIVE_WAIT_COUNT) continue; + count = 0; + if (sendto(_socket, message, (int)strlen(message), 0, + (struct sockaddr*)&_socketAddr, _socketAddrLen) == SOCKET_ERROR) { + std::cerr << "Keep Alive Data Sent Error" << std::endl; + } else { + _sent = true; + } + } + + return true; +} diff --git a/ECTrainer2/KeepAlive.h b/ECTrainer2/KeepAlive.h new file mode 100644 index 0000000..0d86ad7 --- /dev/null +++ b/ECTrainer2/KeepAlive.h @@ -0,0 +1,31 @@ +#pragma once + +#include "BaseProcess.h" + +class KeepAlive : public BaseProcess { + const int PORT = 49152; // The port on which to listen for incoming data + const int KEEP_ALIVE_WAIT_COUNT = 20; // ���M�Ԋu x100ms + + SOCKET _socket; // �\�P�b�g + struct sockaddr_in _socketAddr; // �ڑ���A�h���X + bool _sent; // �V�O�i�����M��� true: ���M�� false: �����M + int _socketAddrLen; // �A�h���X���̃T�C�Y + +public: + static const int SOCKET_BUF_LEN = 512; // Socket�ʐM�o�b�t�@�T�C�Y + + // �R���X�g���N�^ + KeepAlive(ECTrainer* pEct); + // ������ + bool Init(); + // ���C�����[�v + bool MainLoop(); + // �V�O�i�����M��Ԏ擾 + bool IsSent() { return _sent; }; + // �\�P�b�g�擾 + SOCKET GetSocket() { return _socket; } + // �\�P�b�g�A�h���X�擾 + struct sockaddr* GetSocketAddr() { return (struct sockaddr*)&_socketAddr; } + // �\�P�b�g�A�h���X���擾 + int GetSocketAddrLen() { return _socketAddrLen; } +}; diff --git "a/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" "b/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" index 8e4a06a..1685a44 100644 --- "a/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" +++ "b/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" Binary files differ