Changeset c4ec8ae in robotics-hold_release


Ignore:
Timestamp:
08/11/13 05:43:14 (8 years ago)
Author:
Mehmet Gunal <mg@…>
Branches:
master
Children:
7978c08
Parents:
1d87ed2
Message:

algorithm update

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wheelchair/bci2000/deploy/BCI2000/src/shared/modules/application/StimulusTask.cpp

    r1d87ed2 rc4ec8ae  
    11//////////////////////////////////////////////////////////////////////////////// 
    2 // $Id: StimulusTask.cpp 3866 2012-03-06 16:11:02Z mellinger $ 
     2// $Id: StimulusTask.cpp 4447 2013-05-22 14:26:10Z mellinger $ 
    33// Author: juergen.mellinger@uni-tuebingen.de 
    44// Description: A base class for application modules that provide feedback in a 
     
    5858  mPreSequenceDuration( 0 ), 
    5959  mPostSequenceDuration( 0 ), 
     60  mEarlyOffsetPreviousValue( 0.0 ), 
     61  mEarlyOffsetExpression( ), 
    6062  mStimulusDuration( 0 ), 
    6163  mISIMinDuration( 0 ), 
     
    6466  mpMessageField( NULL ), 
    6567  mpAttendedTarget( NULL ), 
     68  mAccumulateEvidence( false ), 
     69  mMinimumEvidence( 0 ), 
    6670  mrDisplay( Window() ) 
    6771{ 
     
    7781   "Application:Sequencing float StimulusDuration= 40ms 40ms 0 % " 
    7882     "// stimulus duration", 
     83   "Application:Sequencing string EarlyOffsetExpression= % % % % " 
     84     "// abort stimulus if this expression becomes true", 
    7985   "Application:Sequencing float ISIMinDuration= 80ms 80ms 0 % " 
    8086     "// minimum duration of inter-stimulus interval", 
     
    9096   "Application:Result%20Processing int DisplayResults= 1 1 0 1 " 
    9197     "// display results of copy/free spelling (boolean)", 
     98 
     99   "Application:Result%20Processing int AccumulateEvidence= 0 0 0 1 " 
     100     "// accumulate evidence until a selection is made (boolean)", 
     101   "Application:Result%20Processing float MinimumEvidence= 0 0 0 % " 
     102     "// do not make a selection unless target evidence exceeds this value. " 
     103     "For a normalized classifier, MinimumEvidence approximates -2.3*log10(Error Probability)", 
    92104  END_PARAMETER_DEFINITIONS 
    93105 
     
    154166            + postSequenceDuration; 
    155167 
    156     if( epochLength > minStimToClassInterval ) 
     168    /*if( epochLength > minStimToClassInterval ) 
    157169      bcierr << "EpochLength is " << epochLength / oneMillisecond << "ms, exceeds " 
    158170             << "allowable maximum of " << minStimToClassInterval / oneMillisecond << "ms. " 
     
    162174             << "StimulusDuration, ISIMinDuration, and PostSequenceDuration " 
    163175             << "parameters, or decrease EpochLength, to fix this problem" 
    164              << endl; 
     176             << endl;*/ 
    165177  } 
    166178 
    167179  OptionalState( "StimulusCodeRes" ); 
    168180  State( "Running" ); 
     181 
     182  string exprstr = Parameter( "EarlyOffsetExpression" ); 
     183  if( exprstr.size() && !Expression( exprstr ).IsValid() ) 
     184  { 
     185    bcierr << "error in EarlyOffsetExpression parameter: "; 
     186    Expression( exprstr ).Evaluate(); 
     187  } 
    169188 
    170189  bcidbg( 2 ) << "Event: Preflight" << endl; 
     
    186205  mISIMinDuration = static_cast<int>( Parameter( "ISIMinDuration" ).InSampleBlocks() ); 
    187206  mISIMaxDuration = static_cast<int>( Parameter( "ISIMaxDuration" ).InSampleBlocks() ); 
     207  mEarlyOffsetExpression = Expression( Parameter( "EarlyOffsetExpression" ) ); 
    188208  mStimToClassDuration = 2 * ( mStimulusDuration + mISIMinDuration ); 
    189209  mStimToClassDuration = static_cast<int>( ::ceil( OptionalParameter( "EpochLength", mStimToClassDuration ).InSampleBlocks() ) ); 
    190210 
    191211  mInterpretMode = Parameter( "InterpretMode" ); 
    192  
     212  mAccumulateEvidence = ( Parameter( "AccumulateEvidence" ) != 0 ); 
     213  mMinimumEvidence = Parameter( "MinimumEvidence" ); 
     214   
    193215  bcidbg( 2 ) << "Event: Initialize" << endl; 
    194216  OnInitialize( Input ); 
     
    249271} 
    250272 
     273bool 
     274StimulusTask::EarlyOffset(  const GenericSignal& Input, const Association& inAssoc ) 
     275{ 
     276  const Expression& expr = inAssoc.HasEarlyOffsetExpression() ? inAssoc.EarlyOffsetExpression() : mEarlyOffsetExpression; 
     277  bool triggered = false; 
     278  if( mBlocksInPhase == 0 ) 
     279    mEarlyOffsetPreviousValue = expr.Evaluate( &Input, 0 ); 
     280  for( int sample = 0; sample < Statevector->Samples() && !triggered; ++sample ) 
     281  { 
     282    double value = expr.Evaluate( &Input, sample ); 
     283    triggered = value && !mEarlyOffsetPreviousValue; 
     284    mEarlyOffsetPreviousValue = value; 
     285  } 
     286  return triggered; 
     287} 
     288 
    251289void 
    252290StimulusTask::Process( const GenericSignal& Input, GenericSignal& Output ) 
     
    265303                << endl; 
    266304    mClassResult[ stimulusCodeRes ].push_back( Input ); 
    267         //AppLog << "Testing " << stimulusCodeRes << Input << endl;  
    268  
    269         //Ramses Alcaide 07.08.2014 Edits for Hold Begin 
    270         int maxThresh, minThresh, consecutiveTrialsBeforeSelection, heldTarget, previousClassifierValue, previousTarget,currentTarget,currentStimulusCode; 
     305 
     306        int maxThresh, minThresh, consecutiveTrialsBeforeSelection, heldTarget, previousClassifierValue, currentStimulusCode; 
    271307        double currentClassifierValue; 
     308 
    272309        maxThresh = 40; 
    273         minThresh =10;  
     310        minThresh = 40; // Currently using only one threshold.  
    274311        consecutiveTrialsBeforeSelection = 0; 
    275         heldTarget = -1; 
    276         previousClassifierValue = 0;  
    277         previousTarget = 0; 
    278         currentTarget = 0; 
     312        previousClassifierValue = 0; 
     313 
     314        // Initialize Target to "Halt". 
     315        heldTarget = 5; 
     316         
    279317        currentStimulusCode = 0;  
    280         currentClassifierValue =0; 
    281  
     318        currentClassifierValue = 0; 
    282319        currentStimulusCode = stimulusCodeRes; 
    283320        currentClassifierValue = Input(0,0); 
    284         if (currentStimulusCode == 1 || currentStimulusCode == 7||currentStimulusCode== 6|| currentStimulusCode== 12){ 
    285         if(currentStimulusCode== 1 || currentStimulusCode== 7){ 
    286                 currentTarget = 0;       
    287                 if (currentClassifierValue >maxThresh) { 
    288                         heldTarget = currentTarget; 
    289  
    290                 }else if(currentClassifierValue <minThresh){ 
    291                         heldTarget = 1;  
    292                 } 
    293                  
     321         
     322        if ((currentStimulusCode == 1 || currentStimulusCode == 7) && (currentClassifierValue > maxThresh)){ // Forward row/col is intensified and classifier is above the threshold. 
     323                heldTarget = 1; // Decision is 1 = Forward  
    294324        } 
    295         else{ 
    296                 currentTarget = 1;  
    297                 if (currentClassifierValue >maxThresh) { 
    298                         heldTarget = currentTarget; 
    299  
    300                 }else if(currentClassifierValue <minThresh){ 
    301                         heldTarget = 0;  
    302                 } 
     325         
     326        else if((currentStimulusCode == 5 || currentStimulusCode == 9) && (currentClassifierValue > maxThresh)) { // Backward. 
     327                heldTarget = 2; 
    303328        }                
    304 } 
    305  
    306         AppLog <<"Input "<<Input(0,0)<<" " <<"CurrentStimulusCode "<<currentStimulusCode<<" "<<"StimulusCodeRes "<<stimulusCodeRes<<endl; 
    307         AppLog<<"CurrentClassifierValue "<<currentClassifierValue<<" "<<"HeldTarget "<<heldTarget << endl;  
    308  
    309         //Ramses Alcaide 07.08.2014 Edits for Hold End */ 
    310            
    311  
    312         //Ramses Alcaide 07.08.2014 Edits for UDP out Begin 
     329         
     330        else if((currentStimulusCode == 4 || currentStimulusCode == 6) && (currentClassifierValue > maxThresh)) { // Rotate left. 
     331                heldTarget = 3; 
     332        }                
     333         
     334        else if((currentStimulusCode == 2 || currentStimulusCode == 10) && (currentClassifierValue > maxThresh)) { // Rotate right. 
     335                heldTarget = 4; 
     336        }                
     337         
     338        else if((currentStimulusCode == 3 || currentStimulusCode == 8) && (currentClassifierValue > maxThresh)) { // Halt. 
     339                heldTarget = 5; 
     340        } 
     341         
     342        else if (currentClassifierValue < minThresh) { 
     343                                heldTarget = 0; // Carry on the last decision.   
     344        } 
     345         
     346        AppLog << "Current Classifier Value: " << currentClassifierValue << " - Held Target: " << heldTarget << endl; 
     347 
     348        // Ramses Alcaide 07.08.2014 Edits for UDP out Begin 
    313349        const char* address = "localhost:20320"; 
    314350         
    315         // write to socket. 
     351        // Read from stdin, write to socket. 
    316352    sending_udpsocket socket( address ); 
    317353    sockstream output( socket ); 
    318     if( !output.is_open() ) 
    319       cerr << "Could not open " << address 
    320            << " for output." << endl; 
    321  
    322     string line; 
    323         line = "1"; 
    324       output << line << endl; 
    325  
    326         //Ramses Alcaide 07.08.2014 Edits for UDP out End*/ 
    327  
    328     bcidbg( 2 ) << "Event: ClassInput" << endl; 
     354    if(!output.is_open()) 
     355      cerr << "Could not open " << address << " for output." << endl; 
     356 
     357    //string line; 
     358        //line = "1"; 
     359    //while( getline( cin, line ) ) 
     360        //AppLog << heldTarget << endl; 
     361        output << heldTarget << endl; 
     362   
     363 
     364 
     365        // Ramses Alcaide 07.08.2014 Edits for UDP out End 
     366 
     367         
     368        bcidbg( 2 ) << "Event: ClassInput" << endl; 
    329369    OnClassInput( stimulusCodeRes, Input ); 
    330370  } 
     
    351391        doProgress = ( mBlocksInPhase >= stimulusDuration ); 
    352392        State( "StimulusBegin" ) = ( mBlocksInPhase == 0 && !doProgress ); 
     393        doProgress |= EarlyOffset( Input, Associations()[ mStimulusCode ] ); 
    353394        DoStimulus( Input, doProgress ); 
    354395      } break; 
     
    362403        if( mInterpretMode != InterpretModes::None 
    363404            && mBlocksSinceStimulus >= mStimToClassDuration 
    364             && !mClassResult.empty() ) 
     405            && !mClassResult.empty() && !mCodesPresented.empty() ) 
    365406        { 
    366407          for( set<int>::const_iterator i = mCodesPresented.begin(); i != mCodesPresented.end(); ++i ) 
     
    373414          if( pTarget != NULL ) 
    374415            pTarget->Select(); 
    375           mClassResult.clear(); 
     416          if( !mAccumulateEvidence || pTarget ) 
     417            mClassResult.clear(); 
    376418          mCodesPresented.clear(); 
    377419        } 
     
    389431 
    390432      default: 
    391         throw bciexception( "Unknown phase value: " << mPhase ); 
     433        throw std_runtime_error( "Unknown phase value: " << mPhase ); 
    392434    } 
    393435    if( doProgress ) 
     
    404446        case preRun: 
    405447          mStimulusCode = OnNextStimulusCode(); 
    406                    
    407448          if( mStimulusCode > 0 ) 
    408449          { // Enter pre sequence phase 
     
    473514 
    474515        default: 
    475           throw bciexception( "Unknown phase value: " << mPhase ); 
     516          throw std_logic_error( "Unknown phase value: " << mPhase ); 
    476517      } 
    477518    } 
     
    498539StimulusTask::OnClassResult( const ClassResult& inResult ) 
    499540{ 
    500   return Associations().ClassifyTargets( inResult ).MostLikelyTarget(); 
     541  double evidence = 0; 
     542  Target* p = Associations().ClassifyTargets( inResult ).MostLikelyTarget( evidence ); 
     543  bcidbg( 2 ) << "Target evidence: " << evidence << endl; 
     544  if( evidence < mMinimumEvidence ) 
     545    p = 0; 
     546  return p; 
    501547} 
    502548 
Note: See TracChangeset for help on using the changeset viewer.