void advanceTrial() { double timeElapsed = globalTimer.getElapsedTimeInMilliSec(); responseFile.precision(3); // max three decimal positions responseFile << fixed << parameters.find("SubjectName") << "\t" << trialNumber << "\t" << repetitions << "\t" << starting_theta << "\t" << final_theta << "\t" << trial.getCurrent()["Tilt_sign"] << "\t" << timeElapsed << "\t" << endl; trialNumber++; if(trial.hasNext()) { trial.next(); initTrial(); } else if (repetitions < max_repetitions) { repetitions++; initVariables(); trial.next(); initTrial(); } else { responseFile.close(); expFinished = true; beepOk(4); } }
void advanceTrial() { beepOk(0); double timeElapsed = timer.getElapsedTimeInMilliSec(); responseFile.precision(3); // max three decimal positions responseFile << fixed << parameters.find("SubjectName") << "\t" << interoculardistance << "\t" << trialNumber << "\t" << trial.getCurrent()["AbsDepth"] << "\t" << objwidth << "\t" << adjDz << "\t" << timeElapsed << endl; trialNumber++; if(trial.hasNext()) { trial.next(); initTrial(); } else { isStimulusDrawn=false; drawGLScene(); responseFile.close(); expFinished = true; } }
/** * @brief advanceTrial * @param response */ void advanceTrial(int response) { responseFile << parameters.find("SubjectName") << "\t" << trialNumber << "\t" << focalDistance << "\t" << response << "\t" << trialTimer.getElapsedTimeInMilliSec() << "\t" << trial.getCurrent().at("ZWidth") << "\t" << trial.getCurrent().at("Slant") << "\t" << trial.getCurrent().at("Tilt") << "\t" << trial.getCurrent().at("StimulusAnchored") << " " << endl; if ( trial.isEmpty() ) { exit(0); } trial.next(); updateStimulus(); beepOk(); trialMode=BLACK_MODE; trialNumber++; trialTimer.start(); frame=0.0; }
void initVariables() { cam.setOrthoGraphicProjection((bool)str2num<int>(parameters.find("OrthographicMode"))); drawInfo = (bool)util::str2num<int>(parameters.find("DrawInfo")); //cam.setOrthoGraphicProjection(orthoMode); cerr << "COMPUTED IOD=" << interoculardistance << endl; trial.init(parameters); stimulusTime=util::str2num<double>(parameters.find("StimulusTime")); trialTimer.start(); trial.next(); interoculardistance = str2num<double>(parameters.find("IOD"))*trial.getCurrent().at("IODFactor"); int textureResolution = util::str2num<int>(parameters.find("TextureResolution")); int maxTextureResolutionZ = (int) std::ceil(textureResolution*util::str2num<double>(parameters.find("MaxCurvatureZ"))); // allocate the texture memory if (parameters.find("UsePolkaDots")=="1") { surface.resize(textureResolution,textureResolution, maxTextureResolutionZ); surface.initializeSurfaceShaders(VolumetricSurfaceIntersection::SurfaceParabolicCylinder); } updateStimulus(trial.getCurrent().at("CurvatureZ")); CurvatureZ=0.0; }
void advanceTrial() { double timeElapsed = timer.getElapsedTimeInMilliSec(); responseFile.precision(3); responseFile << parameters.find("SubjectName") << "\t" << //interoculardistance << "\t" << trialNumber << "\t" << stimPosn << "\t" << "-420" << "\t" <<//trial.getCurrent()["AbsDepth"] <<"\t" << "50" << "\t" <<//trial.getCurrent()["ObjHeight"] <<"\t" << timer.getElapsedTimeInMilliSec() << "\t" << //trial.getCurrent()["HapticFB"] << "\t" << //randCond << "\t" << //randIncrement << "\t" << stimCond << "\t" << pulsingColors << "\t" << endl; trialFile.close(); trialNumber++; if( !trial.isEmpty() ) { trial.next(); initTrial(); } else { exit(0); } }
int main(int argc, char*argv[]) { #ifdef TEST mathcommon::randomizeStart(); // initializing experiment's parameters initRendering(); initStreams(); trial.next(); initTrial(); return 0; #else mathcommon::randomizeStart(); // initializes optotrak and velmex motors initOptotrak(); initMotors(); // initializing glut glutInit(&argc, argv); #ifndef SIMULATION glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STEREO); glutGameModeString("1024x768:32@85"); glutEnterGameMode(); glutFullScreen(); #else glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT); glutCreateWindow("Simulation test"); #endif // initializing experiment's parameters initRendering(); initStreams(); // glut callback glutDisplayFunc(drawGLScene); glutKeyboardFunc(handleKeypress); glutMouseFunc(mouseFunc); glutReshapeFunc(handleResize); glutIdleFunc(idle); glutTimerFunc(TIMER_MS, update, 0); glutSetCursor(GLUT_CURSOR_NONE); boost::thread initVariablesThread(&initVariables); // Application main loop glutMainLoop(); cleanup(); return 0; #endif }
/** * @brief initializeExperiment */ void initializeExperiment() { // MUST BE CALLED WITHIN A VALID OPENGL CONTEXT //Screen screen(SCREEN_WIDE_SIZE, SCREEN_WIDE_SIZE*SCREEN_HEIGHT/SCREEN_WIDTH, alignmentX, alignmentY, focalDistance ); screen.init(SCREEN_WIDE_SIZE, SCREEN_WIDE_SIZE*SCREEN_HEIGHT/SCREEN_WIDTH, alignmentX, alignmentY, focalDistance ); screen.setOffset(alignmentX,alignmentY); screen.setFocalDistance(focalDistance); cam.init(screen); // Initialize all the streams for file output eccetera parameters.loadParameterFile("C:/cncsvisiondata/parametersFiles/Fulvio/expMicroHeadMovements/parametersExpMicroHeadMovementsActive.txt"); // Initialize focal distance and interocular distance from parameter file focalDistance = parameters.get("FocalDistance"); interocularDistance = parameters.get("IOD"); infoDraw = (int)parameters.get("DrawInfo"); useCircularOcclusor = (int)parameters.get("UseCircularOcclusor"); // Initialize trials balance factors trial.init(parameters); trial.next(); // Base directory, full path string baseDir = parameters.find("BaseDir"); // Subject name string subjectName = parameters.find("SubjectName"); // Principal streams file string markersFileName = baseDir + "markersFile_MicroHeadMovementsActive_" + subjectName + ".txt"; string outputFileName = baseDir + "responseFile_MicroHeadMovementsActive_" + subjectName +".txt"; string timingFileName = baseDir + "timingFile_MicroHeadMovementsActive_" + subjectName + ".txt"; // Check for output file existence if ( !util::fileExists((outputFileName)) ) responseFile.open(outputFileName.c_str()); cerr << "File " << outputFileName << " loaded successfully" << endl; // Check for output markers file existence if ( !util::fileExists((markersFileName)) ) markersFile.open(markersFileName.c_str()); cerr << "File " << markersFileName << " loaded successfully" << endl; // Check for output timing file existence if ( !util::fileExists((timingFileName)) ) timingFile.open(( timingFileName ).c_str()); cerr << "File " << timingFileName << " opened successfully" << endl; // Write the response file header responseFile << "# SubjectName\tTrialNumber\tFocalDistance\tKeyPressed\tResponseTime\tfZWidth\tfSlant\tfTilt\tfStimAnchored" << endl; // Finished loading parameter files // Update the stimulus updateStimulus(); trialTimer.start(); globalTimer.start(); }
/** * @brief advanceTrial: This function to the next trial */ void advanceTrial() { fingersTimer.start(); // Here we change trial mode if (trialMode == HANDONSTARTMODE ) { // Wait to show the stimulus that the fingers points are projected in the screen trialMode = STIMULUSMODE; } else // trialMode == STIMULUSMODE { trialMode = HANDONSTARTMODE; paintGL(); beepTrial(); double oldDistance = factors.getCurrent().at("Distances"); // Reinsert the trial if too much occluded frames double maxInvisibleFramesPercent = util::str2num<double>(parameters.find("MaxPercentOccludedFrames"))/100.0; if ( (invisibleIndexFrames / ((double)drawingTrialFrame) > maxInvisibleFramesPercent ) || (invisibleThumbFrames / ((double)drawingTrialFrame) > maxInvisibleFramesPercent )|| (invisibleWristFrames / ((double)drawingTrialFrame) > maxInvisibleFramesPercent ) ) { map<string,double> currentFactorsList = factors.getCurrent(); beepBad(); cerr << "Reinserted current trial (InvIndex,InvThumb,drawingTrialFrame,totTrialFrame)" << invisibleIndexFrames << " " << invisibleThumbFrames << " " << drawingTrialFrame << " " << trialFrame << endl; factors.reinsert(currentFactorsList); } if (factors.isEmpty()) { beepLong(); beepLong(); beepLong(); plato_stop(); exit(0); } invisibleIndexFrames = invisibleThumbFrames = invisibleWristFrames = trialFrame = drawingTrialFrame = 0; totalTrialNumber++; factors.next(); if (oldDistance == factors.getCurrent().at("Distances")) { Timer sleepTimer; sleepTimer.sleep(1000); } double marker5z = markers.at(5).p.z(); generateSphereStimulus( factors.getCurrent().at("StimulusRadius") ); initProjectionScreen(factors.getCurrent().at("Distances")); moveStimulusObject(visualStimCenter,3500); } }
void advanceTrial() { // Save trial responseFile << trialNumber << "\t" << trial.getCurrent().at("CurvatureZ") << "\t" << trial.getCurrent().at("IODFactor") << "\t" << CurvatureZ*util::str2num<double>(parameters.find("RadiusX")) << "\t" << endl; if (!trial.next()) exit(0); trialNumber++; interoculardistance = str2num<double>(parameters.find("IOD"))*trial.getCurrent().at("IODFactor"); updateStimulus(trial.getCurrent().at("CurvatureZ")); // Randomize CurvatureZ again CurvatureZ= 0;//(double)mathcommon::unifRand(1,10)/10; //This is needed to randomize between trials }
void initTrial() { //factors = trial.getNext(); trial.next(); isStimulusDrawn=false; drawGLScene(); initProjectionScreen(trial.getCurrent()["AbsDepth"]); zedge = 0; frame = 0; timeStim=0; judgment=0; occludedFrames = 0; frontRodShown=false; if(trial.getCurrent()["AbsDepth"]==-300) { if(trial.getCurrent()["RelDepthObj"]==30) { estdepth = str2num<double>(subjParams.find("d30@300")); estsd = str2num<double>(subjParams.find("s30@300")); } else if(trial.getCurrent()["RelDepthObj"]==50) { estdepth = str2num<double>(subjParams.find("d50@300")); estsd = str2num<double>(subjParams.find("s50@300")); } } else if(trial.getCurrent()["AbsDepth"]==-450) { if(trial.getCurrent()["RelDepthObj"]==30) { estdepth = str2num<double>(subjParams.find("d30@450")); estsd = str2num<double>(subjParams.find("s30@450")); } else if(trial.getCurrent()["RelDepthObj"]==50) { estdepth = str2num<double>(subjParams.find("d50@450")); estsd = str2num<double>(subjParams.find("s50@450")); } } jitter = unifRand(str2num<double>(parameters.find("VirtualObjRelDepthLowBound")), str2num<double>(parameters.find("VirtualObjRelDepthUpBound"))); beepOk(0); timer.start(); isStimulusDrawn=true; }
/** * @brief initializeExperiment */ void initializeExperiment() { initStreams(); factors.init(parameters); factors.next(); generateSphereStimulus(factors.getCurrent().at("StimulusRadius") ); initProjectionScreen(factors.getCurrent().at("Distances")); vector<double> distances = util::str2num<double>(parameters.find("fDistances")," "); maxCoveredDistance = max(distances.begin(),distances.end()) - min(distances.begin(),distances.end()); selectedFinger = util::str2num<int>(parameters.find("SelectedFinger")); // For the rod initialization thetaRod = M_PI/180.0*parameters.get("RodLatitude"); phiRod = M_PI/180.0*parameters.get("RodLongitude"); r = parameters.get("RodRadius"); rodStart = visualStimCenter + r*Vector3d(sin(thetaRod)*cos(phiRod),cos(thetaRod),sin(thetaRod)*sin(phiRod)); rodEnd= visualStimCenter - r*Vector3d(sin(thetaRod)*cos(phiRod),cos(thetaRod),sin(thetaRod)*sin(phiRod)); }
void advanceTrial() { double timeElapsed = timer.getElapsedTimeInMilliSec(); double percent_occluded_frames = (double)framesOccluded/(frameN-frames_at_start-frames_post_grasp); bool not_enough_frames = percent_occluded_frames > 0.20; if(not_enough_frames) { beepOk(1); trial.reinsert(trial.getCurrent()); good_trial = 0; } else { beepOk(0); good_trial = 1; } responseFile.precision(3); // max three decimal positions responseFile << fixed << parameters.find("SubjectName") << "\t" << interoculardistance << "\t" << trialNumber << "\t" << trial.getCurrent()["AbsDepth"] << "\t" << objwidth << "\t" << objdepth << "\t" << timeElapsed << "\t" << good_trial << endl; markersFile.close(); trialNumber++; if(trial.hasNext()) { trial.next(); initTrial(); } else { responseFile.close(); expFinished = true; } }
void initTrial() { //factors = trial.getNext(); trial.next(); isStimulusDrawn=false; drawGLScene(); initProjectionScreen(trial.getCurrent()["AbsDepth"]); //Vector3d pos(0, -44, (str2num<double>(parameters.find("StartPosObj"))+trial.getCurrent()["RelDepthObj"])); //moveObjectAbsolute(pos, centercal, 5000); //positionObj(pos); xedge = 0; zedge = 0; theta = 0; jitter = unifRand(str2num<double>(parameters.find("VirtualObjRelDepthLowBound")), str2num<double>(parameters.find("VirtualObjRelDepthUpBound"))); jitterX = unifRand(str2num<double>(parameters.find("VirtualObjSizeLowBound")), str2num<double>(parameters.find("VirtualObjSizeUpBound"))); timer.start(); isStimulusDrawn=true; }
void advanceTrial() { //summaryFile.precision(3); summaryFile << parameters.find("SubjectName") << "\t" << interoculardistance << "\t" << trialNumber << "\t" << absDepth <<"\t" << stimulus_height[1] << "\t" << trial.getCurrent()["ConstantStimuli"] << "\t" << stimulus_height[first_interval] << "\t" << stimulus_height[second_interval] << "\t" << stimulus_noise << "\t" << responsekey << "\t" << testJND << endl; trialNumber++; trial.next(); initTrial(); }
void initTrial() { // initializing all variables trial.next(); isStimulusDrawn = false; drawGLScene(); endOfTrial = false; indexDisappeared = false; thumbDisappeared = false; fingersDisappeared = false; frameN=0; fingersOccluded = 0; // roll on initProjectionScreen(trial.getCurrent()["AbsDepth"]); string trialFileName = "C:/Users/visionlab/Dropbox/Shape Lab Shared/Claire/" + parameters.find("SubjectName") + "/" + parameters.find("SubjectName") + "trial_" + stringify<double>(trialNumber) + ".txt"; trialFile.open(trialFileName.c_str()); trialFile << fixed << "subjName\ttrialN\ttime\tframeN\tindexXraw\tindexYraw\tindexZraw\tthumbXraw\tthumbYraw\tthumbZraw\teyeRXraw\teyeRYraw\teyeRZraw\teyeLXraw\teyeLYraw\teyeLZraw\tfingersOccluded\tindexDisappeared\tthumbDisappeared" << endl; timer.start(); isStimulusDrawn = true; }
// Funzione di callback per gestire pressioni dei tasti void handleKeypress(unsigned char key, int x, int y) { switch (key) { //Quit program case 'x': // Facendo cosi si cancella lo stimolo durante il movimento (SINCRONO) del monitor. // Si imposta il isStimulusDrawn a FALSE e si riaggiorna la schermata con una drawGLScene() // infine si muove il monitor, la chiamata blocca il programma per x secondi, si // simula lo spostamento dello schermo di proiezione ed infine si reimposta isStimulusDrawn a TRUE // cosi' la prossima chiamata di drawStimulus() lo disegna correttamente a schermo. Provare per credere... //factors = trial.getNext(); trial.next(); isStimulusDrawn=false; drawGLScene(); initProjectionScreen(trial.getCurrent()["AbsDepth"]); isStimulusDrawn=true; break; case 'i': visibleInfo=!visibleInfo; break; case 'm': interoculardistance += 0.5; break; case 'n': interoculardistance -= 0.5; break; case '+': { // Il trucco per avanzare alla modalita' trial successiva: incrementi di uno e poi tieni il resto della // divisione per due, in questo caso ad esempio sara' sempre: // 0,1,0,1,0,1 // se metti il resto della divisione per 3 invece la variabile trialMode sar' // 0,1,2,0,1,2 // ogni ciclo della variabile trialMode normalmente e' un trial (1) // puoi anche definire una funzione void advanceTrial() che si occupa di andare al trial successivo, // deve contenere una chiamata alla BalanceFactor::getNext() cosi' passi alla nuova lista di fattori // Ad esempio trialMode++; trialMode=trialMode%3; } break; case 't': { if (trial.isEmpty()) exit(0); trial.next(); break; } case 'Q': case 'q': case 27: //corrisponde al tasto ESC { // Ricorda quando chiami una funzione exit() di chiamare prima cleanup cosi // spegni l'Optotrak ed i markers (altrimenti loro restano accesi e li rovini) cleanup(); exit(0); } break; case ' ': { // Here we record the head shape - coordinates of eyes and markers, but centered in (0,0,0) if ( headCalibrationDone==0 && allVisiblePatch ) { headEyeCoords.init(markers[1].p-Vector3d(230,0,0),markers[1].p, markers[5].p,markers[6].p,markers[7].p,interoculardistance ); headCalibrationDone=1; beepOk(0); break; } // Second calibration, you must look a fixed fixation point if ( headCalibrationDone==1 && allVisiblePatch ) { headEyeCoords.init( headEyeCoords.getP1(),headEyeCoords.getP2(), markers[5].p, markers[6].p,markers[7].p,interoculardistance ); headCalibrationDone=2; break; } } break; // Enter key: press to make the final calibration case 13: { if ( headCalibrationDone == 2 && allVisiblePatch ) { headEyeCoords.init( headEyeCoords.getP1(),headEyeCoords.getP2(), markers[1].p, markers[2].p,markers[3].p,interoculardistance ); headCalibrationDone=3; visibleInfo=false; } } break; case '5': { if(dz/2>10) zedge -= .25; else zedge = zedge; } break; case '8': { zedge += .25; } break; case '4': { xedge -= .25; } break; case '6': { xedge += .25; } break; case 'a': { theta -= M_PI/2.0; } break; case 's': { theta += M_PI/2.0; } break; case '0': { advanceTrial(); } break; } }
// Funzione di callback per gestire pressioni dei tasti void handleKeypress(unsigned char key, int x, int y) { switch (key) { #ifdef SIMULATION case '0': { good_trial = 1; advanceTrial(); } break; case '1': allVisibleFingers = !allVisibleFingers; break; case '2': { trial.reinsert(trial.getCurrent()); good_trial = 0; advanceTrial(); } break; #endif case 'i': // show info visibleInfo=!visibleInfo; break; case 'm': // increase IOD interoculardistance += 0.5; break; case 'n': // decrease IOD interoculardistance -= 0.5; break; case 27: // press escape to quit { cleanup(); // clean the optotrak buffer exit(0); } break; // fingers calibration case 'f': case 'F': { // Interpolate the fingertip (fourth virtual marker) if ( fingerCalibrationDone==2 && allVisibleObject && allVisibleFingers ) { fingerCalibrationDone=3; calibration_fingers(fingerCalibrationDone); beepOk(3); break; } // Start the experiment if ( fingerCalibrationDone==3 && allVisibleFingers ) { fingerCalibrationDone=4; beepOk(0); home_position = ind; visibleInfo=false; drawGLScene(); // this is needed otherwise the next motor command freezes the screen // check where the object is object_reset_position = markers[3].p.transpose(); // calculate where the object has to go Vector3d object_position(0.0,object_reset_position.y(),-550.0); // move the object to position from where it is moveObjectAbsolute(object_position, object_reset_position, 5000); trial.next(); initTrial(); } if (fingerCalibrationDone==4 && training) areFingersDrawn = !areFingersDrawn; } break; case ' ': // confirm that you grasped { if(allVisibleFingers) { iGrasped = true; isStimulusDrawn = false; } } break; /* case 't': { training = true; experiment =false; beepOk(0); } break; */ case 'e': { if(training) { training = false; experiment = true; initTrial(); } } break; case 's': { if(training) initTrial(); } break; case 8: // backspace resets calibration { fingerCalibrationDone=0; } break; } }
// Funzione di callback per gestire pressioni dei tasti void handleKeypress(unsigned char key, int x, int y) { switch (key) { //Quit program case 'x': // Facendo cosi si cancella lo stimolo durante il movimento (SINCRONO) del monitor. // Si imposta il isStimulusDrawn a FALSE e si riaggiorna la schermata con una drawGLScene() // infine si muove il monitor, la chiamata blocca il programma per x secondi, si // simula lo spostamento dello schermo di proiezione ed infine si reimposta isStimulusDrawn a TRUE // cosi' la prossima chiamata di drawStimulus() lo disegna correttamente a schermo. Provare per credere... //factors = trial.getNext(); // trial.next(); drawGLScene(); // initProjectionScreen(trial.getCurrent()["AbsDepth"]); break; case 'i': visibleInfo=!visibleInfo; break; case 'm': interoculardistance += 0.5; break; case 'n': interoculardistance -= 0.5; break; case '+': { // Il trucco per avanzare alla modalita' trial successiva: incrementi di uno e poi tieni il resto della // divisione per due, in questo caso ad esempio sara' sempre: // 0,1,0,1,0,1 // se metti il resto della divisione per 3 invece la variabile trialMode sar' // 0,1,2,0,1,2 // ogni ciclo della variabile trialMode normalmente e' un trial (1) // puoi anche definire una funzione void advanceTrial() che si occupa di andare al trial successivo, // deve contenere una chiamata alla BalanceFactor::getNext() cosi' passi alla nuova lista di fattori // Ad esempio trialMode++; trialMode=trialMode%4; } break; case 'Q': case 'q': case 27: //corrisponde al tasto ESC { // Ricorda quando chiami una funzione exit() di chiamare prima cleanup cosi // spegni l'Optotrak ed i markers (altrimenti loro restano accesi e li rovini) cleanup(); exit(0); } break; case 'd': { fingersShown = !fingersShown; } break; case ' ': { // Here we record the head shape - coordinates of eyes and markers, but centered in (0,0,0) if ( headCalibrationDone==0 && allVisiblePatch ) { headEyeCoords.init(markers[1].p-Vector3d(230,0,0),markers[1].p, markers[5].p,markers[6].p,markers[7].p,interoculardistance ); headCalibrationDone=1; beepOk(0); break; } // Second calibration, you must look a fixed fixation point if ( headCalibrationDone==1 && allVisiblePatch ) { headEyeCoords.init( headEyeCoords.getP1(),headEyeCoords.getP2(), markers[5].p, markers[6].p,markers[7].p,interoculardistance ); headCalibrationDone=2; break; } } break; case 'f': case 'F': { // Here we record the finger tip physical markers if ( allVisiblePlatform && (fingerCalibrationDone==0) ) { //platformFingers=markers[1].p; platformIndex=markers[1].p; platformThumb=markers[2].p; //centercal = markers[4].p; fingerCalibrationDone=1; beepOk(0); break; } if ( (fingerCalibrationDone==1) && allVisibleFingers ) { indexCoords.init(platformIndex, markers.at(13).p, markers.at(14).p, markers.at(16).p ); thumbCoords.init(platformThumb, markers.at(15).p, markers.at(17).p, markers.at(18).p ); fingerCalibrationDone=2; beepOk(0); break; } if ( fingerCalibrationDone==2 && allVisibleFingers ) { beepOk(0); fingerCalibrationDone=3; visibleInfo=!visibleInfo; trial.next(); initTrial(); break; } } break; // Enter key: press to make the final calibration case 13: { if ( headCalibrationDone == 2 && allVisiblePatch ) { headEyeCoords.init( headEyeCoords.getP1(),headEyeCoords.getP2(), markers[5].p, markers[6].p,markers[7].p,interoculardistance ); headCalibrationDone=3; visibleInfo=false; } } break; case '5': { theta += 1; } break; case '8': { theta -= 1; } break; case 's': { advanceTrial(); } break; case '0': { training=!training; } break; case 'c': { pulsingColors=!pulsingColors; } break; case 'l': //L { //hapticLarger=!hapticLarger; } } }
// Funzione di callback per gestire pressioni dei tasti void handleKeypress(unsigned char key, int x, int y) { switch (key) { //Quit program case 'x': // Facendo cosi si cancella lo stimolo durante il movimento (SINCRONO) del monitor. // Si imposta il isStimulusDrawn a FALSE e si riaggiorna la schermata con una drawGLScene() // infine si muove il monitor, la chiamata blocca il programma per x secondi, si // simula lo spostamento dello schermo di proiezione ed infine si reimposta isStimulusDrawn a TRUE // cosi' la prossima chiamata di drawStimulus() lo disegna correttamente a schermo. Provare per credere... //factors = trial.getNext(); // trial.next(); drawGLScene(); // initProjectionScreen(trial.getCurrent()["AbsDepth"]); break; case 'i': visibleInfo=!visibleInfo; break; case 'l': exits=!exits; break; case 'm': { interoculardistance += 0.5; headEyeCoords.setInterOcularDistance(interoculardistance); } break; case 'n': { interoculardistance -= 0.5; headEyeCoords.setInterOcularDistance(interoculardistance); } break; case '+': { // Il trucco per avanzare alla modalita' trial successiva: incrementi di uno e poi tieni il resto della // divisione per due, in questo caso ad esempio sara' sempre: // 0,1,0,1,0,1 // se metti il resto della divisione per 3 invece la variabile trialMode sar' // 0,1,2,0,1,2 // ogni ciclo della variabile trialMode normalmente e' un trial (1) // puoi anche definire una funzione void advanceTrial() che si occupa di andare al trial successivo, // deve contenere una chiamata alla BalanceFactor::getNext() cosi' passi alla nuova lista di fattori // Ad esempio trialMode++; trialMode=trialMode%3; } break; case 'Q': case 'q': case 27: //corrisponde al tasto ESC { // Ricorda quando chiami una funzione exit() di chiamare prima cleanup cosi // spegni l'Optotrak ed i markers (altrimenti loro restano accesi e li rovini) cleanup(); exit(0); } break; case 'f': case 'F': { // Interpolate the fingertip (fourth virtual marker) if ( fingerCalibrationDone==2 && allVisibleObject && allVisibleFingers ) { fingerCalibrationDone=3; calibration_fingers(fingerCalibrationDone); beepOk(3); break; } // Start the experiment if ( fingerCalibrationDone==3 && allVisibleFingers ) { fingerCalibrationDone=4; beepOk(0); visibleInfo=false; drawGLScene(); // this is needed otherwise the next motor command freezes the screen // check where the object is object_reset_position = markers[3].p.transpose(); // calculate where the object has to go Vector3d object_position(0.0,object_reset_position.y(),-550.0); // move the object to position from where it is moveObjectAbsolute(object_position, object_reset_position, 5000); trial.next(); initTrial(); break; } } break; case 't': { advanceTrial(); } break; } }
// Funzione di callback per gestire pressioni dei tasti void handleKeypress(unsigned char key, int x, int y) { switch (key) { case 'x': // test for final screen expFinished=true; break; case 'i': // show info visibleInfo=!visibleInfo; break; case 'm': // increase IOD interoculardistance += 0.5; break; case 'n': // decrease IOD interoculardistance -= 0.5; break; case '8': // increase object's depth { adjDz += .25; offsetZ += .25; } break; case '5': // decrease object's depth { adjDz -= .25; offsetZ -= .25; } break; case '0': // go to the next trial { if(expStarted && offsetZ != 0.0) advanceTrial(); } break; case 27: // press escape to quit { cleanup(); // clean the optotrak buffer exit(0); } break; case 13: // press enter to start { if(!expStarted) { // turn off info visibleInfo = false; /* // check where the object is object_reset_position = markers[3].p.transpose(); // calculate where the object has to go Vector3d object_position(0.0,object_reset_position.y(),-330.0); // move the object to position from where it is moveObjectAbsolute(object_position, object_reset_position, 5000); */ // start the experiment expStarted = true; trial.next(); initTrial(); } } break; } }
/*** keypresses ***/ void handleKeypress(unsigned char key, int x, int y) { switch (key) { case 27: // press escape to quit { servo_disengage(wedgeMotors, 2); servo_disengage(wedgeMotors, 3); usleep(500000); servo_rotate(wedgeMotors, 2, 0.0); servo_rotate(wedgeMotors, 3, 90.0); servo_close(wedgeMotors); switch_disconnect(); exit(0); } break; case 13: { expBegun = true; trial.next(); initTrial(); } break; case '4': { final_theta += 5.0; if (final_theta > 170.0) final_theta = 170.0; servo_rotate(wedgeMotors, 3, 90.0 + trial.getCurrent()["Tilt_sign"] * final_theta); } break; case '1': { final_theta -= 5.0; if (final_theta < -80.0) final_theta = -80.0; servo_rotate(wedgeMotors, 3, 90.0 + trial.getCurrent()["Tilt_sign"] * final_theta); } break; case '5': { final_theta += 1.0; if (final_theta > 170.0) final_theta = 170.0; servo_rotate(wedgeMotors, 3, 90.0 + trial.getCurrent()["Tilt_sign"] * final_theta); } break; case '2': { final_theta -= 1.0; if (final_theta < -80.0) final_theta = -80.0; servo_rotate(wedgeMotors, 3, 90.0 + trial.getCurrent()["Tilt_sign"] * final_theta); } break; case '0': { servo_disengage(wedgeMotors, 2); servo_disengage(wedgeMotors, 3); advanceTrial(); } break; } }