Newer
Older
PrismSoftware / ECTrainer2 / EyeTrack.cpp
#include <winsock2.h>
#include <ws2tcpip.h>
#include "EyeTrack.h"
#include "ECTrainer.h"
#include "Marker.h"
#include "RingBuffer.h"
#pragma comment(lib, "ws2_32.lib")

#include <iostream>

// コンストラクタ
EyeTrack::EyeTrack(ECTrainer* pEct, Marker* pMarker)
	: BaseProcess(pEct)
	, _pMarker(pMarker)
	, _GazeV(-1, -1)
	, _GazeI(-1.F, -1.F)
	, _KeepAliveSignal(false)
{
}

// 初期化
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;
}

// データスレッドループ
bool EyeTrack::MainLoop() {

	int slen = sizeof(_socketAddr);
	char buf[BUFLEN];
	int lastGidx = 0;
	cv::Point2f gp;
	cv::Size sceneSize = _pEct->GetSceneSize();
	std::cout << "sceneSize: " << sceneSize.width << "," << sceneSize.height << std::endl;
	RingBuffer gpCx(DATA_MEAN_SIZE), gpCy(DATA_MEAN_SIZE);
	std::ofstream ofs;
	ofs.open("log.txt");

	while (!_KeepAliveSignal) Sleep(1);	// 最初のKeepAlive送信待ち

	while (_pEct->IsRunning()) {

		// データ受信
		memset(buf, '\0', BUFLEN);
		if (recvfrom(_socket, buf, BUFLEN, 0, (struct sockaddr*)&_socketAddr, &slen) == SOCKET_ERROR)
		{
			std::cerr << "Data Receive Error" << std::endl;
			Sleep(10);
			continue;
		}
		//std::cout << buf << std::endl;

		// 受信データ解析
		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);
				_GazeV = cv::Point((int)gpCx.Mean(), (int)gpCy.Mean());
				_GazeI = _pMarker->ConvV2I(_GazeV);
				//printf("_GazeV %d,%d ", _GazeV.x, _GazeV.y);
				//printf("_GazeI %f,%f ", _GazeI.x, _GazeI.y);
			}
			//printf("\n");

			gp = cv::Point(0, 0);
			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);
		}

		// 座標変換
		//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スレッドループ
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->IsRunning()) {
		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->IsRunning(); i++) Sleep(100);
	}

	return true;
}