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 #ifndef PSYCHO_EYETRACKERUDP_C_DEFINED
00038 #define PSYCHO_EYETRACKERUDP_C_DEFINED
00039
00040 #include "Psycho/EyeTrackerUDP.H"
00041
00042 #include "Component/ModelOptionDef.H"
00043 #include "Psycho/PsychoOpts.H"
00044 #include "Component/OptionManager.H"
00045 #include "Util/Timer.H"
00046 #include "Util/sformat.H"
00047
00048 #include <sys/time.h>
00049
00050
00051 EyeTrackerUDP::EyeTrackerUDP(OptionManager& mgr,
00052 const std::string& descrName,
00053 const std::string& tagName) :
00054 EyeTracker(mgr, descrName, tagName),
00055 startMsg(NULL), stopMsg(NULL),
00056 isConnected(false), isFix(false), isSac(false),
00057 sockfd(0), myInfo(NULL), hostInfo(NULL)
00058 {
00059 startMsg = new char[2];
00060 startMsg[0] = (char)1;
00061 startMsg[1] = '\0';
00062
00063 stopMsg = new char[2];
00064 stopMsg[0] = (char)2;
00065 stopMsg[1] = '\0';
00066 }
00067
00068
00069 EyeTrackerUDP::~EyeTrackerUDP()
00070 {
00071 delete startMsg;
00072 delete stopMsg;
00073 }
00074
00075
00076 void EyeTrackerUDP::start1()
00077 {
00078
00079 FD_ZERO(&master);
00080 FD_ZERO(&read_fs);
00081
00082
00083 struct addrinfo hints;
00084 memset(&hints, 0, sizeof hints);
00085 hints.ai_family = AF_UNSPEC;
00086 hints.ai_socktype = SOCK_DGRAM;
00087 hints.ai_flags = AI_PASSIVE;
00088
00089
00090 int rv;
00091 if ((rv = getaddrinfo(NULL, "9999",
00092 &hints, &myInfo)) < 0)
00093 {
00094 std::string ts = sformat("getaddrinfo: %s", gai_strerror(rv));
00095 LINFO("%s", ts.c_str());
00096 freeaddrinfo(myInfo);
00097 LFATAL("Fatal Error");
00098 }
00099
00100
00101 for(; myInfo != NULL; myInfo = myInfo->ai_next)
00102 {
00103 if ((sockfd = socket(myInfo->ai_family, myInfo->ai_socktype,
00104 myInfo->ai_protocol)) == -1)
00105 {
00106 LINFO("Error::Socket");
00107 continue;
00108 }
00109
00110
00111 int bindr;
00112 if ((bindr = bind(sockfd, myInfo->ai_addr, myInfo->ai_addrlen)) < 0)
00113 {
00114 close(sockfd);
00115 LINFO("Error::Listener bind");
00116 continue;
00117 }
00118 else break;
00119 }
00120
00121 if (myInfo == NULL)
00122 {
00123 LINFO("Error: Failed to bind socket");
00124 freeaddrinfo(myInfo);
00125 LFATAL("Fatal Error");
00126 }
00127
00128 if (hostInfo == NULL)
00129 LINFO("No host. Getting host from packets");
00130
00131
00132 FD_SET(sockfd, &master);
00133 isConnected = true;
00134 LINFO("Socket creation succesful");
00135
00136
00137 EyeTracker::start1();
00138 }
00139
00140
00141 void EyeTrackerUDP::start2()
00142 {
00143 Timer itsTimer;
00144
00145
00146 LINFO("Waiting for a UDP packet to complete start "
00147 "(timeout after 60 seconds)");
00148
00149 while(true)
00150 {
00151 if (checkForData())
00152 {
00153 LINFO("Recieved start signal from host");
00154 break;
00155 }
00156
00157 if (itsTimer.getSecs() > 60.0)
00158 {
00159 LINFO("Timed out after 60 seconds. Finishing start without start "
00160 "signal from host");
00161 break;
00162 }
00163 }
00164 clearEyeStatus();
00165 }
00166
00167
00168 void EyeTrackerUDP::stop1()
00169 {
00170 usleep(50000);
00171 FD_CLR(sockfd, &master);
00172 close(sockfd);
00173
00174 if (hostInfo!=myInfo)
00175 freeaddrinfo(hostInfo);
00176 freeaddrinfo(myInfo);
00177 hostInfo = NULL;
00178 myInfo = NULL;
00179 }
00180
00181
00182 void EyeTrackerUDP::startTracking()
00183 {
00184 sendMessage(startMsg);
00185 }
00186
00187
00188 void EyeTrackerUDP::stopTracking()
00189 {
00190 sendMessage(stopMsg);
00191 }
00192
00193
00194 bool EyeTrackerUDP::isFixating()
00195 {
00196
00197
00198
00199
00200 if (isFix)
00201 {
00202 isFix = false;
00203 return true;
00204 }
00205 else
00206 {
00207 checkForData();
00208 if (isFix)
00209 {
00210 isFix = false;
00211 return true;
00212 }
00213 }
00214 return false;
00215 }
00216
00217
00218 bool EyeTrackerUDP::isSaccade()
00219 {
00220
00221
00222
00223
00224 if (isSac)
00225 {
00226 isSac = false;
00227 return true;
00228 }
00229 else
00230 {
00231 checkForData();
00232 if (isSac)
00233 {
00234 isSac = false;
00235 return true;
00236 }
00237 }
00238 return false;
00239 }
00240
00241
00242 void EyeTrackerUDP::clearEyeStatus()
00243 {
00244 while (checkForData()) ;
00245 resetEyeFlags();
00246 }
00247
00248
00249 bool EyeTrackerUDP::checkForData()
00250 {
00251 int numbytes = 0;
00252 if (isConnected)
00253 {
00254 struct timeval tm;
00255 tm.tv_sec = 0;
00256 tm.tv_usec = 0;
00257
00258 read_fs = master;
00259 select(sockfd+1, &read_fs, NULL, NULL, &tm);
00260
00261 if (FD_ISSET(sockfd, &read_fs))
00262 {
00263
00264 lasthost_addrlen = sizeof lasthost_addr;
00265 unsigned char msgBuffer[BUFSIZE];
00266
00267 if ( (numbytes = recvfrom(sockfd, msgBuffer, BUFSIZE-1 , 0,
00268 &lasthost_addr,
00269 &lasthost_addrlen)) <= 0)
00270 {
00271
00272 if (numbytes == 0)
00273 {
00274
00275 pushEvent("Error::socket closed");
00276 LFATAL("The connection closed");
00277 }
00278 else
00279 pushEvent("Error::recieve");
00280 }
00281 else
00282 {
00283 pushEvent("Received Trigger");
00284 setEyeFlags(msgBuffer[0]);
00285 }
00286 }
00287 }
00288 else
00289 {
00290 pushEvent("Must be conncted to listen");
00291 LFATAL("Must be connected to listen");
00292 }
00293
00294 return (bool)numbytes;
00295 }
00296
00297
00298 Point2D<int> EyeTrackerUDP::getEyePos() const
00299 {
00300 LFATAL("Unavailable on UDP tracker, sorry.");
00301 return Point2D<int>(0, 0);
00302 }
00303
00304
00305 Point2D<int> EyeTrackerUDP::getFixationPos() const
00306 {
00307 LFATAL("Unavailable on TIL tracker, sorry.");
00308 return Point2D<int>(0, 0);
00309 }
00310
00311
00312
00313 CalibrationTransform::Data EyeTrackerUDP::getCalibrationSet(nub::soft_ref<PsychoDisplay> d) const
00314 {
00315 CalibrationTransform::Data dummy;
00316 dummy.addData(Point2D<double>(-1.0,-1.0),Point2D<double>(-1.0,-1.0));
00317 return dummy;
00318 }
00319
00320
00321
00322 void EyeTrackerUDP::sendMessage(const char* msg)
00323 {
00324
00325 if (isConnected)
00326 {
00327
00328 int check = 0;
00329 (hostInfo != NULL)?
00330 check = sendto(sockfd, msg, strlen(msg), 0,
00331 hostInfo->ai_addr, hostInfo->ai_addrlen)
00332 :check = sendto(sockfd, msg, strlen(msg), 0,
00333 &lasthost_addr, lasthost_addrlen);
00334
00335 (check < 0)?
00336 pushEvent("Error::Sending"):
00337 pushEvent( std::string("Listener::Sent '" +
00338 std::string(msg) + "'"));
00339 }
00340 else
00341 {
00342 pushEvent("Must be Connected to send a message");
00343 LFATAL("Must be conncted to send a message");
00344 }
00345 }
00346
00347
00348 void EyeTrackerUDP::pushEvent(const std::string& ev)
00349 {
00350 if (itsEventLog.isValid())
00351 itsEventLog->pushEvent(ev);
00352 }
00353
00354
00355 void EyeTrackerUDP::setEyeFlags(const unsigned char msg)
00356 {
00357 switch (msg)
00358 {
00359 case FIXCODE :
00360 isFix = true;
00361 break;
00362 case SACCODE :
00363 isSac = true;
00364 break;
00365 }
00366 }
00367
00368
00369 void EyeTrackerUDP::resetEyeFlags()
00370 {
00371 isFix = false;
00372 isSac = false;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382 #endif // PSYCHO_EYETRACKERUDP_C_DEFINED