#include "ECTrainer.h"
#include "ECTrainerGUI.h"
#include "SceneCamera.h"
#include "Stimulus.h"
#include "Marker.h"
#include "ImageProc.h"
#include "EyeTrack.h"
#include "TobiiREST.h"
// コンストラクタ
ECTrainer::ECTrainer(HINSTANCE hInstance)
: _pGui(NULL)
, _pSceneCam(NULL)
, _pStimulus(NULL)
, _pMarker(NULL)
, _pImageProc(NULL)
, _pEyeTrack(NULL)
, _pTobiiREST(NULL)
, _Running(true)
, _HomographyOK(false)
, _CalibResult(0)
, _hInstance(hInstance)
{
_pMarker = new Marker();
_pGui = new ECTrainerGUI(this);
_pImageProc = new ImageProc(this, _pMarker);
_pSceneCam = new SceneCamera(this, _pImageProc);
_pStimulus = new Stimulus(this, _pMarker);
_pEyeTrack = new EyeTrack(this, _pMarker);
_pTobiiREST = new TobiiREST(this);
}
// デストラクタ
ECTrainer::~ECTrainer() {
if (_pGui) delete _pGui;
if (_pSceneCam) delete _pSceneCam;
if (_pStimulus) delete _pStimulus;
if (_pMarker) delete _pMarker;
if (_pImageProc) delete _pImageProc;
if (_pEyeTrack) delete _pEyeTrack;
if (_pTobiiREST) delete _pTobiiREST;
}
// 初期化
bool ECTrainer::Process() {
if (!_pGui->Init(_hInstance)) return false;
if (!_pSceneCam->Init()) return false;
if (!_pStimulus->Init()) return false;
if (!_pImageProc->Init()) return false;
if (!_pEyeTrack->Init()) return false;
if (!_pTobiiREST->Init()) return false;
DWORD dwThreadIdSceneCam, dwThreadIdStimulus, dwThreadIdImageProc, dwThreadIdEyeTrack, dwThreadIdKeepAlive, dwThreadTobiiREST;
HANDLE hThreadSceneCam = CreateThread(NULL, 0, ThreadEntry, _pSceneCam, 0, &dwThreadIdSceneCam);
HANDLE hThreadStimulus = CreateThread(NULL, 0, ThreadEntry, _pStimulus, 0, &dwThreadIdStimulus);
HANDLE hThreadImageProc = CreateThread(NULL, 0, ThreadEntry, _pImageProc, 0, &dwThreadIdImageProc);
HANDLE hThreadEyeTrack = CreateThread(NULL, 0, ThreadEntry, _pEyeTrack, 0, &dwThreadIdEyeTrack);
HANDLE hThreadKeepAlive = CreateThread(NULL, 0, KeepAliveThreadEntry, this, 0, &dwThreadIdKeepAlive);
HANDLE hThreadTobiiREST = CreateThread(NULL, 0, ThreadEntry, _pTobiiREST, 0, &dwThreadTobiiREST);
_pGui->MainLoop();
HANDLE handles[] = { hThreadSceneCam , hThreadStimulus, hThreadImageProc, hThreadEyeTrack, hThreadKeepAlive, hThreadTobiiREST };
DWORD timeOut = 1000; // タイムアウト(ms)
if (WaitForMultipleObjects(sizeof(handles) / sizeof(HANDLE), handles, TRUE, timeOut) != WAIT_TIMEOUT) {
OutputDebugString(_T("All threads stopped sccessfully.\n"));
} else {
OutputDebugString(_T("Waiting threads stop timeout.\n"));
}
if (hThreadSceneCam) CloseHandle(hThreadSceneCam);
if (hThreadStimulus) CloseHandle(hThreadStimulus);
if (hThreadImageProc) CloseHandle(hThreadImageProc);
if (hThreadEyeTrack) CloseHandle(hThreadEyeTrack);
if (hThreadKeepAlive) CloseHandle(hThreadKeepAlive);
if (hThreadTobiiREST) CloseHandle(hThreadTobiiREST);
return true;
}
// キャリブレーション開始
void ECTrainer::CalibStart() {
_pStimulus->SetStimulus(Stimulus::STIM::CALIB);
_pTobiiREST->Start();
}
// キャリブレーション結果表示
int ECTrainer::CheckCalibResult() {
int res = _CalibResult;
if (res > 0) _pStimulus->SetStimulus(Stimulus::STIM::CALIB_COMPLETE);
if (res < 0) _pStimulus->SetStimulus(Stimulus::STIM::CALIB_FAILED);
_CalibResult = 0;
return res;
}
// 開始
void ECTrainer::Start() {
_pStimulus->SetStimulus(Stimulus::STIM::START);
}
// 次へ
void ECTrainer::Next() {
_pStimulus->SetStimulus(Stimulus::STIM::NEXT);
}
// 視野画像バッファに画像を設定
void ECTrainer::SetSceneBuffer(cv::Mat& img) {
_pGui->SetSceneBuffer(img);
}
// 刺激画像バッファに画像を設定
void ECTrainer::SetDispBuffer(cv::Mat& img) {
_pGui->SetDispBuffer(img);
}
// 共通スレッド開始点
DWORD WINAPI ECTrainer::ThreadEntry(LPVOID lpParameter) {
((BaseProcess*)lpParameter)->MainLoop();
return 0;
}
// KeepAliveスレッド開始点
DWORD WINAPI ECTrainer::KeepAliveThreadEntry(LPVOID lpParameter) {
((ECTrainer*)lpParameter)->_pEyeTrack->KeepAliveLoop();
return 0;
}
// 視野画像中の注視点設定
void ECTrainer::SetGazeV(cv::Point gazeV) {
_pEyeTrack->SetGazeV(gazeV);
}
// 視野画像中の注視点取得
cv::Point ECTrainer::GetGazeV() {
return _pEyeTrack->GetGazeV();
}
// 刺激画像中の注視点取得
cv::Point2f ECTrainer::GetGazeI() {
return _pEyeTrack->GetGazeI();
}
// 右目の位置取得
cv::Point2f ECTrainer::GetEyeR() {
return _pStimulus->GetEyeR();
}
// 右目の位置取得
cv::Point2f ECTrainer::GetEyeL() {
return _pStimulus->GetEyeL();
}
// バッテリー残量取得
int ECTrainer::BatteryLevel() {
return _pTobiiREST->BatteryLevel();
}