00001 /*!@file AppPsycho/psycho-rex.C control psycho display directly from Rex at 00002 Doug Munoz Lab, probably works with other Rex setups too. */ 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00006 // University of Southern California (USC) and the iLab at USC. // 00007 // See http://iLab.usc.edu for information about this project. // 00008 // //////////////////////////////////////////////////////////////////// // 00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00011 // in Visual Environments, and Applications'' by Christof Koch and // 00012 // Laurent Itti, California Institute of Technology, 2001 (patent // 00013 // pending; application number 09/912,225 filed July 23, 2001; see // 00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00017 // // 00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00019 // redistribute it and/or modify it under the terms of the GNU General // 00020 // Public License as published by the Free Software Foundation; either // 00021 // version 2 of the License, or (at your option) any later version. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00026 // PURPOSE. See the GNU General Public License for more details. // 00027 // // 00028 // You should have received a copy of the GNU General Public License // 00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00031 // Boston, MA 02111-1307 USA. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // 00034 // Primary maintainer for this file: David J Berg <dberg@usc.edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/psycho-rex.C $ 00036 // $Id: psycho-rex.C 13556 2010-06-11 00:51:36Z dberg $ 00037 // 00038 00039 #include "Component/ModelManager.H" 00040 #include "Component/EventLog.H" 00041 #include "Component/ComponentOpts.H" 00042 #include "Media/FrameSeries.H" 00043 #include "Media/MediaOpts.H" 00044 #include "Image/Image.H" 00045 #include "Util/MathFunctions.H" 00046 #include "Util/Types.H" 00047 #include "Video/VideoFrame.H" 00048 #include "Psycho/PsychoDisplay.H" 00049 #include "Psycho/EyeTrackerConfigurator.H" 00050 #include "Psycho/EyeTracker.H" 00051 #include "Psycho/PsychoOpts.H" 00052 //#include "Psycho/StimController.H" 00053 #include "rutz/time.h" 00054 #include <deque> 00055 00056 /* 00057 static const ModelOptionDef OPT_exitcode = 00058 { MODOPT_ARG(char), "exitcode", &MOC_INPUT, OPTEXP_CORE, 00059 "code to exit stimulus listening.", 00060 "exitcode", '\0', "<char>", "0" }; 00061 */ 00062 // ###################################################################### 00063 extern "C" int main(const int argc, char** argv) 00064 { 00065 //MYLOGVERB = LOG_INFO; // suppress debug messages 00066 /* 00067 // Instantiate a ModelManager: 00068 ModelManager manager("Psycho Rex"); 00069 00070 // Instantiate our various ModelComponents: 00071 nub::soft_ref<InputFrameSeries> ifs(new InputFrameSeries(manager)); 00072 manager.addSubComponent(ifs); 00073 00074 nub::soft_ref<EventLog> el(new EventLog(manager)); 00075 manager.addSubComponent(el); 00076 00077 nub::soft_ref<EyeTrackerConfigurator> 00078 etc(new EyeTrackerConfigurator(manager)); 00079 manager.addSubComponent(etc); 00080 00081 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager)); 00082 manager.addSubComponent(d); 00083 00084 nub::soft_ref<StimController> stc(new StimController(manager)); 00085 stc->initialzed(new StimListenerDML(itsExitCode)); 00086 stc->setDisplay(d); 00087 stc->pauseDisplay(true); 00088 manager.addSubComponent(stc); 00089 00090 manager.setOptionValString(&OPT_InputMPEGStreamPreload, "true"); 00091 manager.setOptionValString(&OPT_EventLogFileName, "psychodata.psy"); 00092 00093 // Parse command-line: 00094 if (manager.parseCommandLine(argc, argv, 00095 "<stim1> ... <stimN>", 1, -1)==false) 00096 return(1); 00097 00098 //wait when should this stuff be added 00099 // hook our various babies up and do post-command-line configs: 00100 nub::soft_ref<EyeTracker> et = etc->getET(); 00101 d->setEyeTracker(et); 00102 d->setEventLog(el); 00103 et->setEventLog(el); 00104 stc->setEventLog(el); 00105 00106 initRandomNumbers(); 00107 00108 // let's get all our ModelComponent instances started: 00109 manager.start(); 00110 00111 // setup array of indices for stimuli: 00112 uint nbmovies = manager.numExtraArgs(); int index[nbmovies]; 00113 for (uint i = 0; i < nbmovies; i ++) index[i] = i; 00114 LINFO("Randomizing Stimuli..."); 00115 randShuffle(index,nbmovies); 00116 00117 try{ 00118 // main loop: 00119 for (uint i = 0; i < nbmovies; i++) 00120 { 00121 d->clearScreen(); 00122 std::string fname = manager.getExtraArg(index[i]); 00123 LINFO("Buffering/Loading '%s'...", fname.c_str()); 00124 00125 //reset the frame source to the next movie 00126 std::string pre = "buff:"; 00127 ifs->setFrameSource(pre + fname); 00128 00129 //preload stuff into buffer 00130 ifs->startStream(); 00131 00132 LINFO("'%s' ready.", fname.c_str()); 00133 00134 // give a chance to other processes (useful on single-CPU machines): 00135 sleep(1); system("/bin/sync"); 00136 00137 // display fixation to indicate that we are ready: 00138 d->displayRedDotFixation(); 00139 00140 // give us a chance to abort 00141 d->checkForKey(); 00142 00143 // ready to go whenever the monkey is ready (pulse on parallel port): 00144 while(true) 00145 { 00146 if (et->isFixating()) break; 00147 if (d->checkForKey() != -1) break; // allow force start by key 00148 } 00149 00150 int frame = 0; 00151 d->pushEvent(std::string("===== Playing movie: ") + 00152 fname + " ====="); 00153 00154 // start the eye tracker: 00155 et->track(true); 00156 00157 //grab the first frame and set our background 00158 const FrameState is = ifs->updateNext(); 00159 if (is == FRAME_COMPLETE) 00160 LFATAL("No frames in stimulus"); 00161 00162 //get our frame and make sure it is valid 00163 GenericFrame input = ifs->readFrame(); 00164 if (!input.initialized()) 00165 LFATAL("Empty first frame"); 00166 00167 //actually set the background and un-pause. If this is a 00168 //static image, display of the background will hold until Rex 00169 //says to display. This command may already be in the the queue, 00170 //as we have been listening but not displaying commands. When 00171 //we un-pause, the queue will start popping and displaying. If 00172 //this is a movie, the first frame will draw now, even though 00173 //we are paused, anything in the qeue will start to alter 00174 //display on the next frame (call to setBackgroundImage) 00175 stc->getDispController()->setBackground(input,frame); 00176 stc->pauseDisplay(false); 00177 00178 //start passing frames to our display controller 00179 while(1) 00180 { 00181 //update internal counters in ifs, quite if no more frames 00182 const FrameState is = ifs->updateNext(); 00183 if (is == FRAME_COMPLETE) 00184 break; 00185 00186 //get our frame and make sure it is valid 00187 GenericFrame input = ifs->readFrame(); 00188 if (!input.initialized()) 00189 break; 00190 00191 stc->getDispController()->setBackground(input,frame); 00192 }//done with our current stimulus 00193 00194 //pause our listener, destroying the overlay and waiting the thread 00195 stc->pauseDisplay(true); 00196 00197 d->clearScreen(); // sometimes 2 clearScreen() are necessary 00198 00199 // stop the eye tracker: 00200 usleep(50000); 00201 et->track(false); 00202 00203 }//end loop over stimuli 00204 00205 d->displayText("Experiment complete. Thank you!"); 00206 d->waitForKey(true); 00207 00208 }//end try 00209 00210 catch (...) 00211 { 00212 REPORT_CURRENT_EXCEPTION; 00213 }; 00214 00215 // stop all our ModelComponents 00216 manager.stop(); 00217 */ 00218 // all done! 00219 return 0; 00220 } 00221 00222 // ###################################################################### 00223 /* So things look consistent in everyone's emacs... */ 00224 /* Local Variables: */ 00225 /* indent-tabs-mode: nil */ 00226 /* End: */