src/SenseHandler.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000-2003, Jelle Kok, University of Amsterdam
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008 1. Redistributions of source code must retain the above copyright notice, this
00009 list of conditions and the following disclaimer.
00010 
00011 2. Redistributions in binary form must reproduce the above copyright notice,
00012 this list of conditions and the following disclaimer in the documentation
00013 and/or other materials provided with the distribution.
00014 
00015 3. Neither the name of the University of Amsterdam nor the names of its
00016 contributors may be used to endorse or promote products derived from this
00017 software without specific prior written permission.
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00023 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00024 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00025 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00026 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00028 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 */
00030 
00047 #include "SenseHandler.h"
00048 #include "ActHandler.h"  // sigalarmHandler
00049 #include "Parse.h"
00050 
00051 #include <signal.h>   // needed for SIGALARM
00052 #include <string.h>   // needed for strlen
00053 #include <stdio.h>    // needed for printf
00054 #include <iostream>   // needed for cout
00055 
00056 /*****************************************************************************/
00057 /********************* CLASS SENSEHANDLER ************************************/
00058 /*****************************************************************************/
00059 
00065 #ifdef WIN32
00066 DWORD WINAPI sense_callback( LPVOID v )
00067 #else
00068 void* sense_callback( void *v )
00069 #endif
00070 {
00071   Log.log( 1, "Starting to listen for server messages" );
00072   SenseHandler* s = (SenseHandler*)v;
00073   s->handleMessagesFromServer( );
00074   return 0;
00075 }
00076 
00077 
00084 SenseHandler::SenseHandler( Connection *c, WorldModel *wm, ServerSettings *ss,
00085                             PlayerSettings *ps, ActionScheduler *as)
00086 {
00087   connection             = c;
00088   SS                     = ss;
00089   PS                     = ps;
00090   WM                     = wm;
00091   AS                                     = as;
00092   iSimStep               = SS->getSimulatorStep()*1000;
00093   iTimeSignal            = (int)(iSimStep*0.85);
00094   iLastCycle                     = -1;
00095 
00096 #ifdef WIN32
00097   TIMECAPS tc;
00098   UINT     resolution = 1;   // timer resolution for the application (ms)
00099   iTimer = 0;
00100 
00101   // set the minimum timer resolution for an application
00102   if (TIMERR_NOERROR == timeGetDevCaps( &tc, sizeof(TIMECAPS) ))
00103   {
00104     timerRes = min( max( tc.wPeriodMin, resolution ), tc.wPeriodMax );
00105     timeBeginPeriod( timerRes );
00106   }
00107 #else
00108   struct sigaction sigact;
00109 
00110   sigact.sa_flags = SA_RESTART; // do not unblock primitives (like recvfrom)
00111   sigact.sa_handler = (void (*)(int))sigalarmHandler;
00112   sigaction( SIGALRM, &sigact, NULL );
00113 
00114   // set timer signal to indicate when ActHandler should sent commands to the
00115   // server, this structure will later be filled with exact timing values
00116   itv.it_interval.tv_sec  = 0;
00117   itv.it_interval.tv_usec = 0;
00118   itv.it_value.tv_sec     = 0;
00119   itv.it_value.tv_usec    = 0;
00120 #endif
00121 }
00122 
00125 void SenseHandler::handleMessagesFromServer( )
00126 {
00127   char strBuf[MAX_MSG];
00128   int i=0;
00129 
00130   while( 1 )
00131   {
00132     strBuf[0]='\0';
00133     if( i != -1 )                                         // if no error
00134       i = connection->receiveMessage( strBuf, MAX_MSG );  // get message
00135     if( strBuf[0] != '\0' )                               // if not empty
00136       analyzeMessage( strBuf );                           // parse message
00137   }
00138 }
00139 
00140 
00150 void SenseHandler::setTimeSignal( )
00151 {
00152   if( iLastCycle < WM->getCurrentCycle()  ) {
00153         iLastCycle = WM->getCurrentCycle();
00154         AS->dispatchAction( WM->getCurrentCycle() );
00155   }
00156   
00157   if( WM->getAgentViewFrequency() == 1.0 ) // VA_NORMAL AND VQ_HIGH (default)
00158   {
00159     if( iTriCounter % 3 == 0 )             // see will arrive first half cycle
00160     {
00161       iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeBegin() );
00162       iTriCounter = 0;
00163     }
00164     else if( iTriCounter % 3 == 1 )        // see will arrive 2nd half of cycle
00165     {
00166       iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );
00167     }
00168     else                                   // no see will arrive
00169       iTimeSignal = (int)(iSimStep * PS->getFractionWaitNoSee( ) );
00170   }
00171   else if( WM->getAgentViewFrequency() == 2.0 ) // VA_WIDE AND VQ_HIGH
00172   {
00173     if( iTriCounter % 3 == 0 )              // see will arrive
00174     {
00175       iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );
00176       iTriCounter = 0;
00177     }
00178     else                                   // no see will arrive
00179       iTimeSignal = (int)(iSimStep * PS->getFractionWaitNoSee() );
00180   }
00181   else                                     // VA_NARROW AND VQ_HIGH
00182     iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );
00183 
00184   iTriCounter++;
00185 #ifdef WIN32
00186   // kill the previous timer
00187   if (iTimer != 0) timeKillEvent( iTimer );
00188   // start a new one
00189   iTimer = timeSetEvent( iTimeSignal / 1000, timerRes,
00190                          sigalarmHandler, (DWORD)0, TIME_ONESHOT );
00191 #else
00192   itv.it_value.tv_usec = iTimeSignal;
00193   setitimer( ITIMER_REAL, &itv, NULL );
00194 #endif
00195 }
00196 
00201 bool SenseHandler::analyzeMessage( char *strMsg )
00202 {
00203   Log.log( 1, strMsg );
00204   bool bReturn = false;
00205   
00206   switch( strMsg[1] )
00207   {
00208     case 'c':
00209         if( strMsg[2] == 'h' )
00210           return analyzeChangePlayerTypeMessage( strMsg );      // ( c hange_
00211         else
00212           ;                                                    // (clang
00213         break;
00214     case 'f':
00215           return analyzeFullStateMessage( strMsg );      // ( f ullstate_
00216     case 'o':                                                 // ( o k
00217         if( strlen(strMsg) > 14 && strMsg[4] == 'c' && strMsg[10] == 'b' )
00218           analyzeCheckBall( strMsg );                         // (ok check_ball
00219         return true;
00220     case 's':
00221     {
00222       switch( strMsg[3] )
00223       {
00224       case 'e':
00225         if( strMsg[5] == 'g')
00226           return analyzeSeeGlobalMessage  ( strMsg ); // (se e_g
00227         else if( WM->isFullStateOn( ) == false )
00228           return analyzeSeeMessage        ( strMsg ); // (se e
00229         break;                  
00230       case 'n': 
00231         bReturn = analyzeSenseMessage      ( strMsg ); // (se n se
00232         if( WM->isFullStateOn( ) == true  )
00233           WM->updateAfterSenseMessage( );
00234         return bReturn; 
00235         break;
00236       case 'r': return analyzeServerParamMessage( strMsg ); // (se r ver_param
00237       default : break;
00238       }
00239     }
00240         break;
00241     case 'i':     return analyzeInitMessage       ( strMsg ); // ( i nit
00242     case 'h':     return analyzeHearMessage       ( strMsg ); // ( h ear
00243     case 'p':     return ( strMsg[8] == 't')
00244                   ? analyzePlayerTypeMessage ( strMsg )  // (player_ t ype
00245                   : analyzePlayerParamMessage( strMsg ); // (player_ p aram
00246     case 'e':     printf("(%d,%d) %s\n", WM->getCurrentCycle(),
00247                            WM->getPlayerNumber(),strMsg);// ( error
00248         break;
00249     case 't':     Log.logWithTime( 2, " incoming think message" );
00250                   WM->processRecvThink( true );          // ( think
00251         break;
00252     default:      cerr << "(" << WM->getCurrentTime() << ", " <<
00253                         WM->getPlayerNumber()
00254                         << ") (SenseHandler::analyzeMessage) " <<
00255                      "ignored message: " << strMsg << "\n";
00256                   return false;
00257   }
00258   return false;
00259 }
00260 
00261 
00266 bool SenseHandler::analyzeSeeMessage( char *strMsg )
00267 {
00268   strcpy( WM->strLastSeeMessage, strMsg );
00269 
00270   Log.logWithTime( 2, " %s",strMsg );
00271 
00272   if( WM->getRelativeDistance( OBJECT_BALL ) < SS->getVisibleDistance() )
00273     Log.logWithTime( 560, "%s", WM->strLastSeeMessage );
00274 
00275   Time    time = WM->getTimeLastRecvSenseMessage();
00276   int iTime = Parse::parseFirstInt( &strMsg );         // get the time
00277   if( time.getTime() != iTime )
00278   {
00279     cerr << "(SenseHandler:analyzeSeeMessage) see and different time as sense:"
00280          << time.getTime() << " vs. " << iTime << endl;
00281     return false;
00282   }
00283 
00284   // count number of see message in this cycle
00285   if( WM->getTimeLastSeeMessage() == time )
00286     m_iSeeCounter++;
00287   else
00288     m_iSeeCounter = 1;
00289 
00290   // do nothing with second see, since it adds nothings
00291   if( m_iSeeCounter >= 2 )
00292   {
00293     Log.logWithTime( 4, "second see message in cycle; do nothing " );
00294     return true;
00295   }
00296 
00297   // reset the send pattern when previous cycle(s) no see arrived
00298   if( WM->getAgentViewFrequency() == 1.0 && // VA_NORMAL; previous cycle no see
00299       time.getTimeDifference( WM->getTimeLastSeeMessage() )== 2 )
00300     iTriCounter = 1;                // see will arive in 2nd half in next cycle
00301   else if( WM->getAgentViewFrequency() == 2.0 && // VA_WIDE; two cycles no see
00302            time.getTimeDifference( WM->getTimeLastSeeMessage() ) == 3 )
00303     iTriCounter = 1;                // no see will arrive next two cycles
00304 
00305   WM->setTimeLastSeeMessage( time );   // set time of last see message
00306   return true;
00307 }
00308 
00314 bool SenseHandler::analyzeSeeGlobalMessage( char *strMsg )
00315 {
00316   Log.logWithTime( 2, " incoming see global message" );
00317   strcpy( WM->strLastSeeMessage, strMsg );
00318 
00319   ObjectT o;
00320   bool    isGoalie;
00321   double  dX, dY, dVelX, dVelY;
00322   int     iTime;
00323   AngDeg  angBody, angNeck;
00324   Time    time = WM->getCurrentTime();
00325 
00326   iTime = Parse::parseFirstInt( &strMsg );         // get the time
00327   time.updateTime( iTime );
00328 
00329   while( *strMsg != ')' )                          // " ((objname.." or ")"
00330   {
00331     dVelX = dVelY = UnknownDoubleValue;
00332     angBody = angNeck = UnknownAngleValue;
00333     strMsg += 2;          // go the start of the object name
00334 
00335     // get the object type at the current position in the string
00336     o = SoccerTypes::getObjectFromStr( &strMsg, &isGoalie, WM->getTeamName() );
00337     if( o == OBJECT_ILLEGAL )
00338     {
00339       Log.log( 4, "Illegal object" );
00340       Log.log( 4, "total messages: %s", WM->strLastSeeMessage );
00341       Log.log( 4, "rest of message: %s", strMsg );
00342     }
00343 
00344     dX = Parse::parseFirstDouble( &strMsg );        // parse first value
00345     dY = Parse::parseFirstDouble( &strMsg );        // parse second value
00346     if ( *strMsg != ')' )                           // if it was no flag
00347     {
00348       dVelX = Parse::parseFirstDouble( &strMsg );   // parse delta x
00349       dVelY = Parse::parseFirstDouble( &strMsg );   // parse delta y
00350       if( *strMsg != ')' )                          // stil not finished
00351       {                                             // get body and neck angle
00352         angBody = Parse::parseFirstDouble( &strMsg );
00353         angNeck = Parse::parseFirstDouble( &strMsg );
00354       }
00355     }
00356     // skip ending bracket of object information.
00357     Parse::gotoFirstOccurenceOf( ')', &strMsg );
00358     strMsg++;
00359 
00360     // process the parsed information (unread values are Unknown...)
00361     WM->processSeeGlobalInfo( o, time, VecPosition(dX,dY),
00362                     VecPosition(dVelX,dVelY), angBody, angNeck );
00363     }
00364   WM->setTimeLastSeeGlobalMessage( time );  // set time last see global message
00365   return true;
00366 }
00367 
00371 bool SenseHandler::analyzeFullStateMessage( char *strMsg )  
00372 {
00373   Log.restartTimer( );
00374   Log.logWithTime( 2, " incoming fullstate message" );
00375   Log.log( 4, " fullstate message: %s", strMsg );  
00376   strcpy( WM->strLastSeeMessage, strMsg );
00377 
00378   ObjectT o;
00379   bool    isGoalie;  
00380   double  dX, dY, dVelX, dVelY;
00381   int     iTime;
00382   AngDeg  angBody, angNeck;
00383   Time    time = WM->getCurrentTime();
00384 
00385   iTime = Parse::parseFirstInt( &strMsg );         // get the time
00386   time.updateTime( iTime );
00387   Log.log( 4, "fullstate time: %d", time.getTime() );
00388   
00389   strMsg++;                                      // skip space
00390   Parse::gotoFirstOccurenceOf( ' ', &strMsg );   // skip (pmode
00391   strMsg++;                                      // skip space
00392 
00393   Log.log( 4, "fullstate parse ref: %s", strMsg );
00394   RefereeMessageT rm = SoccerTypes::getRefereeMessageFromStr( strMsg ); 
00395   PlayModeT       pm = SoccerTypes::getPlayModeFromRefereeMessage( rm );
00396   if( pm != PM_ILLEGAL )                                
00397     WM->setPlayMode( pm );                              
00398       
00399   Parse::gotoFirstOccurenceOf( 'e', &strMsg );   // go to end of vmode
00400   strMsg++;                                      // skip 'e'
00401   strMsg++;                                      // skip space
00402 
00403   Log.log( 4, "fullstate parse qua: %s", strMsg );
00404   ViewQualityT vq = SoccerTypes::getViewQualityFromStr( strMsg ); 
00405   Parse::gotoFirstOccurenceOf( ' ', &strMsg );   // go to end of quality
00406   strMsg++;                                      
00407   Log.log( 4, "fullstate parse ang: %s", strMsg );  
00408   ViewAngleT   va = SoccerTypes::getViewAngleFromStr( strMsg );
00409 
00410   Log.log( 4, "fullstate parse count: %s", strMsg );  
00411   WM->setNrOfCommands( CMD_KICK       , Parse::parseFirstInt( &strMsg ) );
00412   WM->setNrOfCommands( CMD_DASH       , Parse::parseFirstInt( &strMsg ) );
00413   WM->setNrOfCommands( CMD_TURN       , Parse::parseFirstInt( &strMsg ) );
00414   WM->setNrOfCommands( CMD_CATCH      , Parse::parseFirstInt( &strMsg ) );
00415   WM->setNrOfCommands( CMD_MOVE       , Parse::parseFirstInt( &strMsg ) );  
00416   WM->setNrOfCommands( CMD_TURNNECK   , Parse::parseFirstInt( &strMsg ) );
00417   WM->setNrOfCommands( CMD_CHANGEVIEW , Parse::parseFirstInt( &strMsg ) );
00418   WM->setNrOfCommands( CMD_SAY        , Parse::parseFirstInt( &strMsg ) );
00419 
00420   int iArmMovable = Parse::parseFirstInt( &strMsg );
00421   int iArmExpires = Parse::parseFirstInt( &strMsg );
00422   Parse::parseFirstDouble( &strMsg ); // skip pointto info, comes later
00423   Parse::parseFirstDouble( &strMsg ); // skip pointto info, comes later
00424   WM->setNrOfCommands( CMD_POINTTO    , Parse::parseFirstInt( &strMsg ) );
00425 
00426   Parse::gotoFirstOccurenceOf( 'b', &strMsg );   // go to ball position  
00427   
00428   Log.log( 4, "fullstate parse ball: %s", strMsg );    
00429   dX    = Parse::parseFirstDouble( &strMsg );    // parse first value
00430   dY    = Parse::parseFirstDouble( &strMsg );    // parse second value  
00431   dVelX = Parse::parseFirstDouble( &strMsg );    // parse third value  
00432   dVelY = Parse::parseFirstDouble( &strMsg );    // parse fourth value  
00433   if( WM->isBeforeKickOff() ) 
00434     dX = dY = dVelX = dVelY = 0.0;
00435   if( WM->getSide() == SIDE_RIGHT )
00436   {
00437     dX    *= -1;
00438     dY    *= -1;    
00439     dVelX *= -1;    
00440     dVelY *= -1;          
00441   }  
00442   WM->processSeeGlobalInfo( OBJECT_BALL, time, VecPosition(dX,dY),
00443                     VecPosition(dVelX,dVelY), -1, -1 );
00444   strMsg++;
00445   Log.log( 4, "fullstate ball: %f %f %f %f", dX, dY, dVelX, dVelY );
00446     
00447   while( *strMsg != ')' )                          // " ((objname.." or ")"
00448   {
00449     dVelX = dVelY = UnknownDoubleValue;
00450     angBody = angNeck = UnknownAngleValue;
00451     strMsg += 2;          // go the start of the object name
00452     Log.log( 4, "fullstate parse object: %s", strMsg );    
00453     // get the object type at the current position in the string
00454     o = SoccerTypes::getObjectFromStr( &strMsg, &isGoalie, 
00455                           (WM->getSide() == SIDE_LEFT ) ? "l" : "r" );
00456 
00457     dX      = Parse::parseFirstDouble( &strMsg );   // parse x position
00458     dY      = Parse::parseFirstDouble( &strMsg );   // parse y position
00459     dVelX   = Parse::parseFirstDouble( &strMsg );   // parse x velocity
00460     dVelY   = Parse::parseFirstDouble( &strMsg );   // parse y velocity
00461     angBody = Parse::parseFirstDouble( &strMsg );   // parse body angle
00462     angNeck = Parse::parseFirstDouble( &strMsg );   // parse neck angle
00463 
00464     if( WM->getSide() == SIDE_RIGHT )
00465     {
00466       dX    *= -1;
00467       dY    *= -1;    
00468       dVelX *= -1;    
00469       dVelY *= -1;          
00470       angBody = VecPosition::normalizeAngle( angBody + 180 );
00471     }    
00472 
00473     double dStamina  = Parse::parseFirstDouble( &strMsg );  // get stamina
00474     double dEffort   = Parse::parseFirstDouble( &strMsg );  // get effort
00475                        Parse::parseFirstDouble( &strMsg );  // skip recovery
00476 
00477     // skip ending bracket of stamina and then of object information.
00478     Parse::gotoFirstOccurenceOf( ')', &strMsg );
00479     Parse::gotoFirstOccurenceOf( ')', &strMsg );
00480     
00481     strMsg++;
00482     strMsg++;    
00483 
00484     Log.log( 1, "fullstate obj %d: %f %f %f %f %f %f", o, dX, dY, dVelX, dVelY,
00485                  angBody, angNeck );
00486     // process the parsed information 
00487     if( o == WM->getAgentObjectType() )
00488       WM->processNewAgentInfo( vq, va, dStamina, dEffort, -1.0, -1.0, -angNeck,
00489                                -1,iArmMovable, iArmExpires, VecPosition(0,0));
00490       
00491     WM->processSeeGlobalInfo( o, time, VecPosition(dX,dY),
00492                               VecPosition(dVelX,dVelY), angBody, angNeck );
00493     
00494   }
00495   WM->setTimeLastSeeGlobalMessage( time );  // set time last see global message
00496   WM->setTimeLastSenseMessage( time );      // set time last see global message
00497 
00498   return true;
00499 }
00500 
00508 bool SenseHandler::analyzeSenseMessage( char *strMsg )
00509 {
00510   Log.log( 999, "%s", strMsg );
00511   // cerr << strMsg << endl; 
00512   // set the synchronization counter, this is a value [0..2] indicating the
00513   // section of the pattern this cycle is in. It gives an indication when new
00514   // visual information will arrive.
00515 
00516   if( SS->getSynchMode() == false )
00517     setTimeSignal();                        // set signal when to send action
00518   strcpy( WM->strLastSenseMessage, strMsg );
00519 
00520   if( WM->getRelativeDistance( OBJECT_BALL ) < SS->getVisibleDistance() )
00521     Log.logWithTime( 560, "%s", WM->strLastSenseMessage );
00522 
00523   int iTime = Parse::parseFirstInt( &strMsg );// get time
00524   Time timeOld = WM->getCurrentTime();
00525   Time timeNew = timeOld;
00526   timeNew.updateTime( iTime );
00527 
00528   if( timeNew.getTimeDifference( timeOld ) > 1 )
00529     Log.log( 1, "Missed a sense!!" );
00530 
00531   Log.logWithTime ( 2, "\n\nSENSE (%d, %d)", timeNew.getTime(),
00532   timeNew.getTimeStopped() );
00533   Log.restartTimer( );
00534   iSimStep               = SS->getSimulatorStep()*1000;
00535   iTimeSignal            = (int)(iSimStep*0.85); 
00536   Log.logWithTime ( 2, " alarm after %d", iTimeSignal );
00537 
00538   WM->setTimeLastSenseMessage( timeNew ); // set the time
00539 
00540 //  Log.logWithTime( 2, " end analyzing sense" );
00541   return true;
00542 }
00543 
00549 bool SenseHandler::analyzeInitMessage( char *strMsg )
00550 {
00551   Log.log( 999, "%s", strMsg );
00552   strMsg += 6;                                            // go to Side
00553   WM->setSide( SoccerTypes::getSideFromStr( strMsg ) );   // get and set Side
00554   int nr = Parse::parseFirstInt( &strMsg );               // get and set number
00555   if( nr == 0 )                                           // coach
00556   {
00557      WM->setPlayerNumber( nr );
00558      cerr << strMsg  << endl;
00559      return true;
00560   }
00561   WM->setAgentObjectType( SoccerTypes::getTeammateObjectFromIndex( nr - 1 ) );
00562   WM->setPlayerNumber( nr );
00563   strMsg++;                                               // skip space to pm
00564   WM->setPlayMode( SoccerTypes::getPlayModeFromStr( strMsg ) ); // get playmode
00565   return true;
00566 }
00567 
00576 bool SenseHandler::analyzeHearMessage( char *strMsg )
00577 {
00578   RefereeMessageT rm;
00579   PlayModeT       pm;
00580   strcpy( WM->strLastHearMessage, strMsg);
00581 
00582   int iTime = Parse::parseFirstInt( &strMsg );              // ignore time
00583   Time time( iTime );
00584 
00585   switch( Parse::gotoFirstNonSpace( &strMsg ) )
00586   {
00587     case 'r':                                               // referee
00588       Log.log( 999, "%s", WM->strLastHearMessage );
00589       WM->setTimeLastRefereeMessage( time );
00590       Parse::gotoFirstOccurenceOf( ' ', &strMsg );          // go to start
00591       Parse::gotoFirstNonSpace   ( &strMsg      );          // and first part
00592       rm = SoccerTypes::getRefereeMessageFromStr( strMsg ); // get the ref msg
00593       Log.logWithTime( 2, " referee message: %s %s",
00594       SoccerTypes::getRefereeMessageStr(rm), WM->strLastHearMessage);
00595       pm = SoccerTypes::getPlayModeFromRefereeMessage( rm );// get play mode
00596       if( pm != PM_ILLEGAL )                                // from ref msg
00597         WM->setPlayMode( pm );                              // if was pm, set 
00598 
00599       switch( rm )
00600       {
00601         case REFC_GOAL_LEFT:                            // goal left
00602           if( WM->getSide() == SIDE_LEFT )
00603             WM->addOneToGoalDiff();
00604           else
00605             WM->subtractOneFromGoalDiff();
00606           WM->processSeeGlobalInfo( OBJECT_BALL, time, VecPosition( 0, 0 ),
00607                VecPosition( 0, 0 ), 0, 0 );
00608           break;
00609         case REFC_GOAL_RIGHT:                      // goal right
00610           if( WM->getSide() == SIDE_RIGHT )
00611             WM->addOneToGoalDiff();
00612           else
00613             WM->subtractOneFromGoalDiff();
00614           WM->processSeeGlobalInfo( OBJECT_BALL, time, VecPosition( 0, 0 ),
00615                VecPosition( 0, 0 ), 0, 0 );
00616           break;
00617         case REFC_GOALIE_CATCH_BALL_LEFT:         // catch ball
00618         case REFC_GOALIE_CATCH_BALL_RIGHT:
00619           WM->processCatchedBall( rm, time );
00620           break;
00621         case REFC_PENALTY_ONFIELD_LEFT:
00622           WM->setSidePenalty( SIDE_LEFT );
00623           break;
00624         case REFC_PENALTY_ONFIELD_RIGHT:
00625           WM->setSidePenalty( SIDE_RIGHT );
00626           break;
00627         case REFC_PENALTY_MISS_LEFT:
00628         case REFC_PENALTY_SCORE_LEFT:
00629           WM->setPlayMode( PM_FROZEN );
00630           break;
00631         case REFC_PENALTY_MISS_RIGHT:
00632         case REFC_PENALTY_SCORE_RIGHT:
00633           WM->setPlayMode( PM_FROZEN );         
00634           break;
00635         case REFC_PENALTY_FOUL_LEFT:
00636         case REFC_PENALTY_FOUL_RIGHT:
00637         default:
00638           break;
00639       }
00640       break;
00641     case 'o':                                               // online_coach_
00642         analyzeCoachMessage( strMsg );
00643         break;
00644     case 's':                                               // self
00645       break;                                                // do nothing
00646     default:                                                // from direction
00647         Log.logWithTime( 600, "incoming hear: %s", WM->strLastHearMessage );
00648         analyzePlayerMessage( iTime, strMsg );    // from player
00649       break;
00650   }
00651 
00652   return true;
00653 }
00654 
00661 bool SenseHandler::analyzePlayerMessage( int iTime, char *strMsg )
00662 {
00663   Parse::gotoFirstNonSpace( &strMsg );            // skip space
00664 
00665   if( WM->getPlayerNumber() == 0 )                // if i am coach
00666     return false;                                 //   skip message
00667   if( strlen( strMsg ) < 2 || strMsg[0] == 'o' )  // skip message since no dir.
00668     return false;                                 // thus no content
00669 
00670   Parse::parseFirstInt( &strMsg );                // skip direction
00671   Parse::gotoFirstNonSpace( &strMsg );            // skip space
00672   if( strlen( strMsg ) < 2 || strMsg[1] == 'p' )  // skip message when from opp
00673     return false;
00674 
00675   int iPlayer = Parse::parseFirstInt( &strMsg );  // get player number
00676   Parse::gotoFirstNonSpace( &strMsg );            // skip space
00677   strMsg++;                                       // skip " (=quote)
00678 
00679   if( strlen( strMsg ) < 4 )              // < 2 + two ending charactres ")
00680   {
00681     Log.log( 600, "communication string too small" );
00682     return false;
00683   }
00684 
00685   // get the cycle number from the encoding
00686   int iModCycle = (int)(strMsg[0] - 'a');
00687 
00688   if( iModCycle < 0 || iModCycle > 9 )
00689   {
00690     Log.log( 600, "communication cycle nr out of bounds: %d", iModCycle );
00691     return false;
00692   }
00693 
00694   // get the time difference between the current time and the send time
00695   int iDiff = (iTime % 10) - iModCycle;
00696   if( iDiff < 0 )
00697     iDiff += 10;
00698 
00699   // if it is too old; skip parsing; otherwise determine actual send time
00700   if( iDiff > 2  )
00701   {
00702     Log.log( 600, "communication string too old time %d mod %d diff %d",
00703                         iTime, iModCycle, iDiff);
00704     return false;
00705   }
00706   iTime -= iDiff;
00707 
00708   Log.log( 600, "process comm msg, diff %d time %d, %s", iDiff, iTime, strMsg);
00709   WM->storePlayerMessage( iPlayer, strMsg, iTime );
00710   return true;
00711 }
00712 
00713 bool SenseHandler::analyzeCoachMessage( char *strMsg )
00714 {
00715   Log.log( 605, "received coach messages: %s" , strMsg );
00716 
00717   return true;
00718 }
00725 bool SenseHandler::analyzeCheckBall( char *strMsg )
00726 {
00727   WM->setTimeCheckBall( Parse::parseFirstInt( &strMsg ) );
00728   strMsg++;
00729   WM->setCheckBallStatus( SoccerTypes::getBallStatusFromStr( strMsg ) );
00730   return true;
00731 }
00732 
00739 bool SenseHandler::analyzeChangePlayerTypeMessage( char *strMsg )
00740 {
00741   Log.log( 999, "%s", strMsg );
00742   int iPlayer = Parse::parseFirstInt( &strMsg );
00743   if( *strMsg != ')' ) // we are dealing with player of own team
00744   {
00745     int      iType = Parse::parseFirstInt( &strMsg );
00746     ObjectT  obj   = SoccerTypes::getTeammateObjectFromIndex( iPlayer - 1 );
00747     Log.log( 605, "change player from message %d -> %d", obj, iType );
00748     WM->setHeteroPlayerType( obj, iType );
00749     Log.log( 605, "changed player from message %d -> %d", obj, 
00750               WM->getHeteroPlayerType( obj ) );
00751     return true;
00752   }
00753   else
00754   {
00755     ObjectT  obj   = SoccerTypes::getOpponentObjectFromIndex( iPlayer - 1 );
00756     return WM->setSubstitutedOpp( obj );
00757   }
00758 
00759 
00760   return false;
00761 }
00762 
00769 bool SenseHandler::analyzeServerParamMessage( char *strMsg )
00770 {
00771 
00772   Log.log( 4, "%s", strMsg );
00773 
00774   readServerParam( "goal_width",               strMsg );
00775   readServerParam( "player_size",              strMsg );
00776   readServerParam( "player_decay",             strMsg );
00777   readServerParam( "player_rand",              strMsg );
00778   readServerParam( "player_weight",            strMsg );
00779   readServerParam( "player_speed_max",         strMsg );
00780   readServerParam( "player_accel_max",         strMsg );
00781   readServerParam( "stamina_max",              strMsg );
00782   readServerParam( "stamina_inc_max",          strMsg );
00783   readServerParam( "recover_dec_thr",          strMsg );
00784   readServerParam( "recover_min",              strMsg );
00785   readServerParam( "recover_dec",              strMsg );
00786   readServerParam( "effort_dec_thr",           strMsg );
00787   readServerParam( "effort_min",               strMsg );
00788   readServerParam( "effort_dec",               strMsg );
00789   readServerParam( "effort_inc_thr",           strMsg );
00790   readServerParam( "effort_inc",               strMsg );
00791   readServerParam( "kick_rand",                strMsg );
00792   readServerParam( "ball_size",                strMsg );
00793   readServerParam( "ball_decay",               strMsg );
00794   readServerParam( "ball_rand",                strMsg );
00795   readServerParam( "ball_weight",              strMsg );
00796   readServerParam( "ball_speed_max",           strMsg );
00797   readServerParam( "ball_accel_max",           strMsg );
00798   readServerParam( "dash_power_rate",          strMsg );
00799   readServerParam( "kick_power_rate",          strMsg );
00800   readServerParam( "kickable_margin",          strMsg );
00801   readServerParam( "catch_probability",        strMsg );
00802   readServerParam( "catchable_area_l",         strMsg );
00803   readServerParam( "catchable_area_w",         strMsg );
00804   readServerParam( "goalie_max_moves",         strMsg );
00805   readServerParam( "maxpower",                 strMsg );
00806   readServerParam( "minpower",                 strMsg );
00807   readServerParam( "maxmoment",                strMsg );
00808   readServerParam( "minmoment",                strMsg );
00809   readServerParam( "maxneckmoment",            strMsg );
00810   readServerParam( "minneckmoment",            strMsg );
00811   readServerParam( "maxneckang",               strMsg );
00812   readServerParam( "minneckang",               strMsg );
00813   readServerParam( "visible_angle",            strMsg );
00814   readServerParam( "visible_distance",         strMsg );
00815   readServerParam( "audio_cut_dist",           strMsg );
00816   readServerParam( "quantize_step",            strMsg );
00817   readServerParam( "quantize_step_l",          strMsg );
00818   readServerParam( "ckick_margin",             strMsg );
00819   readServerParam( "wind_dir",                 strMsg );
00820   readServerParam( "wind_force",               strMsg );
00821   readServerParam( "wind_rand",                strMsg );
00822   readServerParam( "wind_random",              strMsg );
00823   readServerParam( "inertia_moment",           strMsg );
00824   readServerParam( "half_time",                strMsg );
00825   readServerParam( "drop_ball_time",           strMsg );
00826   readServerParam( "port",                     strMsg );
00827   readServerParam( "coach_port",               strMsg );
00828   readServerParam( "olcoach_port",             strMsg );
00829   readServerParam( "say_coach_cnt_max",        strMsg );
00830   readServerParam( "say_coach_msg_size",       strMsg );
00831   readServerParam( "simulator_step",           strMsg );
00832   readServerParam( "send_step",                strMsg );
00833   readServerParam( "recv_step",                strMsg );
00834   readServerParam( "sense_body_step",          strMsg );
00835   readServerParam( "say_msg_size",             strMsg );
00836   readServerParam( "clang_win_size",           strMsg );
00837   readServerParam( "clang_define_win",         strMsg );
00838   readServerParam( "clang_meta_win",           strMsg );
00839   readServerParam( "clang_advice_win",         strMsg );
00840   readServerParam( "clang_info_win",           strMsg );
00841   readServerParam( "clang_mess_delay",         strMsg );
00842   readServerParam( "clang_mess_per_cycle",     strMsg );
00843   readServerParam( "hear_max",                 strMsg );
00844   readServerParam( "hear_inc",                 strMsg );
00845   readServerParam( "hear_decay",               strMsg );
00846   readServerParam( "catch_ban_cycle",          strMsg );
00847   readServerParam( "send_vi_step",             strMsg );
00848   readServerParam( "use_offside",              strMsg );
00849   readServerParam( "offside_active_area_size", strMsg );
00850   readServerParam( "forbid_kick_off_offside",  strMsg );
00851   readServerParam( "verbose",                  strMsg );
00852   readServerParam( "offside_kick_margin",      strMsg );
00853   readServerParam( "slow_down_factor",         strMsg );
00854   readServerParam( "synch_mode",               strMsg );
00855   readServerParam( "fullstate_l",              strMsg );
00856   readServerParam( "fullstate_r",              strMsg );
00857   readServerParam( "pen_dist_x",               strMsg );
00858   readServerParam( "pen_max_goalie_dist_x",    strMsg );
00859   readServerParam( "pen_allow_mult_kicks",     strMsg );
00860   readServerParam( "tackle_dist",              strMsg );
00861   readServerParam( "tackle_back_dist",         strMsg );
00862   readServerParam( "tackle_width",             strMsg );
00863   readServerParam( "tackle_cycles",            strMsg );
00864   readServerParam( "tackle_power_rate",        strMsg );
00865   readServerParam( "tackle_exponent",          strMsg );
00866 
00867   SS->setMaximalKickDist      ( SS->getKickableMargin() +
00868                                 SS->getPlayerSize()     +
00869                                 SS->getBallSize()          );
00870 // SS->show( cerr, ":" );
00871   return true;
00872 }
00873 
00874 bool SenseHandler::readServerParam( char *strParam, char *strMsg )
00875 {
00876   char strFormat[128];
00877   char strValue[128] = "";
00878   sprintf( strValue, "none" );
00879 
00880   sprintf( strFormat, "%s ", strParam );        // add space after parameters
00881   char *str = strstr( strMsg, strFormat );      // and find param definition
00882   sprintf( strFormat, "%s %%[^)]", strParam );  // read till closing bracket
00883 
00884   if( str == NULL )
00885   {
00886     cerr << "(SenseHandler::readServerParam) " << WM->getPlayerNumber() <<
00887             "  error finding " << strParam <<endl;
00888     return false;
00889   }
00890   int ret = sscanf( str, strFormat, strValue ); // read in values
00891 
00892   if( ret == 1 )
00893     SS->setValue( strParam, strValue );
00894   else
00895     cerr << "(SenseHandler::readServerParam) error reading " <<strParam <<endl;
00896   return (ret == 1 ) ? true : false ;
00897 }
00898 
00899 
00906 bool SenseHandler::analyzePlayerTypeMessage ( char *strMsg )
00907 {
00908   Log.log( 999, "%s", strMsg );
00909 // cerr << strMsg << endl;
00910 
00911   // analyze all heterogeneous player information
00912   int    iIndex           = Parse::parseFirstInt( &strMsg );
00913   double dPlayerSpeedMax  = Parse::parseFirstDouble( &strMsg );
00914   double dStaminaIncMax   = Parse::parseFirstDouble( &strMsg );
00915   double dPlayerDecay     = Parse::parseFirstDouble( &strMsg );
00916   double dInertiaMoment   = Parse::parseFirstDouble( &strMsg );
00917   double dDashPowerRate   = Parse::parseFirstDouble( &strMsg );
00918   double dPlayerSize      = Parse::parseFirstDouble( &strMsg );
00919   double dKickableMargin  = Parse::parseFirstDouble( &strMsg );
00920   double dKickRand        = Parse::parseFirstDouble( &strMsg );
00921   double dExtraStamina    = Parse::parseFirstDouble( &strMsg );
00922   double dEffortMax       = Parse::parseFirstDouble( &strMsg );
00923   double dEffortMin       = Parse::parseFirstDouble( &strMsg );
00924 
00925   WM->processNewHeteroPlayer( iIndex, dPlayerSpeedMax, dStaminaIncMax,
00926       dPlayerDecay,    dInertiaMoment, dDashPowerRate, dPlayerSize,
00927       dKickableMargin, dKickRand,      dExtraStamina,  dEffortMax,
00928       dEffortMin );
00929   return true;
00930 }
00931 
00937 bool SenseHandler::analyzePlayerParamMessage( char *strMsg )
00938 {
00939 //  cout << strMsg << endl;
00940   Log.log( 999, "%s", strMsg );
00941   readServerParam( "player_types",                     strMsg );
00942   readServerParam( "subs_max",                         strMsg );
00943   readServerParam( "player_speed_max_delta_min",       strMsg );
00944   readServerParam( "player_speed_max_delta_max",       strMsg );
00945   readServerParam( "stamina_inc_max_delta_factor",     strMsg );
00946   readServerParam( "player_decay_delta_min",           strMsg );
00947   readServerParam( "player_decay_delta_max",           strMsg );
00948   readServerParam( "inertia_moment_delta_factor",      strMsg );
00949   readServerParam( "dash_power_rate_delta_min",        strMsg );
00950   readServerParam( "dash_power_rate_delta_max",        strMsg );
00951   readServerParam( "player_size_delta_factor",         strMsg );
00952   readServerParam( "kickable_margin_delta_min",        strMsg );
00953   readServerParam( "kickable_margin_delta_max",        strMsg );
00954   readServerParam( "kick_rand_delta_factor",           strMsg );
00955   readServerParam( "extra_stamina_delta_min",          strMsg );
00956   readServerParam( "extra_stamina_delta_max",          strMsg );
00957   readServerParam( "effort_max_delta_factor",          strMsg );
00958   readServerParam( "effort_min_delta_factor",          strMsg );
00959   readServerParam( "new_dash_power_rate_delta_min",    strMsg );
00960   readServerParam( "new_dash_power_rate_delta_max",    strMsg );
00961   readServerParam( "new_stamina_inc_max_delta_factor", strMsg );
00962 
00963   return true;
00964 }
00965 
00966 /*****************************************************************************/
00967 /********************* TESTING PURPOSES **************************************/
00968 /*****************************************************************************/
00969 
00970 /*
00971 int main( void )
00972 {
00973   Connection c( "localhost", 6000 );
00974   WorldModel wm;
00975   SenseHandler i( &c,  &wm );
00976   i.analyzeMessage( "(see 0 ((g r) 64.1 13) ((f r t) 65.4 -16) ((f r b) 79 38) ((f p r t) 46.1 -6) ((f p r c) 48.4 18) ((f p r b) 58 37) ((f g r t) 62.8 7) ((f g r b) 66 19) ((f t r 20) 38.5 -38) ((f t r 30) 46.5 -30) ((f t r 40) 55.7 -25) ((f t r 50) 64.7 -21) ((f b r 50) 80.6 41) ((f r t 30) 69.4 -12) ((f r t 20) 67.4 -4) ((f r t 10) 67.4 4) ((f r 0) 69.4 12) ((f r b 10) 72.2 20) ((f r b 20) 75.9 27) ((f r b 30) 81.5 33) ((l r) 62.8 -89))" );
00977    cout << "2" << endl;
00978   i.analyzeMessage( "(see 0 ((g l) 49.9 -24) ((f l t) 50.9 14) ((f p l t) 31.5 1 0 0) ((f p l c) 34.5 -33) ((f g l t) 47.9 -17) ((f g l b) 52.5 -32) ((f t l 50) 50.9 20) ((f t l 40) 42.5 26) ((f t l 30) 34.8 36) ((f l t 30) 54.6 8) ((f l t 20) 53 -2) ((f l t 10) 53 -12) ((f l 0) 54.6 -23) ((f l b 10) 58 -32) ((f l b 20) 62.8 -41) ((p \"l\" 2) 5 -7 0 0 172 172) ((l l) 47.9 82))" );
00979   c.disconnect();
00980   cout << "exit" << endl ;
00981 
00982 }
00983 
00984 */
00985 

Generated on Thu Apr 26 22:45:27 2007 for GangOfSix(GOS)-RoboCupTeamProject by  doxygen 1.5.1-p1