Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

SenseHandler.C

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000,2001, 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 */
00042 #include "SenseHandler.h"
00043 #include "ActHandler.h"  // sigalarmHandler
00044 #include "Parse.h"
00045 
00046 #include <signal.h>   // needed for SIGALARM
00047 #include <string.h>   // needed for strlen
00048 #include <stdio.h>    // needed for printf
00049 #include <iostream.h> // needed for cout
00050 
00051 /******************************************************************************/
00052 /********************** CLASS SENSEHANDLER ************************************/
00053 /******************************************************************************/
00054 
00060 void* sense_callback( void *v )
00061 {
00062   Log.log( 1, "Starting to listen for server messages" );
00063   SenseHandler* s = (SenseHandler*)v;
00064   s->handleMessagesFromServer( );
00065   return NULL;
00066 }
00067 
00068 
00075 SenseHandler::SenseHandler( Connection *c, WorldModel *wm, ServerSettings *ss,
00076                             PlayerSettings *ps )
00077 {
00078   connection             = c;
00079   SS                     = ss;
00080   PS                     = ps;
00081   WM                     = wm;
00082   iSimStep               = SS->getSimulatorStep()*1000;
00083   iTimeSignal            = (int)(iSimStep*0.85);
00084 
00085   struct sigaction sigact;
00086 
00087   sigact.sa_flags = SA_RESTART; // primitives (recvfrom) should not be unblocked
00088   sigact.sa_handler = (void (*)(int))sigalarmHandler;
00089   sigaction( SIGALRM, &sigact, NULL );
00090 
00091   // set timer signal to indicate when ActHandler should sent commands to the
00092   // server, this structure will later be filled with exact timing values
00093   itv.it_interval.tv_sec  = 0;
00094   itv.it_interval.tv_usec = 0;
00095   itv.it_value.tv_sec     = 0;
00096   itv.it_value.tv_usec    = 0;
00097 }
00098 
00101 void SenseHandler::handleMessagesFromServer( )
00102 {
00103   char strBuf[MAX_MSG];
00104   int i=0;
00105 
00106   while( 1 )
00107   {
00108     strBuf[0]='\0';
00109     if( i != -1 )                                         // if no error
00110       i = connection->receiveMessage( strBuf, MAX_MSG );  // get message
00111     if( strBuf[0] != '\0' )                               // if not empty
00112       analyzeMessage( strBuf );                           // parse message
00113   }
00114 }
00115 
00116 
00125 void SenseHandler::setTimeSignal( )
00126 {
00127   if( WM->getAgentViewFrequency() == 1.0 ) // VA_NORMAL AND VQ_HIGH (default)
00128   {
00129     if( iTriCounter % 3 == 0 )             // see will arrive first half cycle
00130     {
00131       iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeBegin() );
00132       iTriCounter = 0;
00133     }
00134     else if( iTriCounter % 3 == 1 )        // see will arrive 2nd half of cycle
00135     {
00136       iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );
00137     }
00138     else                                   // no see will arrive
00139       iTimeSignal = (int)(iSimStep * PS->getFractionWaitNoSee( ) );
00140   }
00141   else if( WM->getAgentViewFrequency() == 2.0 ) // VA_WIDE AND VQ_HIGH
00142   {
00143     if( iTriCounter % 3 == 0 )              // see will arrive
00144     {
00145       iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );
00146       iTriCounter = 0;
00147     }
00148     else                                   // no see will arrive
00149       iTimeSignal = (int)(iSimStep * PS->getFractionWaitNoSee() );
00150   }
00151   else                                     // VA_NARROW AND VQ_HIGH
00152     iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );
00153 
00154   iTriCounter++;
00155   itv.it_value.tv_usec = iTimeSignal;
00156   setitimer( ITIMER_REAL, &itv, NULL );
00157 }
00158 
00163 bool SenseHandler::analyzeMessage( char *strMsg )
00164 {
00165   switch( strMsg[1] )
00166   {
00167     case 'c':
00168         return analyzeChangePlayerTypeMessage( strMsg );      // ( c hange_
00169     case 'o':                                                 // ( o k
00170         if( strlen(strMsg) > 14 && strMsg[4] == 'c' && strMsg[10] == 'b' )
00171           analyzeCheckBall( strMsg );                         // (ok check_ball
00172         return true;
00173     case 's':
00174     {
00175       switch( strMsg[3] )
00176       {
00177         case 'e':
00178              if( strMsg[5] == 'g' )
00179                   return analyzeSeeGlobalMessage  ( strMsg ); // (se e_g
00180              else
00181                   return analyzeSeeMessage        ( strMsg ); // (se e
00182         case 'n': return analyzeSenseMessage      ( strMsg ); // (se n se
00183         case 'r': return analyzeServerParamMessage( strMsg ); // (se r ver_param
00184         default : break;
00185       }
00186     }
00187     case 'i':     return analyzeInitMessage       ( strMsg ); // ( i nit
00188     case 'h':     return analyzeHearMessage       ( strMsg ); // ( h ear
00189     case 'p':     return ( strMsg[8] == 't')
00190                   ? analyzePlayerTypeMessage ( strMsg )  // (player_ t ype
00191                   : analyzePlayerParamMessage( strMsg ); // (player_ p aram
00192     case 'e':     printf("%s", strMsg);                  // ( error
00193     default:      cerr << "(SenseHandler::analyzeMessage) " <<
00194                      "ignored message: " << strMsg << endl;
00195                   return false;
00196   }
00197   return false;
00198 }
00199 
00200 
00206 bool SenseHandler::analyzeSeeMessage( char *strMsg )
00207 {
00208   strcpy( WM->strLastSeeMessage, strMsg );
00209   Log.logWithTime( 2, " incoming see message" );
00210 
00211   ObjectT o;
00212   double  dDist, dDistChange,    dDirChange,     dTemp;
00213   int     iDir,  iBodyFacingDir, iHeadFacingDir, iTime = UnknownTime;
00214   Time    time = WM->getTimeLastSenseMessage();
00215   bool    isGoalie;
00216 
00217   iTime = Parse::parseFirstInt( &strMsg );         // get the time
00218   if( time.getTime() != iTime )
00219   {
00220     cerr << "(SenseHandler:analyzeSeeMessage) see with different time as sense:"
00221          << time.getTime() << " vs. " << iTime << endl;
00222     return false;
00223   }
00224 
00225   // reset the send pattern when previous cycle(s) no see arrived
00226   if( WM->getAgentViewFrequency() == 1.0 && // VA_NORMAL; previous cycle no see
00227       time.getTimeDifference( WM->getTimeLastSeeMessage() )== 2 )
00228     iTriCounter = 1;                // see will arive in 2nd half in next cycle
00229   else if( WM->getAgentViewFrequency() == 2.0 && // VA_WIDE; two cycles no see
00230            time.getTimeDifference( WM->getTimeLastSeeMessage() ) == 3 )
00231     iTriCounter = 1;                // no see will arrive next two cycles
00232 
00233   while( *strMsg != ')' )                          // " ((objname.." or ")"
00234   {
00235     dDist = dDistChange    = dDirChange     = dTemp = UnknownDoubleValue;
00236     iDir  = iBodyFacingDir = iHeadFacingDir =         UnknownIntValue;
00237     strMsg += 2;          // get the object name
00238 
00239     // get the object name from the first part of the string
00240     o = SoccerTypes::getObjectFromStr( &strMsg, &isGoalie, WM->getTeamName() );
00241     if( o == OBJECT_ILLEGAL )
00242     {
00243       Log.log( 4, "Illegal object in: ", WM->strLastSeeMessage );
00244       Log.log( 4, "rest of message: ", strMsg );
00245     }
00246 
00247     dTemp = Parse::parseFirstDouble( &strMsg );   // parse first value
00248     if ( *strMsg == ')' )                         // if it was the only value
00249       iDir = (int)dTemp;                          // it was the direction
00250     else
00251     {
00252       dDist = dTemp;                              // else it was distance
00253       iDir = Parse::parseFirstInt( &strMsg );     // and have to get direction
00254       if( *strMsg != ')' )                        // stil not finished
00255       {                                           // get dist and dir change
00256         dDistChange = Parse::parseFirstDouble( &strMsg );
00257         dDirChange  = Parse::parseFirstDouble( &strMsg );
00258       }
00259       if( *strMsg != ')' )                        // and stil not finished
00260       {                                           // get also facing dir.
00261         iBodyFacingDir = Parse::parseFirstInt( &strMsg );
00262         iHeadFacingDir = Parse::parseFirstInt( &strMsg );
00263       }
00264     }
00265     // skip ending bracket of object information.
00266     strMsg++;
00267 
00268     // process the parsed information (unread values are Unknown...)
00269     WM->processNewObjectInfo( o, time, dDist, iDir, dDistChange,
00270            dDirChange, (AngDeg)iBodyFacingDir, (AngDeg)iHeadFacingDir,
00271            isGoalie );
00272     }
00273   WM->mapUnknownPlayers( time );       // map players with unknown nr
00274   WM->setTimeLastSeeMessage( time );   // set time of last see message
00275                                        // this must be done after mapping since
00276                                        // otherwise mutex in WM is unlocked!
00277   return true;
00278 }
00279 
00285 bool SenseHandler::analyzeSeeGlobalMessage( char *strMsg )
00286 {
00287   Log.logWithTime( 2, " incoming see global message" );
00288   strcpy( WM->strLastSeeMessage, strMsg );
00289 
00290   ObjectT o;
00291   bool    isGoalie;
00292   double  dX, dY, dVelX, dVelY;
00293   int     iTime;
00294   AngDeg  angBody, angNeck;
00295   Time    time = WM->getCurrentTime();
00296 
00297   iTime = Parse::parseFirstInt( &strMsg );         // get the time
00298   time.updateTime( iTime );
00299 
00300   while( *strMsg != ')' )                          // " ((objname.." or ")"
00301   {
00302     dX = dY = dVelX = dVelY = UnknownDoubleValue;
00303     angBody = angNeck = UnknownAngleValue;
00304     strMsg += 2;          // go the start of the object name
00305 
00306     // get the object type at the current position in the string
00307     o = SoccerTypes::getObjectFromStr( &strMsg, &isGoalie, WM->getTeamName() );
00308     if( o == OBJECT_ILLEGAL )
00309     {
00310       Log.log( 4, "Illegal object" );
00311       Log.log( 4, "total messages: %s", WM->strLastSeeMessage );
00312       Log.log( 4, "rest of message: %s", strMsg );
00313     }
00314 
00315     dX = Parse::parseFirstDouble( &strMsg );        // parse first value
00316     dY = Parse::parseFirstDouble( &strMsg );        // parse second value
00317     if ( *strMsg != ')' )                           // if it was no flag
00318     {
00319       dVelX = Parse::parseFirstDouble( &strMsg );   // parse delta x
00320       dVelY = Parse::parseFirstDouble( &strMsg );   // parse delta y
00321       if( *strMsg != ')' )                          // stil not finished
00322       {                                             // get body and neck angle
00323         angBody = Parse::parseFirstDouble( &strMsg );
00324         angNeck = Parse::parseFirstDouble( &strMsg );
00325       }
00326     }
00327     // skip ending bracket of object information.
00328     strMsg++;
00329 
00330     // process the parsed information (unread values are Unknown...)
00331     WM->processSeeGlobalInfo( o, time, VecPosition(dX,dY),
00332                     VecPosition(dVelX,dVelY), angBody, angNeck );
00333     }
00334   WM->setTimeLastSeeGlobalMessage( time );  // set time last see global message
00335   return true;
00336 }
00337 
00345 bool SenseHandler::analyzeSenseMessage( char *strMsg )
00346 {
00347 
00348   setTimeSignal();                            // set signal when to send action
00349   strcpy( WM->strLastSenseMessage, strMsg );
00350 
00351   int iTime = Parse::parseFirstInt( &strMsg );// get time
00352   Time timeOld = WM->getCurrentTime();
00353   Time timeNew = timeOld;
00354   timeNew.updateTime( iTime );
00355 
00356   if( timeNew.getTimeDifference( timeOld ) > 1 )
00357     Log.log( 1, "Missed a sense!!" );
00358 
00359   Log.logWithTime ( 2, "\n\nSENSE (%d)", timeNew.getTime() );
00360   Log.restartTimer( );
00361   Log.logWithTime ( 2, " alarm after %d", iTimeSignal );
00362 
00363   strMsg++;                                      // go to ( before view_mode
00364 
00365   Parse::gotoFirstOccurenceOf( ' ', &strMsg );   // skip view_mode
00366   strMsg++;                                      // skip space
00367 
00368   ViewQualityT vq = SoccerTypes::getViewQualityFromStr( strMsg ); // get quality
00369   Parse::gotoFirstOccurenceOf( ' ', &strMsg );
00370   strMsg++;                                      // skip space; get view_angle
00371   ViewAngleT va = SoccerTypes::getViewAngleFromStr( strMsg );
00372   double dStamina = Parse::parseFirstDouble( &strMsg );  // get stamina
00373   double dEffort  = Parse::parseFirstDouble( &strMsg );  // get effort
00374 
00375   double dSpeed   = Parse::parseFirstDouble( &strMsg );  // get speed
00376   AngDeg angSpeed = Parse::parseFirstDouble( &strMsg );  // get speed ang
00377 
00378   // minus sign since we store angle between neck and body and not vice versa
00379   int iHeadAngle = - Parse::parseFirstInt( &strMsg );    // get head_angle
00380 
00381   WM->processNewAgentInfo( vq, va, dStamina, dEffort, dSpeed,
00382         (AngDeg) angSpeed, (AngDeg)iHeadAngle );
00383 
00384   // set all number of performed commands
00385   WM->setNrOfCommands( CMD_KICK       , Parse::parseFirstInt( &strMsg ) );
00386   WM->setNrOfCommands( CMD_DASH       , Parse::parseFirstInt( &strMsg ) );
00387   WM->setNrOfCommands( CMD_TURN       , Parse::parseFirstInt( &strMsg ) );
00388   WM->setNrOfCommands( CMD_SAY        , Parse::parseFirstInt( &strMsg ) );
00389   WM->setNrOfCommands( CMD_TURNNECK   , Parse::parseFirstInt( &strMsg ) );
00390   WM->setNrOfCommands( CMD_CATCH      , Parse::parseFirstInt( &strMsg ) );
00391   WM->setNrOfCommands( CMD_MOVE       , Parse::parseFirstInt( &strMsg ) );
00392   WM->setNrOfCommands( CMD_CHANGEVIEW , Parse::parseFirstInt( &strMsg ) );
00393 
00394   WM->setTimeLastSenseMessage( timeNew );                     // set the time
00395   Log.logWithTime( 2, " end analyzing sense" );
00396   return true;
00397 }
00398 
00404 bool SenseHandler::analyzeInitMessage( char *strMsg )
00405 {
00406   strMsg += 6;                                            // go to Side
00407   WM->setSide( SoccerTypes::getSideFromStr( strMsg ) );   // get and set Side
00408   int nr = Parse::parseFirstInt( &strMsg );               // get and set number
00409   if( nr == 0 )                                           // coach
00410   {
00411      WM->setPlayerNumber( nr );
00412      return true;
00413   }
00414   WM->setAgentObjectType( SoccerTypes::getTeammateObjectFromIndex( nr - 1 ) );
00415   WM->setPlayerNumber( nr );
00416   strMsg++;                                               // skip space to pm
00417   WM->setPlayMode( SoccerTypes::getPlayModeFromStr( strMsg ) ); // get playmode
00418   return true;
00419 }
00420 
00428 bool SenseHandler::analyzeHearMessage( char *strMsg )
00429 {
00430   RefereeMessageT rm;
00431   PlayModeT       pm;
00432   strcpy( WM->strLastHearMessage, strMsg);
00433 
00434   Parse::parseFirstInt( &strMsg );                          // ignore time
00435   Time time = WM->getCurrentTime();
00436 
00437   switch( Parse::gotoFirstNonSpace( &strMsg ) )
00438   {
00439     case 'r':                                               // referee
00440       WM->setTimeLastRefereeMessage( time );
00441       Parse::gotoFirstOccurenceOf( ' ', &strMsg );          // go to start
00442       Parse::gotoFirstNonSpace   ( &strMsg      );          // and first part
00443       rm = SoccerTypes::getRefereeMessageFromStr( strMsg ); // get the ref msg
00444       Log.logWithTime( 2, " referee message: %s %s",
00445       SoccerTypes::getRefereeMessageStr(rm), WM->strLastHearMessage);
00446       pm = SoccerTypes::getPlayModeFromRefereeMessage( rm );// get play mode
00447       if( pm != PM_ILLEGAL )                                // from ref msg
00448         WM->setPlayMode( pm );                              // if was pm, set it
00449 
00450       if( rm == REFC_GOAL_LEFT )                            // goal left
00451       {
00452         if( WM->getSide() == SIDE_LEFT )
00453           WM->addOneToGoalDiff();
00454         else
00455           WM->subtractOneFromGoalDiff();
00456         WM->processSeeGlobalInfo( OBJECT_BALL, time, VecPosition( 0, 0 ),
00457              VecPosition( 0, 0 ), 0, 0 );
00458       }
00459       else if( rm == REFC_GOAL_RIGHT )                      // goal right
00460       {
00461         if( WM->getSide() == SIDE_RIGHT )
00462           WM->addOneToGoalDiff();
00463         else
00464           WM->subtractOneFromGoalDiff();
00465         WM->processSeeGlobalInfo( OBJECT_BALL, time, VecPosition( 0, 0 ),
00466              VecPosition( 0, 0 ), 0, 0 );        
00467       }
00468       else if( rm == REFC_GOALIE_CATCH_BALL_LEFT ||         // catch ball
00469                rm == REFC_GOALIE_CATCH_BALL_RIGHT )
00470         WM->processCatchedBall( rm, time );
00471       break;
00472     case 's':                                               // self
00473       break;                                                // do nothing
00474     default:                                                // from direction
00475         analyzePlayerMessage( strMsg );                     // from player
00476       break;
00477   }
00478 
00479   return true;
00480 }
00481 
00493 bool SenseHandler::analyzePlayerMessage( char *strMsg )
00494 {
00495   Parse::parseFirstInt( &strMsg );        // skip direction
00496   Parse::gotoFirstNonSpace( &strMsg );    // skip space
00497   strMsg++;                               // skip " (=quote)
00498 
00499   // first character is team side
00500   char cSide = (WM->getSide() == SIDE_LEFT) ? 'l' : 'r' ;
00501 
00502   if( cSide != strMsg[0] )                // not team side probably msg from opp
00503     return false;
00504 
00505   strMsg++;                              // go to next
00506 
00507   if( strlen(strMsg) < 7    ||           // encoding always at least 7 chars
00508       strMsg[0]      < 'a'  ||           // and between 'a' and 'a' + 9 since
00509       strMsg[0]      > 'a'+ 9 )          // it is a number added to 'a'.
00510     return false;                        // not right -> message from opponent
00511 
00512   int i[4];                              // decode message by subracting
00513   i[0] =        (int)(strMsg[0] - 'a');  // string 'acegi' from message.
00514   i[1] =        (int)(strMsg[1] - 'c');  // resulting number indicate cycle and
00515   i[2] =        (int)(strMsg[2] - 'e');  // player number.
00516   i[3] =        (int)(strMsg[3] - 'g');
00517   int iPlayer = (int)(strMsg[4] - 'i');
00518 
00519   int iTime = i[0]*1000+i[1]*100+i[2]*10+i[3];
00520 
00521   int    iDiff = iTime - WM->getCurrentCycle()%10000;
00522   double dDiff = iDiff/100;
00523 
00524   if( fabs(iDiff) > 2 && strMsg[0] != 'F' )
00525   {
00526     printf( "(SenseHandler::%s) information is outdated:%d %d in:",
00527                       __FUNCTION__, iTime, WM->getCurrentCycle() );
00528     printf( "%s\n", WM->strLastHearMessage );
00529     return false;
00530   }
00531 
00532   // is message from teammate, so start retrieving information
00533   VecPosition pos, vel;
00534   double      dConf;
00535   ObjectT     obj;
00536 
00537   // parse information from player that sent the message
00538   pos.setX( Parse::parseFirstDouble( &strMsg ) );
00539   pos.setY( Parse::parseFirstDouble( &strMsg ) );
00540   vel.setX( Parse::parseFirstDouble( &strMsg ) );
00541   vel.setY( Parse::parseFirstDouble( &strMsg ) );
00542   obj = SoccerTypes::getTeammateObjectFromIndex( iPlayer - 1 );
00543 
00544   WM->processPerfectHearInfo( obj, pos, 1.00 ); // vel is not parsed.
00545 
00546   // parse the information from the ball, the confidence is subtracted with
00547   // dDiff that denotes the confidence difference between the sent time and
00548   // the heard time. When message is heard one cycle later than it is sent,
00549   // confidence should be lower.
00550   Parse::gotoFirstOccurenceOf( '(', &strMsg );
00551   strMsg++;
00552   if( *strMsg != ')' )                                  // ball info available
00553   {
00554     pos.setX( Parse::parseFirstDouble( &strMsg ) );
00555     pos.setY( Parse::parseFirstDouble( &strMsg ) );
00556     vel.setX( Parse::parseFirstDouble( &strMsg ) );
00557     vel.setY( Parse::parseFirstDouble( &strMsg ) );
00558     dConf = Parse::parseFirstDouble( &strMsg );
00559     WM->processPerfectHearInfoBall( pos, vel, dConf - dDiff );
00560   }
00561 
00562   Parse::gotoFirstOccurenceOf( ')', &strMsg );          // go to teammate info
00563   strMsg++; // skip ')'
00564   strMsg++; // skip '('
00565   while( *strMsg != ')' )                               // as long as new info
00566   {
00567     iPlayer = Parse::parseFirstInt( &strMsg );          // get the number
00568     if( iPlayer == -1 )                                 // if illegal
00569       obj = OBJECT_TEAMMATE_UNKNOWN;                    // we don't know nr
00570     else
00571       obj = SoccerTypes::getTeammateObjectFromIndex( iPlayer - 1 );
00572     pos.setX( Parse::parseFirstDouble( &strMsg ) );
00573     pos.setY( Parse::parseFirstDouble( &strMsg ) );
00574     dConf = Parse::parseFirstDouble( &strMsg ) ;
00575     Parse::gotoFirstNonSpace( &strMsg );
00576     WM->processPerfectHearInfo( obj, pos, dConf - dDiff ); // process all info
00577   }
00578 
00579   bool bIsGoalie = false;
00580 
00581   strMsg++; // skip ')'                                 // go to opponent info
00582   strMsg++; // skip '('
00583   while( *strMsg != ')' )
00584   {
00585     iPlayer = Parse::parseFirstInt( &strMsg );
00586     if( iPlayer == -1 )                                 // if illegal
00587       obj = OBJECT_OPPONENT_UNKNOWN;                    // we don't know nr
00588     else
00589       obj = SoccerTypes::getOpponentObjectFromIndex( iPlayer - 1 );
00590     bIsGoalie = ( *strMsg == 'g' );                     // i.e. 1g
00591     pos.setX( Parse::parseFirstDouble( &strMsg ) );
00592     pos.setY( Parse::parseFirstDouble( &strMsg ) );
00593     dConf = Parse::parseFirstDouble( &strMsg ) ;
00594     Parse::gotoFirstNonSpace( &strMsg );
00595     WM->processPerfectHearInfo( obj, pos, dConf - dDiff, bIsGoalie );
00596   }
00597   return true;
00598 }
00599 
00606 bool SenseHandler::analyzeCheckBall( char *strMsg )
00607 {
00608   WM->setTimeCheckBall( Parse::parseFirstInt( &strMsg ) );
00609   strMsg++;
00610   WM->setCheckBallStatus( SoccerTypes::getBallStatusFromStr( strMsg ) );
00611   return true;
00612 }
00613 
00620 bool SenseHandler::analyzeChangePlayerTypeMessage( char *strMsg )
00621 {
00622   int iPlayer = Parse::parseFirstInt( &strMsg );
00623   if( *strMsg != ')' && WM->getPlayerNumber() == iPlayer )
00624   {
00625     int iPlayerType = Parse::parseFirstInt( &strMsg );
00626     return WM->updateSSToHeteroPlayerType( iPlayerType );
00627   }
00628   return false;
00629 }
00630 
00637 bool SenseHandler::analyzeServerParamMessage( char *strMsg )
00638 {
00639   // get the server parameters one by one
00640   SS->setGoalWidth            ( Parse::parseFirstDouble( &strMsg ) );
00641   SS->setInertiaMoment        ( Parse::parseFirstDouble( &strMsg ) );
00642   SS->setPlayerSize           ( Parse::parseFirstDouble( &strMsg ) );
00643   SS->setPlayerDecay          ( Parse::parseFirstDouble( &strMsg ) );
00644   SS->setPlayerRand           ( Parse::parseFirstDouble( &strMsg ) );
00645   SS->setPlayerWeight         ( Parse::parseFirstDouble( &strMsg ) );
00646   SS->setPlayerSpeedMax       ( Parse::parseFirstDouble( &strMsg ) );
00647   SS->setPlayerAccelMax       ( Parse::parseFirstDouble( &strMsg ) );
00648   SS->setStaminaMax           ( Parse::parseFirstDouble( &strMsg ) );
00649   SS->setStaminaIncMax        ( Parse::parseFirstDouble( &strMsg ) );
00650   Parse::parseFirstDouble( &strMsg ); // skip recover_init = 0
00651   SS->setRecoverDecThr        ( Parse::parseFirstDouble( &strMsg ) );
00652   SS->setRecoverMin           ( Parse::parseFirstDouble( &strMsg ) );
00653   SS->setRecoverDec           ( Parse::parseFirstDouble( &strMsg ) );
00654   Parse::parseFirstDouble( &strMsg ); // skip effort_init = 0
00655   SS->setEffortDecThr         ( Parse::parseFirstDouble( &strMsg ) );
00656   SS->setEffortMin            ( Parse::parseFirstDouble( &strMsg ) );
00657   SS->setEffortDec            ( Parse::parseFirstDouble( &strMsg ) );
00658   SS->setEffortIncThr         ( Parse::parseFirstDouble( &strMsg ) );
00659   SS->setEffortInc            ( Parse::parseFirstDouble( &strMsg ) );
00660   SS->setKickRand             ( Parse::parseFirstDouble( &strMsg ) );
00661   Parse::parseFirstDouble( &strMsg ); // skip team_actuator noise
00662   Parse::parseFirstDouble( &strMsg ); // skip prand_factor_l
00663   Parse::parseFirstDouble( &strMsg ); // skip prand_factor_r
00664   Parse::parseFirstDouble( &strMsg ); // skip kick_rand_factor_l
00665   Parse::parseFirstDouble( &strMsg ); // skip kick_rand_factor_r
00666   SS->setBallSize             ( Parse::parseFirstDouble( &strMsg ) );
00667   SS->setBallDecay            ( Parse::parseFirstDouble( &strMsg ) );
00668   SS->setBallRand             ( Parse::parseFirstDouble( &strMsg ) );
00669   SS->setBallWeight           ( Parse::parseFirstDouble( &strMsg ) );
00670   SS->setBallSpeedMax         ( Parse::parseFirstDouble( &strMsg ) );
00671   SS->setBallAccelMax         ( Parse::parseFirstDouble( &strMsg ) );
00672   SS->setDashPowerRate        ( Parse::parseFirstDouble( &strMsg ) );
00673   SS->setKickPowerRate        ( Parse::parseFirstDouble( &strMsg ) );
00674   SS->setKickableMargin       ( Parse::parseFirstDouble( &strMsg ) );
00675   Parse::parseFirstDouble( &strMsg ); // skip control radius
00676   Parse::parseFirstDouble( &strMsg ); // skip control radius width
00677   SS->setMaxPower             ( Parse::parseFirstInt( &strMsg ) );
00678   SS->setMinPower             ( Parse::parseFirstInt( &strMsg ) );
00679   SS->setMaxMoment            ( Parse::parseFirstInt( &strMsg ) );
00680   SS->setMinMoment            ( Parse::parseFirstInt( &strMsg ) );
00681   SS->setMaxNeckMoment        ( Parse::parseFirstInt( &strMsg ) );
00682   SS->setMinNeckMoment        ( Parse::parseFirstInt( &strMsg ) );
00683   SS->setMaxNeckAng           ( Parse::parseFirstInt( &strMsg ) );
00684   SS->setMinNeckAng           ( Parse::parseFirstInt( &strMsg ) );
00685   SS->setVisibleAngle         ( Parse::parseFirstDouble( &strMsg ) );
00686   SS->setVisibleDistance      ( Parse::parseFirstDouble( &strMsg ) );
00687   SS->setWindDir              ( Parse::parseFirstDouble( &strMsg ) );
00688   SS->setWindForce            ( Parse::parseFirstDouble( &strMsg ) );
00689   Parse::parseFirstDouble( &strMsg ); // skip winang
00690   SS->setWindRand             ( Parse::parseFirstDouble( &strMsg ) );
00691   SS->setMaximalKickDist      ( Parse::parseFirstDouble( &strMsg ) );
00692   SS->setCatchableAreaL       ( Parse::parseFirstDouble( &strMsg ) );
00693   SS->setCatchableAreaW       ( Parse::parseFirstDouble( &strMsg ) );
00694   SS->setCatchProbability     ( Parse::parseFirstDouble( &strMsg ) );
00695   SS->setGoalieMaxMoves       ( Parse::parseFirstInt( &strMsg ) );
00696   SS->setCkickMargin          ( Parse::parseFirstDouble( &strMsg ) );
00697   SS->setOffsideActiveAreaSize( Parse::parseFirstDouble( &strMsg ) );
00698   Parse::parseFirstDouble( &strMsg ); // skip win_no: wind factor is none
00699   Parse::parseFirstDouble( &strMsg ); // skip win_random: wind factor is random
00700   SS->setSayCoachCntMax       ( Parse::parseFirstInt( &strMsg ) );
00701   SS->setSayCoachMsgSize      ( Parse::parseFirstInt( &strMsg ) );
00702   SS->setClangWinSize         ( Parse::parseFirstInt( &strMsg ) );
00703   SS->setClangDefineWin       ( Parse::parseFirstInt( &strMsg ) );
00704   SS->setClangMetaWin         ( Parse::parseFirstInt( &strMsg ) );
00705   SS->setClangAdviceWin       ( Parse::parseFirstInt( &strMsg ) );
00706   SS->setClangInfoWin         ( Parse::parseFirstInt( &strMsg ) );
00707   SS->setClangMessDelay       ( Parse::parseFirstInt( &strMsg ) );
00708   SS->setClangMessPerCycle    ( Parse::parseFirstInt( &strMsg ) );
00709   SS->setHalfTime             ( Parse::parseFirstInt( &strMsg ) );
00710   SS->setSimulatorStep        ( Parse::parseFirstInt( &strMsg ) );
00711   SS->setSendStep             ( Parse::parseFirstInt( &strMsg ) );
00712   SS->setRecvStep             ( Parse::parseFirstInt( &strMsg ) );
00713   SS->setSenseBodyStep        ( Parse::parseFirstInt( &strMsg ) );
00714   Parse::parseFirstInt( &strMsg ); // ignore lcm (lowest common multiplier?)
00715   SS->setSayMsgSize           ( Parse::parseFirstInt( &strMsg ) );
00716   SS->setHearMax              ( Parse::parseFirstInt( &strMsg ) );
00717   SS->setHearInc              ( Parse::parseFirstInt( &strMsg ) );
00718   SS->setHearDecay            ( Parse::parseFirstInt( &strMsg ) );
00719   SS->setCatchBanCycle        ( Parse::parseFirstInt( &strMsg ) );
00720   SS->setSlowDownFactor       ( Parse::parseFirstInt( &strMsg ) );
00721   SS->setUseOffside           ( Parse::parseFirstInt( &strMsg ) );
00722   SS->setForbidKickOffOffside ( Parse::parseFirstInt( &strMsg ) );
00723   SS->setOffsideKickMargin    ( Parse::parseFirstDouble( &strMsg ) );
00724   SS->setAudioCutDist         ( Parse::parseFirstDouble( &strMsg ) );
00725   SS->setQuantizeStep         ( Parse::parseFirstDouble( &strMsg ) );
00726   SS->setQuantizeStepL        ( Parse::parseFirstDouble( &strMsg ) );
00727   Parse::parseFirstDouble( &strMsg ); // skip dir_qstep
00728   Parse::parseFirstDouble( &strMsg ); // skip dist_qstep_l
00729   Parse::parseFirstDouble( &strMsg ); // skip dist_qstep_r
00730   Parse::parseFirstDouble( &strMsg ); // skip land_qstep_l
00731   Parse::parseFirstDouble( &strMsg ); // skip land_qstep_r
00732   Parse::parseFirstDouble( &strMsg ); // skip dir_qstep_l
00733   Parse::parseFirstDouble( &strMsg ); // skip dir_qstep_r
00734   Parse::parseFirstInt( &strMsg );    // skip CoachMode (coach allowed or not)
00735   Parse::parseFirstInt( &strMsg );    // skip CwRMode (referee allowed with c)
00736   Parse::parseFirstInt( &strMsg );    // old_hear (old format for coach hear)
00737   Parse::parseFirstInt( &strMsg );    // setCoachLookInterval equals viStep?
00738   Parse::parseFirstInt( &strMsg );    // skip start_goal_l
00739   Parse::parseFirstInt( &strMsg );    // skip start_goal_r
00740   Parse::parseFirstInt( &strMsg );    // skip fullstate_l
00741   Parse::parseFirstInt( &strMsg );    // skip fullstate_r
00742   Parse::parseFirstInt( &strMsg );    // skip drop_time
00743 
00744   return true;
00745 }
00746 
00753 bool SenseHandler::analyzePlayerTypeMessage ( char *strMsg )
00754 {
00755   // analyze all heterogeneous player information
00756   int    iIndex           = Parse::parseFirstInt( &strMsg );
00757   double dPlayerSpeedMax  = Parse::parseFirstDouble( &strMsg );
00758   double dStaminaIncMax   = Parse::parseFirstDouble( &strMsg );
00759   double dPlayerDecay     = Parse::parseFirstDouble( &strMsg );
00760   double dInertiaMoment   = Parse::parseFirstDouble( &strMsg );
00761   double dDashPowerRate   = Parse::parseFirstDouble( &strMsg );
00762   double dPlayerSize      = Parse::parseFirstDouble( &strMsg );
00763   double dKickableMargin  = Parse::parseFirstDouble( &strMsg );
00764   double dKickRand        = Parse::parseFirstDouble( &strMsg );
00765   double dExtraStamina    = Parse::parseFirstDouble( &strMsg );
00766   double dEffortMax       = Parse::parseFirstDouble( &strMsg );
00767   double dEffortMin       = Parse::parseFirstDouble( &strMsg );
00768   WM->processNewHeteroPlayer( iIndex, dPlayerSpeedMax, dStaminaIncMax,
00769       dPlayerDecay,    dInertiaMoment, dDashPowerRate, dPlayerSize,
00770       dKickableMargin, dKickRand,      dExtraStamina,  dEffortMax,
00771       dEffortMin );
00772   return true;
00773 }
00774 
00780 bool SenseHandler::analyzePlayerParamMessage( char *strMsg )
00781 {
00782   return true;
00783 }
00784 
00785 /******************************************************************************/
00786 /********************** TESTING PURPOSES **************************************/
00787 /******************************************************************************/
00788 
00789 /*
00790 int main( void )
00791 {
00792   Connection c( "localhost", 6000 );
00793   WorldModel wm;
00794   SenseHandler i( &c,  &wm );
00795   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))" );
00796    cout << "2" << endl;
00797   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))" );
00798   c.disconnect();
00799   cout << "exit" << endl ;
00800 
00801 }
00802 
00803 */

Generated on Thu Mar 7 00:37:43 2002 for UvA Trilearn 2001 by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001