diff --git a/ECTrainer2/BaseProcess.cpp b/ECTrainer2/BaseProcess.cpp index 7f8440f..e54bff3 100644 --- a/ECTrainer2/BaseProcess.cpp +++ b/ECTrainer2/BaseProcess.cpp @@ -1,10 +1,20 @@ #include "BaseProcess.h" #include "ECTrainer.h" -#include +#include "MyWinUtils.h" // �R���X�g���N�^ -BaseProcess::BaseProcess(ECTrainer* pEct) : _pEct(pEct) { +BaseProcess::BaseProcess(ECTrainer* pEct) + : _pEct(pEct) + , _messageQueReady(false) + , _threadHandle(NULL) + , _threadID(0) +{ +} +// �X���b�h�N�� +bool BaseProcess::Launch() { + _threadHandle = ::CreateThread(NULL, 0, ThreadEntry, this, 0, &_threadID); + return true; } // ������ @@ -12,10 +22,60 @@ return true; } -// ���[�v +// �X���b�h�{�� bool BaseProcess::MainLoop() { - while (_pEct->IsAppRun()) { - Sleep(1); + if (_threadID == 0) { + _threadID = ::GetCurrentThreadId(); // ���C���X���b�hID�擾 } + mwut::DebugPrintf(_T("Main thread id=%d\n"), ::GetCurrentThreadId()); + + // ���b�Z�[�W�L���[�̍쐬 + MSG msg; + ::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); + _messageQueReady = true; + + // ���[�v + while (1) { + if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { + if (!::GetMessage(&msg, NULL, 0, 0)) break; + if (!this->EventProc(msg)) break; + } else { + if (!this->Routine()) break; + } + } + return true; +} + +// �񃁃b�Z�[�W���̏��� +bool BaseProcess::Routine() { + + return true; +} + +// ���b�Z�[�W���� +bool BaseProcess::EventProc(MSG &msg) { + mwut::DebugPrintf(_T("Receive Th %d msg %d\n"), _threadID, msg.message); + + return true; +} + +// �X���b�h�N���_ +DWORD WINAPI BaseProcess::ThreadEntry(LPVOID lpParameter) { + if (!((BaseProcess*)lpParameter)->MainLoop()) return 1; + return 0; +} + +// �X���b�h�I���҂� +bool BaseProcess::WaitForExit(DWORD timeOut) { + if (!_threadHandle) return false; + DWORD rv = ::WaitForSingleObject(_threadHandle, timeOut); + return (rv == WAIT_OBJECT_0); +} + +// ���b�Z�[�W�𑗂� +bool BaseProcess::Tell(int msgid) { + if (!_messageQueReady || !_threadID) return false; // ���b�Z�[�W�L���[�̏����m�F + if (::GetCurrentThreadId() == _threadID) ::PostQuitMessage(0); + else ::PostThreadMessage(_threadID, msgid, 0, 0); return true; } diff --git a/ECTrainer2/BaseProcess.h b/ECTrainer2/BaseProcess.h index 93ae5c2..dcd3c0a 100644 --- a/ECTrainer2/BaseProcess.h +++ b/ECTrainer2/BaseProcess.h @@ -1,15 +1,37 @@ #pragma once +#include + class ECTrainer; + // �e�����̊�{�N���X class BaseProcess { protected: ECTrainer* _pEct; + bool _messageQueReady; // ���b�Z�[�W�L���[�̏����� + HANDLE _threadHandle; // �X���b�h�n���h�� + DWORD _threadID; // �X���b�hID + + // �X���b�h�G���g���|�C���g + static DWORD WINAPI ThreadEntry(LPVOID lpParameter); + // �񃁃b�Z�[�W���̏��� + virtual bool Routine(); + // ���b�Z�[�W���� + virtual bool EventProc(MSG& msg); public: + // �R���X�g���N�^ BaseProcess(ECTrainer* pEct); + // �X���b�h�N�� + virtual bool Launch(); + // ������ virtual bool Init(); + // �X���b�h�{�́iprotected, ��virtual) virtual bool MainLoop(); + // �X���b�h�I���҂� + bool WaitForExit(DWORD timeOut = 3000); + // ���b�Z�[�W�𑗂� + bool Tell(int msgid); }; diff --git a/ECTrainer2/BitalMonitor.cpp b/ECTrainer2/BitalMonitor.cpp index f794815..e323248 100644 --- a/ECTrainer2/BitalMonitor.cpp +++ b/ECTrainer2/BitalMonitor.cpp @@ -5,21 +5,25 @@ :BaseProcess(pEct) , _rrInterval(ECTrainer::RINGBUFSIZE, 0) , _useDevice(false) + , _lastRR(0) { + ::ZeroMemory(lastBuf, BUF_LEN); } // ������ bool BitalMonitor::Init() { - char comBuf[256] = { '\0' }; - + // �f�o�C�X�̒T�� for (int com = 1; com <= GComPort::COM_SEARCH_MAX; com++) { if (!_Com.Open(com, _T("baud=19200 parity=N data=8 stop=1"))) continue; // �|�[�g�`�F�b�N - DWORD readBytes = _Com.Receive((BYTE*)comBuf, 256); + char comBuf[BUF_LEN] = { '\0' }; + DWORD readBytes = _Com.Receive((BYTE*)comBuf, BUF_LEN - 1); if (readBytes < 1) continue; + std::cout << "com " << com << " '" << comBuf << "'" << std::endl; + //mwut::DebugPrintf(_T("check com %d\n"), com); if ((*comBuf >= '0' && *comBuf <= '9') || *comBuf == '#' || *comBuf == LF) { mwut::DebugPrintf(_T("Bital device found on com%d\n"), com); _useDevice = true; @@ -33,55 +37,49 @@ } // ���[�v -bool BitalMonitor::MainLoop() { +bool BitalMonitor::Routine() { if (!_useDevice) return true; - char lastBuf[256] = { '\0' }; - char comBuf[256] = { '\0' }; - char valueStr[10] = { '\0' }; - - DWORD lastRR = 0; // �O���RR�擾���ԁi�^�C���A�E�g�� 0�j - while (_pEct->IsAppRun()) { - - // �o�C�^�� - DWORD readBytes = _Com.Receive((BYTE*)comBuf, 256); - if (readBytes > 0) { - comBuf[readBytes] = '\0'; - //std::cout << "comBuf:" << comBuf << std::endl; - strcat_s(lastBuf, 256, comBuf); - //std::cout << "lastBuf:" << lastBuf << std::endl; - char* sp = lastBuf; - char* pt = sp; - for (; *pt != '\0'; pt++) { - if (*pt == LF) { - //*pt = '\0'; - //std::cout << "value:" << sp << std::endl; - if (*sp == '#') { - int RR = atoi(sp + 1); - if (RR > 0) { - _rrInterval.Put(RR); - lastRR = timeGetTime(); - } - //std::cout << "Read:" << RR << std::endl; + // �o�C�^�� + char comBuf[BUF_LEN] = { '\0' }; + DWORD readBytes = _Com.Receive((BYTE*)comBuf, BUF_LEN /2); + if (readBytes > 0) { + std::cout << "readBytes:" << readBytes << std::endl; + comBuf[readBytes] = '\0'; + //std::cout << "comBuf:" << comBuf << std::endl; + strcat_s(lastBuf, BUF_LEN - 1, comBuf); + //std::cout << "lastBuf:" << lastBuf << std::endl; + char* sp = lastBuf; + char* pt = sp; + for (; *pt != '\0'; pt++) { + if (*pt == LF) { + //*pt = '\0'; + //std::cout << "value:" << sp << std::endl; + if (*sp == '#') { + int RR = atoi(sp + 1); + if (RR > 0) { + _rrInterval.Put(RR); + _lastRR = timeGetTime(); } - sp = pt + 1; + //std::cout << "Read:" << RR << std::endl; } + sp = pt + 1; } - if (*sp == '\0') lastBuf[0] = '\0'; - else strcpy_s(lastBuf, 256, sp); - - //std::cout << "lastBuf2:" << lastBuf << std::endl; } + if (*sp == '\0') lastBuf[0] = '\0'; + else strcpy_s(lastBuf, BUF_LEN - 1, sp); - // ���M�����o - if (lastRR > 0 && timeGetTime() - lastRR > NO_SIGNAL_TIMEOUT) { - _rrInterval.Put(0); - lastRR = 0; - } - - Sleep(10); + //std::cout << "lastBuf2:" << lastBuf << std::endl; } + // ���M�����o + if (_lastRR > 0 && timeGetTime() - _lastRR > NO_SIGNAL_TIMEOUT) { + _rrInterval.Put(0); + _lastRR = 0; + } + + Sleep(10); + return true; } diff --git a/ECTrainer2/BitalMonitor.h b/ECTrainer2/BitalMonitor.h index 91f7cc0..db931dc 100644 --- a/ECTrainer2/BitalMonitor.h +++ b/ECTrainer2/BitalMonitor.h @@ -7,18 +7,21 @@ class BitalMonitor : public BaseProcess { - const int COM_PORT = 4; + //const int COM_PORT = 4; const char LF = 10; const DWORD NO_SIGNAL_TIMEOUT = 5000; // ���M���Ɣ��肷�鎞�� (ms) + static const int BUF_LEN = 256; GComPort _Com; RingBuffer _rrInterval; bool _useDevice; + DWORD _lastRR; // �O���RR�擾���ԁi�^�C���A�E�g�� 0�j + char lastBuf[BUF_LEN]; public: BitalMonitor(ECTrainer* pEct); bool Init(); - bool MainLoop(); + bool Routine(); bool IsUseDevice() { return _useDevice; } int GetRR() { return _rrInterval.Get(); } int GetHB() { return _rrInterval.Get() < 1 ? 0 : 60000 / _rrInterval.Get(); } diff --git a/ECTrainer2/ECTrainer.cpp b/ECTrainer2/ECTrainer.cpp index a7d436a..b4f6649 100644 --- a/ECTrainer2/ECTrainer.cpp +++ b/ECTrainer2/ECTrainer.cpp @@ -14,7 +14,6 @@ // �R���X�g���N�^ ECTrainer::ECTrainer(HINSTANCE hInstance) : _AppRunning(true) - //, _CalibResult(0) , _hInstance(hInstance) { _pMarker = new Marker(); @@ -40,20 +39,27 @@ // ������ bool ECTrainer::Process() { // �v���Z�X������ - if (!((ECTrainerGUI*)_pProcs[GUI])->Init(_hInstance)) return false; - for (int i = 0; i < PROC::NUM - 1; i++) { + for (int i = 0; i < PROC::NUM; i++) { if (!_pProcs[i]->Init()) return false; } // �X���b�h�J�n - const int N_THREADS = PROC::NUM - 1; // GUI�̓��C���X���b�h�Ŏ��s����̂� -1 + const int N_THREADS = PROC::NUM - 4; // GUI�̓��C���X���b�h�Ŏ��s����̂� -1 DWORD thIds[N_THREADS]; HANDLE thHandles[N_THREADS]; for (int i = 0; i < N_THREADS; i++) { - thHandles[i] = CreateThread(NULL, 0, ThreadEntry, _pProcs[i], 0, &thIds[i]); + thHandles[i] = CreateThread(NULL, 0, ThreadEntry, _pProcs[i+1], 0, &thIds[i]); + } + for (int i = BITAL; i < NUM; i++) { + if (!_pProcs[i]->Launch()) return false; } _pProcs[GUI]->MainLoop(); + for (int i = BITAL; i < NUM; i++) { + auto rv = _pProcs[i]->WaitForExit(); + mwut::DebugPrintf(_T("Process %d exit %s\n"), i, rv ? _T("ok") : _T("ng")); + } + // �X���b�h�I�� DWORD timeOut = 1000; // �^�C���A�E�g(ms) if (WaitForMultipleObjects(N_THREADS, thHandles, TRUE, timeOut) != WAIT_TIMEOUT) { @@ -68,6 +74,12 @@ return true; } +// �A�v���P�[�V�������~ +void ECTrainer::StopApp() { + _AppRunning = false; + for (int i = 0; i < PROC::NUM; i++) _pProcs[i]->Tell(WM_QUIT); +} + // ���ʃX���b�h�J�n�_ DWORD WINAPI ECTrainer::ThreadEntry(LPVOID lpParameter) { ((BaseProcess*)lpParameter)->MainLoop(); diff --git a/ECTrainer2/ECTrainer.h b/ECTrainer2/ECTrainer.h index 25d4c30..f0dadcb 100644 --- a/ECTrainer2/ECTrainer.h +++ b/ECTrainer2/ECTrainer.h @@ -22,11 +22,11 @@ class ECTrainer { private: - // �v���Z�X�ꗗ KeepAlive -> EyeTrack �̏��K�{ - enum PROC { REST, IMGPROC, SCNCAM, STIM, ALIVE, EYETR, BITAL, WORKER, GUI, NUM }; + // �v���Z�X�ꗗ�i���������j GUI�擪, ALIVE -> EYETR + enum PROC { GUI, REST, IMGPROC, STIM, ALIVE, EYETR, BITAL, WORKER, SCNCAM, NUM }; BaseProcess* _pProcs[PROC::NUM]; - HINSTANCE _hInstance; Marker* _pMarker; + HINSTANCE _hInstance; bool _AppRunning; // ���s���t���O std::wstring _MovieToShow; // �Đ����铮��t�@�C�� @@ -50,8 +50,10 @@ bool Process(); // �C�����C���֐� + HINSTANCE GetInstance() { return _hInstance; } // �C���X�^���X�n���h�� bool IsAppRun() { return _AppRunning; } // �A�v���P�[�V�������s�����ǂ��� - void StopApp() { _AppRunning = false; } // �A�v���P�[�V�������~ + // �A�v���P�[�V�������~ + void StopApp(); void SetMovieToShow(std::wstring file) { _MovieToShow = file; } std::wstring GetMovieToShow() { return _MovieToShow; } }; diff --git a/ECTrainer2/ECTrainerGUI.cpp b/ECTrainer2/ECTrainerGUI.cpp index 93c0514..1d8b86a 100644 --- a/ECTrainer2/ECTrainerGUI.cpp +++ b/ECTrainer2/ECTrainerGUI.cpp @@ -49,7 +49,7 @@ } // ������ -bool ECTrainerGUI::Init(HINSTANCE hInstance) { +bool ECTrainerGUI::Init() { // ���s�‹��̏��擾 std::vector _Displays = mwut::GetDisplayInfo(); // GUI�E�C���h�E @@ -84,7 +84,7 @@ _blank.copyTo(_DispImage); _Logo = cv::imread("../images/ECTLogo2_1480l.png"); - return InitDx(hInstance); + return InitDx(_pEct->GetInstance()); } // DirectX�̏����� @@ -124,236 +124,154 @@ return true; } +// �񃁃b�Z�[�W���̏��� +bool ECTrainerGUI::Routine() { + // ���C���E�C���h�E�t���[���N���A + _MainFrame = cv::Scalar(49, 52, 49); + + //cv::Point2f imagePos = cv::Point2f(-1.F, -1.F); + //if (cvui::iarea(DISP_IMAGE_POS.x, DISP_IMAGE_POS.y, IMAGE_WIDTH, _DispImageHeight) == cvui::OVER) { + // imagePos.x = (float)(mp.x - DISP_IMAGE_POS.x) / IMAGE_WIDTH; + // imagePos.y = (float)(mp.y - DISP_IMAGE_POS.y) / _DispImageHeight; + //} + + // �\���o�b�t�@���� + cv::Mat sceneBuf = _pEct->PImageProc()->GetImage(); + if (sceneBuf.empty()) sceneBuf = _blank; + + cv::Mat CurDisplay = _DispImage.clone(); + + // �����_�̕\�� + if (_pEct->PEyeTrack()->GetGazeV().x >= 0) { + cv::circle(sceneBuf, _pEct->PEyeTrack()->GetGazeV(), 10, CV_RGB(0, 0, 255), 2); + } + + // UI�`�� + cvui::image(_MainFrame, 0, 0, _Logo); + cvui::beginColumn(_MainFrame, 10, 100, 140, -1, 10); + switch (_pEct->PWorker()->GetAppStatus()) { + case APP_STATUS::IDLE: + if (cvui::button(140, 30, "CALIBRATION")) { + _pEct->PSceneCamera()->Tell(WM_USER); + _pEct->PECTrainerGUI()->Tell(WM_USER); + _pEct->PWorker()->StartCalibration(); + } + if (cvui::button(140, 30, "START")) { + //fStimulus = true; + //fKeepContact = false; + //if (!PlayMovie()) _pEct->Stop(); + _pEct->PWorker()->StartStim(); + } + break; + case APP_STATUS::EXEC: + if (cvui::button(140, 30, "STOP")) { + if (!StopMovie()) _pEct->StopApp(); + //fKeepContact = false; + _pEct->PWorker()->StopStim(); + //fStimulus = false; + } + //cvui::trackbar(140, &targetSize, (float)0, (float)3.0); + //cvui::checkbox("Show Eyes", &fShowEyesPos); + //cvui::text(fContact ? "Eyes Contact!" : "No contact"); + break; + } + //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->PEyeTrack()->GetGazeV().x, _pEct->PEyeTrack()->GetGazeV().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->PTobiiREST()->GetBatteryLevel()); + if (IsPlaying()) { + REFTIME tm; + _pMediaPosition->get_CurrentPosition(&tm); + cvui::printf("Movie pos: %.1f", tm); + } + bool snapshot = cvui::button(140, 30, "SNAPSHOT"); + if (cvui::button(140, 30, "QUIT")) _pEct->StopApp(); + if (_pEct->PBitalMonitor()->IsUseDevice()) { + cvui::printf("HeartBeat (bpm)"); + cvui::text(cv::format("%3d", _pEct->PBitalMonitor()->GetHB()), 2.0); + } else { + cvui::printf("HeartBeat no device"); + } + cvui::endColumn(); + cvui::text(_MainFrame, SCENE_BUFFER_POS.x, 100, "SCENE CAMERA"); + //cv::Mat sceneDisp; + //cv::resize(sceneBuf, sceneDisp, DISP_SIZE); + cv::Mat resized = KeepAspectResize(sceneBuf, DISP_SIZE.width); + cvui::image(_MainFrame, SCENE_BUFFER_POS.x, SCENE_BUFFER_POS.y, resized); + cvui::text(_MainFrame, DISP_IMAGE_POS.x, 100, "STIMULUS IMAGE"); + cv::Mat disp; + cv::resize(CurDisplay, disp, cv::Size(IMAGE_WIDTH, _DispImageHeight)); + cvui::image(_MainFrame, DISP_IMAGE_POS.x, DISP_IMAGE_POS.y, disp); + + // �h������ + std::wstring movieToShow = _pEct->GetMovieToShow(); + if (movieToShow.size() > 0) { + _pEct->SetMovieToShow(L""); + if (movieToShow == L"STOP") { + if (!StopMovie()) _pEct->StopApp(); + } else { + if (!PlayMovie(movieToShow)) { + mwut::DebugPrintf(_T("Can't play movie: %s\n"), movieToShow.c_str()); + _pEct->StopApp(); + } + } + } + + // �Đ��I���̃`�F�b�N + if (_pMediaEvent) { + long eventCode; + _pMediaEvent->WaitForCompletion(1, &eventCode);//����̏�Ԃ�⑫ + if (eventCode != 0) { + if (!StopMovie()) _pEct->StopApp(); + //_PlayIndex = (_PlayIndex + 1) % _MovieFiles.size(); + //if (!PlayMovie()) _pEct->Stop(); + } + } + + // ��ʕ\�� + cvui::update(); + cv::imshow(WIN_MAIN, _MainFrame); + cv::imshow(WIN_DISP, _DispBuffer); + if (snapshot) cv::imwrite("d:/usr/dl/snapshot.jpg", _MainFrame); + int key = cv::waitKey(1); + switch (key) { + case '1': + PlaySound(_T("../voices/Good_S.wav"), NULL, SND_FILENAME | SND_ASYNC); + break; + case '2': + PlaySound(_T("../voices/Nice_S.wav"), NULL, SND_FILENAME | SND_ASYNC); + break; + case '3': + PlaySound(_T("../voices/Great_S.wav"), NULL, SND_FILENAME | SND_ASYNC); + break; + case '4': + PlaySound(_T("../voices/Excellent_S.wav"), NULL, SND_FILENAME | SND_ASYNC); + break; + case '5': + PlaySound(_T("../voices/Good_L.wav"), NULL, SND_FILENAME | SND_ASYNC); + break; + case '6': + PlaySound(_T("../voices/Nice_L.wav"), NULL, SND_FILENAME | SND_ASYNC); + break; + case '7': + PlaySound(_T("../voices/Great_L.wav"), NULL, SND_FILENAME | SND_ASYNC); + break; + case '8': + PlaySound(_T("../voices/Excellent_L.wav"), NULL, SND_FILENAME | SND_ASYNC); + break; + } + if (key == KEY_ESC) _pEct->StopApp(); + + return true; +} + // �C�x���g���[�v bool ECTrainerGUI::MainLoop() { - bool fShowEyesPos = true; - //bool fStimulus = false; - bool fContact = false; - bool fCaliblated = true; - //bool fKeepContact = false; - int contactLevel = 0; - float targetSize = 2.0; - clock_t startContact = 0; - while (_pEct->IsAppRun() && cv::getWindowProperty(WIN_MAIN, 0) >= 0) { - - // ���C���E�C���h�E�t���[���N���A - _MainFrame = cv::Scalar(49, 52, 49); - - // �}�E�X�J�[�\���𒍎��_�Ƃ��鏈�� - //cvui::rect(_MainFrame, SCENE_BUFFER_POS.x, SCENE_BUFFER_POS.y, - // SCENE_BUFFER_SIZE.width, SCENE_BUFFER_SIZE.height, 0xFF0000); - cv::Point mp = cvui::mouse(WIN_MAIN); - //if (cvui::iarea(SCENE_BUFFER_POS.x, SCENE_BUFFER_POS.y, IMAGE_WIDTH, _SceneBufferHeight) == cvui::DOWN) { - // _pEct->SetGazeV(cv::Point( - // (int)((mp.x - SCENE_BUFFER_POS.x) / _SceneBufferScale), - // (int)((mp.y - SCENE_BUFFER_POS.y) / _SceneBufferScale))); - //} else { - // _pEct->SetGazeV(cv::Point(-1, -1)); - //} - cv::Point2f imagePos = cv::Point2f(-1.F, -1.F); - if (cvui::iarea(DISP_IMAGE_POS.x, DISP_IMAGE_POS.y, IMAGE_WIDTH, _DispImageHeight) == cvui::OVER) { - imagePos.x = (float)(mp.x - DISP_IMAGE_POS.x) / IMAGE_WIDTH; - imagePos.y = (float)(mp.y - DISP_IMAGE_POS.y) / _DispImageHeight; - } - - // �\���o�b�t�@���� - cv::Mat sceneBuf = _pEct->PImageProc()->GetImage(); - if (sceneBuf.empty()) sceneBuf = _blank; - - cv::Mat CurDisplay = _DispImage.clone(); - - // �����_�̕\�� - if (_pEct->PEyeTrack()->GetGazeV().x >= 0) { - cv::circle(sceneBuf, _pEct->PEyeTrack()->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); - //} - - // �h���摜 - //fContact = false; - //if (fStimulus) { - // float dx = _pEct->GetEyeR().x - _pEct->GetEyeL().x; - // float dy = _pEct->GetEyeR().y - _pEct->GetEyeL().y; - // float eyesDistance = sqrtf(dx * dx + dy * dy); - // float areaSize = eyesDistance * targetSize / 2.0F; - // if (fShowEyesPos) { - // cv::circle(_DispImage, - // cv::Point((int)(_DispImage.cols * _pEct->GetEyeR().x), (int)(_DispImage.rows * _pEct->GetEyeR().y)), - // (int)(_DispImage.rows * 0.03), CV_RGB(0, 128, 0), 2); - // cv::circle(_DispImage, - // cv::Point((int)(_DispImage.cols * _pEct->GetEyeL().x), (int)(_DispImage.rows * _pEct->GetEyeL().y)), - // (int)(_DispImage.rows * 0.03), CV_RGB(0, 128, 0), 2); - // cv::circle(_DispImage, - // cv::Point((int)(_DispImage.cols * _pEct->GetEyeR().x), (int)(_DispImage.rows * _pEct->GetEyeR().y)), - // (int)(_DispImage.cols * areaSize), CV_RGB(200, 200, 0), 2); - // cv::circle(_DispImage, - // cv::Point((int)(_DispImage.cols * _pEct->GetEyeL().x), (int)(_DispImage.rows * _pEct->GetEyeL().y)), - // (int)(_DispImage.cols * areaSize), CV_RGB(200, 200, 0), 2); - // } - // if (_pEct->GetGazeI().x >= 0) { - // float dxR = _pEct->GetEyeR().x - _pEct->GetGazeI().x; - // float dyR = _pEct->GetEyeR().y - _pEct->GetGazeI().y; - // float edR = sqrtf(dxR * dxR + dyR * dyR); - // float dxL = _pEct->GetEyeL().x - _pEct->GetGazeI().x; - // float dyL = _pEct->GetEyeL().y - _pEct->GetGazeI().y; - // float edL = sqrtf(dxL * dxL + dyL * dyL); - // if (edR <= areaSize || edL <= areaSize) { - // fContact = true; - // } - // } - // if (_pEct->GetGazeV().x > 200 && _pEct->GetGazeV().x < 1600 - // && _pEct->GetGazeV().y >100 && _pEct->GetGazeV().y < 900 - // && _PlayIndex % 2 == 1) { - // fContact = true; - // } - //} - - // �R���^�N�g���� - if (fContact) { - if (contactLevel == 0) { - contactLevel = 1; - startContact = clock(); - PlaySound(_T("../voices/Good_S.wav"), NULL, SND_FILENAME | SND_ASYNC); - } else { - if ((clock() - startContact) / CLOCKS_PER_SEC >= (3 * contactLevel)) { - if (contactLevel == 1) PlaySound(_T("../voices/Nice_S.wav"), NULL, SND_FILENAME | SND_ASYNC); - if (contactLevel == 2) PlaySound(_T("../voices/Great_S.wav"), NULL, SND_FILENAME | SND_ASYNC); - if (contactLevel == 3) PlaySound(_T("../voices/Excellent_S.wav"), NULL, SND_FILENAME | SND_ASYNC); - - ++contactLevel; - if (contactLevel > 4) contactLevel = 0; - //targetSize -= 0.2F; - //_pEct->Next(); - } - } - } else { - contactLevel = 0; - } - - // �L�����u���[�V�������� - //if (_pEct->CheckCalibResult() > 0) fCaliblated = true; - - // UI�`�� - cvui::image(_MainFrame, 0, 0, _Logo); - cvui::beginColumn(_MainFrame, 10, 100, 140, -1, 10); - switch (_pEct->PWorker()->GetAppStatus()) { - case APP_STATUS::IDLE: - if (cvui::button(140, 30, "CALIBRATION")) { - _pEct->PWorker()->StartCalibration(); - } - if (fCaliblated) { - if (cvui::button(140, 30, "START")) { - //fStimulus = true; - //fKeepContact = false; - //if (!PlayMovie()) _pEct->Stop(); - _pEct->PWorker()->StartStim(); - } - } - break; - case APP_STATUS::EXEC: - if (cvui::button(140, 30, "STOP")) { - if (!StopMovie()) _pEct->StopApp(); - //fKeepContact = false; - _pEct->PWorker()->StopStim(); - //fStimulus = false; - } - cvui::trackbar(140, &targetSize, (float)0, (float)3.0); - cvui::checkbox("Show Eyes", &fShowEyesPos); - cvui::text(fContact ? "Eyes Contact!" : "No contact"); - break; - } - 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->PEyeTrack()->GetGazeV().x, _pEct->PEyeTrack()->GetGazeV().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->PTobiiREST()->GetBatteryLevel()); - if (IsPlaying()) { - REFTIME tm; - _pMediaPosition->get_CurrentPosition(&tm); - cvui::printf("Movie pos: %.1f", tm); - } - bool snapshot = cvui::button(140, 30, "SNAPSHOT"); - if (cvui::button(140, 30, "QUIT")) _pEct->StopApp(); - if (_pEct->PBitalMonitor()->IsUseDevice()) { - cvui::printf("HeartBeat (bpm)"); - cvui::text(cv::format("%3d", _pEct->PBitalMonitor()->GetHB()), 2.0); - } else { - cvui::printf("HeartBeat no device"); - } - cvui::endColumn(); - cvui::text(_MainFrame, SCENE_BUFFER_POS.x, 100, "SCENE CAMERA"); - //cv::Mat sceneDisp; - //cv::resize(sceneBuf, sceneDisp, DISP_SIZE); - cv::Mat resized = KeepAspectResize(sceneBuf, DISP_SIZE.width); - cvui::image(_MainFrame, SCENE_BUFFER_POS.x, SCENE_BUFFER_POS.y, resized); - cvui::text(_MainFrame, DISP_IMAGE_POS.x, 100, "STIMULUS IMAGE"); - cv::Mat disp; - cv::resize(CurDisplay, disp, cv::Size(IMAGE_WIDTH, _DispImageHeight)); - cvui::image(_MainFrame, DISP_IMAGE_POS.x, DISP_IMAGE_POS.y, disp); - - // �h������ - std::wstring movieToShow = _pEct->GetMovieToShow(); - if (movieToShow.size() > 0) { - _pEct->SetMovieToShow(L""); - if (movieToShow == L"STOP") { - if (!StopMovie()) _pEct->StopApp(); - } else { - if (!PlayMovie(movieToShow)) { - mwut::DebugPrintf(_T("Can't play movie: %s\n"), movieToShow.c_str()); - _pEct->StopApp(); - } - } - } - - // �Đ��I���̃`�F�b�N - if (_pMediaEvent) { - long eventCode; - _pMediaEvent->WaitForCompletion(1, &eventCode);//����̏�Ԃ�⑫ - if (eventCode != 0) { - if (!StopMovie()) _pEct->StopApp(); - //_PlayIndex = (_PlayIndex + 1) % _MovieFiles.size(); - //if (!PlayMovie()) _pEct->Stop(); - } - } - - // ��ʕ\�� - cvui::update(); - cv::imshow(WIN_MAIN, _MainFrame); - cv::imshow(WIN_DISP, _DispBuffer); - if (snapshot) cv::imwrite("d:/usr/dl/snapshot.jpg", _MainFrame); - int key = cv::waitKey(1); - switch (key) { - case '1': - PlaySound(_T("../voices/Good_S.wav"), NULL, SND_FILENAME | SND_ASYNC); - break; - case '2': - PlaySound(_T("../voices/Nice_S.wav"), NULL, SND_FILENAME | SND_ASYNC); - break; - case '3': - PlaySound(_T("../voices/Great_S.wav"), NULL, SND_FILENAME | SND_ASYNC); - break; - case '4': - PlaySound(_T("../voices/Excellent_S.wav"), NULL, SND_FILENAME | SND_ASYNC); - break; - case '5': - PlaySound(_T("../voices/Good_L.wav"), NULL, SND_FILENAME | SND_ASYNC); - break; - case '6': - PlaySound(_T("../voices/Nice_L.wav"), NULL, SND_FILENAME | SND_ASYNC); - break; - case '7': - PlaySound(_T("../voices/Great_L.wav"), NULL, SND_FILENAME | SND_ASYNC); - break; - case '8': - PlaySound(_T("../voices/Excellent_L.wav"), NULL, SND_FILENAME | SND_ASYNC); - break; - } - if (key == KEY_ESC) _pEct->StopApp(); + this->Routine(); } _pEct->StopApp(); return true; diff --git a/ECTrainer2/ECTrainerGUI.h b/ECTrainer2/ECTrainerGUI.h index dcfc64c..51a63aa 100644 --- a/ECTrainer2/ECTrainerGUI.h +++ b/ECTrainer2/ECTrainerGUI.h @@ -57,7 +57,8 @@ public: ECTrainerGUI(ECTrainer* pEct); ~ECTrainerGUI(); - bool Init(HINSTANCE hInstance); + bool Init(); + bool Routine(); bool MainLoop(); HWND GetMainHWnd() { return _hWndMain; } void SetDispBuffer(cv::Mat& img); diff --git a/ECTrainer2/SceneCamera.cpp b/ECTrainer2/SceneCamera.cpp index 85bb27d..668db27 100644 --- a/ECTrainer2/SceneCamera.cpp +++ b/ECTrainer2/SceneCamera.cpp @@ -4,6 +4,8 @@ #include "ECTrainer.h" #include "SceneCamera.h" +#include "ECTrainerGUI.h" +#include "MyWinUtils.h" // �R���X�g���N�^ SceneCamera::SceneCamera(ECTrainer* pEct) @@ -32,14 +34,14 @@ } // ���[�v -bool SceneCamera::MainLoop() { - while (_pEct->IsAppRun()) { - // �V�[���B�e - cv::Mat scene; - _SceneCam >> scene; - _buffer.Put(scene); - Sleep(0); - } +bool SceneCamera::Routine() { + // �V�[���B�e + cv::Mat scene; + _SceneCam >> scene; + _buffer.Put(scene); + Sleep(0); + + _pEct->PECTrainerGUI()->Tell(WM_USER + 1); return true; } diff --git a/ECTrainer2/SceneCamera.h b/ECTrainer2/SceneCamera.h index 1b9c40b..289792e 100644 --- a/ECTrainer2/SceneCamera.h +++ b/ECTrainer2/SceneCamera.h @@ -15,7 +15,7 @@ public: SceneCamera(ECTrainer* pEct); bool Init(); - bool MainLoop(); + bool Routine(); cv::Size GetSize() { return _sceneSize; } cv::Mat GetImage() { return _buffer.Get(); } bool IsNew() { return _buffer.IsNew(); } diff --git a/ECTrainer2/Worker.cpp b/ECTrainer2/Worker.cpp index e81eaec..df51edf 100644 --- a/ECTrainer2/Worker.cpp +++ b/ECTrainer2/Worker.cpp @@ -15,42 +15,45 @@ } _ftprintf(_fpLog, _T("time,gazeVx,gazeVy,H11,H12,H13,H21,H22,H23,H31,H32,H33,RR\n")); - return true; -} - -bool Worker::MainLoop() { _AppStatus = APP_STATUS::IDLE; _StartTime = cv::getTickCount(); - while (_pEct->IsAppRun()) { - // �������X�V��҂� - Sleep(0); - if (!_pEct->PEyeTrack()->IsNewGazeV()) continue; + return true; +} - // ��ԍX�V - if (_AppStatus == APP_STATUS::CALIB) { - switch (_pEct->PTobiiREST()->GetCalibStatus()) { - case CALIB_STATUS::DONE: - _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB_COMPLETE); - this->WriteLog(_T("Calibration complete.")); - _AppStatus = APP_STATUS::IDLE; - break; - case CALIB_STATUS::FAIL: - case CALIB_STATUS::ERR: - _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB_FAILED); - this->WriteLog(_T("Calibration failed.")); - _AppStatus = APP_STATUS::IDLE; - break; - } +bool Worker::Routine() { + + // �������X�V��҂� + Sleep(0); + if (!_pEct->PEyeTrack()->IsNewGazeV()) return true; + + // ��ԍX�V + if (_AppStatus == APP_STATUS::CALIB) { + switch (_pEct->PTobiiREST()->GetCalibStatus()) { + case CALIB_STATUS::DONE: + _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB_COMPLETE); + this->WriteLog(_T("Calibration complete.")); + _AppStatus = APP_STATUS::IDLE; + break; + case CALIB_STATUS::FAIL: + case CALIB_STATUS::ERR: + _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB_FAILED); + this->WriteLog(_T("Calibration failed.")); + _AppStatus = APP_STATUS::IDLE; + break; } - - this->WriteLog(); } - fclose(_fpLog); + this->WriteLog(); + return true; } +// �f�X�g���N�^ +Worker::~Worker() { + fclose(_fpLog); +} + // �L�����u���[�V�����J�n bool Worker::StartCalibration() { if (_AppStatus != APP_STATUS::IDLE) return false; diff --git a/ECTrainer2/Worker.h b/ECTrainer2/Worker.h index 4b20aef..356b72c 100644 --- a/ECTrainer2/Worker.h +++ b/ECTrainer2/Worker.h @@ -21,8 +21,10 @@ public: Worker(ECTrainer* pEct); + // �f�X�g���N�^ + ~Worker(); bool Init(); - bool MainLoop(); + bool Routine(); bool StartCalibration(); bool StartStim(); bool StopStim();