⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sensehandler.cpp

📁 2003年RoboCup仿真组世界冠军源代码 足球机器人 仿真组 的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*Copyright (c) 2000-2003, Jelle Kok, University of AmsterdamAll rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions are met:1. Redistributions of source code must retain the above copyright notice, thislist of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice,this list of conditions and the following disclaimer in the documentationand/or other materials provided with the distribution.3. Neither the name of the University of Amsterdam nor the names of itscontributors may be used to endorse or promote products derived from thissoftware without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLEFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIALDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ORSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVERCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USEOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*//*! \file SenseHandler.cpp<pre><b>File:</b>          SenseHandler.cpp<b>Project:</b>       Robocup Soccer Simulation Team: UvA Trilearn<b>Authors:</b>       Jelle Kok<b>Created:</b>       28/11/2000<b>Last Revision:</b> $ID$<b>Contents:</b>      This file contains the class SenseHandler that is used               to process the information coming from the server.<hr size=2><h2><b>Changes</b></h2><b>Date</b>             <b>Author</b>          <b>Comment</b>28/11/2000       Jelle Kok       Initial version created</pre>*/#include "SenseHandler.h"#include "ActHandler.h"  // sigalarmHandler#include "Parse.h"#include <signal.h>   // needed for SIGALARM#include <string.h>   // needed for strlen#include <stdio.h>    // needed for printf#include <iostream>   // needed for cout/*****************************************************************************//********************* CLASS SENSEHANDLER ************************************//*****************************************************************************//*! This function is needed to start the Sense Thread (thread that continually    waits for input and parses the input). This function is needed since it is    not possible to call a method from a class using a thread. So this function    calls handleMessagesFromServer from the SenseHandler class.    \param v pointer to a SenseHandler class.*/#ifdef WIN32DWORD WINAPI sense_callback( LPVOID v )#elsevoid* sense_callback( void *v )#endif{  Log.log( 1, "Starting to listen for server messages" );  SenseHandler* s = (SenseHandler*)v;  s->handleMessagesFromServer( );  return NULL;}/*! Constructor for the SenseHandler. It needs a reference to a connection and    a reference to a worldmodel.    \param c Connection from which input is received    \param wm WorldModel to which new information will be sent for processing    \param ss ServerSettings that contain the parameters used by the server    \param ps PlayerSettings that determine how to interact with messages. */SenseHandler::SenseHandler( Connection *c, WorldModel *wm, ServerSettings *ss,                            PlayerSettings *ps ){  connection             = c;  SS                     = ss;  PS                     = ps;  WM                     = wm;  iSimStep               = SS->getSimulatorStep()*1000;  iTimeSignal            = (int)(iSimStep*0.85);#ifdef WIN32  TIMECAPS tc;  UINT     resolution = 1;   // timer resolution for the application (ms)  iTimer = NULL;  // set the minimum timer resolution for an application  if (TIMERR_NOERROR == timeGetDevCaps( &tc, sizeof(TIMECAPS) ))  {    timerRes = min( max( tc.wPeriodMin, resolution ), tc.wPeriodMax );    timeBeginPeriod( timerRes );  }#else  struct sigaction sigact;  sigact.sa_flags = SA_RESTART; // do not unblock primitives (like recvfrom)  sigact.sa_handler = (void (*)(int))sigalarmHandler;  sigaction( SIGALRM, &sigact, NULL );  // set timer signal to indicate when ActHandler should sent commands to the  // server, this structure will later be filled with exact timing values  itv.it_interval.tv_sec  = 0;  itv.it_interval.tv_usec = 0;  itv.it_value.tv_sec     = 0;  itv.it_value.tv_usec    = 0;#endif}/*! This is the main routine of this class. It loops forever (till the thread    is destroyed) and receives and parses the incoming messages.   */void SenseHandler::handleMessagesFromServer( ){  char strBuf[MAX_MSG];  int i=0;  while( 1 )  {    strBuf[0]='\0';    if( i != -1 )                                         // if no error      i = connection->receiveMessage( strBuf, MAX_MSG );  // get message    if( strBuf[0] != '\0' )                               // if not empty      analyzeMessage( strBuf );                           // parse message  }}/*! This method sets the time signal. This is the time that should be    waited before the next action should be sent to the server. As    soon as a sense message arrives this method is called. Using the    information from the member variable 'iTriCounter' which denotes    when the see message will arrive in this cycle (0=first half,    1=2nd half, 2=no see, all for the default view frequency) the    timer is set. The values that denote the fraction of the    simulation step that is waited are all defined in PlayerSettings,    such that they can be easily changed. */void SenseHandler::setTimeSignal( ){  if( WM->getAgentViewFrequency() == 1.0 ) // VA_NORMAL AND VQ_HIGH (default)  {    if( iTriCounter % 3 == 0 )             // see will arrive first half cycle    {      iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeBegin() );      iTriCounter = 0;    }    else if( iTriCounter % 3 == 1 )        // see will arrive 2nd half of cycle    {      iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );    }    else                                   // no see will arrive      iTimeSignal = (int)(iSimStep * PS->getFractionWaitNoSee( ) );  }  else if( WM->getAgentViewFrequency() == 2.0 ) // VA_WIDE AND VQ_HIGH  {    if( iTriCounter % 3 == 0 )              // see will arrive    {      iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );      iTriCounter = 0;    }    else                                   // no see will arrive      iTimeSignal = (int)(iSimStep * PS->getFractionWaitNoSee() );  }  else                                     // VA_NARROW AND VQ_HIGH    iTimeSignal = (int)(iSimStep * PS->getFractionWaitSeeEnd() );  iTriCounter++;#ifdef WIN32  // kill the previous timer  if (iTimer != NULL) timeKillEvent( iTimer );  // start a new one  iTimer = timeSetEvent( iTimeSignal / 1000, timerRes,                         sigalarmHandler, (DWORD)0, TIME_ONESHOT );#else  itv.it_value.tv_usec = iTimeSignal;  setitimer( ITIMER_REAL, &itv, NULL );#endif}/*! This method analyzes the type of the incoming message and calls the    message that corresponds to this message.    \param strMsg message that should be parsed.    \return bool indicating whether the message was parsed or not */bool SenseHandler::analyzeMessage( char *strMsg ){  Log.log( 1, strMsg );  bool bReturn = false;    switch( strMsg[1] )  {    case 'c':        if( strMsg[2] == 'h' )          return analyzeChangePlayerTypeMessage( strMsg );      // ( c hange_        else          ;                                                    // (clang        break;    case 'f':          return analyzeFullStateMessage( strMsg );      // ( f ullstate_    case 'o':                                                 // ( o k        if( strlen(strMsg) > 14 && strMsg[4] == 'c' && strMsg[10] == 'b' )          analyzeCheckBall( strMsg );                         // (ok check_ball        return true;    case 's':    {      switch( strMsg[3] )      {      case 'e':        if( strMsg[5] == 'g')          return analyzeSeeGlobalMessage  ( strMsg ); // (se e_g        else if( WM->isFullStateOn( ) == false )          return analyzeSeeMessage        ( strMsg ); // (se e        break;                        case 'n':         bReturn = analyzeSenseMessage      ( strMsg ); // (se n se        if( WM->isFullStateOn( ) == true  )          WM->updateAfterSenseMessage( );        return bReturn;         break;      case 'r': return analyzeServerParamMessage( strMsg ); // (se r ver_param      default : break;      }    }        break;    case 'i':     return analyzeInitMessage       ( strMsg ); // ( i nit    case 'h':     return analyzeHearMessage       ( strMsg ); // ( h ear    case 'p':     return ( strMsg[8] == 't')                  ? analyzePlayerTypeMessage ( strMsg )  // (player_ t ype                  : analyzePlayerParamMessage( strMsg ); // (player_ p aram    case 'e':     printf("(%d,%d) %s\n", WM->getCurrentCycle(),                           WM->getPlayerNumber(),strMsg);// ( error        break;    case 't':     Log.logWithTime( 2, " incoming think message" );                  WM->processRecvThink( true );          // ( think        break;    default:      cerr << "(" << WM->getCurrentTime() << ", " <<                        WM->getPlayerNumber()                        << ") (SenseHandler::analyzeMessage) " <<                     "ignored message: " << strMsg << "\n";                  return false;  }  return false;}/*! This method analyzes a see Message. It gets the time from the message and    tries to synchronize with the server. Then the message is stored in the    world model, which processes it when it performs an update.    \return bool indicating whether the message was parsed correctly. */bool SenseHandler::analyzeSeeMessage( char *strMsg ){  strcpy( WM->strLastSeeMessage, strMsg );  Log.logWithTime( 2, " %s",strMsg );  if( WM->getRelativeDistance( OBJECT_BALL ) < SS->getVisibleDistance() )    Log.logWithTime( 560, "%s", WM->strLastSeeMessage );  Time    time = WM->getTimeLastRecvSenseMessage();  int iTime = Parse::parseFirstInt( &strMsg );         // get the time  if( time.getTime() != iTime )  {    cerr << "(SenseHandler:analyzeSeeMessage) see and different time as sense:"         << time.getTime() << " vs. " << iTime << endl;    return false;  }  // count number of see message in this cycle  if( WM->getTimeLastSeeMessage() == time )    m_iSeeCounter++;  else    m_iSeeCounter = 1;  // do nothing with second see, since it adds nothings  if( m_iSeeCounter >= 2 )  {    Log.logWithTime( 4, "second see message in cycle; do nothing " );    return true;  }  // reset the send pattern when previous cycle(s) no see arrived  if( WM->getAgentViewFrequency() == 1.0 && // VA_NORMAL; previous cycle no see      time.getTimeDifference( WM->getTimeLastSeeMessage() )== 2 )    iTriCounter = 1;                // see will arive in 2nd half in next cycle  else if( WM->getAgentViewFrequency() == 2.0 && // VA_WIDE; two cycles no see           time.getTimeDifference( WM->getTimeLastSeeMessage() ) == 3 )    iTriCounter = 1;                // no see will arrive next two cycles  WM->setTimeLastSeeMessage( time );   // set time of last see message  return true;}/*! This method analyzes a see Message. All information from the different    objects that is stored in a see message is send to worldmodel.    A see message looks like(see 0 ((g r) 64.1 13) ((f r t) 65.4 -16) ....    \param strMsg message that should be parsed    \return bool indicating whether the message was parsed correctly. */bool SenseHandler::analyzeSeeGlobalMessage( char *strMsg ){  Log.logWithTime( 2, " incoming see global message" );  strcpy( WM->strLastSeeMessage, strMsg );  ObjectT o;  bool    isGoalie;  double  dX, dY, dVelX, dVelY;  int     iTime;  AngDeg  angBody, angNeck;  Time    time = WM->getCurrentTime();  iTime = Parse::parseFirstInt( &strMsg );         // get the time  time.updateTime( iTime );  while( *strMsg != ')' )                          // " ((objname.." or ")"  {    dVelX = dVelY = UnknownDoubleValue;    angBody = angNeck = UnknownAngleValue;    strMsg += 2;          // go the start of the object name

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -