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-2002, 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 */
00046 #include "SenseHandler.h"
00047 #include "ActHandler.h"  // sigalarmHandler
00048 #include "Parse.h"
00049 
00050 #include <signal.h>   // needed for SIGALARM
00051 #include <string.h>   // needed for strlen
00052 #include <stdio.h>    // needed for printf
00053 #include <iostream.h> // needed for cout
00054 
00055 /******************************************************************************/
00056 /********************** CLASS SENSEHANDLER ************************************/
00057 /******************************************************************************/
00058 
00064 void* sense_callback( void *v )
00065 {
00066   Log.log( 1, "Starting to listen for server messages" );
00067   SenseHandler* s = (SenseHandler*)v;
00068   s->handleMessagesFromServer( );
00069   return NULL;
00070 }
00071 
00072 
00079 SenseHandler::SenseHandler( Connection *c, WorldModel *wm, ServerSettings *ss,
00080                             PlayerSettings *ps )
00081 {
00082   connection             = c;
00083   SS                     = ss;
00084   PS                     = ps;
00085   WM                     = wm;
00086   iSimStep               = SS->getSimulatorStep()*1000;
00087   iTimeSignal            = (int)(iSimStep*0.85);
00088   
00089   struct sigaction sigact;
00090 
00091   sigact.sa_flags = SA_RESTART; // primitives (recvfrom) should not be unblocked
00092   sigact.sa_handler = (void (*)(int))sigalarmHandler;
00093   sigaction( SIGALRM, &sigact, NULL );
00094 
00095   // set timer signal to indicate when ActHandler should sent commands to the
00096   // server, this structure will later be filled with exact timing values
00097   itv.it_interval.tv_sec  = 0;
00098   itv.it_interval.tv_usec = 0;
00099   itv.it_value.tv_sec     = 0;
00100   itv.it_value.tv_usec    = 0;
00101 }
00102 
00105 void SenseHandler::handleMessagesFromServer( )
00106 {
00107   char strBuf[MAX_MSG];
00108   int i=0;
00109 
00110   while( 1 )
00111   {
00112     strBuf[0]='\0';
00113     if( i != -1 )                                         // if no error
00114       i = connection->receiveMessage( strBuf, MAX_MSG );  // get message
00115     if( strBuf[0] != '\0' )                               // if not empty
00116       analyzeMessage( strBuf );                           // parse message
00117   }
00118 }
00119 
00120 
00129 void SenseHandler::setTimeSignal( )
00130 {
00131   if( WM->getAgentViewFrequency() == 1.0 ) // VA_NORMAL AND VQ_HIGH (default)
00132   {
00133     if( iTriCounter % 3 == 0 )             // see will arrive first half cycle
00134     {
00135       iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeBegin() );
00136       iTriCounter = 0;
00137     }
00138     else if( iTriCounter % 3 == 1 )        // see will arrive 2nd half of cycle
00139     {
00140       iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );
00141     }
00142     else                                   // no see will arrive
00143       iTimeSignal = (int)(iSimStep * PS->getFractionWaitNoSee( ) );
00144   }
00145   else if( WM->getAgentViewFrequency() == 2.0 ) // VA_WIDE AND VQ_HIGH
00146   {
00147     if( iTriCounter % 3 == 0 )              // see will arrive
00148     {
00149       iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );
00150       iTriCounter = 0;
00151     }
00152     else                                   // no see will arrive
00153       iTimeSignal = (int)(iSimStep * PS->getFractionWaitNoSee() );
00154   }
00155   else                                     // VA_NARROW AND VQ_HIGH
00156     iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );
00157 
00158   iTriCounter++;
00159   itv.it_value.tv_usec = iTimeSignal;
00160   setitimer( ITIMER_REAL, &itv, NULL );
00161 }
00162 
00167 bool SenseHandler::analyzeMessage( char *strMsg )
00168 {
00169   switch( strMsg[1] )
00170   {
00171     case 'c':
00172         return analyzeChangePlayerTypeMessage( strMsg );      // ( c hange_
00173     case 'o':                                                 // ( o k
00174         if( strlen(strMsg) > 14 && strMsg[4] == 'c' && strMsg[10] == 'b' )
00175           analyzeCheckBall( strMsg );                         // (ok check_ball
00176         return true;
00177     case 's':
00178     {
00179       switch( strMsg[3] )
00180       {
00181         case 'e':
00182              if( strMsg[5] == 'g' )
00183                   return analyzeSeeGlobalMessage  ( strMsg ); // (se e_g
00184              else
00185                   return analyzeSeeMessage        ( strMsg ); // (se e
00186         case 'n': return analyzeSenseMessage      ( strMsg ); // (se n se
00187         case 'r': return analyzeServerParamMessage( strMsg ); // (se r ver_param
00188         default : break;
00189       }
00190     }
00191     case 'i':     return analyzeInitMessage       ( strMsg ); // ( i nit
00192     case 'h':     return analyzeHearMessage       ( strMsg ); // ( h ear
00193     case 'p':     return ( strMsg[8] == 't')
00194                   ? analyzePlayerTypeMessage ( strMsg )  // (player_ t ype
00195                   : analyzePlayerParamMessage( strMsg ); // (player_ p aram
00196     case 'e':     printf("%s", strMsg);                  // ( error
00197     default:      cerr << "(" << WM->getCurrentTime() << ", " <<
00198                         WM->getPlayerNumber()
00199                         << ") (SenseHandler::analyzeMessage) " <<
00200                      "ignored message: " << strMsg << endl;
00201                   return false;
00202   }
00203   return false;
00204 }
00205 
00206 
00211 bool SenseHandler::analyzeSeeMessage( char *strMsg )
00212 {
00213   strcpy( WM->strLastSeeMessage, strMsg );
00214 
00215   Log.logWithTime( 2, " incoming see message" );
00216   Log.logWithTime( 2, " %s",strMsg );
00217 
00218   if( WM->getRelativeDistance( OBJECT_BALL ) < SS->getVisibleDistance() )
00219     Log.logWithTime( 560, "%s", WM->strLastSeeMessage );  
00220 
00221   Time    time = WM->getTimeLastSenseMessage();
00222   int iTime = Parse::parseFirstInt( &strMsg );         // get the time
00223   if( time.getTime() != iTime )
00224   {
00225     cerr << "(SenseHandler:analyzeSeeMessage) see with different time as sense:"
00226          << time.getTime() << " vs. " << iTime << endl;
00227     return false;
00228   }
00229 
00230   // count number of see message in this cycle
00231   if( WM->getTimeLastSeeMessage() == time )
00232     m_iSeeCounter++;
00233   else
00234     m_iSeeCounter = 1;
00235 
00236   // do nothing with second see, since it adds nothings
00237   if( m_iSeeCounter >= 2 )
00238   {
00239     Log.logWithTime( 4, "second see message in cycle; do nothing " );
00240     return true;
00241   }
00242 
00243   // reset the send pattern when previous cycle(s) no see arrived
00244   if( WM->getAgentViewFrequency() == 1.0 && // VA_NORMAL; previous cycle no see
00245       time.getTimeDifference( WM->getTimeLastSeeMessage() )== 2 )
00246     iTriCounter = 1;                // see will arive in 2nd half in next cycle
00247   else if( WM->getAgentViewFrequency() == 2.0 && // VA_WIDE; two cycles no see
00248            time.getTimeDifference( WM->getTimeLastSeeMessage() ) == 3 )
00249     iTriCounter = 1;                // no see will arrive next two cycles
00250 
00251   WM->setTimeLastSeeMessage( time );   // set time of last see message
00252   return true;
00253 }
00254 
00260 bool SenseHandler::analyzeSeeGlobalMessage( char *strMsg )
00261 {
00262   Log.logWithTime( 2, " incoming see global message" );
00263   strcpy( WM->strLastSeeMessage, strMsg );
00264 
00265   ObjectT o;
00266   bool    isGoalie;
00267   double  dX, dY, dVelX, dVelY;
00268   int     iTime;
00269   AngDeg  angBody, angNeck;
00270   Time    time = WM->getCurrentTime();
00271 
00272   iTime = Parse::parseFirstInt( &strMsg );         // get the time
00273   time.updateTime( iTime );
00274 
00275   while( *strMsg != ')' )                          // " ((objname.." or ")"
00276   {
00277     dX = dY = dVelX = dVelY = UnknownDoubleValue;
00278     angBody = angNeck = UnknownAngleValue;
00279     strMsg += 2;          // go the start of the object name
00280 
00281     // get the object type at the current position in the string
00282     o = SoccerTypes::getObjectFromStr( &strMsg, &isGoalie, WM->getTeamName() );
00283     if( o == OBJECT_ILLEGAL )
00284     {
00285       Log.log( 4, "Illegal object" );
00286       Log.log( 4, "total messages: %s", WM->strLastSeeMessage );
00287       Log.log( 4, "rest of message: %s", strMsg );
00288     }
00289 
00290     dX = Parse::parseFirstDouble( &strMsg );        // parse first value
00291     dY = Parse::parseFirstDouble( &strMsg );        // parse second value
00292     if ( *strMsg != ')' )                           // if it was no flag
00293     {
00294       dVelX = Parse::parseFirstDouble( &strMsg );   // parse delta x
00295       dVelY = Parse::parseFirstDouble( &strMsg );   // parse delta y
00296       if( *strMsg != ')' )                          // stil not finished
00297       {                                             // get body and neck angle
00298         angBody = Parse::parseFirstDouble( &strMsg );
00299         angNeck = Parse::parseFirstDouble( &strMsg );
00300       }
00301     }
00302     // skip ending bracket of object information.
00303     strMsg++;
00304 
00305     // process the parsed information (unread values are Unknown...)
00306     WM->processSeeGlobalInfo( o, time, VecPosition(dX,dY),
00307                     VecPosition(dVelX,dVelY), angBody, angNeck );
00308     }
00309   WM->setTimeLastSeeGlobalMessage( time );  // set time last see global message
00310   return true;
00311 }
00312 
00320 bool SenseHandler::analyzeSenseMessage( char *strMsg )
00321 {
00322   setTimeSignal();                            // set signal when to send action
00323 
00324   strcpy( WM->strLastSenseMessage, strMsg );
00325  
00326   if( WM->getRelativeDistance( OBJECT_BALL ) < SS->getVisibleDistance() )
00327     Log.logWithTime( 560, "%s", WM->strLastSenseMessage );
00328 
00329   int iTime = Parse::parseFirstInt( &strMsg );// get time
00330   Time timeOld = WM->getCurrentTime();
00331   Time timeNew = timeOld;
00332   timeNew.updateTime( iTime );
00333 
00334   if( timeNew.getTimeDifference( timeOld ) > 1 )
00335     Log.log( 1, "Missed a sense!!" );
00336 
00337   Log.logWithTime ( 2, "\n\nSENSE (%d, %d)", timeNew.getTime(),
00338   timeNew.getTimeStopped() );
00339   Log.restartTimer( );
00340   Log.logWithTime ( 2, " alarm after %d", iTimeSignal );
00341 
00342   strMsg++;                                      // go to ( before view_mode
00343 
00344   Parse::gotoFirstOccurenceOf( ' ', &strMsg );   // skip view_mode
00345   strMsg++;                                      // skip space
00346 
00347   ViewQualityT vq = SoccerTypes::getViewQualityFromStr( strMsg ); // get quality
00348   Parse::gotoFirstOccurenceOf( ' ', &strMsg );
00349   strMsg++;                                      // skip space; get view_angle
00350   ViewAngleT va = SoccerTypes::getViewAngleFromStr( strMsg );
00351   double dStamina = Parse::parseFirstDouble( &strMsg );  // get stamina
00352   double dEffort  = Parse::parseFirstDouble( &strMsg );  // get effort
00353 
00354   double dSpeed   = Parse::parseFirstDouble( &strMsg );  // get speed
00355   AngDeg angSpeed = Parse::parseFirstDouble( &strMsg );  // get speed ang
00356 
00357   // minus sign since we store angle between neck and body and not vice versa
00358   int iHeadAngle = - Parse::parseFirstInt( &strMsg );    // get head_angle
00359 
00360   WM->processNewAgentInfo( vq, va, dStamina, dEffort, dSpeed,
00361         (AngDeg) angSpeed, (AngDeg)iHeadAngle );
00362 
00363   // set all number of performed commands
00364   WM->setNrOfCommands( CMD_KICK       , Parse::parseFirstInt( &strMsg ) );
00365   WM->setNrOfCommands( CMD_DASH       , Parse::parseFirstInt( &strMsg ) );
00366   WM->setNrOfCommands( CMD_TURN       , Parse::parseFirstInt( &strMsg ) );
00367   WM->setNrOfCommands( CMD_SAY        , Parse::parseFirstInt( &strMsg ) );
00368   WM->setNrOfCommands( CMD_TURNNECK   , Parse::parseFirstInt( &strMsg ) );
00369   WM->setNrOfCommands( CMD_CATCH      , Parse::parseFirstInt( &strMsg ) );
00370   WM->setNrOfCommands( CMD_MOVE       , Parse::parseFirstInt( &strMsg ) );
00371   WM->setNrOfCommands( CMD_CHANGEVIEW , Parse::parseFirstInt( &strMsg ) );
00372 
00373   WM->setTimeLastSenseMessage( timeNew ); // set the time
00374 
00375   Log.logWithTime( 2, " end analyzing sense" );
00376   return true;
00377 }
00378 
00384 bool SenseHandler::analyzeInitMessage( char *strMsg )
00385 {
00386   strMsg += 6;                                            // go to Side
00387   WM->setSide( SoccerTypes::getSideFromStr( strMsg ) );   // get and set Side
00388   int nr = Parse::parseFirstInt( &strMsg );               // get and set number
00389   if( nr == 0 )                                           // coach
00390   {
00391      WM->setPlayerNumber( nr );
00392      return true;
00393   }
00394   WM->setAgentObjectType( SoccerTypes::getTeammateObjectFromIndex( nr - 1 ) );
00395   WM->setPlayerNumber( nr );
00396   strMsg++;                                               // skip space to pm
00397   WM->setPlayMode( SoccerTypes::getPlayModeFromStr( strMsg ) ); // get playmode
00398   return true;
00399 }
00400 
00408 bool SenseHandler::analyzeHearMessage( char *strMsg )
00409 {
00410   RefereeMessageT rm;
00411   PlayModeT       pm;
00412   strcpy( WM->strLastHearMessage, strMsg);
00413 
00414   Parse::parseFirstInt( &strMsg );                          // ignore time
00415   Time time = WM->getCurrentTime();
00416 
00417   switch( Parse::gotoFirstNonSpace( &strMsg ) )
00418   {
00419     case 'r':                                               // referee
00420       WM->setTimeLastRefereeMessage( time );
00421       Parse::gotoFirstOccurenceOf( ' ', &strMsg );          // go to start
00422       Parse::gotoFirstNonSpace   ( &strMsg      );          // and first part
00423       rm = SoccerTypes::getRefereeMessageFromStr( strMsg ); // get the ref msg
00424       Log.logWithTime( 2, " referee message: %s %s",
00425       SoccerTypes::getRefereeMessageStr(rm), WM->strLastHearMessage);
00426       pm = SoccerTypes::getPlayModeFromRefereeMessage( rm );// get play mode
00427       if( pm != PM_ILLEGAL )                                // from ref msg
00428         WM->setPlayMode( pm );                              // if was pm, set it
00429 
00430       if( rm == REFC_GOAL_LEFT )                            // goal left
00431       {
00432         if( WM->getSide() == SIDE_LEFT )
00433           WM->addOneToGoalDiff();
00434         else
00435           WM->subtractOneFromGoalDiff();
00436         WM->processSeeGlobalInfo( OBJECT_BALL, time, VecPosition( 0, 0 ),
00437              VecPosition( 0, 0 ), 0, 0 );
00438       }
00439       else if( rm == REFC_GOAL_RIGHT )                      // goal right
00440       {
00441         if( WM->getSide() == SIDE_RIGHT )
00442           WM->addOneToGoalDiff();
00443         else
00444           WM->subtractOneFromGoalDiff();
00445         WM->processSeeGlobalInfo( OBJECT_BALL, time, VecPosition( 0, 0 ),
00446              VecPosition( 0, 0 ), 0, 0 );
00447       }
00448       else if( rm == REFC_GOALIE_CATCH_BALL_LEFT ||         // catch ball
00449                rm == REFC_GOALIE_CATCH_BALL_RIGHT )
00450         WM->processCatchedBall( rm, time );
00451       break;
00452     case 's':                                               // self
00453       break;                                                // do nothing
00454     default:                                                // from direction
00455         analyzePlayerMessage( strMsg );                     // from player
00456       break;
00457   }
00458 
00459   return true;
00460 }
00461 
00467 bool SenseHandler::analyzePlayerMessage( char *strMsg )
00468 {
00469   Parse::gotoFirstNonSpace( &strMsg );            // skip space
00470   
00471   if( WM->getPlayerNumber() == 0 )                // if i am coach
00472     return false;                                 //   skip message
00473   if( strlen( strMsg ) < 2 || strMsg[0] == 'o' )  // skip message since no dir.
00474     return false;                                 // thus no content
00475 
00476   Parse::parseFirstInt( &strMsg );                // skip direction
00477   Parse::gotoFirstNonSpace( &strMsg );            // skip space  
00478   if( strlen( strMsg ) < 2 || strMsg[1] == 'p' )  // skip message when from opp
00479     return false;                                 
00480 
00481   int iPlayer = Parse::parseFirstInt( &strMsg );  // get player number
00482   Parse::gotoFirstNonSpace( &strMsg );            // skip space  
00483   strMsg++;                                       // skip " (=quote)
00484 
00485   if( strlen( strMsg ) < 4 )              // < 2 + two ending charactres ")
00486     return false;
00487 
00488   WM->storePlayerMessage( iPlayer, strMsg, WM->getCurrentCycle() );
00489   return true;
00490 }
00491 
00492 
00499 bool SenseHandler::analyzeCheckBall( char *strMsg )
00500 {
00501   WM->setTimeCheckBall( Parse::parseFirstInt( &strMsg ) );
00502   strMsg++;
00503   WM->setCheckBallStatus( SoccerTypes::getBallStatusFromStr( strMsg ) );
00504   return true;
00505 }
00506 
00513 bool SenseHandler::analyzeChangePlayerTypeMessage( char *strMsg )
00514 {
00515   int iPlayer = Parse::parseFirstInt( &strMsg );
00516   if( *strMsg != ')' && WM->getPlayerNumber() == iPlayer )
00517   {
00518     int iPlayerType = Parse::parseFirstInt( &strMsg );
00519     return WM->updateSSToHeteroPlayerType( iPlayerType );
00520   }
00521   return false;
00522 }
00523 
00530 bool SenseHandler::analyzeServerParamMessage( char *strMsg )
00531 {
00532 //  cout << strMsg << endl;
00533   readServerParam( "goal_width",               strMsg );
00534   readServerParam( "player_size",              strMsg );
00535   readServerParam( "player_decay",             strMsg );
00536   readServerParam( "player_rand",              strMsg );
00537   readServerParam( "player_weight",            strMsg );
00538   readServerParam( "player_speed_max",         strMsg );
00539   readServerParam( "player_accel_max",         strMsg );
00540   readServerParam( "stamina_max",              strMsg );
00541   readServerParam( "stamina_inc_max",          strMsg );
00542   readServerParam( "recover_dec_thr",          strMsg );
00543   readServerParam( "recover_min",              strMsg );
00544   readServerParam( "recover_dec",              strMsg );
00545   readServerParam( "effort_dec_thr",           strMsg );
00546   readServerParam( "effort_min",               strMsg );
00547   readServerParam( "effort_dec",               strMsg );
00548   readServerParam( "effort_inc_thr",           strMsg );
00549   readServerParam( "effort_inc",               strMsg );
00550   readServerParam( "kick_rand",                strMsg );
00551   readServerParam( "ball_size",                strMsg );
00552   readServerParam( "ball_decay",               strMsg );
00553   readServerParam( "ball_rand",                strMsg );
00554   readServerParam( "ball_weight",              strMsg );
00555   readServerParam( "ball_speed_max",           strMsg );
00556   readServerParam( "ball_accel_max",           strMsg );
00557   readServerParam( "dash_power_rate",          strMsg );
00558   readServerParam( "kick_power_rate",          strMsg );
00559   readServerParam( "kickable_margin",          strMsg );
00560   readServerParam( "catch_probability",        strMsg );
00561   readServerParam( "catchable_area_l",         strMsg );
00562   readServerParam( "catchable_area_w",         strMsg );
00563   readServerParam( "goalie_max_moves",         strMsg );
00564   readServerParam( "maxpower",                 strMsg );
00565   readServerParam( "minpower",                 strMsg );
00566   readServerParam( "maxmoment",                strMsg );
00567   readServerParam( "minmoment",                strMsg );
00568   readServerParam( "maxneckmoment",            strMsg );
00569   readServerParam( "minneckmoment",            strMsg );
00570   readServerParam( "maxneckang",               strMsg );
00571   readServerParam( "minneckang",               strMsg );
00572   readServerParam( "visible_angle",            strMsg );
00573   readServerParam( "visible_distance",         strMsg );
00574   readServerParam( "audio_cut_dist",           strMsg );
00575   readServerParam( "quantize_step",            strMsg );
00576   readServerParam( "quantize_step_l",          strMsg );
00577   readServerParam( "ckick_margin",             strMsg );
00578   readServerParam( "wind_dir",                 strMsg );
00579   readServerParam( "wind_force",               strMsg );
00580   readServerParam( "wind_rand",                strMsg );
00581   readServerParam( "wind_random",              strMsg );  
00582   readServerParam( "inertia_moment",           strMsg );
00583   readServerParam( "half_time",                strMsg );
00584   readServerParam( "drop_ball_time",           strMsg );
00585   readServerParam( "port",                     strMsg );
00586   readServerParam( "coach_port",               strMsg );
00587   readServerParam( "olcoach_port",             strMsg );
00588   readServerParam( "say_coach_cnt_max",        strMsg );
00589   readServerParam( "say_coach_msg_size",       strMsg );
00590   readServerParam( "simulator_step",           strMsg );
00591   readServerParam( "send_step",                strMsg );
00592   readServerParam( "recv_step",                strMsg );
00593   readServerParam( "sense_body_step",          strMsg );
00594   readServerParam( "say_msg_size",             strMsg );
00595   readServerParam( "clang_win_size",           strMsg );
00596   readServerParam( "clang_define_win",         strMsg );
00597   readServerParam( "clang_meta_win",           strMsg );
00598   readServerParam( "clang_advice_win",         strMsg );
00599   readServerParam( "clang_info_win",           strMsg );
00600   readServerParam( "clang_mess_delay",         strMsg );
00601   readServerParam( "clang_mess_per_cycle",     strMsg );
00602   readServerParam( "hear_max",                 strMsg );
00603   readServerParam( "hear_inc",                 strMsg );
00604   readServerParam( "hear_decay",               strMsg );
00605   readServerParam( "catch_ban_cycle",          strMsg );
00606   readServerParam( "send_vi_step",             strMsg );
00607   readServerParam( "use_offside",              strMsg );
00608   readServerParam( "offside_active_area_size", strMsg );
00609   readServerParam( "forbid_kick_off_offside",  strMsg );
00610   readServerParam( "verbose",                  strMsg );
00611   readServerParam( "offside_kick_margin",      strMsg );
00612   readServerParam( "slow_down_factor",         strMsg );
00613 
00614   SS->setMaximalKickDist      ( SS->getKickableMargin() +
00615                                 SS->getPlayerSize()     +
00616                                 SS->getBallSize()          );
00617   return true;
00618 }
00619 
00628 bool SenseHandler::readServerParam( char *strParam, char *strMsg )
00629 {
00630   char strFormat[128];
00631   char strValue[128] = "";
00632   sprintf( strValue, "none" );
00633 
00634   sprintf( strFormat, "%s ", strParam );        // add space after parameters
00635   char *str = strstr( strMsg, strFormat );      // and find param definition
00636   sprintf( strFormat, "%s %%[^)]", strParam );  // read till closing bracket
00637 
00638   if( str == NULL )
00639   {
00640     cerr << "(SenseHandler::readServerParam) error finding " << strParam <<endl;
00641     return false;
00642   }
00643   int ret = sscanf( str, strFormat, strValue ); // read in values
00644 
00645   if( ret == 1 )
00646     SS->setValue( strParam, strValue );
00647   else
00648     cerr << "(SenseHandler::readServerParam) error reading " << strParam <<endl;
00649   return (ret == 1 ) ? true : false ;
00650 }
00651 
00652 
00659 bool SenseHandler::analyzePlayerTypeMessage ( char *strMsg )
00660 {
00661 // cerr << strMsg << endl;
00662 
00663   // analyze all heterogeneous player information
00664   int    iIndex           = Parse::parseFirstInt( &strMsg );
00665   double dPlayerSpeedMax  = Parse::parseFirstDouble( &strMsg );
00666   double dStaminaIncMax   = Parse::parseFirstDouble( &strMsg );
00667   double dPlayerDecay     = Parse::parseFirstDouble( &strMsg );
00668   double dInertiaMoment   = Parse::parseFirstDouble( &strMsg );
00669   double dDashPowerRate   = Parse::parseFirstDouble( &strMsg );
00670   double dPlayerSize      = Parse::parseFirstDouble( &strMsg );
00671   double dKickableMargin  = Parse::parseFirstDouble( &strMsg );
00672   double dKickRand        = Parse::parseFirstDouble( &strMsg );
00673   double dExtraStamina    = Parse::parseFirstDouble( &strMsg );
00674   double dEffortMax       = Parse::parseFirstDouble( &strMsg );
00675   double dEffortMin       = Parse::parseFirstDouble( &strMsg );
00676 
00677   WM->processNewHeteroPlayer( iIndex, dPlayerSpeedMax, dStaminaIncMax,
00678       dPlayerDecay,    dInertiaMoment, dDashPowerRate, dPlayerSize,
00679       dKickableMargin, dKickRand,      dExtraStamina,  dEffortMax,
00680       dEffortMin );
00681   return true;
00682 }
00683 
00689 bool SenseHandler::analyzePlayerParamMessage( char *strMsg )
00690 {
00691 // cerr << strMsg << endl;
00692   readServerParam( "player_types",                     strMsg );
00693   readServerParam( "subs_max",                         strMsg );
00694   readServerParam( "player_speed_max_delta_min",       strMsg );
00695   readServerParam( "player_speed_max_delta_max",       strMsg );
00696   readServerParam( "stamina_inc_max_delta_factor",     strMsg );
00697   readServerParam( "player_decay_delta_min",           strMsg );
00698   readServerParam( "player_decay_delta_max",           strMsg );
00699   readServerParam( "inertia_moment_delta_factor",      strMsg );
00700   readServerParam( "dash_power_rate_delta_min",        strMsg );
00701   readServerParam( "dash_power_rate_delta_max",        strMsg );
00702   readServerParam( "player_size_delta_factor",         strMsg );
00703   readServerParam( "kickable_margin_delta_min",        strMsg );
00704   readServerParam( "kickable_margin_delta_max",        strMsg );
00705   readServerParam( "kick_rand_delta_factor",           strMsg );
00706   readServerParam( "extra_stamina_delta_min",          strMsg );
00707   readServerParam( "extra_stamina_delta_max",          strMsg );
00708   readServerParam( "effort_max_delta_factor",          strMsg );
00709   readServerParam( "effort_min_delta_factor",          strMsg );
00710   readServerParam( "new_dash_power_rate_delta_min",    strMsg );
00711   readServerParam( "new_dash_power_rate_delta_max",    strMsg );
00712   readServerParam( "new_stamina_inc_max_delta_factor", strMsg );
00713 
00714   return true;
00715 }
00716 
00717 /******************************************************************************/
00718 /********************** TESTING PURPOSES **************************************/
00719 /******************************************************************************/
00720 
00721 /*
00722 int main( void )
00723 {
00724   Connection c( "localhost", 6000 );
00725   WorldModel wm;
00726   SenseHandler i( &c,  &wm );
00727   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))" );
00728    cout << "2" << endl;
00729   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))" );
00730   c.disconnect();
00731   cout << "exit" << endl ;
00732 
00733 }
00734 
00735 */

Generated on Tue Jul 2 10:18:53 2002 for UvA Trilearn 2002 by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001