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

📄 basicplayer.c

📁 机器足球2D比赛程序 对trlen_base_2002的改进
💻 C
📖 第 1 页 / 共 5 页
字号:
    {      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->getCatchableAreaL() )        return soc;    }  }  // did not succeed  return SoccerCommand( CMD_ILLEGAL );}/*! This skill enables an agent to kick the ball from its current position to a   given position 'posTarget' in such a way that it has a remaining speed equal   to 'dEndSpeed' when it reaches this position. However, it is possible that   the ball cannot reach this velocity with a single kick either because the   needed magnitude of the generated velocity vector exceeds the maximum speed   of the ball or due to the fact that the current ball speed in combination   with the position of the ball relative to the agent make it impossible to   achieve the required acceleration. If the magnitude of needed velocity vector   is larger than ball speed max it is certain that even in the optimal   situation (i.e. if the ball lies directly in front of the agent and has zero   velocity) the agent will not be able to kick the ball to the target position   at the desired speed. In this case the expected ball movement is computed   after executing a kick with maximum power into the direction of 'posTarget'.   If the magnitude of the resulting movement vector is larger than a given   percentage ('getPlayerWhenToKick' defined in the PlayerSettings)  of the   maximum ball speed then this kick is actually performed despite the fact   that it cannot produce the wanted effect. Otherwise, the agent shoots the   ball close to his body and directly in front of him using the   kickBallCloseToBody skill. In this way he will be able to kick the ball with   more power in the next cycle. However, if the magnitude of the desired   velocity vector is smaller than ball speed max it is possible to reach the   target point at the desired speed in the optimal situation.   If the power that must be supplied to the kick command to achieve this   acceleration is less than or equal to the maximum power the   accelerateBallToVelocity skill is used to perform the desired kick.   Otherwise, the agent uses the kickBallCloseToBody skill to put the   ball in a better kicking position for the next cycle.   \param posTarget target position where the ball should be shot to   \param endSpeed desired speed ball should have in target position   \return SoccerCommand that produces kick  */SoccerCommand BasicPlayer::kickTo( VecPosition posTarget, double dEndSpeed ){  VecPosition posBall = WM->getBallPos();  VecPosition velBall = WM->getGlobalVelocity(OBJECT_BALL);  VecPosition posTraj = posTarget - posBall;  VecPosition velDes  = VecPosition(               WM->getKickSpeedToTravel( posTraj.getMagnitude(), dEndSpeed ),               posTraj.getDirection(),               POLAR                                                        );  double      dPower;  AngDeg      angActual;  Log.log( 101, "ball (%f,%f), agent (%f,%f), to (%f,%f) ang %f %f" ,          WM->getBallPos().getX(), WM->getBallPos().getY(),          WM->getAgentGlobalPosition().getX(),          WM->getAgentGlobalPosition().getY(),          posTarget.getX(), posTarget.getY(),          WM->getAgentGlobalBodyAngle(),          WM->getAgentGlobalNeckAngle() );  Log.log( 101, "rel pos body (%f,%f), velocity ball: (%f,%f) kick_dist: %f  (%f,%f,%f)" ,          WM->getRelativeDistance( OBJECT_BALL ),          WM->getRelativeAngle( OBJECT_BALL, true ),           velBall.getX(), velBall.getY(),           SS->getMaximalKickDist(), SS->getPlayerSize(), SS->getBallSize(),              SS->getKickableMargin() );  if( WM->isKickInUs() || WM->isFreeKickUs())  {    Log.log( 101, "kick in or free kick, accelerate ball" );    return accelerateBallToVelocity( velDes );    }  if( velDes.getMagnitude() > SS->getBallSpeedMax() ) // can never reach point  {           dPower     = SS->getMaxPower();    double dSpeed     = WM->getActualKickPowerRate() * dPower;    double tmp        = velBall.rotate(-velDes.getDirection()).getY();           angActual  = velDes.getDirection() - asinDeg( tmp / dSpeed );    double dSpeedPred = ( WM->getGlobalVelocity(OBJECT_BALL)+                         VecPosition(dSpeed,angActual, POLAR )).getMagnitude();    // but ball acceleration in right direction is very high    if( dSpeedPred > PS->getPlayerWhenToKick()*SS->getBallAccelMax() )    {      Log.log( 101, "point (%f,%f) too far, but can acccelerate ball good to %f k=%f,%f",                     velDes.getX(), velDes.getY(), dSpeedPred, dSpeed, tmp );      return accelerateBallToVelocity( velDes );    // shoot nevertheless    }    else if( WM->getActualKickPowerRate() >        PS->getPlayerWhenToKick() * SS->getKickPowerRate() )    {      Log.log( 101, "point too far, freeze ball" ); // ball well-positioned      return freezeBall();                          // freeze ball    }    else    {      Log.log( 101, "point too far, reposition ball (k_r = %f)",                      WM->getActualKickPowerRate()/(SS->getKickPowerRate()) );      return kickBallCloseToBody( 0 );            // else position ball better    }  }  else                                            // can reach point  {    VecPosition accBallDes = velDes - velBall;    dPower = WM->getKickPowerForSpeed(accBallDes.getMagnitude());    if( dPower <= 1.05*SS->getMaxPower() )        // with current ball speed    {                               // 1.05 since cannot get ball fully perfect      Log.log( 101, "point good and can reach point" );      return accelerateBallToVelocity( velDes );  // perform shooting action    }    else    {      Log.log( 101, "point good, but reposition ball since need %f",dPower );      return kickBallCloseToBody( 0 );            // else position ball better    }  }}/*! This skill enables an agent to turn towards a global angle while keeping    the ball in front of him. It is used, for example, when a defender has    intercepted the ball in his defensive area and faces his own goal. In this    situation the defender usually wants to pass the ball up the field into an    area that is currently not visible to him and to this end he will first use    this skill to turn with the ball towards the opponent's goal. Turning with    the ball requires a sequence of commands to be performed. The ball first has    to be kicked to a desired position relative to the agent, then it has to be    stopped dead at that position and finally the agent must turn towards the    ball again. Each time when this skill is called it has to be determined    which part of the sequence still has to be executed. This is done as follows.    If the absolute difference between the desired angle and the global angle    of the ball relative to the position of the agent is larger than the    value 'angKickThr' then the kickBallCloseToBody skill is used to kick    the ball to a position close to the agent and at the desired angle.    Otherwise, it is checked whether the ball still has speed from the previous    action. If the remaining ball speed exceeds the given value    'dFreezeThr' then the ball is stopped dead at its current position    using the freezeBall skill. In all other cases the agent turns his body    towards the specified angle 'ang'.    \param ang global direction in which ball and player should be faced    \param angKickThr when ball angle difference is larger than this value                      ball is repositioned    \param dFreezeThr when ball lies correct, but has speed higher than this                      value, ball is frozen.    \return Soccercommand to turn with the ball to global angle 'ang'.   *//*SoccerCommand BasicPlayer::turnWithBallTo( AngDeg ang, AngDeg angKickThr,                                           double dFreezeThr ){  // if opponent is close  // if ball is located more than 'angKickThr' degrees from ang  //  kick ball to point right in front of player in direction ang  // else if ball has still speed higher than 'dFreezeThr'  /// freezeBall  // else  //  turn to direction 'ang'  VecPosition posAgent = WM->getAgentGlobalPosition();  VecPosition posBall  = WM->getBallPos();  AngDeg      angBody  = WM->getAgentGlobalBodyAngle();  AngDeg      angDiff  = (posBall-posAgent).getDirection() - ang;              angDiff  = VecPosition::normalizeAngle( angDiff );  double      dDist;  ObjectT     objOpp   = WM->getClosestInSetTo( OBJECT_SET_OPPONENTS,                           WM->getAgentObjectType(), &dDist );  VecPosition posOpp   = WM->getGlobalPosition( objOpp );  if( objOpp != OBJECT_ILLEGAL && dDist < 2.5 )  {    if( posBall.getDistanceTo( posOpp ) < posBall.getDistanceTo( posAgent ) )    {      ang = (posOpp - posAgent).getDirection() + 180;      return kickBallCloseToBody( VecPosition::normalizeAngle( ang - angBody ));    }  }  else if( fabs( angDiff ) > angKickThr )  {    Log.log( 101, "turnWithBall: kick ball close %f", ang );    return kickBallCloseToBody( VecPosition::normalizeAngle( ang - angBody ) );  }  // hier niet altijd freezen -> kan dan niet meer goed liggen omdat je zelf  // doorschiet.  if( WM->getBallSpeed() > dFreezeThr )  {    Log.log( 101, "turnWithBall: freeze ball" );    return freezeBall();  }  ACT->putCommandInQueue( alignNeckWithBody() );  return turnBodyToPoint( posAgent + VecPosition(1.0, ang, POLAR ) );}*/SoccerCommand BasicPlayer::turnWithBallTo( AngDeg ang, AngDeg angKickThr,                                           double dFreezeThr ){  // if opponent is closer to the ball than I am  //  kick ball away from his direction  // if the ball will be in my kick_range in the next cycle  //  turn to direction ang  // if ball will be in kick range if frozen  //   freeze_ball  // else  //   kickBallCloseToBody(ang)  VecPosition   posAgent= WM->getAgentGlobalPosition();  VecPosition   posBall = WM->getBallPos();  AngDeg        angBody = WM->getAgentGlobalBodyAngle();  double        dDist;  ObjectT       objOpp  = WM->getClosestInSetTo( OBJECT_SET_OPPONENTS,                          WM->getAgentObjectType(), &dDist );  VecPosition   posOpp  = WM->getGlobalPosition( objOpp );  SoccerCommand soc     = turnBodyToPoint(posAgent+VecPosition(1.0,ang,POLAR));  if( objOpp != OBJECT_ILLEGAL && dDist < 2.5 )  {    AngDeg angBall = (posBall-posAgent).getDirection();    AngDeg angOpp  = (posOpp -posAgent).getDirection();    if( fabs( VecPosition::normalizeAngle( angBall - angOpp ) ) < 90  )    {      ang = angOpp + 180;      Log.log( 101, "turnWithBall: kick ball away from opp at ang %f", angOpp );      return kickBallCloseToBody( VecPosition::normalizeAngle( ang - angBody ));    }  }  VecPosition posAgentPred = WM->predictAgentPosAfterCommand( soc );  VecPosition posBallPred  = WM->predictPosAfterNrCycles( OBJECT_BALL, 1 );  if( posAgentPred.getDistanceTo( posBallPred ) < 0.8*SS->getMaximalKickDist()   ||    ( posAgentPred.getDistanceTo(posBallPred) < 0.9*SS->getMaximalKickDist()      && WM->getBallSpeed() < 0.1 ))  {    Log.log( 101, "turnWithBall: turn since ball will be kickable in t+1" );    return soc;  }  posAgentPred = WM->predictPosAfterNrCycles( WM->getAgentObjectType(), 1, 0 );  // if ball will not be in kickable distance in next turn, we have to freeze  // the ball. Do this only when current ball position (same as frozen ball  // position) lies within kickable distance of predicted agent position in  // next cycle. When ball lies at edge of the kickable distance, do not  // freeze, since when vel.is not completely correct can move outside area  if( posAgentPred.getDistanceTo( posBall ) < 0.8*SS->getMaximalKickDist() &&       WM->getBallSpeed() > 0.1  )

⌨️ 快捷键说明

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