andrewm@0: /*
andrewm@0:  * logger.cpp
andrewm@0:  *
andrewm@0:  *  Created on: Aug 6, 2014
andrewm@0:  *      Author: VIctor Zappi and Andrew McPherson
andrewm@0:  */
andrewm@0: 
andrewm@0: #include "logger.h"
andrewm@0: 
andrewm@0: // main extern vars
andrewm@0: extern bool gShouldStop;
andrewm@0: extern int gVerbose;
andrewm@0: 
andrewm@0: // file nanme extern vars
andrewm@0: extern char gId;
andrewm@0: extern char gGroup;
andrewm@0: 
andrewm@0: 
andrewm@0: // logged extern vars
andrewm@0: extern int s0TouchNum;
andrewm@0: extern float s0Touches_[MAX_TOUCHES];
andrewm@0: extern float s0Size_[MAX_TOUCHES];
andrewm@0: extern int s0LastIndex;
andrewm@0: 
andrewm@0: extern int s1TouchNum;
andrewm@0: extern float s1Touches_[MAX_TOUCHES];
andrewm@0: extern float s1Size_[MAX_TOUCHES];
andrewm@0: extern int s1LastIndex;
andrewm@0: 
andrewm@0: extern int fsr;
andrewm@0: 
andrewm@0: 
andrewm@0: 
andrewm@0: string logPath			= "/boot/uboot/instrumentLog";
andrewm@0: string logFileIncipit	= "/datalog";
andrewm@0: string logFileName		= "";
andrewm@0: ofstream logFile;
andrewm@0: timeval logTimeVal;
andrewm@0: unsigned long long logTimeOrig;
andrewm@0: int logCnt				= 0;	// counts how many lines so far
andrewm@0: int logCntSwap			= 50;	// how many log lines before closing and re-opening the file
andrewm@0: 
andrewm@0: 
andrewm@0: // create the log file, using incremental name convention
andrewm@0: int initLogLoop()
andrewm@0: {
andrewm@0: 	if(gVerbose==1)
andrewm@0: 		cout << "---------------->Init Log Thread" << endl;
andrewm@0: 
andrewm@0: 
andrewm@0: 	// transform chars into strings via stringstream objs
andrewm@0: 	stringstream id_ss, group_ss, freedom_ss;
andrewm@0: 	id_ss 		<< gId;
andrewm@0: 	group_ss 	<< gGroup;
andrewm@0: 
andrewm@0: 	int logNum	= -1;
andrewm@0: 	int logMax	= -1;
andrewm@0: 	int pathLen	= logPath.length() + logFileIncipit.length() + 4;	// + 4 is: "_", id, group, "_"
andrewm@0: 	glob_t globbuf;
andrewm@0: 
andrewm@0: 	// check how many log files are already there, and choose name according to this
andrewm@0: 	glob( (logPath + logFileIncipit + "*").c_str(), 0, NULL, &globbuf);
andrewm@0: 
andrewm@0: 	// cycle through all and find the highest index
andrewm@0: 	for(unsigned int i=0; i<globbuf.gl_pathc; i++)
andrewm@0: 	{
andrewm@0: 		// playing with 0-9 char digits, forming a number from 0 to 9999
andrewm@0: 		logNum  = (globbuf.gl_pathv[i][pathLen]-48)   * 1000;	// 42 to 45 are the indices of the chars forming the file index
andrewm@0: 		logNum += (globbuf.gl_pathv[i][pathLen+1]-48) * 100;
andrewm@0: 		logNum += (globbuf.gl_pathv[i][pathLen+2]-48) * 10;
andrewm@0: 		logNum +=  globbuf.gl_pathv[i][pathLen+3]-48;
andrewm@0: 		if(logNum > logMax)
andrewm@0: 			logMax = logNum;
andrewm@0: 	}
andrewm@0: 	logNum = logMax + 1;	// new index
andrewm@0: 
andrewm@0: 	globfree(&globbuf);
andrewm@0: 
andrewm@0: 	ostringstream numString;
andrewm@0: 	numString << setw (4) << setfill ('0') << logNum;	// set integer with 4 figures
andrewm@0: 
andrewm@0: 	// here are the new names: PATH + DIR + INCIPIT + _ + id + group + freedom + _ + NUM (4figures) + _A.txt
andrewm@0: 	logFileName	= logPath + logFileIncipit;
andrewm@0: 	logFileName	+= "_" + id_ss.str() + group_ss.str() + freedom_ss.str();
andrewm@0: 	logFileName	+= "_" + numString.str();	 //static_cast<ostringstream*>( &(ostringstream() << logNum) )->str();
andrewm@0: 	logFileName	+= ".txt";
andrewm@0: 
andrewm@0: 
andrewm@0: 	// create new files
andrewm@0: 	FILE *fp_a		= fopen(logFileName.c_str(), "wb");
andrewm@0: 	if(!fp_a)
andrewm@0: 	{
andrewm@0: 		dbox_printf("Cannot create files...\n");
andrewm@0: 		return 2;
andrewm@0: 	}
andrewm@0: 	fclose(fp_a);
andrewm@0: 
andrewm@0: 	// ready to append
andrewm@0: 	logFile.open(logFileName.c_str(), ios::out | ios::app);
andrewm@0: 
andrewm@0: 	dbox_printf("Logging on file %s\n", logFileName.c_str());
andrewm@0: 
andrewm@0: 	return 0;
andrewm@0: }
andrewm@0: 
andrewm@0: 
andrewm@0: void writeData(unsigned long long time)
andrewm@0: {
andrewm@0: 
andrewm@0: 	float fsr_ = ((float)(1799-fsr)/1799.0);
andrewm@0: 	logFile << time 				<< "\t"		// timestamp
andrewm@0: 			<< s0TouchNum			<< "\t";	// sensor 0 touch count
andrewm@0: 	for(int i=0; i<MAX_TOUCHES; i++)
andrewm@0: 		logFile << s0Touches_[i] 	<< "\t";	// sensor 0 touch pos x
andrewm@0: 	for(int i=0; i<MAX_TOUCHES; i++)
andrewm@0: 		logFile << s0Size_[i] 		<< "\t";	// sensor 0 touch size
andrewm@0: 	logFile << s0LastIndex 			<< "\t"		// sensor 0 last index
andrewm@0: 			<< fsr_					<< "\t"		// sensor 0 FSR pressure
andrewm@0: 			<< s1TouchNum			<< "\t";	// sensor 1 touch count
andrewm@0: 	for(int i=0; i<MAX_TOUCHES; i++)
andrewm@0: 		logFile << s1Touches_[i] 	<< "\t";	// sensor 1 touch pos x
andrewm@0: 	for(int i=0; i<MAX_TOUCHES; i++)
andrewm@0: 		logFile	<< s1Size_[i] 		<< "\t";	// sensor 1 touch size
andrewm@0: 	logFile << s1LastIndex 			<< "\t"		// sensor 1 last index
andrewm@0: 	//... AND SO ON
andrewm@0: 			<< "\n";
andrewm@0: 
andrewm@0: 	//dbox_printf("%d\n", s0LastIndex);
andrewm@0: 	//dbox_printf("s0TouchNum: %d\t s0Touches[0]: %f\t s0Size[0]: %f\t s0LastIndex: %d\n", s0TouchNum, s0Touches_[0], s0Size_[0], s0LastIndex);
andrewm@0: 
andrewm@0: }
andrewm@0: 
andrewm@0: void logData(unsigned long long time)
andrewm@0: {
andrewm@0: 	// if it's time to change write-file
andrewm@0: 	if(logCnt >= logCntSwap)
andrewm@0: 	{
andrewm@0: 		logFile.close();	// close file, dump stream
andrewm@0: 		logCnt = 0;		// ready for another whole round
andrewm@0: 
andrewm@0: 		// open again, ready to append
andrewm@0: 		logFile.open(logFileName.c_str(), ios::out | ios::app);
andrewm@0: 	}
andrewm@0: 
andrewm@0: 	writeData(time);
andrewm@0: 
andrewm@0: 	logCnt++;
andrewm@0: }
andrewm@0: 
andrewm@0: 
andrewm@0: 
andrewm@0: 
andrewm@0: void *logLoop(void *)
andrewm@0: {
andrewm@0: 	set_realtime_priority(10);
andrewm@0: 
andrewm@0: 	if(gVerbose==1)
andrewm@0: 		dbox_printf("_________________Log Thread!\n");
andrewm@0: 
andrewm@0: 	// get time reference
andrewm@0: 	gettimeofday(&logTimeVal, NULL);
andrewm@0: 	logData(0);
andrewm@0: 
andrewm@0: 	logTimeOrig = logTimeVal.tv_usec;
andrewm@0: 	logTimeOrig *= 0.001;					// from usec to msec
andrewm@0: 	logTimeOrig += logTimeVal.tv_sec*1000;	// from sec to msec
andrewm@0: 
andrewm@0: 	usleep(5000);
andrewm@0: 
andrewm@0: 	while(!gShouldStop)
andrewm@0: 	{
andrewm@0: 		gettimeofday(&logTimeVal, NULL);
andrewm@0: 		unsigned long long currentTime = logTimeVal.tv_usec;
andrewm@0: 		currentTime *= 0.001;					// from usec to msec
andrewm@0: 		currentTime += logTimeVal.tv_sec*1000;	// from sec to msec
andrewm@0: 
andrewm@0: 		logData(currentTime-logTimeOrig);
andrewm@0: 
andrewm@0: 		usleep(5000);
andrewm@0: 	}
andrewm@0: 
andrewm@0: 	if(logFile!=NULL)
andrewm@0: 		logFile.close();
andrewm@0: 
andrewm@0: 	dbox_printf("log thread ended\n");
andrewm@0: 
andrewm@0: 	return (void *)0;
andrewm@0: }