Пример #1
0
void handleKeypress(unsigned char key, int x, int y)
{
    switch (key)
    {   //Quit program
    case 'q':
    case 27:
    {
		optotrak.stopCollection();
		Sleep(1000);
        exit(0);
    }
    break;
    case 'i':
        infoDrawn=!infoDrawn;
        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[17].p,markers[18].p, markers[1].p,markers[2].p,markers[3].p,interoculardistance );
            headCalibrationDone=1;
            beepOk();
            break;
        }
        // Second calibration, you must look a fixed fixation point
        if ( headCalibrationDone==1  && allVisiblePatch)
        {
            headEyeCoords.init( headEyeCoords.getP1().p,headEyeCoords.getP2().p, markers[1].p, markers[2].p,markers[3].p,interoculardistance );
            headCalibrationDone=2;
            beepOk();
            break;
        }
        if ( headCalibrationDone==2  && allVisiblePatch )
        {   headEyeCoords.init( headEyeCoords.getP1().p,headEyeCoords.getP2().p, markers[1].p, markers[2].p,markers[3].p,interoculardistance );
            beepOk();
            break;
        }
    }
    break;
    // Enter key: press to make the final calibration
    case 13:
    {
        if ( canCalibrate && headCalibrationDone == 2 && allVisiblePatch )
        {
            headEyeCoords.init( headEyeCoords.getP1().p,headEyeCoords.getP2().p, markers[1].p, markers[2].p,markers[3].p,interoculardistance );
            headCalibrationDone=3;
            infoDrawn=false;
            for (int i=0; i<3; i++)
                beepOk();
        }
    }
    break;
    }
}
Пример #2
0
Vector3d getEyeProjectionPoint()
{
    Eigen::Hyperplane<double,3> focalPlane = Eigen::Hyperplane<double,3>::Through   ( Vector3d(1,0,focalDistance), Vector3d(0,1,focalDistance),Vector3d(0,0,focalDistance) );

    // Projection of view normal on the focal plane
    Vector3d directionOfSight = (headEyeCoords.getRigidStart().getFullTransformation().rotation()*Vector3d(0,0,-1)).normalized();
    Eigen::ParametrizedLine<double,3> lineOfSightRight = Eigen::ParametrizedLine<double,3>::Through( eyeRight , eyeRight+directionOfSight );

    double dist = lineOfSightRight.intersection(focalPlane);

    return (dist*(directionOfSight)+ (eyeRight));
}
Пример #3
0
Affine3d getPassiveMatrix()
{
    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(Vector3d(0,0,focalDistance)));
    VRCamera camPassive;
    camPassive.init(screenPassive);
    camPassive.setDrySimulation(true);
    camPassive.setEye(eyeRight);
    return ( camPassive.getModelViewMatrix()*objectActiveTransformation );
}
Пример #4
0
void drawInfo()
{
    if ( !infoDrawn )
        return;
    GLText text;
    text.init(SCREEN_WIDTH, SCREEN_HEIGHT,glWhite);
    text.enterTextInputMode();
    string strfactors;
    for ( map<string,double>::iterator iter = factors.begin(); iter!=factors.end(); ++iter)
    {
        text.draw( (iter->first) + "= " + util::stringify<int>( (int )(iter->second)) );
    }
    switch ( headCalibrationDone )
    {
    case 0:
    {
        if ( allVisibleHead )
            text.draw("OK! Press SPACEBAR");
        else
            text.draw("---");
    }
    break;
    case 1:
    case 2:
    {
        text.draw( "EL " + stringify<int>(eyeLeft.x() ) + " " + stringify<int>(eyeLeft.y() ) + " " + stringify<int>(eyeLeft.z()) );
        text.draw( "ER " + stringify<int>(eyeRight.x() ) + " " + stringify<int>(eyeRight.y() ) + " " + stringify<int>(eyeRight.z()) );
        text.draw("EC " + stringify<int>(cyclopeanEye.x())+" " + stringify<int>(cyclopeanEye.y())+" " + stringify<int>(cyclopeanEye.z()));
        text.draw("Dist " + stringify<int>(cyclopeanEye.z()-focalDistance+60.0));
        text.draw(" ");
        text.draw( "PITCH " + stringify<int>(toDegrees(headEyeCoords.getPitch())));
        text.draw( "YAW " + stringify<int>(toDegrees(headEyeCoords.getYaw())));
        text.draw( "ROLL " + stringify<int>(toDegrees(headEyeCoords.getRoll())));
    }
    break;
    }
    text.leaveTextInputMode();
}
Пример #5
0
void writeContinuosDataFile()
{
    ofstream outputfile;
    outputfile.open("data.dat");

    outputfile << "Yaw: " << toDegrees(headEyeCoords.getYaw()) << endl <<"Pitch: " << toDegrees(headEyeCoords.getPitch()) << endl;
    outputfile << "EyeLeft: " <<  eyeLeft.transpose() << endl;
    outputfile << "EyeRight: " << eyeRight.transpose() << endl << 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 << "Trials done: " << trialNumber << endl;
	if (trialNumber!=0)
		outputfile << "Last response (right=0, left=1): " << response << endl;
    outputfile.clear();
    outputfile.seekp(0,ios::beg);
}
Пример #6
0
void idle()
{   // Set the time during which the stimulus is drawn, it depents on the phase (adaption or test)
    double drawStimTime = 0;
    if ( block.at("Phase") == 1 )
        drawStimTime = str2num<double>(parameters.find("AdaptStimulusDuration"));
    else
        drawStimTime = str2num<double>(parameters.find("TestStimulusDuration"));
    double deltaT = (double)TIMER_MS;
    optotrak->updateMarkers(deltaT);
    markers = optotrak->getAllMarkers();
    // Coordinates picker
    allVisiblePlatform = isVisible(markers.at(15).p) && isVisible(markers.at(16).p);
    allVisibleThumb = isVisible(markers.at(11).p) && isVisible(markers.at(12).p) && isVisible(markers.at(13).p);
    allVisibleIndex = isVisible(markers.at(7).p) && isVisible(markers.at(8).p) && isVisible(markers.at(9).p);
    allVisibleFingers = allVisibleThumb && allVisibleIndex;

    allVisiblePatch = isVisible(markers.at(1).p) && isVisible(markers.at(2).p) && isVisible(markers.at(3).p);
    allVisibleHead = allVisiblePatch && isVisible(markers.at(17).p) && isVisible(markers.at(18).p);

    //if ( allVisiblePatch )
    headEyeCoords.update(markers.at(1).p,markers.at(2).p,markers.at(3).p,deltaT);
// update thumb coordinates
    thumbCoords.update(markers.at(11).p,markers.at(12).p,markers.at(13).p,deltaT);
// update index coordinates
    indexCoords.update(markers.at(7).p, markers.at(8).p, markers.at(9).p,deltaT);

    eyeLeft = headEyeCoords.getLeftEye().p;
    eyeRight = headEyeCoords.getRightEye().p;

    checkBounds();
    indexInside[1]=indexInside[0];

    // Controlla i frames occlusi, se il dito di test è fuori dalla sfera
    // ed ha superato una percentuale di tempo maggiore di
    // TestPercentOccludedFrames rispetto al tempo di presentazione dello
    // stimolo allora fa un beep

    if ( headCalibrationDone==3 && fingerCalibrationDone==3 && !indexInside[0] && (int) block.at("Phase")!=1 && isDrawing )
    {
        bool visibleFinger=true;
        switch ( str2num<int>(parameters.find("TestFinger")) )
        {
        case 0:
            visibleFinger=isVisible(thumbCoords.getP1().p);
            break;
        case 1:
            visibleFinger=isVisible(indexCoords.getP1().p);
            break;
        case 2:
            visibleFinger=isVisible(thumbCoords.getP1().p) && isVisible(indexCoords.getP1().p);
            break;
        }
        // XXX scommentare per far si che anche il polso venga controllato per missing frames
        //visibleFinger = visibleFinger && isVisible(markers.at(6).p);
        if ( !visibleFinger )
        {   occludedFrames++;
            if ( str2num<int>(parameters.find("AudioFeedback") ) )
                boost::thread invisibleBeep( beepInvisible);
        }
        trialOk=true;	// mentre disegna lo stimolo
    }
    // Qui durante la fase di delay dopo la scomparsa dello stimolo controlla che il numero
    // di frames occlusi non abbia superato il limite consentito
    if ( isDrawing==0 && headCalibrationDone==3 && (block.at("Phase")!=1) && !indexInside[0] )
    {
        double percentOccludedFrames = ((double)occludedFrames/(double)drawingTrialFrame )*100.0;
        trialOk=(percentOccludedFrames < str2num<double>(parameters.find("TestPercentOccludedFrames")));
    }
    // Calcola le coordinate delle dita offsettate durante la fase di adattamento
    if ( block.at("Phase") == 1 )
    {   double fingerOffset =   adaptOffsets.at(block1TrialNumber) ;
        switch ( str2num<int>(parameters.find("AdaptFinger")) )
        {
        case 0:  //index
            visualThumb = thumbCoords.getP1().p +  Vector3d(0,0,fingerOffset);
            break;
        case 1:  //thumb
            visualIndex = indexCoords.getP1().p +  Vector3d(0,0,fingerOffset);
            break;
        case 2:
        {   visualThumb = thumbCoords.getP1().p +  Vector3d(0,0,fingerOffset);
            visualIndex = indexCoords.getP1().p +  Vector3d(0,0,fingerOffset);
        }
        break;
        }
        drawingTrialFrame=0;
        occludedFrames=0;
    }
    if ( headCalibrationDone==3 && fingerCalibrationDone==3 && trialMode==STIMULUSMODE )
    {
        if ( globalTimer.getElapsedTimeInMilliSec() <= drawStimTime )
        {   isDrawing=1;
            delayedTimer.start();
        }
        else
        {   // non disegna nulla
            if ( delayedTimer.getElapsedTimeInMilliSec() < str2num<int>(parameters.find("DelayTime")) )
                isDrawing=0;
            else
            {   delayedTimer.start();
                advanceTrial();
            }
        }
    }
    if ( (int) block.at("Phase") != 1 && isDrawing==1 )
    {   drawingTrialFrame++;
    }
#define WRITE

    int thisBlockTrialNumber=0;
    switch ( block.at("Phase") )
    {
    case 0:
        thisBlockTrialNumber=block0TrialNumber;
        break;
    case 1:
        thisBlockTrialNumber=block1TrialNumber;
        break;
    case 2:
        thisBlockTrialNumber=block2TrialNumber;
        break;
    }

    if ( !isMovingRod )
    {
        RowVector3d junk(9999,9999,9999);
// Write to file
        if ( headCalibrationDone==3 && fingerCalibrationDone==3 )
        {


            if ( totalFrame==0)
            {
                markersFile << fixed << setprecision(3) <<
                            "SubjectName\tAdaptFinger\tTestFinger\tAdaptOffset\tAdaptHapticFeedback\tFingerDist\tTotalTrial\tPhase\tTrialNumber\tTrialFrame\tdT\tTotTime\tIndexInside\tIsDrawing\tTrialOk\tVisualStimX\tVisualStimY\tVisualStimZ\tHapticRodX\tHapticRodY\tHapticRodZ\tfRelDepth\tfDistances\tDeltaXRods\tEyeLeftXraw\tEyeLeftYraw\tEyeLeftZraw\tEyeRightXraw\tEyeRightYraw\tEyeRightZraw\tWristXraw\tWristYraw\tWristZraw\tThumbXraw\tThumbYraw\tThumbZraw\tIndexXraw\tIndexYraw\tIndexZraw" << endl;
                totalFrame++;
            }
            markersFile << fixed << setprecision(3) <<
                        parameters.find("SubjectName") << "\t" <<
                        parameters.find("AdaptFinger") << "\t" <<
                        parameters.find("TestFinger") << "\t" <<
                        adaptOffsets.at(block1TrialNumber) << "\t" <<
                        parameters.find("AdaptHapticFeedback") << "\t" <<
                        fingerDistance << "\t" <<
                        totalTrialNumber << "\t" <<
                        block.at("Phase") << "\t" <<
                        thisBlockTrialNumber << "\t" <<
                        trialFrame << "\t" <<
                        deltaT*1000 << "\t" <<
                        totalTime.getElapsedTimeInMilliSec() << "\t" <<
                        indexInside[0] << "\t" <<
                        isDrawing << "\t" <<
                        trialOk << "\t" <<
                        visualRodCenter.transpose() << "\t" <<
                        hapticRodCenter.transpose() << "\t" <<
                        ((block.at("Phase")!=1) ? factors.at("RelDepth") : 9999) << "\t" <<
                        ((block.at("Phase")!=1) ? factors.at("Distances") : 9999) << "\t" <<
                        deltaXRods << "\t" <<
                        ( isVisible(eyeLeft) ? eyeLeft.transpose() : junk ) << "\t" <<
                        ( isVisible(eyeRight) ? eyeRight.transpose() : junk ) << "\t" <<
                        ( isVisible(markers.at(6).p) ? markers.at(6).p.transpose() : junk ) << "\t" <<
                        ( isVisible(thumbCoords.getP1().p) ? thumbCoords.getP1().p.transpose() : junk ) << "\t" <<
                        ( isVisible(indexCoords.getP1().p) ? indexCoords.getP1().p.transpose() : junk ) << endl;

        }
        trialFrame++;
    }
#ifdef SAVEDATADAT
    eulerAngles.init( headEyeCoords.getRigidStart().getFullTransformation().rotation() );
    // Write datafile to real-time streaming of data
    ofstream outputfile;
    outputfile.open("data.dat");
    outputfile << "Subject Name: " << parameters.find("SubjectName") << endl;
    outputfile << "AdaptHapticFeedback: " << parameters.find("AdaptHapticFeedback") << endl;
    outputfile << "AdaptFinger: " << parameters.find("AdaptFinger") << endl;
    outputfile << "TestFinger: " << parameters.find("TestFinger") << endl;
    outputfile << "IndexInside: " << indexInside[0] << endl;
    //outputfile << "Yaw: " << toDegrees(eulerAngles.getYaw()) << endl <<"Pitch: " << toDegrees(eulerAngles.getPitch()) << endl << "Roll: " << toDegrees(eulerAngles.getRoll()) << endl;
    outputfile << "EyeLeft: " <<  headEyeCoords.getLeftEye().p.transpose() << endl;
    outputfile << "EyeRight: " << headEyeCoords.getRightEye().p.transpose() << endl << endl;
    outputfile << "Thumb: " << thumbCoords.getP1().p.transpose() << endl;
    outputfile << "Index: " << indexCoords.getP1().p.transpose() << endl;
    outputfile << "Wrist: " << markers.at(6).p.transpose() << endl;
    outputfile << "IsDrawing: " << isDrawing << " TrialOk: " << trialOk << " OccludedFrames: " << occludedFrames << " DrawingTrialFrames: " << drawingTrialFrame << endl;
    outputfile << "HapticRodCenter: " << hapticRodCenter.transpose() << endl;
    outputfile << "VisualRodCenter: " << visualRodCenter.transpose() << endl;
    outputfile << "Markers(5): " << markers.at(5).p.transpose() << endl;
    outputfile << "AdaptOffset: " << adaptOffsets.at(block1TrialNumber) << endl;
    outputfile << "Phase: " << block.at("Phase") << endl;
    outputfile << "TrialNumber: " << thisBlockTrialNumber << endl;
    outputfile << "Total trials: " << totalTrialNumber << endl;
#endif
    frameTimer.start();
}
Пример #7
0
void checkBounds()
{   if ( fingerCalibrationDone==3 && headCalibrationDone==3 )
    {
        switch ( trialMode )
        {   /*
            Vector3d trueIndex = indexCoords.getP1().p;
            Vector3d trueThumb = thumbCoords.getP1().p;
            case STIMULUSMODE:
            {  // Check if the index tip stays inside the stimulus
            Vector2d indexOnPlane = Vector2d(trueIndex.x(),trueIndex.z());
            Vector2d hapticRodCenterOnPlane = Vector2d(hapticRodCenter.x(), hapticRodCenter.z()+10);
            double stimHeight=0, stimRadius=0;
            switch ( block.at("Phase") )
            {  case 0:
            case 2:
            {  stimHeight = str2num<double>(parameters.find("TestStimulusHeight") );
            stimRadius = str2num<double>(parameters.find("TestStimulusRadius") );
            }
            break;
            case 1:
            {  stimHeight = str2num<double>(parameters.find("AdaptStimulusHeight") );
            stimRadius = str2num<double>(parameters.find("AdaptStimulusRadius") );
            }
            break;
            }
            bool yInside = (trueIndex.y()-(hapticRodCenter.y()+stimulusRodOffsetY))<(stimHeight/2) && (trueIndex.y()-(hapticRodCenter.y()+stimulusRodOffsetY))> (-stimHeight/2) ;
            if ( ( (indexOnPlane - hapticRodCenterOnPlane).norm() <= stimRadius ) && yInside )
            indexInside[0]=true;
            else
            indexInside[0]=false;
            }

            break;
            */

        case HANDONSTARTMODE: //handsonstart
        {   // Define a sphere around physicalRigidBodyTip in which the thumb must stay
            bool indexVisible = isVisible(markers.at(7).p) && isVisible(markers.at(8).p) && isVisible(markers.at(9).p);
            if ( indexVisible )
            {   bool triggerCondition=false;
                if ( parameters.find("Task") == "MSE" && (block.at("Phase") != 1) )
                    triggerCondition = (globalTimer.getElapsedTimeInMilliSec() < 1500);
                else
                    triggerCondition=((indexCoords.getP1().p  - physicalRigidBodyTip).norm() < ballRadius);

                if ( triggerCondition ) //5 centimeters
                {   indexInside[0]=true;
                    if ( indexInside[1]==false)
                        globalTimer.start();
                }
                else
                {   indexInside[0]=false;

                    double distance = (indexCoords.getP1().p  - physicalRigidBodyTip).norm();
                    // IMPORTANTE: controlla che il dito sia uscito ma esclude i casi in cui il dito esce da invisibile e diventa visibile fuori dalla palla... una soglia decente è 10 mm
                    if ( indexInside[1]==true && distance<(ballRadius+10) ) //è appena uscito
                    {   globalTimer.start();
                        trialMode=STIMULUSMODE;
                    }
                }
            }
        }
        break;
        }
    }
}
Пример #8
0
void handleKeypress(unsigned char key, int x, int y)
{   switch (key)
    {   //Quit program
    case 'q':
    case 27:
    {   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 && allVisibleHead )
        {   headEyeCoords.init(markers.at(17).p,markers.at(18).p, markers.at(1).p,markers.at(2).p,markers.at(3).p,interoculardistance );
            headCalibrationDone=1;
            beepOk();
            break;
        }
        if ( headCalibrationDone==1 && allVisiblePatch )
        {
            headCalibrationDone=3;
            beepOk();
        }
    }
    break;
    case 'i':
        infoDraw=!infoDraw;
        break;
    case 'f':
    case 'F':
    {   // Here we record the finger tip physical markers
        if ( allVisiblePlatform && (fingerCalibrationDone==0) )
        {   platformIndex=markers.at(16).p;
            platformThumb=markers.at(15).p;
            fingerCalibrationDone=1;
            beepOk();
            break;
        }
        if ( (fingerCalibrationDone==1) && allVisibleFingers )
        {   thumbCoords.init(platformThumb, markers.at(11).p, markers.at(12).p, markers.at(13).p);
            indexCoords.init(platformIndex, markers.at(7).p, markers.at(8).p, markers.at(9).p );
            fingerCalibrationDone=2;
            beepOk();
            break;
        }
        if ( fingerCalibrationDone==2  && allVisibleFingers )
        {   infoDraw=false;
            drawGLScene();
            physicalRigidBodyTip = indexCoords.getP1().p;
            fingerCalibrationDone=3;

            switch ( block.at("Phase") )
            {
            case 0:
            case 2:
            {   factors = trial.getNext();
                initStimulus(testStimHeight,testStimRadius);
                moveScreenAbsolute(factors.at("Distances"),homeFocalDistance,SCREENSPEED);
                initProjectionScreen(factors.at("Distances"));
                visualRodCenter = Vector3d(0,0,factors.at("Distances"));
                hapticRodCenter = rodAway;	// keep it away
                moveRod(rodAway,RODSPEED);
            }
            break;
            case 1:
            {   double zadaptmin = str2num<double>(parameters.find("AdaptZMin"));
                double zadaptmax = str2num<double>(parameters.find("AdaptZMax"));

                if (str2num<int>(parameters.find("AdaptMoveMonitor"))==1)
                    visualRodCenter = Vector3d(0,0,mathcommon::unifRand(zadaptmin,zadaptmax));
                else
                    visualRodCenter = Vector3d(0,0,(zadaptmax+zadaptmin)/2);

                if ( str2num<int>(parameters.find("AdaptHapticFeedback"))==1 )
                    hapticRodCenter = visualRodCenter - Vector3d(0,0,adaptOffsets.at(block1TrialNumber));
                else
                    hapticRodCenter = rodAway;

                initProjectionScreen( visualRodCenter.z() );
                initStimulus(str2num<double>(parameters.find("AdaptStimulusHeight")),str2num<double>(parameters.find("AdaptStimulusRadius")));
                moveScreenAbsoluteAsynchronous(visualRodCenter.z(),homeFocalDistance,SCREENSPEED);
                moveRod(hapticRodCenter,RODSPEED);
            }
            break;
            }
            trialMode = HANDONSTARTMODE;
            fingerDistance = (indexCoords.getP1().p-thumbCoords.getP1().p).norm();
            beepTrial();
            trialFrame=0;
            globalTimer.start();
            totalTime.start();
            break;
        }
    }
    break;
    }
}
Пример #9
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();
    }
}
Пример #10
0
void handleKeypress(unsigned char key, int x, int y)
{   switch (key)
    {   //Quit program
    case 'q':
    case 27:
    {   
		plato_stop();
		exit(0);
    }
    break;
    case ' ':
    {   // Here we record the head shape - coordinates of eyes and markers, but centered in (0,0,0)
        if ( headCalibrationDone==0 && allVisibleHead )
        {   headEyeCoords.init(markers.at(17).p,markers.at(18).p, markers.at(1).p,markers.at(2).p,markers.at(3).p,interoculardistance );
            headCalibrationDone=1;
            beepOk();
            break;
        }
        if ( headCalibrationDone==1 && allVisiblePatch )
        {
            headCalibrationDone=3;
            RoveretoMotorFunctions::moveObjectAbsolute( platformCalibration, rodTipHome, 3500);
            beepOk();
        }
    }
    break;
    case 'i':
        infoDraw=!infoDraw;
        break;
    case 'f':
    case 'F':
    {
        if (headCalibrationDone < 3 )
            break;
        // Here we record the finger tip physical markers
        if ( allVisiblePlatform && (fingerCalibrationDone==0) )
        {   platformIndex=markers.at(16).p;
            platformThumb=markers.at(15).p;
            fingerCalibrationDone=1;
            beepOk();
            break;
        }
		// Calibrate the index first
        if ( (fingerCalibrationDone==1) && allVisibleIndex )
        {   
			indexCoords.init(platformIndex, markers.at(7).p, markers.at(8).p, markers.at(9).p );
			rigidStartIndex.setRigidBody(markers.at(7).p-platformIndex,markers.at(8).p-platformIndex,markers.at(9).p-platformIndex);
			fingerCalibrationDone=2;
            beepOk();
            break;
        }
		// Calibrate the thumb then
		if ( (fingerCalibrationDone==2) && allVisibleThumb )
        {   
			rigidStartThumb.setRigidBody(markers.at(11).p-platformThumb,markers.at(12).p-platformThumb,markers.at(13).p-platformThumb);
            thumbCoords.init(platformThumb, markers.at(11).p, markers.at(12).p, markers.at(13).p);
            fingerCalibrationDone=3;
            beepOk();
            break;
        }
        if ( fingerCalibrationDone==3  && allVisibleFingers )
        {
			fingerCalibrationDone=4;
            infoDraw=false;
            paintGL();
            physicalRigidBodyTip = indexCoords.getP1().p;
            trialMode = HANDONSTARTMODE;
            fingerDistance = (indexCoords.getP1().p-thumbCoords.getP1().p).norm();
            moveStimulusObject(visualStimCenter,3500);
            beepTrial();
            trialFrame=0;
            drawingTrialFrame=0;
            globalTimer.start();
			plato_write(PLATO_LEFT_RIGHT_OPEN);

            break;
        }
    }
    break;
    }
}
Пример #11
0
/**
 * @brief idle
 */
void idle()
{
    double deltaT = (double)TIMER_MS;
    optotrak.updateMarkers(deltaT);
    markers = optotrak.getAllMarkers();
    // Coordinates picker
    allVisiblePlatform = isVisible(markers.at(15).p) && isVisible(markers.at(16).p);
    allVisibleThumb = isVisible(markers.at(11).p) && isVisible(markers.at(12).p) && isVisible(markers.at(13).p);
    allVisibleIndex = isVisible(markers.at(7).p) && isVisible(markers.at(8).p) && isVisible(markers.at(9).p);
    allVisibleFingers = allVisibleThumb && allVisibleIndex;

    allVisiblePatch = isVisible(markers.at(1).p) && isVisible(markers.at(2).p) && isVisible(markers.at(3).p);
    allVisibleHead = allVisiblePatch && isVisible(markers.at(17).p) && isVisible(markers.at(18).p);

    //if ( allVisiblePatch )
    headEyeCoords.update(markers.at(1).p,markers.at(2).p,markers.at(3).p,deltaT);
    // update thumb coordinates
    thumbCoords.update(markers.at(11).p,markers.at(12).p,markers.at(13).p,deltaT);
    // update index coordinates
    indexCoords.update(markers.at(7).p, markers.at(8).p, markers.at(9).p,deltaT);

    // Compute the coordinates of visual thumb
    thumb = thumbCoords.getP1().p;
    index = indexCoords.getP1().p;

    eyeLeft = headEyeCoords.getLeftEye().p;
    eyeRight = headEyeCoords.getRightEye().p;

	rigidCurrentThumb.setRigidBody(markers.at(11).p,markers.at(12).p,markers.at(13).p);
    rigidCurrentIndex.setRigidBody(markers.at(7).p,markers.at(8).p,markers.at(9).p);

    rigidStartThumb.computeTransformation(rigidCurrentThumb);
    rigidStartIndex.computeTransformation(rigidCurrentIndex);

    if (headCalibrationDone==3 && fingerCalibrationDone==4)
    {
		if ( !allVisibleIndex || !allVisibleThumb || !isVisible(markers.at(6).p))
			boost::thread invisibleBeep( beepInvisible);

        Vector2d thumbProjection = cam.computeProjected(thumb);
        thumbProjectedInside = ( thumbProjection.x() >= 0 && thumbProjection.x() <= SCREEN_WIDTH ) && ( thumbProjection.y() >= 0 && thumbProjection.y() <= SCREEN_HEIGHT );

        Vector2d indexProjection = cam.computeProjected(index);
        indexProjectedInside = ( indexProjection.x() >= 0 && indexProjection.x() <= SCREEN_WIDTH ) && ( indexProjection.y() >= 0 && indexProjection.y() <= SCREEN_HEIGHT );

        trialFrame++;
        // Work on fingers coordinates
        double wThumb=0.5, wIndex=0.5;
        Vector3d m = (wThumb*thumb+wIndex*index)/(wThumb+wIndex);
        Vector3d d = thumb-index;

        visualThumb = thumb;
        visualIndex = index;

        double clamp= 2*factors.getCurrent().at("StimulusRadius");
        double gain = 1.0;//in quello di Bob era invece: factors.getCurrent().at("Gain");
        if ( d.norm() > clamp )
        {
            visualThumb = m + 0.5*d.normalized()*(gain*d.blueNorm() - clamp*(gain-1));
            visualIndex = m - 0.5*d.normalized()*(gain*d.blueNorm() - clamp*(gain-1));
        }

        // Check when to advance trial
        double stimRadius = factors.getCurrent().at("StimulusRadius");
        double radiusTolerance = util::str2num<double>(parameters.find("RadiusTolerance"));
        fingNow = fingersInSphericalVolume(thumb,index, visualStimCenter, stimRadius-radiusTolerance, stimRadius+radiusTolerance, selectedFinger );

		// SubjectName\tFingerDist\tTrialNumber\tTrialFrame\tTotTime\tVisualStimX\tVisualStimY\tVisualStimZ\tfStimulusRadius\tfDistances\tfGain\tEyeLeftXraw\tEyeLeftYraw\tEyeLeftZraw\tEyeRightXraw\tEyeRightYraw\tEyeRightZraw\tWristXraw\tWristYraw\tWristZraw\tThumbXraw\tThumbYraw\tThumbZraw\tIndexXraw\tIndexYraw\tIndexZraw\tVisualThumbXraw\tVisualThumbYraw\tVisualThumbZraw\tVisualIndexXraw\tVisualIndexYraw\tVisualIndexZraw\tIsDrawing\tIsThumbProjected\tIsIndexProjected
        if (!isSaving)
			return;
		RowVector3d junk(9999,9999,9999);
        markersFile << fixed << setprecision(3) <<
                    parameters.find("SubjectName") << "\t" <<
                    fingerDistance << "\t" <<
                    totalTrialNumber << "\t" <<
                    trialFrame << "\t" <<
                    globalTimer.getElapsedTimeInMilliSec() << "\t" <<
                    visualStimCenter.x() << "\t" <<
                    visualStimCenter.y() << "\t" <<
                    visualStimCenter.z() << "\t" <<
                    factors.getCurrent().at("StimulusRadius") << "\t" <<
                    factors.getCurrent().at("Distances") << "\t" <<
                    factors.getCurrent().at("Gain") << "\t" <<
					factors.getCurrent().at("DisappearRadius") << "\t" << 
                    ( isVisible(eyeLeft) ? eyeLeft.transpose() : junk ) << "\t" <<
                    ( isVisible(eyeRight) ? eyeRight.transpose() : junk ) << "\t" <<
                    ( isVisible(markers.at(6).p) ? markers.at(6).p.transpose() : junk ) << "\t" <<
                    ( isVisible(thumb) ? thumb.transpose() : junk ) << "\t" <<
                    ( isVisible(index) ? index.transpose() : junk ) << "\t" <<
                    ( isVisible(visualThumb) ? visualThumb.transpose() : junk ) << "\t" <<
                    ( isVisible(visualIndex) ? visualIndex.transpose() : junk ) << "\t" <<
                    isDrawing << "\t" <<
                    thumbProjectedInside << "\t" <<
                    indexProjectedInside << "\t" <<
					fingNow <<
                    endl;

        // Switch to this function if you want cylindrical stimulus
        //fingersInCylindricalVolume( thumb,index, Vector3d(0,0,factors.getCurrent().at("Distances")), util::str2num<double>(parameters.find("StimulusHeight")), stimRadius,stimRadius+20, selectedFinger );
        if (trialMode == STIMULUSMODE )
        {
            if ( !fingNow ) // always starts counting the time if the finger is outside
            {
                fingersTimer.start();
            }
			// only if the finger is inside the volume the counter has counted more that 1 second
            if ( fingersTimer.getElapsedTimeInMilliSec() > util::str2num<double>(parameters.find("LeaningTime")) )
            {
					plato_write(PLATO_LEFT_RIGHT_CLOSED);
                    advanceTrial();
					plato_write(PLATO_LEFT_RIGHT_OPEN);
            }
			trialTimer.start(); // continue keeping it starting during stimulus
			drawingTrialFrame++;
            invisibleIndexFrames+=!allVisibleIndex;
            invisibleThumbFrames+=!allVisibleThumb;
			invisibleWristFrames+=!isVisible(markers.at(6).p);
        }
		else
		{
			if ( trialTimer.getElapsedTimeInMilliSec() > util::str2num<double>(parameters.find("IntervalTime")) )
			{
				boost::thread trialBeep( beepTrial );
				trialMode=STIMULUSMODE;
			}
		}
        isDrawing = (trialMode == STIMULUSMODE);
    }
}
Пример #12
0
/**
 * @brief drawInfo
 */
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();
        text.draw("Marker5= " + stringify<Eigen::Matrix<double,1,3> >(markers.at(5).p.transpose()) );
        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 on platform markers to record ghost finger tips, then press F");
                break;
			case 2:
                text.draw("Move THUMB on platform markers to record ghost finger tips, then press F");
                break;
			case 3:
                text.draw("Move BOTH INDEX AND THUMB to rigidbody tip, then press F");
				break;
            }
        }
        break;
        }
        if ( headCalibrationDone==3 && fingerCalibrationDone==4 )
        {   text.draw("Trial mode " + stringify<int>(trialMode ));
            text.draw("ThumbProjectedInside " + stringify<int>(thumbProjectedInside));
            text.draw("DrawingTrialFrame= " + stringify<int>(drawingTrialFrame));
            text.draw("TrialFrame= " + stringify<int>(trialFrame));
            text.draw("IsDrawing?= " + stringify<int>(isDrawing));
            text.draw("VisualRod= " + stringify<Eigen::Matrix<double,1,3> >(visualStimCenter.transpose()) );
            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()));
            text.draw("TrialTimer= " + stringify<int>(trialTimer.getElapsedTimeInMilliSec()));
			text.draw("FingersTime= " + stringify<int>(fingersTimer.getElapsedTimeInMilliSec()));
        }
        //text.draw("Gain=" + stringify<double>(factors.getCurrent().at("Gain")));
        text.leaveTextInputMode();
    }
}
Пример #13
0
void idle()
{
    if (trialNumber >= maxTotalTrials )
        exit(0);
	double elapsedFrameTime = totalTimer.getTimeIntervalInMilliSec();
    optotrak.updateMarkers(elapsedFrameTime);
    markers = optotrak.getAllMarkers();
    headEyeCoords.update(markers[1],markers[2],markers[3],TIMER_MS);

    allVisiblePatch =  markers[1].isVisible() && markers[2].isVisible()
                       && markers[3].isVisible();
    allVisibleHead = markers[17].isVisible() && markers[18].isVisible() && allVisibleHead;

    eyeLeft = headEyeCoords.getLeftEye().p;
    eyeRight = headEyeCoords.getRightEye().p;
    cyclopeanEye = (eyeLeft+eyeRight)/2.0;

    projPointEyeRight = getEyeProjectionPoint();

    checkBounds(nOscillationsFixation,
                eyeRight.x(),
                trialMode,
                headCalibrationDone,
                minOscTime,
                maxOscTime,
                maxXOscillation,
                translationTimer,
                beepOk,
                tweeter,
                woofer,tweeter);

    if ( trialMode == STIMULUSMODE )
        deltaT+=TIMER_MS;
    else
        deltaT=0;

    if (headCalibrationDone == 3 && trialMode != PROBEMODE )
    {
        // Questo rende conto del fatto che lo stimolo appare solo quando l'occhio è quasi in centro
		int actualTrialMode = trialMode;
		if ( trialMode == STIMULUSMODE && ( eyeRight.x()) > centerTolerance )
			actualTrialMode=FIXATIONMODE;

	markersFile << fixed <<   trialNumber << " " << actualTrialMode << " " ;
        markersFile << fixed << setprecision(3) << eyeRight.transpose() << " " << eyeLeft.transpose() << " " << toDegrees(headEyeCoords.getPitch()) << " " << toDegrees(headEyeCoords.getYaw()) << " " << toDegrees(headEyeCoords.getRoll()) << " " ;
        markersFile <<	fixed << setprecision(0)<<
                    factors["OmegaY"] << " " <<
                    factors["Binocular"] << " " <<
                    factors["Tilt"] << " " <<
                    factors["Slant"] << " " <<
                    totalTimer.getElapsedTimeInMilliSec() << endl;

        //objectPassiveTransformation.setIdentity();
		if ( actualTrialMode == STIMULUSMODE )
		{
        objectPassiveTransformation = getPassiveMatrix();
        matrixFile << setw(6) << left <<
                   trialNumber << " "  ;
        for ( int i=0; i<3; i++)
            matrixFile << objectPassiveTransformation.matrix().row(i) << " " ;
        matrixFile << endl;
		}

		if ( actualTrialMode == STIMULUSMODE )
		{
				vector< Vector3d> projPoints = stimDrawer.projectStimulusPoints(objectActiveTransformation,headEyeCoords.getRigidStart().getFullTransformation(),cam,focalDistance,screen,Vector3d(0,0,0),false,false);

				MatrixXd a1toa6 = stimDrawer.computeOpticFlow(projPoints, focalDistance, elapsedFrameTime/1000);
				flowsFile << trialNumber << " " << a1toa6.transpose() << endl;
		}
		}

    writeContinuosDataFile();

}
Пример #14
0
void handleKeypress(unsigned char key, int x, int y)
{   switch (key)
    {   //Quit program
    case 'q':
    case 27:
    {   exit(0);
    }
    break;
    case ' ':
    {   // Here we record the head shape - coordinates of eyes and markers, but centered in (0,0,0)
        if ( headCalibrationDone==0 && allVisibleHead )
        {
            headEyeCoords.init(markers.at(18).p-Vector3d(ChinRestWidth,0,0),markers.at(18).p, markers.at(1).p,markers.at(2).p,markers.at(3).p,interoculardistance );
            headCalibrationDone=1;
            beepOk();
            break;
        }
        if ( headCalibrationDone==1 && allVisiblePatch )
        {
            headCalibrationDone=3;
            beepOk();
        }
    }
    break;

    case 'i':
        infoDraw=!infoDraw;
        break;
    case 'f':
    case 'F':
    {   // Here we record the finger tip physical markers
        if ( allVisiblePlatform && (fingerCalibrationDone==0) )
        {
            platformIndex=markers.at(16).p;
            platformThumb=markers.at(15).p;
            fingerCalibrationDone=1;
            beepOk();
            break;
        }
        if ( (fingerCalibrationDone==1) && allVisibleFingers )
        {
            thumbCoords.init(platformThumb, markers.at(11).p, markers.at(12).p, markers.at(13).p);
            indexCoords.init(platformIndex, markers.at(7).p, markers.at(8).p, markers.at(9).p );
            fingerCalibrationDone=2;
            // XXX sposto l'oggetto a home per permettere le dita di calibrarsi
            // TriesteMotorFunctions::homeObject(3500); //// XXX commentato: A TS no servi
            beepOk();
            break;
        }
        if ( fingerCalibrationDone==2  && allVisibleFingers )
        {   infoDraw=false;
            drawGLScene();
            physicalRigidBodyTip = indexCoords.getP1().p;
            fingerCalibrationDone=3;

            switch ( block.at("Phase") )
            {
            case 0:
            {
                cerr << "Key 721 case 0" << endl;
                factors = trial.getNext();
                deltaXRods = mathcommon::unifRand(str2num<double>(parameters.find("DeltaXMin")),str2num<double>(parameters.find("DeltaXMax")));
                initStimulus(factors.at("StimulusHeight"),deltaXRods,factors.at("RelDepth"));
                // moveMonitorAbsolute(factors.at("Distances"),homeFocalDistance,SCREENSPEED);
                initProjectionScreen(factors.at("Distances"));
                visualRodCenter = Vector3d(0,0,factors.at("Distances"));
                hapticRodCenter = rodAway;	// keep it away
                // moveRod(rodAway,RODSPEED);
                cerr << "Key 730 case 0" << endl;
            }
            beepOk();
            break;
            case 2:
            {   factors = trial.getNext();
                deltaXRods = mathcommon::unifRand(str2num<double>(parameters.find("DeltaXMin")),str2num<double>(parameters.find("DeltaXMax")));
                initStimulus(factors.at("StimulusHeight"),deltaXRods,factors.at("RelDepth"));
                // moveMonitorAbsolute(factors.at("Distances"),homeFocalDistance,SCREENSPEED);
                initProjectionScreen(factors.at("Distances"));
                visualRodCenter = Vector3d(0,0,factors.at("Distances"));
                hapticRodCenter = rodAway;	// keep it away
                // moveRod(rodAway,RODSPEED);
            }
            break;
            case 1:
            {
                cerr << "Key 735 case 1" << endl;
                double zadaptmin = str2num<double>(parameters.find("AdaptZMin"));
                double zadaptmax = str2num<double>(parameters.find("AdaptZMax"));

                if (str2num<int>(parameters.find("AdaptMoveMonitor"))==1)
                    visualRodCenter = Vector3d(0,0,mathcommon::unifRand(zadaptmin,zadaptmax));
                else
                    visualRodCenter = Vector3d(0,0,(zadaptmax+zadaptmin)/2);

                if ( str2num<int>(parameters.find("AdaptHapticFeedback"))==1 )
                    hapticRodCenter = visualRodCenter - Vector3d(0,0,adaptOffsets.at(block1TrialNumber));
                else
                    hapticRodCenter = rodAway;

                initProjectionScreen( visualRodCenter.z() );
                initStimulus(str2num<double>(parameters.find("AdaptStimulusHeight")),adaptStimRadius*2,adaptStimRadius*2);
                moveMonitorAbsoluteAsynchronous(visualRodCenter.z(),homeFocalDistance,SCREENSPEED);
                moveRod(hapticRodCenter,RODSPEED);
            }
            break;
            }
            cerr << "Key 756 " << endl;
            trialMode = HANDONSTARTMODE;
            cerr << "Key 758 " << endl;
            fingerDistance = (indexCoords.getP1().p-thumbCoords.getP1().p).norm();
            cerr << "Key 760 " << endl;
            beepTrial();
            cerr << "Key 762 " << endl;
            trialFrame=0;
            globalTimer.start();
            totalTime.start();
            break;
        }
    }
    break;
    }
}