Пример #1
0
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);
	}
}
Пример #2
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();
}
Пример #3
0
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);
		}
}
Пример #4
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();
}
Пример #5
0
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;
	}
}
Пример #6
0
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);
    }
}
Пример #7
0
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();
    }
}
Пример #8
0
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);
}