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