Newer
Older
PrismSoftware / ECTrainer2 / Worker.cpp
#include "BaseProcess.h"
#include "Worker.h"
#include "ECTrainer.h"
#include "EyeTrack.h"
#include "Stimulus.h"
#include "BitalMonitor.h"
#include "Marker.h"
#include "myWinUtils.h"

// コンストラクタ
Worker::Worker(ECTrainer* pEct) : BaseProcess(pEct)
	, _AppStatus(APP_STATUS::BOOT)
	, _fpLogData(NULL)
	, _fpLogEvent(NULL)
	, _pTimer(NULL)
{
}

// デストラクタ
Worker::~Worker() {
	if (_fpLogData) fclose(_fpLogData);
	if (_fpLogEvent) fclose(_fpLogEvent);
	mwut::SafeDelete((void**)&_pTimer);
}

// 初期化
bool Worker::Init() {
	if (_tfopen_s(&_fpLogData, DATA_LOG_FILE, _T("w")) != 0) {
		_pEct->MsgBox(_T("Can't open data log file."), MB_ICONERROR);
		return false;
	}
	_ftprintf(_fpLogData, _T("time,gazeVx,gazeVy,H11,H12,H13,H21,H22,H23,H31,H32,H33,RR\n"));

	if (_tfopen_s(&_fpLogEvent, EVENT_LOG_FILE, _T("w")) != 0) {
		_pEct->MsgBox(_T("Can't open event log file."), MB_ICONERROR);
		return false;
	}

	_AppStatus = APP_STATUS::IDLE;
	_pTimer = new mwut::HPTimer();

	return true;
}

// 基本処理
bool Worker::Routine() {

	// 視線情報更新を待つ
	Sleep(0);
	if (!_pEct->PEyeTrack()->IsNewGazeV()) return true;

	this->DataLog();

	return true;
}

// イベント処理
bool Worker::EventProc(MSG& msg) {
	switch (msg.message) {
	case (int)ECTMSG::CALIB_START: // キャリブレーション開始
		if (_AppStatus == APP_STATUS::IDLE) {
			_AppStatus = APP_STATUS::CALIB;
			((BaseProcess*)_pEct->PStimulus())->Tell(ECTMSG::CALIB_START);
			((BaseProcess*)_pEct->PTobiiREST())->Tell(ECTMSG::CALIB_START);
			this->EventLog(_T("Calibration Start"));
		}
		break;

	case (int)ECTMSG::CALIB_OK:	// キャリブレーション成功
		_AppStatus = APP_STATUS::IDLE;
		((BaseProcess*)_pEct->PStimulus())->Tell(ECTMSG::CALIB_OK);
		this->EventLog(_T("Calibration Success"));
		break;

	case (int)ECTMSG::CALIB_FAILED:	// キャリブレーション失敗
	case (int)ECTMSG::CALIB_ERR:	// キャリブレーションエラー
		_AppStatus = APP_STATUS::IDLE;
		((BaseProcess*)_pEct->PStimulus())->Tell(ECTMSG::CALIB_FAILED);
		this->EventLog(_T("Calibration Failed"));
		break;

	case (int)ECTMSG::EXP_START: // 実験開始
		if (_AppStatus == APP_STATUS::IDLE) {
			_AppStatus = APP_STATUS::STIM;
			((BaseProcess*)_pEct->PStimulus())->Tell(ECTMSG::EXP_START);
			this->EventLog(_T("Experiment Start"));
		}
		break;

	case (int)ECTMSG::EXP_STOP: // 実験停止
		if (_AppStatus == APP_STATUS::STIM) {
			_AppStatus = APP_STATUS::IDLE;
			((BaseProcess*)_pEct->PStimulus())->Tell(ECTMSG::EXP_STOP);
			this->EventLog(_T("Experiment Stopped"));
		}
		break;

	case (int)ECTMSG::EXP_END: // 実験終了
		if (_AppStatus == APP_STATUS::STIM) {
			_AppStatus = APP_STATUS::IDLE;
			((BaseProcess*)_pEct->PStimulus())->Tell(ECTMSG::EXP_STOP);
			this->EventLog(_T("Experiment Finished"));
		}
		break;

	case (int)ECTMSG::EXP_NEXT: // 次の刺激に移動
		this->EventLog(_T("Next stimulation"));
		break;

	case (int)ECTMSG::MOVIE_START: // 動画再生開始
		this->EventLog(_T("Movie Start"));
		break;

	case (int)ECTMSG::MOVIE_STOP: // 動画再生停止
		this->EventLog(_T("Movie Stopped"));
		break;

	case (int)ECTMSG::MOVIE_END: // 動画再生終了
		this->EventLog(_T("Movie End"));
		break;

	case (int)ECTMSG::MOVIE_ERROR: // 動画エラー
		this->EventLog(_T("Movie Error"));
		break;
	}
	return true;
}

// データログ出力
void Worker::DataLog() {
	_ftprintf(_fpLogData, _T("%.1f"), _pTimer->Elapse());

	cv::Point2f gazeV = (_pEct->PEyeTrack()->GetGazeV());
	_ftprintf(_fpLogData, _T(",%.1f,%.1f"), gazeV.x, gazeV.y);
	cv::Mat h = _pEct->PMarker()->GetHomography();
	if (!h.empty() && h.rows == 3 && h.cols == 3) {
		double* ptr = h.ptr<double>(0);
		for (int i = 0; i < 9; i++) {
			_ftprintf(_fpLogData, _T(",%lf"), *(ptr + i));
		}
	}

	_ftprintf(_fpLogData, _T(",%d"), _pEct->PBitalMonitor()->GetRR());
	_ftprintf(_fpLogData, _T("\n"));
}

// イベントログ出力
void Worker::EventLog(const TCHAR* msg) {
	_ftprintf(_fpLogEvent, _T("%.1f"), _pTimer->Elapse());
	_ftprintf(_fpLogEvent, _T(" %s\n"), msg);
}