psycho-sra.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "Component/ModelManager.H"
00040 #include "Image/Image.H"
00041 #include "Psycho/PsychoDisplay.H"
00042 #include "Psycho/EyeTrackerConfigurator.H"
00043 #include "Psycho/EyeTracker.H"
00044 #include "Psycho/PsychoOpts.H"
00045 #include "Component/EventLog.H"
00046 #include "Component/ComponentOpts.H"
00047 #include "Raster/Raster.H"
00048 #include "Util/MathFunctions.H"
00049 #include "Util/Types.H"
00050 #include "GameBoard/basic-graphics.H"
00051 #include <sys/types.h>
00052 #include <dirent.h>
00053 #include <errno.h>
00054 #include <vector>
00055 #include <string>
00056 #include <iostream>
00057 #include <SDL/SDL.h>
00058 #include <SDL/SDL_image.h>
00059 #include <SDL/SDL_mixer.h>
00060 #include <stdio.h>
00061 #include <stdlib.h>
00062 #include <sstream>
00063 #include <time.h>
00064 #include "Image/DrawOps.H"
00065 #include "GameBoard/resize.h"
00066 #include <iostream>
00067 #include <fstream>
00068 #include <set>
00069 #include <algorithm>
00070 #include <ctime>
00071
00072 #ifndef INVT_HAVE_LIBSDL_IMAGE
00073 #include <cstdio>
00074 int main()
00075 {
00076 fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00077 return 1;
00078 }
00079
00080 #else
00081
00082
00083
00084 using namespace std;
00085
00086
00087
00088 ModelManager manager("Psycho sra");
00089 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00090 map<string,string> argMap ;
00091
00092
00093
00094
00095 template <class T> std::string stringify(T i)
00096 {
00097 ostringstream o ;
00098 o << i ;
00099 return o.str();
00100 }
00101
00102
00103
00104
00105
00106 int addArgument(const string st,const string delim="="){
00107 int i = st.find(delim) ;
00108 argMap[st.substr(0,i)] = st.substr(i+1);
00109
00110 return 0 ;
00111 }
00112
00113 std::string getArgumentValue(string arg){
00114 return argMap[arg] ;
00115 }
00116
00117
00118
00119 std::string getUsageComment(){
00120
00121 string com = string("\nlist of arguments : \n");
00122
00123 com += "\nlogfile=[logfilename.psy] {default = psycho-sm-or.psy}\n" ;
00124 com += "\nmemo=[a_string_without_white_space]\n";
00125 com += "\nsubject=[subject_name] \n" ;
00126 com += "\nnum-of-trials=[>1] (number of trials ) {default=10}\n";
00127 com += "\nmode=[1,2](1 for horizontal and 2 for vertical layout}\n";
00128 com += "\ndot-onset=[>1](number of frames that the single dot should be presented){default=16}\n";
00129 com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00130 com += "\ntone1=[a valid file name](name of wav file without extension for tone 1){default=sin}\n";
00131 com += "\ntone2=[a valid file name](name of wav file without extension for tone 2){default=square}\n";
00132 com += "\ndelay=[ delay value in terms of frames befor recall signal]\n";
00133 com += "\ngaze-park1-x\n";
00134 com += "\ngaze-park1-y\n";
00135 com += "\ngaze-park2-x\n";
00136 com += "\ngaze-park2-y\n";
00137 return com ;
00138 }
00139
00140 void initialize(){
00141 argMap["experiment"]="spatial-recall-accuracy(sra)";
00142 argMap["logfile"]="./psycho-sra.psy" ;
00143 argMap["num-of-trials"]="10";
00144 argMap["subject"]="" ;
00145 argMap["memo"]="" ;
00146 argMap["delay1"]="60";
00147 argMap["delay2"]="120";
00148 argMap["mode"]="1" ;
00149 argMap["sound-dir"]="..";
00150 argMap["tone1"]="sine";
00151 argMap["tone2"]="square";
00152 argMap["gaze-park-x"]="-1";
00153 argMap["gaze-park-y"]="-1";
00154 argMap["dot-onset"]="30";
00155 argMap["number-of-intervals"]="3";
00156 argMap["interval-distance"]="120";
00157 argMap["interval-width"]="120";
00158 argMap["gaze-park1-x"]="840";
00159 argMap["gaze-park1-y"]="240";
00160 argMap["gaze-park2-x"]="1080";
00161 argMap["gaze-park2-y"]="240";
00162 }
00163
00164 extern "C" int main(const int argc, char** argv)
00165 {
00166 MYLOGVERB = LOG_INFO;
00167 initialize();
00168
00169 manager.addSubComponent(d);
00170 nub::soft_ref<EventLog> el(new EventLog(manager));
00171 manager.addSubComponent(el);
00172 d->setEventLog(el);
00173 nub::soft_ref<EyeTrackerConfigurator>
00174 etc(new EyeTrackerConfigurator(manager));
00175 manager.addSubComponent(etc);
00176 if (manager.parseCommandLine(argc, argv,"at least one argument needed", 1, -1)==false){
00177 cout<<getUsageComment()<<endl;
00178 return(1);
00179 }
00180
00181 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00182 addArgument(manager.getExtraArg(i),std::string("=")) ;
00183 }
00184
00185 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00186 manager.setOptionValString(&OPT_EyeTrackerType, "EL");
00187 nub::soft_ref<EyeTracker> eyet = etc->getET();
00188 d->setEyeTracker(eyet);
00189 eyet->setEventLog(el);
00190 manager.start();
00191
00192
00193
00194
00195
00196
00197
00198
00199 eyet->setBackgroundColor(d);
00200
00201
00202 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00203
00204
00205
00206
00207 int mode = atoi(argMap["mode"].c_str());
00208 int num_of_trials = atoi(argMap["num-of-trials"].c_str());
00209 int gaze1_x = atoi(argMap["gaze-park1-x"].c_str());
00210 int gaze1_y = atoi(argMap["gaze-park1-y"].c_str());
00211 int gaze2_x = atoi(argMap["gaze-park2-x"].c_str());
00212 int gaze2_y = atoi(argMap["gaze-park2-y"].c_str());
00213 int delay1 = atoi(argMap["delay1"].c_str());
00214 int delay2 = atoi(argMap["delay2"].c_str());
00215 int dot_onset = atoi(argMap["dot-onset"].c_str());
00216 int interval_distance = atoi(argMap["interval-distance"].c_str());
00217 int interval_width = atoi(argMap["interval-width"].c_str());
00218
00219
00220
00221 Mix_Music* tone1 = NULL;
00222 Mix_Music* tone2 = NULL;
00223
00224 if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00225 LINFO( "did not open the mix-audio") ;
00226
00227 }
00228 string tmpstr = argMap["sound-dir"]+"/"+argMap["tone1"]+".wav";
00229 tone1 = Mix_LoadMUS(tmpstr.c_str());
00230 tmpstr = argMap["sound-dir"]+"/"+argMap["tone2"]+".wav";
00231 tone2 = Mix_LoadMUS(tmpstr.c_str());
00232
00233
00234
00235
00236 d->clearScreen();
00237 d->displayISCANcalib();
00238 d->waitForMouseClick();
00239 d->clearScreen();
00240 d->waitForMouseClick();
00241 d->displayText("Here the experiment starts! click to start!");
00242 d->waitForMouseClick();
00243 d->displayText("CLICK for calibration!");
00244 d->waitForMouseClick();
00245 eyet->calibrate(d);
00246 d->clearScreen();
00247
00248
00249 for(int tr = 0 ; tr < num_of_trials ; tr++){
00250 int intr = rand()%3 -1;
00251 int gaze_park_x=0;
00252 int gaze_park_y=0;
00253 if(intr == -1){
00254 gaze_park_x = gaze1_x ; gaze_park_y = gaze1_y;
00255 }
00256 if(intr == 0){
00257 int peshk = rand()%2;
00258 if (peshk == 0){
00259 gaze_park_x = gaze1_x ; gaze_park_y = gaze1_y;
00260 }else{
00261 gaze_park_x = gaze2_x ; gaze_park_y = gaze2_y;
00262 }
00263 }
00264 if(intr == 1){
00265 gaze_park_x = gaze2_x ; gaze_park_y = gaze2_y;
00266 }
00267
00268
00269 d->displayFixationBlink(gaze_park_x,gaze_park_y,true);
00270 d->pushEvent("*** trial start : " + stringify(tr) +" ***");
00271 d->pushEvent("gaze parked at :["+stringify(gaze_park_x)+","+stringify(gaze_park_y)+"]");
00272 d->waitForMouseClick();
00273 d->clearScreen();
00274
00275
00276 int xS=0;
00277 int yS=0;
00278
00279
00280
00281 int del = rand()%2;
00282 int delay=0;
00283 switch(del){
00284 case 0 : delay = delay1 ; break ;
00285 case 1 : delay = delay2 ; break ;
00286 }
00287
00288 int lft = intr * interval_distance - interval_width/2 + interval_width*intr;
00289
00290 d->pushEvent("delay: "+ stringify(delay) );
00291 d->pushEvent("interval: "+stringify(intr));
00292
00293
00294
00295 int thePos = lft+ rand()%interval_width;
00296 int x = d->getWidth() /2 ; int y = d->getHeight()/2;
00297 switch(mode){
00298 case 1 : x += thePos;break;
00299 case 2 : y += thePos;break;
00300 }
00301 xS = x ; yS = y;
00302 d->pushEvent("presentation "+stringify(intr) + " : [" +stringify(xS)+","+ stringify(yS)+"]" );
00303 if( Mix_PlayMusic( tone1, 0 ) == -1 ) { LINFO("tone 1 is not there, what should I play?");return 1; }
00304 while( Mix_PlayingMusic() == 1 ){}
00305 d->displayRedDotFixation(x,y,true);
00306 d->pushEvent("displayEvent start gazing at : "+stringify(tr)+"." +stringify(intr)+"."+stringify(xS)+"."+stringify(yS));
00307 eyet->track(true);
00308 d->waitFrames(dot_onset);
00309 d->clearScreen();
00310 eyet->track(false);
00311 d->pushEvent("displayEvent stop gazing at : "+stringify(tr)+"." +stringify(intr)+"."+stringify(xS)+"."+stringify(yS));
00312
00313 if( Mix_PlayMusic( tone2, 0 ) == -1 ) { LINFO("tone 2 is not there, what should I play?");return 1; }
00314 while( Mix_PlayingMusic() == 1 ){}
00315 d->displayFixation(gaze_park_x,gaze_park_y,true);
00316 d->waitFrames(delay);
00317 d->clearScreen();
00318
00319
00320 if( Mix_PlayMusic( tone1, 0 ) == -1 ) { LINFO("tone 1 is not there, what should I play?");return 1; }
00321 while( Mix_PlayingMusic() == 1 ){}
00322 d->pushEvent("recall "+ stringify(intr) + " : [" +stringify(xS)+","+stringify(yS)+"]" );
00323 d->pushEvent("displayEvent start racall gaze at : "+stringify(tr)+"." +stringify(intr)+"."+stringify(xS)+"."+stringify(yS));
00324 eyet->track(true);
00325 d->waitFrames(dot_onset);
00326 d->clearScreen();
00327 eyet->track(false);
00328 d->pushEvent("displayEvent stop recall gaze at : "+stringify(tr)+"." +stringify(intr)+"."+stringify(xS)+"."+stringify(yS));
00329
00330
00331 if( Mix_PlayMusic( tone2, 0 ) == -1 ) { LINFO("tone 2 is not there, what should I play?");return 1; }
00332 while( Mix_PlayingMusic() == 1 ){}
00333
00334 }
00335
00336
00337 d->displayText("That\'s it!");
00338 d->waitForMouseClick();
00339 manager.stop();
00340 return 0;
00341 }
00342
00343 #endif // INVT_HAVE_LIBSDL_IMAGE
00344