void advanceTrial() { beepOk(0); double timeElapsed = timer.getElapsedTimeInMilliSec(); responseFile.precision(3); responseFile << fixed << parameters.find("SubjectName") << "\t" << (eyeLeft-eyeRight).norm() << "\t" << trialNumber << "\t" << trial.getCurrent()["AbsDepth"] << "\t" << trial.getCurrent()["RelDepthObj"] << "\t" << xedge << "\t" << xedge + jitter << "\t" << zedge << "\t" << zedge + (jitter/2) << "\t" << jitter << "\t" << jitterX << "\t" << theta << "\t" << trial.getCurrent()["Orientation"] << "\t" << timeElapsed << endl; trialNumber++; if(trial.getRemainingTrials() != 0) initTrial(); else { cleanup(); // shut down Optotrak exit(0); } }
void initVariables() { interoculardistance = str2num<double>(parameters.find("IOD")); // Create the factors-staircase object TrialGenerator trial.init(parameters); maxTotalTrials = trial.getRemainingTrials(); cerr << "There are " << maxTotalTrials << " total trials to do..." << endl; factors = trial.getNext(); redDotsPlane.setNpoints(300); redDotsPlane.setDimensions(50,50,0.1); redDotsPlane.compute(); //stimDrawer.drawSpecialPoints(); stimDrawer.setStimulus(&redDotsPlane); stimDrawer.setSpheres(false); stimDrawer.initList(&redDotsPlane,glRed,3); // Set the maximum x displacement of head maxXOscillation = util::str2num<double>(parameters.find("MaxXOscillation")); nOscillationsFixation = util::str2num<int>(parameters.find("NOscillationsFixation")); minOscTime = util::str2num<double>(parameters.find("MinOscillationTime")); maxOscTime = util::str2num<double>(parameters.find("MaxOscillationTime")); centerTolerance = util::str2num<double>(parameters.find("CenterTolerance")); totalTimer.start(); }
void advanceTrial() { beepOk(0); double timeElapsed = timer.getElapsedTimeInMilliSec(); double stimPresentation = stimTimer.getElapsedTimeInMilliSec(); responseFile.precision(3); responseFile << fixed << trialNumber << "\t" << interoculardistance << "\t" << estsize << "\t" << estdepth << "\t" << factors["AbsDepth"] << "\t" << timeElapsed << "\t" << stimPresentation << endl; trialNumber++; if( trial.getRemainingTrials() != 0) { initTrial(); } else { cleanup(); // shut down Optotrak exit(0); } }
void mouseFunc(int button, int state, int _x , int _y) { if ( trialMode == PROBEMODE ) { glutWarpPointer(SCREEN_WIDTH/2,SCREEN_HEIGHT/2); if ( button == GLUT_LEFT_BUTTON && (state==GLUT_DOWN) ) probeAngle+=90; if ( button == GLUT_RIGHT_BUTTON && (state==GLUT_DOWN) ) probeAngle-=90; if( button== GLUT_MIDDLE_BUTTON ) { double responseTime=responseTimer.getElapsedTimeInMilliSec(); double clickDelay=100; //milliseconds before the click is valid if ( responseTime > clickDelay ) { timeFrame=0.0; //this put the stimulus in the center each central time mouse is clicked in bool contraction = ( factors["Tilt"]==90 ) || (factors["Tilt"]==0); double angleResponse = (mod(probeAngle+probeStartingAngle,360)); if ( trial.getRemainingTrials()==0 ) { responseFile << setw(6) << left << trialNumber << " " << factors["Def"] <<" " << factors["Tilt"] <<" " << factors["Slant"] << " " << factors["Anchored"] << " " << factors["FollowingSpeed"] << " " << factors["Onset"] << " " << (focalDistance - eyeCalibration.z()) << " " << angleResponse << " " << responseTime << " " << contraction << endl; cleanup(); exit(0); } else { responseFile << setw(6) << left << trialNumber << " " << factors["Def"] <<" " << factors["Tilt"] <<" " << factors["Slant"] << " " << factors["Anchored"] << " " << factors["FollowingSpeed"] << " " << factors["Onset"] << " " << (focalDistance - eyeCalibration.z()) << " " << angleResponse << " " << responseTime << " " << contraction << endl; factors = trial.getNext(); trialNumber++; } advanceTrial(); double possibleAngles[]= {0,90,180,270}; probeStartingAngle=possibleAngles[rand()%4]; probeAngle=0; if ( atoi(parameters.find("DrawOccluder").c_str()) ==1 ) { redDotsPlane.setNpoints(500); //XXX controllare densita di distribuzione dei punti redDotsPlane.setDimensions(200,200,0.1); } else { redDotsPlane.setNpoints(75); //XXX controllare densita di distribuzione dei punti redDotsPlane.setDimensions(50,50,0.1); } //redDotsPlane.setSlantTilt( factors["Slant"], (int) factors["Tilt"] ); redDotsPlane.compute(); stimDrawer.initList(&redDotsPlane); mouseButton=0; } } } glutPostRedisplay(); }
void advanceTrial() { beepOk(0); double timeElapsed = timer.getElapsedTimeInMilliSec(); if(abs(mirrorAlignment - 45.0) < 0.25) { trialNumber++; if(trial.getRemainingTrials() != 0) { initTrial(); } else { cleanup(); // shut down Optotrak exit(0); } }else { visibleInfo = !visibleInfo; } }
void keyPressed() { if ( trialMode == PROBEMODE ) { if ( trialNumber==0) { responseFile << setw(6) << left << "TrialNumber Tilt Slant Translation Onset TranslationConstant EyeCalx EyeCaly EyeCalz StimFrames ProbeAngle" << endl; } stimulusDuration.stop(); responseFile << setw(6) << left << trialNumber << " " << factors["Tilt"] << " " << factors["Slant"] << " " << factors["Translation"] << " " << factors["Onset"] << " " << factors["TranslationConstant"] << " " << eyeCalibration.transpose() << " " << stimulusFrames << " " << probeAngle << endl; if ( trial.getRemainingTrials()==0 ) { cleanup(); exit(0); } else { factors = trial.getNext(); trialNumber++; } trialMode++; trialMode=trialMode%4; double possibleAngles[]= {0,90,180,270}; probeStartingAngle=possibleAngles[rand()%4]; redDotsPlane.compute(); stimDrawer.initList(&redDotsPlane); } }
void drawInfo() { if ( infoDraw ) { glDisable(GL_COLOR_MATERIAL); glDisable(GL_BLEND); glDisable(GL_LIGHTING); GLText text; if ( gameMode ) text.init(SCREEN_WIDTH,SCREEN_HEIGHT,glWhite,GLUT_BITMAP_HELVETICA_18); else text.init(640,480,glWhite,GLUT_BITMAP_HELVETICA_12); text.enterTextInputMode(); switch ( headCalibrationDone ) { case 0: { if ( allVisibleHead ) text.draw("==== Head Calibration OK ==== Press Spacebar to continue"); else text.draw("Be visible with the head and glasses"); } break; case 1: case 2: { if ( allVisiblePatch ) text.draw("Cyclopean(x,y,z)= " + stringify<int>((eyeRight.x()+eyeLeft.x())/2)+", "+ stringify<int>((eyeRight.y()+eyeLeft.y())/2)+", "+ stringify<int>((eyeRight.z()+eyeLeft.z())/2)+", " ); else text.draw("Be visible with the patch"); } break; case 3: // When the head calibration is done then calibrate the fingers { switch ( fingerCalibrationDone ) { case 0: text.draw("Press F to record platform markers"); break; case 1: text.draw("Move index and thumb on platform markers to record ghost finger tips, then press F"); break; case 2: { text.draw("Move index and thumb to rigidbody tip to define starting position, then press F"); } break; } } break; } if ( headCalibrationDone==3 && fingerCalibrationDone==3 ) { text.draw("Phase 0 Trial number= " + stringify<int>(block0TrialNumber)); text.draw("Phase 1 Trial number= " + stringify<int>(block1TrialNumber)); text.draw("Phase 2 Trial number= " + stringify<int>(block2TrialNumber)); text.draw("Trial mode " + stringify<int>(trialMode )); text.draw("DrawingTrialFrame= " + stringify<int>(drawingTrialFrame)); text.draw("IsDrawing?= " + stringify<int>(isDrawing)); text.draw("VisualRod= " + stringify<Eigen::Matrix<double,1,3> >(visualRodCenter.transpose()) ); text.draw("HapticRod= " + stringify<Eigen::Matrix<double,1,3> >(hapticRodCenter.transpose()) ); text.draw("AdaptOffsets= " + stringify< vector<double> >(adaptOffsets) ); text.draw("ThisAdaptOffset= " + stringify< double >(adaptOffsets.at(block1TrialNumber)) ); text.draw("Index= " + stringify< Eigen::Matrix<double,1,3> >(indexCoords.getP1().p )); text.draw("Thumb= " + stringify< Eigen::Matrix<double,1,3> >(thumbCoords.getP1().p )); text.draw("GlobTime= " + stringify<int>(globalTimer.getElapsedTimeInMilliSec())); if ( block.at("Phase")!=1 ) { text.draw("CurrentFactor= " + stringify<int>(factors.at("Distances")) ); text.draw("Remaining= " + stringify<int>( trial.getRemainingTrials() )); } } text.leaveTextInputMode(); } }
void update(int value) { // Conta i cicli di presentazione dello stimolo if ( (sumOutside > str2num<int>(parameters.find("StimulusCycles")) ) && (trialMode == STIMULUSMODE) ) { sumOutside=0; trialMode++; trialMode=trialMode%4; } if (conditionInside && (sumOutside*2 > str2num<int>(parameters.find("FixationCycles"))) && (trialMode ==FIXATIONMODE ) ) { sumOutside=0; trialMode++; trialMode=trialMode%4; stimulusDuration.start(); } if ( trialMode == STIMULUSMODE ) stimulusFrames++; if ( trialMode == FIXATIONMODE ) stimulusFrames=0; Screen screenPassive; screenPassive.setWidthHeight(SCREEN_WIDE_SIZE, SCREEN_WIDE_SIZE*SCREEN_HEIGHT/SCREEN_WIDTH); screenPassive.setOffset(alignmentX,alignmentY); screenPassive.setFocalDistance(0); screenPassive.transform(headEyeCoords.getRigidStart().getFullTransformation()*Translation3d(center)); camPassive.init(screenPassive); camPassive.setDrySimulation(true); camPassive.setEye(eyeRight); objectPassiveTransformation = ( camPassive.getModelViewMatrix()*objectActiveTransformation ); // Coordinates picker markers = optotrak.getAllPoints(); if ( isVisible(markers[1]) && isVisible(markers[2]) && isVisible(markers[3]) ) headEyeCoords.update(markers[1],markers[2],markers[3]); Affine3d active = headEyeCoords.getRigidStart().getFullTransformation(); eulerAngles.init( headEyeCoords.getRigidStart().getFullTransformation().rotation() ); eyeLeft = headEyeCoords.getLeftEye(); eyeRight = headEyeCoords.getRightEye(); cyclopeanEye = (eyeLeft+eyeRight)/2.0; // Projection of view normal on the focal plane Vector3d directionOfSight = (active.rotation()*Vector3d(0,0,-1)).normalized(); Eigen::ParametrizedLine<double,3> lineOfSightRight = Eigen::ParametrizedLine<double,3>::Through( eyeRight , eyeRight+directionOfSight ); Eigen::ParametrizedLine<double,3> lineOfSightLeft = Eigen::ParametrizedLine<double,3>::Through( eyeLeft, eyeLeft+directionOfSight ); double lineOfSightRightDistanceToFocalPlane = lineOfSightRight.intersection(focalPlane); double lineOfSightLeftDistanceToFocalPlane = lineOfSightLeft.intersection(focalPlane); //double lenghtOnZ = (active*(center-eyeCalibration )+eyeRight).z(); projPointEyeRight = lineOfSightRightDistanceToFocalPlane *(directionOfSight)+ (eyeRight); projPointEyeLeft= lineOfSightLeftDistanceToFocalPlane * (directionOfSight) + (eyeLeft); // second projection the fixation point computed with z non constant but perfectly parallel to projPointEyeRight lineOfSightRightDistanceToFocalPlane= (( active.rotation()*(center)) - eyeRight).norm(); Vector3d secondProjection = lineOfSightRightDistanceToFocalPlane *(directionOfSight)+ (eyeRight); if ( !zOnFocalPlane ) projPointEyeRight=secondProjection ; // Compute the translation to move the eye in order to avoid shear components Vector3d posAlongLineOfSight = (headEyeCoords.getRigidStart().getFullTransformation().rotation())*(eyeRight -eyeCalibration); switch ( (int)factors["Translation"] ) { case -1: case -2: translationFactor.setZero(); if ( trialMode == STIMULUSMODE ) projPointEyeRight=center; break; case 0: translationFactor.setZero(); break; case 1: translationFactor = factors["TranslationConstant"]*Vector3d(posAlongLineOfSight.z(),0,0); break; case 2: translationFactor = factors["TranslationConstant"]*Vector3d(0,posAlongLineOfSight.z(),0); break; } if ( passiveMode ) initProjectionScreen(0,headEyeCoords.getRigidStart().getFullTransformation()*Translation3d(Vector3d(0,0,focalDistance))); else initProjectionScreen(focalDistance,Affine3d::Identity()); checkBounds(); /**** Save to file part ****/ // Markers file save the used markers and time-depending experimental variable to a file // (Make sure that in passive experiment the list of variables has the same order) markersFile << trialNumber << " " << headCalibrationDone << " " << trialMode << " " ; markersFile <<markers[1].transpose() << " " << markers[2].transpose() << " " << markers[3].transpose() << " " << markers[17].transpose() << " " << markers[18].transpose() << " " ; markersFile << factors["Tilt"] << " " << factors["Slant"] << " " << factors["Translation"] << " " << factors["Onset"] << " " << factors["TranslationConstant"] << endl; ofstream outputfile; outputfile.open("data.dat"); outputfile << "Subject Name: " << parameters.find("SubjectName") << endl; outputfile << "Passive matrix:" << endl << objectPassiveTransformation.matrix() << endl; outputfile << "Yaw: " << toDegrees(eulerAngles.getYaw()) << endl <<"Pitch: " << toDegrees(eulerAngles.getPitch()) << endl; outputfile << "EyeLeft: " << headEyeCoords.getLeftEye().transpose() << endl; outputfile << "EyeRight: " << headEyeCoords.getRightEye().transpose() << endl << endl; outputfile << "Slant: " << instantPlaneSlant << endl; outputfile << "(Width,Height) [px]: " << getPlaneDimensions().transpose() << " " << endl; outputfile << "Factors:" << endl; for (map<string,double>::iterator iter=factors.begin(); iter!=factors.end(); ++iter) { outputfile << "\t\t" << iter->first << "= " << iter->second << endl; } outputfile << "Trial remaining: " << trial.getRemainingTrials()+1 << endl; outputfile << "Last response: " << probeAngle << endl; // Here we save plane projected width and height // now rewind the file outputfile.clear(); outputfile.seekp(0,ios::beg); // Write down frame by frame the trajectories and angles of eyes and head if ( trialMode == STIMULUSMODE && headCalibrationDone > 2 ) { trajFile << setw(6) << left << trialNumber << " " << stimulusFrames << " " << eyeRight.transpose() << endl; anglesFile << setw(6) << left << trialNumber << " " << stimulusFrames << " " << toDegrees(eulerAngles.getPitch()) << " " << toDegrees(eulerAngles.getRoll()) << " " << toDegrees(eulerAngles.getYaw()) << " " << instantPlaneSlant << endl; matrixFile << setw(6) << left << trialNumber << " " << stimulusFrames << " " ; for (int i=0; i<3; i++) matrixFile << objectPassiveTransformation.matrix().row(i) << " " ; matrixFile << endl; // Write the 13 special extremal points on stimFile stimFile << setw(6) << left << trialNumber << " " << stimulusFrames << " " ; double winx=0,winy=0,winz=0; for (PointsRandIterator iRand = redDotsPlane.specialPointsRand.begin(); iRand!=redDotsPlane.specialPointsRand.end(); ++iRand) { Point3D *p=(*iRand); Vector3d v = objectActiveTransformation*Vector3d( p->x, p->y, p->z); gluProject(v.x(),v.y(),v.z(), (&cam)->getModelViewMatrix().data(), (&cam)->getProjectiveMatrix().data(), (&cam)->getViewport().data(), &winx,&winy,&winz); stimFile << winx << " " << winy << " " << winz << " "; } stimFile << endl; } glutPostRedisplay(); glutTimerFunc(TIMER_MS, update, 0); }