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

📄 basicplayer.cpp

📁 自己写的robocup-2d程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    return SoccerCommand( CMD_ATTENTIONTO, -1.0, -1.0 );

  return SoccerCommand( CMD_ATTENTIONTO,
     1.0,                                       // 1.0 denotes our team
     SoccerTypes::getIndex( obj ) + 1 );
}

/*! This method returns the command to tackle the ball. */
SoccerCommand BasicPlayer::tackle( )
{
  return SoccerCommand( CMD_TACKLE, 100.0 );
}

/********************** INTERMEDIATE LEVEL SKILLS ****************************/

/*! This skill enables an agent to turn his body towards an object o which is
    supplied to it as an argument. To this end the object's global position
    o in the next cycle is predicted based on its current velocity.
    This predicted position is passed as an argument to the turnBodyToPoint
    skill which generates a turn command that causes the agent to turn his
    body towards the object.
    \param o object to which agent wants to turn
    \return SoccerCommand that turns to this object */
SoccerCommand BasicPlayer::turnBodyToObject( ObjectT o )
{
  return turnBodyToPoint( WM->predictPosAfterNrCycles(o, 1) );
}

///*! This skill enables an agent to turn his neck towards an object. It
//    receives as arguments this object o as well as a primary action command
//    'soc' that will be executed by the agent at the end of the current cycle.
//    Turning the neck towards an object amounts to predicting the object's
//    global position in the next cycle and passing this predicted position
//    together with the 'soc' command as arguments to the turnNeckToPoint skill.
//    This low-level skill will then generate a turn neck command that causes the
//    agent to turn his neck towards the given object. Note that the 'soc'
//    command is supplied as an argument for predicting the agent's global
//    position and neck angle after executing the command. This is necessary
//    because a turn neck command can be executed in the same cycle as a kick,
//    dash, turn , move or catch command.
//   \param o object to which the agent wants to turn his neck
//   \param soc SoccerCommand that is performed in this cycle.
//   \return SoccerCommand that turns the neck of the agent to this object */
//SoccerCommand BasicPlayer::turnNeckToObject( ObjectT o, SoccerCommand soc )
//{
//  return turnNeckToPoint( WM->predictPosAfterNrCycles(o, 1), soc );
//}

SoccerCommand BasicPlayer::directTowards( VecPosition posTurnTo,
   AngDeg angWhenToTurn, VecPosition *pos, VecPosition *vel, AngDeg *angBody  )
{
//  return turnBodyToPoint( posTurnTo );
  // copy values or initialize when not set
  VecPosition posAgent= (pos    ==NULL)?WM->getAgentGlobalPosition ():*pos;
  VecPosition velAgent= (vel    ==NULL)?WM->getAgentGlobalVelocity ():*vel;
  AngDeg  angBodyAgent= (angBody==NULL)?WM->getAgentGlobalBodyAngle():*angBody;

  // first predict what happens when the agents rolls out.
  VecPosition posPred    = WM->predictFinalAgentPos();
  AngDeg      angTo      = ( posTurnTo - posPred ).getDirection();
  AngDeg      ang        = VecPosition::normalizeAngle( angTo - angBodyAgent );
  AngDeg      angNeck = 0;

  int iTurn = 0;
  while( fabs( ang ) > angWhenToTurn && iTurn < 5 )
  {
    iTurn++;
    WM->predictStateAfterTurn(
          WM->getAngleForTurn( ang, velAgent.getMagnitude() ),
          &posAgent,
          &velAgent,
          &angBodyAgent,
          &angNeck );
    ang = VecPosition::normalizeAngle( angTo - angBodyAgent );
  }
  Log.log( 509, "direct towards: %d turns", iTurn );
  posAgent = (pos    ==NULL)?WM->getAgentGlobalPosition ():*pos;  
  velAgent = (vel    ==NULL)?WM->getAgentGlobalVelocity ():*vel;      
  angBodyAgent = (angBody==NULL)?WM->getAgentGlobalBodyAngle():*angBody;

  switch( iTurn )
  {
    case 0:   cerr << "direct towards: 0 turns" ;
              return SoccerCommand( CMD_ILLEGAL );
    case 1: 
    case 2:   return turnBodyToPoint( posTurnTo, 2 );
    default:  return dashToPoint( 
             (pos==NULL)?WM->getAgentGlobalPosition ():*pos   );  // stop
  }
}

/*! This skill enables an agent to move to a global position 'pos' on
    the field which is supplied to it as an argument. Since the agent
    can only move forwards or backwards into the direction of his
    body, the crucial decision in the execution of this skill is
    whether he should perform a turn or a dash. Turning has the
    advantage that in the next cycle the agent will be orientated
    correctly towards the point he wants to reach. However, it has the
    disadvantage that performing the turn will cost a cycle and will
    reduce the agent's velocity since no acceleration vector is added
    in that cycle.  Apart from the target position 'pos', this skill
    receives several additional arguments for determining whether a
    turn or dash should be performed in the current situation. If the
    target point is in front of the agent then a dash is performed
    when the relative angle to this point is smaller than a given
    angle 'angWhenToTurn'. However, if the target point is behind the
    agent then a dash is only performed if the distance to point is
    less than a given value 'dDistBack' and if the angle relative to
    the back direction of the agent is smaller than
    'angWhenToTurn'. In all other cases a turn is performed. Note that
    in the case of the goalkeeper it is sometimes desirable that he
    moves backwards towards his goal in order to keep sight of the
    rest of the field. To this end an additional boolean argument
    'bMoveBack' is supplied to this skill that indicates whether the
    agent should always move backwards to the target point. If this
    value equals true then the agent will turn his back towards the
    target point if the angle relative to his back direction is larger
    than 'angToTurn'. In all other cases he will perform a (backward)
    dash towards 'posTo' regardless of whether the distance to this
    point is larger than 'dDistBack'.

    \param posTo global target position to which the agent wants to move
    \param angWhenToTurn angle determining when turn command is returned
    \param dDistBack when posTo lies closer than this value to the back of
          the agent (and within angWhenToTurn) a backward dash is returned
    \param bMoveBack boolean determing whether to move backwards to 'posTo'
    \return SoccerCommand that determines next action to move to 'posTo' */
SoccerCommand BasicPlayer::moveToPos( VecPosition posTo, AngDeg angWhenToTurn,
                            double dDistBack, bool bMoveBack, int iCycles )
{
// previously we only turned relative to position in next cycle, now take
// angle relative to position when you're totally rolled out...
//  VecPosition posPred   = WM->predictAgentPos( 1, 0 );
  VecPosition posAgent  = WM->getAgentGlobalPosition();
  VecPosition posPred   = WM->predictFinalAgentPos();
  
  AngDeg      angBody   = WM->getAgentGlobalBodyAngle();
  AngDeg      angTo     = ( posTo - posPred ).getDirection();
              angTo     = VecPosition::normalizeAngle( angTo - angBody );
  AngDeg      angBackTo = VecPosition::normalizeAngle( angTo + 180 );
  
  double      dDist     = posAgent.getDistanceTo( posTo );

  Log.log( 509, "moveToPos (%f,%f): body %f to %f diff %f now %f when %f", 
          posTo.getX(), posTo.getY(), angBody, 
           ( posTo - posPred ).getDirection(), angTo, 
           ( posTo -  WM->predictAgentPos( 1, 0 )).getDirection(),
           angWhenToTurn );
  if( bMoveBack )
  {
    if( fabs( angBackTo ) < angWhenToTurn )
      return dashToPoint( posTo, iCycles );
    else
      return turnBackToPoint( posTo );
  }
  else if(  fabs( angTo     ) < angWhenToTurn ||
           (fabs( angBackTo ) < angWhenToTurn && dDist < dDistBack ) )
    return dashToPoint( posTo, iCycles );
  else
    return directTowards( posTo, angWhenToTurn );
//return turnBodyToPoint( posTo );
}


/*! This method returns a command that can be used to collide with the ball
    on purpose. When this is not possible. CMD_ILLEGAL is returned. Colliding
    with the ball may be useful when the player is turned with his back to the
    opponent goal and is intercepting a moving ball, by colliding both the ball
    and the player will loose all their velocity. Now the player can turn at
    once to the desired direction. Otherwise he first has to freeze the ball,
    freeze his own speed and then turn around. */
SoccerCommand BasicPlayer::collideWithBall( )
{
  SoccerCommand soc( CMD_ILLEGAL );
  if( WM->getRelativeDistance( OBJECT_BALL ) > 
      WM->getBallSpeed() + SS->getPlayerSpeedMax() )
    return soc;
   
  VecPosition posBallPred  = WM->predictPosAfterNrCycles( OBJECT_BALL, 1 );
  
  // first try turn
  soc                      = turnBodyToPoint( WM->getAgentGlobalPosition() + 
                                              VecPosition( 1, 0, POLAR ) );
  VecPosition posAgentPred = WM->predictAgentPosAfterCommand( soc );
  if( posAgentPred.getDistanceTo( posBallPred ) < 
      SS->getBallSize() + SS->getPlayerSize() )
  {
    Log.log( 511, "can collide with ball by turning" );
    return soc;
  }
                               
  soc          = dashToPoint( posBallPred, 1 );
  posAgentPred = WM->predictAgentPosAfterCommand( soc );
  if( posAgentPred.getDistanceTo( posBallPred ) < 
      SS->getBallSize() + SS->getPlayerSize() )
  {
    Log.log( 511, "can collide with ball by dashing %f", soc.dPower );
    return soc;
  }
    
  return SoccerCommand( CMD_ILLEGAL );  
}
/*! This skill enables an agent to intercept a ball which is close to him. The
    objective is to move in such a way that the ball will come within the
    kickable distance from the agent in one or two cycles. To this end the
    prediction methods from the world model are used to predict the ball
    position in the next cycle and two cycles into the future. It is then
    determined whether it is possible to move the agent within kickable
    distance from one of these positions using all logical combinations of
    turn and dash commands. If it is not possible to intercept the ball within
    two cycles then this skill returns an illegal command to indicate that
    it cannot be performed. First it is determined whether the agent can
    intercept the ball in one cycle. To this end the position of the ball in
    the next cycle is predicted and a calculation is performed to decide
    whether a single dash can move the agent within the kickable distance from
    this position. In order to be able to kick the ball efficiently after
    intercepting it, it is important that the agent moves to a good position
    relative to the ball (i.e. the ball must be in front of him). At the same
    time the agent must make sure that he does not collide with the ball when
    trying to intercept it. Let l be a line that runs forwards and backwards
    from the predicted position of the agent in the next cycle into the
    direction of his body. This line thus denotes the possible movement
    direction of the agent. Note that we have to use the agent's predicted
    position in the next cycle since his current velocity must be taken into
    account. In addition, let c be a circle which is centered on the predicted
    ball position and which has a radius equal to the sum of the radius of the
    agent, the radius of the ball and a small buffer (kickable margin/6). It
    is now determined whether the agent can intercept the ball in the next
    cycle by looking at the number of intersection points between l and c. If
    l and c have exactly one point in common then this point is the desired
    interception point for the next cycle. However, if the number of
    intersection points equals two then the desired point is the one for
    which the absolute angle of the ball relative to that point is the
    smallest. This amounts to the intersection point which is closest to
    the agent when the ball lies in front of him and to the furthest one when
    the ball is behind his back. As a result, the desired interception point
    will always be such that the agent has the ball in front of him in the
    next cycle. Then a dash command is generated
    that will bring the agent as close as possible to the desired point.
    Next, the position of the agent after executing this command is predicted
    and if it turns out that this predicted position lies within the kickable
    distance from the ball then the dash is performed. However, if the
    predicted position is not close enough to the ball or if l and c have no
    points in common then it is assumed that the ball cannot be intercepted
    with a single dash. In these cases, two alternatives are explored to see
    if the ball can be intercepted in two cycles.
    The first alternative is to determine whether the agent can intercept the
    ball by performing a turn followed by a dash. To this end the global
    position of the ball is predicted two cycles into the future and a turn
    command is generated that will turn
    the agent towards this point. The agent's position after executing this
    command is then predicted after which a dash command is generated
    that will bring the agent as close as possible to
    the predicted ball position in two cycles. If it turns out that the
    predicted position of the agent after the dash lies within kickable
    distance from the ball then the first command (i.e. the turn) in the
    sequence of two is performed. Otherwise, a second alternative is tried to
    determine whether the agent can intercept the ball by performing two dash

⌨️ 快捷键说明

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