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

📄 basicplayer.c

📁 机器足球2D比赛程序 对trlen_base_2002的改进
💻 C
📖 第 1 页 / 共 5 页
字号:
    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    commands. To this end two dash commands are generated to get closer to the    predicted ball position after two cycles.    If the predicted position of the agent after these two dashes lies within    kickable distance from the ball then the first dash is performed.    Otherwise, an illegal command is returned to indicate that the skill    cannot be performed. The close interception procedure is heavily based on    a similar method introduced in CMU'99 by Peter Stone.    \return command to intercept ball in two cycles, CMD_ILLEGAL otherwise */SoccerCommand BasicPlayer::interceptClose( ){  SoccerCommand soc;  double        dPower, dDist;  AngDeg        ang,    ang2;  VecPosition   s1,     s2;  // first determine whether the distance to the ball is not too large  dDist = 2*SS->getPlayerSpeedMax()          + (1.0 + SS->getBallDecay())*SS->getBallSpeedMax()          + SS->getMaximalKickDist();  if( WM->getRelativeDistance( OBJECT_BALL ) > dDist )    return SoccerCommand( CMD_ILLEGAL );  // initialize all variables with information from the worldmodel.  VecPosition   posAgent = WM->getAgentGlobalPosition( );  VecPosition   posPred  = WM->predictAgentPos( 1, 0 );  VecPosition   posBall  = WM->predictPosAfterNrCycles( OBJECT_BALL, 1 );  VecPosition   velMe    = WM->getAgentGlobalVelocity( );  Stamina       sta      = WM->getAgentStamina( );  AngDeg        angBody  = WM->getAgentGlobalBodyAngle( );  // make a line from center of body in next cycle with direction of body  // use next cycle since current velocity is always propogated to position in  // next cycle.  Make a circle around the ball with a radius equal to the  // sum of your own body, the ball size and a small buffer. Then calculate  // the intersection between the line and this circle. These are the (two)  // points that denote the possible agent locations close to the ball  // From these two points we take the point where the body direction of the  // agent makes the smallest angle with the ball (with backward  // dashing we sometime have to dash "over" the ball to face it up front)  Line line = Line::makeLineFromPositionAndAngle(posPred,angBody);  dDist     = SS->getPlayerSize()+SS->getBallSize()+SS->getKickableMargin()/6;  int  iSol = line.getCircleIntersectionPoints( Circle(posBall,dDist), &s1, &s2);  if (iSol > 0)                                          // if a solution  {    if (iSol == 2)                                       // take the best one    {     ang  = VecPosition::normalizeAngle((posBall - s1).getDirection() -angBody);     ang2 = VecPosition::normalizeAngle((posBall - s2).getDirection() -angBody);     if ( fabs(ang2) < 90)       s1 = s2;                                          // and put it in s1    }    // try one dash    // now we have the interception point we try to reach in one cycle. We    // calculate the needed dash power from the current position to this point,    // predict were we will stand if we execute this command and check whether    // we are in the kickable distance    dPower  = WM->getPowerForDash(s1-posAgent, angBody, velMe,sta.getEffort() );    posPred = WM->predictAgentPos( 1, (int)dPower);    if ( posPred.getDistanceTo( posBall ) < SS->getMaximalKickDist() )      return SoccerCommand( CMD_DASH, dPower );  }  // try one dash by getting close to ball  // this handles situation where ball cannot be reached within distance  // SS->getKickableMargin()/6  soc = dashToPoint( posBall );  WM->predictAgentStateAfterCommand(soc,&posPred,&velMe,&angBody,&ang,&sta );  if ( posPred.getDistanceTo( posBall ) < SS->getMaximalKickDist() )    return soc;    // try turn and then dash  // first predict the angle between the agent and the ball after two cycles,  // is this larger than the angle when to turn, turn to position of the ball  // after two cycles. Then perform a dash based on the position of the ball  // after two cycles and the position of the agent after the turn. If after  // these two command the agent is in the kickable distance, return turn  // command.  posBall = WM->predictPosAfterNrCycles( OBJECT_BALL, 2 );  posPred = WM->predictAgentPos( 2, 0 );  ang     = (posBall - posPred).getDirection();  ang     = VecPosition::normalizeAngle( ang - angBody );  if (fabs( ang ) > PS->getPlayerWhenToTurnAngle() ) // if we want to turn  {    soc = turnBodyToPoint( posBall, 2 );             // perform turn    WM->predictAgentStateAfterCommand(soc,&posPred,&velMe,&angBody,&ang,&sta );    dPower = WM->getPowerForDash(posBall-posPred,angBody,velMe,sta.getEffort());    WM->predictStateAfterDash( dPower, &posPred, &velMe, &sta, angBody);    if (posPred.getDistanceTo(posBall) < SS->getMaximalKickDist())      return soc;  }  // try two dashes  // first predict the position in the next cycle when dash with full power  // is performed. Then calculate the dash power to reach the point where the  // ball will be in two cycles and predict the global position of the agent  // after a dash with this power. If the position is in the kickable distance  // return a dash with full power.  soc = SoccerCommand( CMD_DASH, SS->getMaxPower() );  WM->predictAgentStateAfterCommand(soc,&posPred,&velMe,&angBody,&ang,&sta );  dPower=WM->getPowerForDash(posBall-posPred,angBody,velMe,sta.getEffort());  WM->predictStateAfterDash( dPower, &posPred, &velMe, &sta, angBody );  if (posPred.getDistanceTo(posBall) < SS->getMaximalKickDist())    return soc;  // try three dashes  // same as with two dashes, but now try two maximum dashes and  posBall = WM->predictPosAfterNrCycles( OBJECT_BALL, 3 );  soc = SoccerCommand( CMD_DASH, SS->getMaxPower() );  WM->predictAgentStateAfterCommand(soc,&posPred,&velMe,&angBody,&ang,&sta );  WM->predictStateAfterCommand( soc, &posPred, &velMe, &angBody, &ang,&sta );  dPower=WM->getPowerForDash(posBall-posPred,angBody,velMe,sta.getEffort());  WM->predictStateAfterDash( dPower, &posPred, &velMe, &sta, angBody );  if (posPred.getDistanceTo(posBall) < SS->getMaximalKickDist())    return soc;  // cannot intercept ball in two cycles  return SoccerCommand( CMD_ILLEGAL );}/*! This skill enables a goalkeeper 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    catchable 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 the    catchable area 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 goalkeeper    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 catchable distance from    this position. If it turns out that this is the case, the corresponding    dash is performed. However, if the predicted position is not close enough    to the ball 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 two dash commands. To this end two dash commands are    generated. If the predicted position of the agent after these two    dashes lies within catchable distance from the ball then the first dash is    performed. Otherwise, a second alternative is tried 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. If it turns out that the predicted position of the agent    after the dash lies within catchable distance from the ball then the first    command (i.e. the turn) in the sequence of two is performed.    Otherwise, an illegal command is returned to indicate that the    skill cannot be performed. The close interception procedure is heavily    based on the method used by CMU'99 by Peter Stone.    \return command to intercept ball in two cycles, CMD_ILLEGAL otherwise */SoccerCommand BasicPlayer::interceptCloseGoalie( ){  SoccerCommand soc;  double        dPower, dDist;  AngDeg        ang;  VecPosition   posClosestToBall;  // initialize all variables with information from worldmodel.  VecPosition   posPred   = WM->predictAgentPos( 1, 0 );  VecPosition   posBall   = WM->predictPosAfterNrCycles( OBJECT_BALL, 1 );  VecPosition   velMe     = WM->getAgentGlobalVelocity( );  Stamina       sta       = WM->getAgentStamina( );  AngDeg        angBody   = WM->getAgentGlobalBodyAngle( );  Line          lineGoalie=Line::makeLineFromPositionAndAngle(posPred,angBody);  // when it is theoretical possible  // try one dash and check whether ball is in catchable area  dDist = SS->getBallSpeedMax()+SS->getPlayerSpeedMax()+SS->getCatchableAreaL();  if( WM->getRelativeDistance( OBJECT_BALL ) < dDist )  {    posClosestToBall = lineGoalie.getPointOnLineClosestTo( posBall );    dPower           = WM->getPowerForDash(                          posClosestToBall-posPred,                          angBody,                          velMe,                          sta.getEffort()           );    posPred          = WM->predictAgentPos( 1, (int)dPower);    if ( posPred.getDistanceTo( posBall ) < SS->getCatchableAreaL() )      return SoccerCommand( CMD_DASH, dPower );  }  // when it is theoretical possible  // try two dashes and check whether ball is in catchable area  // otherwise try first two  dashes and check whether ball is in catchable  // area, thereafter for turn and dash.  dDist = SS->getBallSpeedMax()*(1.0+SS->getBallDecay())           + 2*SS->getPlayerSpeedMax()           + SS->getCatchableAreaL();  if( WM->getRelativeDistance( OBJECT_BALL ) < dDist )  {    // try two dashes    // first predict the position in the next cycle when dash with full power    // is performed. Then calculate the dash power to reach the point where the    // ball will be in two cycles and predict the global position of the agent    // after a dash with this power. If the position is in the catchable area    // return a dash with full power.    posBall = WM->predictPosAfterNrCycles( OBJECT_BALL, 2 );    soc     = dashToPoint( posBall );    WM->predictAgentStateAfterCommand(soc,&posPred,&velMe,&angBody,&ang,&sta );    dPower=WM->getPowerForDash(posBall-posPred,angBody,velMe,sta.getEffort());    WM->predictStateAfterDash( dPower, &posPred, &velMe, &sta, angBody );    if( posPred.getDistanceTo(posBall) < SS->getCatchableAreaL() )      return soc;    // try one turn and a dash    posBall = WM->predictPosAfterNrCycles( OBJECT_BALL, 2 );    posPred = WM->predictAgentPos( 2, 0 );    ang     = (posBall - posPred).getDirection();    ang     = VecPosition::normalizeAngle( ang - angBody );    if (fabs( ang ) > PS->getPlayerWhenToTurnAngle() ) // if we want to turn

⌨️ 快捷键说明

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