RobotCup2D代码学习记录(二)

RobotCup2D代码学习记录(二)

  本篇博客在上篇博客基础上记录一下高层代码bhv_attackers_move.cpp阅读过程中的一些个人理解。

//这里的话参考了一下队长的解释,该函数的主要作用是负责球员在各个块之间的移动
bool
Bhv_AttackersMove::Body_ForestallBlock(PlayerAgent * agent)
{

  int S_count_no_move = 0 ;//一个计数变量,用于统计多少个周期未移动
  const rcsc::WorldModel & wm = agent->world();
  rcsc:Vector2D home_pos = Strategy::i().getPosition(wm.self().unum());
  rcsc::Vector2D block_point = home_pos;

  if (!block_point.isValid())
  {
    return false;
  }

  double dist_thr = 1.0;

 // agent->debugClient().addMessage("forestall");
 // agent->debugClient().setTarget(block_point);
 // agent->debugClient().addCircle(block_point, dist_thr);

  double dash_power = wm.self().getSafetyDashPower(
      rcsc::ServerParam::i().maxPower());

  if (rcsc::Body_GoToPoint(block_point, dist_thr, dash_power, 5, // cycle
      false, // no back dash
      true, // save recovery
      40.0 // dir_thr
      ).execute(agent))
  {
    S_count_no_move = 0;
    return true;
  }

#if 1
  ++S_count_no_move;

  if (S_count_no_move >= 10)
  {
 //   rcsc::dlog.addText(rcsc::Logger::TEAM,
 //       __FILE__": forestall. long no move. attack to the ball");
 //   agent->debugClient().addMessage("ForestallAttack");
    Body_Intercept2009(true).execute(agent);
    return true;
  }
#endif

//这个地方话是来计算一下身体与球的角度的。abs函数是取绝对值,根据情况来调整身体的角度
  rcsc::AngleDeg body_angle = wm.ball().angleFromSelf() + 90.0;
  if (body_angle.abs() < 90.0)
  {
    body_angle += 180.0;
  }

  rcsc::Body_TurnToAngle(body_angle).execute(agent);

  return true;
}

//主要作用是根据敌人的位置、自己的位置、球的位置等等因素来判断自己的耐力值应该选择消耗多少
double
Bhv_AttackersMove::getDashPower(const PlayerAgent * agent,
    const Vector2D & target_point)
{
  const WorldModel & wm = agent->world();
  int mate_min = wm.interceptTable()->teammateReachCycle();
  int opp_min = wm.interceptTable()->opponentReachCycle();

  if (target_point.x > wm.self().pos().x
      && wm.self().stamina() > ServerParam::i().staminaMax() * 0.7
      && mate_min <= 8)
  {
    Vector2D receive_pos = wm.ball().inertiaPoint(mate_min);
    if (std::fabs(receive_pos.y - target_point.y) < 15.0)
    {
 //     dlog.addText(Logger::TEAM, __FILE__": getDashPower. chance. fast move");
      return ServerParam::i().maxPower();
    }
  }

  if (wm.self().pos().x > wm.offsideLineX()
      && (wm.existKickableTeammate() || mate_min <= opp_min + 2))
  {
    Vector2D receive_pos = wm.ball().inertiaPoint(mate_min);
    if (target_point.x < receive_pos.x + 30.0
        && wm.self().pos().dist(receive_pos) < 30.0
        && wm.self().pos().dist(target_point) < 20.0)
    {
//      dlog.addText(Logger::TEAM, __FILE__": getDashPower. offside max power");

      return ServerParam::i().maxPower();
    }
  }

  //------------------------------------------------------
  // decide dash power
  static bool s_recover_mode = false;
  if (wm.self().stamina() < ServerParam::i().staminaMax() * 0.4)
  {
 //   dlog.addText(Logger::TEAM,
 //       __FILE__": getDashPower. change to recover mode.");
    s_recover_mode = true;
  }
  else if (wm.self().stamina() > ServerParam::i().staminaMax() * 0.7)
  {
//    dlog.addText(Logger::TEAM,
//        __FILE__": getDashPower. came back from recover mode");
    s_recover_mode = false;
  }

  const double my_inc = wm.self().playerType().staminaIncMax()
      * wm.self().recovery();

  // dash power
  if (s_recover_mode)
  {
    // Magic Number.
    // recommended one cycle's stamina recover value
 //   dlog.addText(Logger::TEAM, __FILE__": getDashPower. recover mode");
    return std::max(0.0, my_inc - 30.0);
  }

  if (!wm.opponentsFromSelf().empty()
      && wm.opponentsFromSelf().front()->distFromSelf() < 1.0)
  {
    // opponent is very close
    // full power
    dlog.addText(Logger::TEAM,
        __FILE__": getDashPower. exist near opponent. full power");
    return ServerParam::i().maxPower();
  }

  if (wm.ball().pos().x < wm.self().pos().x
      && wm.self().pos().x < wm.offsideLineX())
  {
    // ball is back
    // not offside
 //   dlog.addText(Logger::TEAM,
//        __FILE__": getDashPower. ball is back and not offside.");
    if (wm.self().stamina() < ServerParam::i().staminaMax() * 0.8)
    {
      return std::min(std::max(5.0, my_inc - 30.0), ServerParam::i().maxPower());
    }
    else
    {
      return std::min(my_inc * 1.1, ServerParam::i().maxPower());
    }
  }

  if (wm.ball().pos().x > wm.self().pos().x + 3.0)
  {
    // ball is front
    if (opp_min <= mate_min - 3)
    {
      if (wm.self().stamina() < ServerParam::i().staminaMax() * 0.6)
      {
  //      dlog.addText(Logger::TEAM,
  //          __FILE__": getDashPower. ball is front. recover");
        return std::min(std::max(0.1, my_inc - 30.0),
            ServerParam::i().maxPower());
      }
      else if (wm.self().stamina() < ServerParam::i().staminaMax() * 0.8)
      {
 //       dlog.addText(Logger::TEAM,
 //           __FILE__": getDashPower. ball is front. keep");
        return std::min(my_inc, ServerParam::i().maxPower());
      }
      else
      {
 //       dlog.addText(Logger::TEAM,
//            __FILE__": getDashPower. ball is front. max");
        return ServerParam::i().maxPower();
      }
    }
    else
    {
 //     dlog.addText(Logger::TEAM,
 //         __FILE__": getDashPower. ball is front full powerr");
      return ServerParam::i().maxPower();
    }
  }

 // dlog.addText(Logger::TEAM, __FILE__": getDashPower. normal mode.");
  if (target_point.x > wm.self().pos().x + 2.0
      && wm.self().stamina() > ServerParam::i().staminaMax() * 0.6)
  {
    return ServerParam::i().maxPower();
  }
  else if (wm.self().stamina() < ServerParam::i().staminaMax() * 0.8)
  {
    return std::min(my_inc * 0.9, ServerParam::i().maxPower());
  }
  else
  {
    return std::min(my_inc * 1.5, ServerParam::i().maxPower());
  }
}
//这个函数的主要作用就是返回maxPower,里面最为麻烦的是大量的计算和判断式,而且其中进行计算的具体数据不是特别地理解。

bool
Bhv_AttackersMove::doCheckCrossPoint( rcsc::PlayerAgent * agent )
{
    const rcsc::WorldModel & wm = agent->world();

    if ( wm.self().pos().x < 35.0 )
    {
        return false;
    }

    const rcsc::PlayerObject * opp_goalie = wm.getOpponentGoalie();
    if ( opp_goalie && opp_goalie->posCount() > 2 )
    {
        rcsc::dlog.addText( rcsc::Logger::ROLE,
                            __FILE__": doCheckCrossTarget  goalie should be checked" );
        return false;
    }
    //这里根据对手守门员的posCount进行判断的,这个函数所返回的值这里在不清楚
    rcsc::Vector2D opposite_pole( 46.0, 7.0 );
    if ( wm.self().pos().y > 0.0 ) opposite_pole.y *= -1.0;
//这里进行的是y数值的方向变化,应该是类似个人坐标系的变化
    rcsc::AngleDeg opposite_pole_angle = ( opposite_pole - wm.self().pos() ).th();


    if ( wm.dirCount( opposite_pole_angle ) <= 1 )
    {
        rcsc::dlog.addText( rcsc::Logger::ROLE,
                            __FILE__": doCheckCrossTarget enough accuracy to angle %.1f",
                            opposite_pole_angle.degree() );
        return false;
    }

    rcsc::AngleDeg angle_diff
        = agent->effector().queuedNextAngleFromBody( opposite_pole );
    if ( angle_diff.abs() > 100.0 )
    {
        rcsc::dlog.addText( rcsc::Logger::ROLE,
                            __FILE__": doCheckCrossPoint. want to face opposite pole,"
                            " but over view range. angle_diff=%.1f",
                            angle_diff.degree() );
        return false;
    }


    agent->setNeckAction( new rcsc::Neck_TurnToPoint( opposite_pole ) );//转向操作
    agent->debugClient().addMessage( "NeckToOpposite" );
    rcsc::dlog.addText( rcsc::Logger::ROLE,
                        __FILE__": doCheckCrossPoint Neck to oppsite pole" );
    return true;
}

//这个函数虽然很长,但是代码并不是特别难懂,主要作用就是去抢球,在一些模块中都给下具体的注解
void
Bhv_AttackersMove::doGoToCrossPoint( rcsc::PlayerAgent * agent)
{
    rcsc::dlog.addText( rcsc::Logger::ROLE,
                        __FILE__": doGoToCrossPoint" );

    const rcsc::WorldModel & wm = agent->world();
    //------------------------------------------------------
    // tackle
    if ( Bhv_BasicTackle( 0.75, 90.0 ).execute( agent ) )
    {
        return;
    }

    //----------------------------------------------
    // intercept check
    int self_min = wm.interceptTable()->selfReachCycle();
    int mate_min = wm.interceptTable()->teammateReachCycle();
    int opp_min = wm.interceptTable()->opponentReachCycle();

    if ( self_min < mate_min
         || ( mate_min != 0 // ! wm.existKickableTeammate()  //try mate_min > 1
              && self_min <= 6
              && wm.ball().pos().dist( M_home_pos ) < 10.0 )
         //|| wm.interceptTable()->isSelfFastestPlayer()
         )
    {
        rcsc::dlog.addText( rcsc::Logger::ROLE,
                            __FILE__": doGoToCross. get ball" );
        agent->debugClient().addMessage( "CrossGetBall" );

        rcsc::Body_Intercept2009().execute( agent );

        if ( self_min == 3 && opp_min >= 3 )
        {
            agent->setViewAction( new rcsc::View_Normal() );
        }

        if ( wm.self().pos().x > 30.0 )
        {
            if ( ! doCheckCrossPoint( agent ) )
            {
                agent->setNeckAction( new rcsc::Neck_TurnToGoalieOrScan() );
            }
        }
        else
        {
            agent->setNeckAction( new rcsc::Neck_TurnToBallOrScan() );
        }
        return;
    }
//根据自己的位置来设置自身方向是对着对方守门员还是球
    //----------------------------------------------
    // ball owner check
    if ( ! wm.interceptTable()->isOurTeamBallPossessor() )
    {
        const rcsc::PlayerObject * opp = wm.getOpponentNearestToBall( 3 );

        if ( opp
             && opp->distFromSelf() < 2.0 ) //3.0?
        {
            rcsc::dlog.addText( rcsc::Logger::ROLE,
                                __FILE__": doGoToCross. opp has ball" );
            agent->debugClient().addMessage( "CrossOppOwn(2)" );
            Bhv_BasicMove().execute( agent );
            return;
        }
    }
//看到这里的log应该就能明白,对方持球人员进入了自己的拦截范围,进行抢球的准备
    //----------------------------------------------
    // set target

    rcsc::Vector2D target_point = M_home_pos;
    rcsc::Vector2D trap_pos = ( mate_min < 100
                                ? wm.ball().inertiaPoint( mate_min )
                                : wm.ball().pos() );

    if ( mate_min <= opp_min
         && mate_min < 3
         && target_point.x < 38.0
         && wm.self().pos().x < wm.offsideLineX() - 1.0
         //&& target_point.x < wm.self().pos().x
         //&& std::fabs( target_point.x - wm.self().pos().x ) < 20.0
         && std::fabs( target_point.y - wm.self().pos().y ) < 5.0
         && std::fabs( wm.self().pos().y - trap_pos.y ) < 13.0
         )
    {
        target_point.y = wm.self().pos().y * 0.9 + M_home_pos.y * 0.1;
        rcsc::dlog.addText( rcsc::Logger::ROLE,
                            __FILE__": doGoToCross. chance keep current." );
        agent->debugClient().addMessage( "CrossCurPos" );
    }
//这里的话也就是参数比较难理解,执行的动作和前面一样的。
    // consider near opponent
    if ( target_point.x > 36.0 )
    {
        double opp_dist = 200.0;
        const rcsc::PlayerObject * opp = wm.getOpponentNearestTo( target_point,
                                                                  10,
                                                                  &opp_dist );//参数不太理解,from to???
        if ( opp && opp_dist < 2.0 )
        {
            rcsc::Vector2D tmp_target = target_point;
            for ( int i = 0; i < 3; ++i )
            {
                tmp_target.x -= 1.0;

                double d = 0.0;
                opp = wm.getOpponentNearestTo( tmp_target, 10, &d );
                if ( ! opp )
                {
                    opp_dist = 0.0;
                    target_point = tmp_target;
                    break;
                }
                if ( opp
                     && opp_dist < d )
                {
                    opp_dist = d;
                    target_point = tmp_target;
                }
            }
            rcsc::dlog.addText( rcsc::Logger::ROLE,
                                __FILE__": doGoToCross. avoid(%.2f, %.2f)->(%.2f, %.2f)",
                                M_home_pos.x, M_home_pos.y,
                                target_point.x, target_point.y );
            agent->debugClient().addMessage( "Avoid" );
        }
    }

    if ( target_point.dist( trap_pos ) < 6.0 )
    {
        rcsc::Circle2D target_circle( trap_pos, 6.0 );
        rcsc::Line2D target_line( target_point, rcsc::AngleDeg( 90.0 ) );
        rcsc::Vector2D sol_pos1, sol_pos2;
        int n_sol = target_circle.intersection( target_line, &sol_pos1, &sol_pos2 );

        if ( n_sol == 1 ) target_point = sol_pos1;
        if ( n_sol == 2 )
        {
            target_point = ( wm.self().pos().dist2( sol_pos1 ) < wm.self().pos().dist2( sol_pos2 )
                             ? sol_pos1
                             : sol_pos2 );

        }

        rcsc::dlog.addText( rcsc::Logger::ROLE,
                            __FILE__": doGoToCross. adjust ot avoid the ball owner." );
        agent->debugClient().addMessage( "Adjust" );
    }
//这里的逻辑没有整明白,没有思考到对应的场景
    //----------------------------------------------
    // set dash power
    // check X buffer & stamina
    static bool s_recover_mode = false;
    if ( wm.self().pos().x > 35.0
         && wm.self().stamina()
         < rcsc::ServerParam::i().recoverDecThrValue() + 500.0 )
    {
        s_recover_mode = true;//模式调整,个人觉得引入的模式机制很nice
        rcsc::dlog.addText( rcsc::Logger::ROLE,
                            __FILE__": doGoToCross. recover on" );
    }

    if ( wm.self().stamina() > rcsc::ServerParam::i().staminaMax() * 0.5 )
    {
        s_recover_mode = false;
        rcsc::dlog.addText( rcsc::Logger::ROLE,
                            __FILE__": doGoToCross. recover off" );
    }
//根据体力调整 s_recover_mode 
    double dash_power = rcsc::ServerParam::i().maxPower();
    if ( s_recover_mode )
    {
        const double my_inc
            = wm.self().playerType().staminaIncMax()
            * wm.self().recovery();
        dash_power = std::max( 1.0, my_inc - 25.0 );
        //dash_power = wm.self().playerType().staminaIncMax() * 0.6;
    }
    else if ( wm.ball().pos().x > wm.self().pos().x )
    {
        if ( wm.existKickableTeammate()
             && wm.ball().distFromSelf() < 10.0
             && std::fabs( wm.self().pos().x - wm.ball().pos().x ) < 5.0
             && wm.self().pos().x > 30.0
             && wm.ball().pos().x > 35.0 )
        {
            dash_power *= 0.5;
        }
    }
    else if ( wm.self().pos().dist( target_point ) < 3.0 )
    {
        const double my_inc
            = wm.self().playerType().staminaIncMax()
            * wm.self().recovery();
        dash_power = std::min( rcsc::ServerParam::i().maxPower(),
                               my_inc + 10.0 );
        //dash_power = rcsc::ServerParam::i().maxPower() * 0.8;
    }
    else if ( mate_min <= 1
              && wm.ball().pos().x > 33.0
              && wm.ball().pos().absY() < 7.0
              && wm.ball().pos().x < wm.self().pos().x
              && wm.self().pos().x < wm.offsideLineX()
              && wm.self().pos().absY() < 9.0
              && std::fabs( wm.ball().pos().y - wm.self().pos().y ) < 3.5
              && std::fabs( target_point.y - wm.self().pos().y ) > 5.0 )
    {
        dash_power = wm.self().playerType()
            .getDashPowerToKeepSpeed( 0.3, wm.self().effort() );
        dash_power = std::min( rcsc::ServerParam::i().maxPower() * 0.75,
                               dash_power );
        rcsc::dlog.addText( rcsc::Logger::ROLE,
                            __FILE__": doGoToCross. slow for cross. power=%.1f",
                            dash_power );
    }
//逻辑都是容易理解的,但是感觉参数和计算很乱很繁琐,而且不知道为什么会这么考虑,可能改代码,大量的工作都在这一部分
#if 1


    bool intentional = true;    //false;

    const Vector2D mate_trap_pos = wm.ball().inertiaPoint(mate_min);

    const double max_x = std::max(wm.offsideLineX(), mate_trap_pos.x);

    if (wm.existKickableTeammate() || mate_min <= 5 || mate_min <= opp_min + 1)
    {
    }
    else if (M_forward_player
    //&& wm.audioMemory().dribbleTime() != wm.time()
        && mate_min <= 2 && opp_min >= 3
        && mate_trap_pos.x > wm.offsideLineX() - 10.0
        && wm.self().stamina() > ServerParam::i().staminaMax() * 0.8
        && 5.0 < wm.self().pos().x && wm.self().pos().x < 27.0
        && wm.self().pos().x > max_x - 7.0 && wm.self().pos().x < max_x - 1.0
        && wm.self().pos().x < mate_trap_pos.x + 10.0
        && (std::fabs(mate_trap_pos.y - wm.self().pos().y) < 8.0
            || (mate_trap_pos - wm.self().pos()).th().abs() < 110.0
        //|| ( mate_trap_pos.x > wm.offsideLineX() - 8.0
        //     && std::fabs( mate_trap_pos.y - wm.self().pos().y ) < 20.0 )
        ) && wm.self().pos().dist(mate_trap_pos) < 20.0
        && std::fabs(M_home_pos.y - wm.self().pos().y) < 15.0)
    {
      double x_diff = max_x - wm.self().pos().x;
      int dash_step = wm.self().playerType().cyclesToReachDistance(x_diff);
      if (mate_min < dash_step - 1)
      {
        target_point.x = std::min(wm.self().pos().x + 20.0, 50.0);
        target_point.y = wm.self().pos().y * 0.8 + mate_trap_pos.y * 0.2;
        if (target_point.absY() > 8.0
            && target_point.absY() > M_home_pos.absY())
        {
//          target_point.y = M_home_pos.y;
        }
        intentional = true;
      }
    }
#endif // 1

    //----------------------------------------------
    // positioning to make the cross course!!

    double dist_thr = wm.ball().distFromSelf() * 0.1;
    if ( dist_thr < 0.5 ) dist_thr = 0.5;

    agent->debugClient().addMessage( "GoToCross%.0f", dash_power );
    agent->debugClient().setTarget( target_point );
    agent->debugClient().addCircle( target_point, dist_thr );

    rcsc::dlog.addText( rcsc::Logger::ROLE,
                        __FILE__": doGoToCross. to (%.2f, %.2f)",
                        target_point.x, target_point.y );

    if ( wm.self().pos().x > target_point.x + dist_thr
         && std::fabs( wm.self().pos().x - target_point.x ) < 3.0
         && wm.self().body().abs() < 10.0 )
    {
        agent->debugClient().addMessage( "Back" );
        double back_dash_power
            = wm.self().getSafetyDashPower( -dash_power );
        rcsc::dlog.addText( rcsc::Logger::ROLE,
                            __FILE__": doShootAreaMove. Back Move" );
        agent->doDash( back_dash_power );
    }
    else
    {
        if ( ! rcsc::Body_GoToPoint( target_point, dist_thr, dash_power,
                                     5, // cycle
                                     false, // no back dash
                                     true, // save recovery
                                     30.0 // dir thr
                                     ).execute( agent ) )
        {
            rcsc::Body_TurnToAngle( 0.0 ).execute( agent );
        }
        else
        {
            if (intentional)
            {
         //     agent->debugClient().addMessage("BreakAway");

          //    agent->debugClient().addMessage("Sayh");
              agent->addSayMessage(new PassRequestMessage(target_point));

         //     dlog.addText(Logger::TEAM, __FILE__": intention breakaway");
              agent->setArmAction(new Arm_PointToPoint(target_point));
            }
        }
    }

    if ( wm.self().pos().x > 30.0 )
    {
        agent->setNeckAction( new rcsc::Neck_TurnToGoalieOrScan() );
    }
    else
    {
        agent->setNeckAction( new rcsc::Neck_TurnToLowConfTeammate() );
    }
}
//进攻球员执行跑位的函数
bool
Bhv_AttackersMove::AttackersMove(PlayerAgent * agent)
{
  const WorldModel & wm = agent->world();

//  dlog.addText(Logger::TEAM,
//      __FILE__": AttackerOffensiveMove. target=(%.2f %.2f)", M_home_pos.x,
  //    M_home_pos.y);

  //------------------------------------------------------
  // tackle
  if (Bhv_BasicTackle(0.75, 90.0).execute(agent))
  {
    return true;;
  }

  //------------------------------------------------------
  int self_min = wm.interceptTable()->selfReachCycle();
  int mate_min = wm.interceptTable()->teammateReachCycle();
  int opp_min = wm.interceptTable()->opponentReachCycle();
 // dlog.addText(Logger::TEAM,
 //     __FILE__": execute. intercept cycle. self=%d, mate=%d, opp=%d", self_min,
 //     mate_min, opp_min);
  //------------------------------------------------------
  if (wm.self().stamina() > ServerParam::i().staminaMax() * 0.6
      && opp_min < 3
      && opp_min < mate_min - 2
      && (opp_min < self_min - 2 || opp_min == 0
          || (opp_min == 1 && self_min > 1))
      && wm.ball().pos().dist(M_home_pos) < 10.0
      && wm.ball().distFromSelf() < 15.0)
  {
    if (Body_ForestallBlock(agent))//这个函数上面解释过,球员在块之间的移动
    {
      agent->setNeckAction(new Neck_TurnToBall());
#ifdef DEBUG2014
      std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": Body_ForestallBlock.\n";
#endif
      return true;
    }
  }

  //------------------------------------------------------
  if ((mate_min >= 2 && self_min <= 4)
      || (self_min <= mate_min + 1 && mate_min >= 4))
  {
 //   dlog.addText(Logger::TEAM, __FILE__": execute. get ball");
 //   agent->debugClient().addMessage("AttGetBall");
    Vector2D face_point(52.5, wm.self().pos().y);

    Body_Intercept2009(true, face_point).execute(agent);
    if (self_min == 4 && opp_min >= 2)
    {
      agent->setViewAction(new View_Wide());
    }
    else if (self_min == 3 && opp_min >= 2)
    {
      agent->setViewAction(new rcsc::View_Normal());
    }
    agent->setNeckAction(new Neck_TurnToBallOrScan());
#ifdef DEBUG2014
    std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": Body_Intercept.\n";
#endif // DEBUG2014

    return true;
  }
//函数最终执行的结果都简单,难点都是在于各种情形的计算判断
  //------------------------------------------------------

  const Vector2D mate_trap_pos = wm.ball().inertiaPoint(mate_min);

  Vector2D target_point = M_home_pos;

  const double max_x = std::max(wm.offsideLineX(), mate_trap_pos.x);
//  dlog.addText(Logger::TEAM, __FILE__": max x = %.1f", max_x);

  if (wm.self().pos().x > max_x && wm.self().pos().x < 42.0
  //&& std::fabs( wm.self().pos().y - M_home_pos.y ) < 10.0
      )
  {
    target_point.y = wm.self().pos().y;
  }

  if (std::fabs(mate_trap_pos.y - M_home_pos.y) < 15.0
      || mate_trap_pos.x > max_x - 5.0)
  {
    if (target_point.x > max_x - 1.5)
    {
      target_point.x = std::min(M_home_pos.x, max_x - 1.5);
    }
  }
  else
  {
    if (target_point.x > max_x - 3.0)
    {
      target_point.x = std::min(M_home_pos.x, max_x - 3.0);
    }
  }
//各种计算移动的目标位置的x
#if 1
  // 2008-04-23 akiyama
  if (mate_min >= 3 && wm.self().pos().dist2(target_point) < 5.0 * 5.0)
  {
    double opp_dist = 1000.0;
    const PlayerObject * opp = wm.getOpponentNearestTo(target_point, 10,
        &opp_dist);
    if (opp && opp_dist < 4.0 && std::fabs(opp->pos().y - target_point.y) < 2.0)
    {
//             target_point.y += ( target_point.y > opp->pos().y
//                                 ? +3.0
//                                 : -3.0 );
      target_point.y = (
          target_point.y > opp->pos().y ?
              opp->pos().y + 2.0 : opp->pos().y - 2.0 );
//      dlog.addText(Logger::TEAM,
 //         __FILE__": adjust target point to avvoid opponent. y=%.1f",
 //         target_point.y);
    }
  }
#endif
#if 1
  // 2008-04-28 akiyama
  if (mate_min < 3 && std::fabs(wm.self().pos().y - M_home_pos.y) < 3.0)
  {
    target_point.y = wm.self().pos().y * 0.9 + M_home_pos.y * 0.1;
    ;
 //   dlog.addText(Logger::TEAM,
  //      __FILE__": adjust target point to prepare receive. y=%.1f",
  //      target_point.y);
  }
#endif

  bool breakaway = false;
  bool intentional = false;

  if (wm.existKickableTeammate() || mate_min <= 5 || mate_min <= opp_min + 1)
  {
    if (wm.self().pos().x > max_x)
    {
      if (std::fabs(mate_trap_pos.y - target_point.y) < 4.0)
      {
        double abs_y = wm.ball().pos().absY();
        bool outer = (wm.self().pos().absY() > abs_y );
        if (abs_y > 25.0)
          target_point.y = (outer ? 30.0 : 20.0 );
        else if (abs_y > 20.0)
          target_point.y = (outer ? 25.0 : 15.0 );
        else if (abs_y > 15.0)
          target_point.y = (outer ? 20.0 : 10.0 );
        else if (abs_y > 10.0)
          target_point.y = (outer ? 15.0 : 5.0 );
        else if (abs_y > 5.0)
          target_point.y = (outer ? 10.0 : 0.0 );
        else
          target_point.y = (outer ? 5.0 : -5.0 );

        if (wm.self().pos().y < 0.0)
        {
          target_point.y *= -1.0;
        }

   //     agent->debugClient().addMessage("AvoidOffside");
   //     dlog.addText(Logger::TEAM,
   //         __FILE__": avoid offside possibility. new_target=(%.1f %.1f)",
   //         target_point.x, target_point.y);
      }
    }
    else if (M_forward_player
    //&& wm.audioMemory().dribbleTime() != wm.time()
        && mate_min <= 2 && opp_min >= 3
        && mate_trap_pos.x > wm.offsideLineX() - 10.0
        && wm.self().stamina() > ServerParam::i().staminaMax() * 0.8
        && 5.0 < wm.self().pos().x && wm.self().pos().x < 27.0
        && wm.self().pos().x > max_x - 7.0 && wm.self().pos().x < max_x - 1.0
        && wm.self().pos().x < mate_trap_pos.x + 10.0
        && (std::fabs(mate_trap_pos.y - wm.self().pos().y) < 8.0
            || (mate_trap_pos - wm.self().pos()).th().abs() < 110.0
        //|| ( mate_trap_pos.x > wm.offsideLineX() - 8.0
        //     && std::fabs( mate_trap_pos.y - wm.self().pos().y ) < 20.0 )
        ) && wm.self().pos().dist(mate_trap_pos) < 20.0
        && std::fabs(M_home_pos.y - wm.self().pos().y) < 15.0)
    {
      double x_diff = max_x - wm.self().pos().x;
      int dash_step = wm.self().playerType().cyclesToReachDistance(x_diff);
      if (mate_min < dash_step - 1)
      {
        target_point.x = std::min(wm.self().pos().x + 20.0, 50.0);
        target_point.y = wm.self().pos().y * 0.8 + mate_trap_pos.y * 0.2;
        if (target_point.absY() > 8.0
            && target_point.absY() > M_home_pos.absY())
        {
          target_point.y = M_home_pos.y;
        }
        intentional = true;
      }

 //     dlog.addText(Logger::TEAM, __FILE__": try breakaway=(%.1f %.1f)",
  //        target_point.x, target_point.y);
      breakaway = true;
    }
  }
//这两个参数用于下面计算dashpoweer
  const double dash_power = (
      breakaway ?
          ServerParam::i().maxPower() : getDashPower(agent, target_point) );

  if (dash_power < 1.0)
  {
    agent->debugClient().addMessage("AttackGoRecover");
    agent->debugClient().setTarget(target_point);
    AngleDeg face_angle = wm.ball().angleFromSelf() + 90.0;
    if (face_angle.abs() > 90.0)
      face_angle += 180.0;
    Body_TurnToAngle(face_angle).execute(agent);
    agent->setNeckAction(new Neck_TurnToBallOrScan());
    return true;
  }

  ///

  agent->debugClient().addMessage("AttackGo%.0f", dash_power);

  double dist_thr = std::fabs(wm.ball().pos().x - wm.self().pos().x) * 0.2
      + 0.25;
  //double dist_thr = wm.ball().pos().dist( target_point ) * 0.1 + 0.5;
  if (dist_thr < 1.0)
    dist_thr = 1.0;
  if (target_point.x > wm.self().pos().x - 0.5
      && wm.self().pos().x < wm.offsideLineX()
      && std::fabs(target_point.x - wm.self().pos().x) > 1.0)
  {
    dist_thr = std::min(1.0, wm.ball().pos().dist(target_point) * 0.1 + 0.5);
  }

 // agent->debugClient().setTarget(target_point);
//  agent->debugClient().addCircle(target_point, dist_thr);
 // dlog.addText(Logger::TEAM,
//      __FILE__": execute. go to (%.2f, %.2f) dash_power=%.2f", target_point.x,
//      target_point.y, dash_power);

  if (Body_GoToPoint(target_point, dist_thr, dash_power, 100, // cycle
      false, // back
      true, // stamina save
      25.0 // angle threshold
      ).execute(agent))
  {
    if (intentional)
    {
 //     agent->debugClient().addMessage("BreakAway");

  //    agent->debugClient().addMessage("Sayh");
      agent->addSayMessage(new PassRequestMessage(target_point));

 //     dlog.addText(Logger::TEAM, __FILE__": intention breakaway");
      agent->setArmAction(new Arm_PointToPoint(target_point));
    }
    #ifdef DEBUG2014
    std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": Body_GoToPoint.\n";
    #endif // DEBUG2014

  }
  else
  {
    AngleDeg body_angle(0.0);
    Body_TurnToAngle(body_angle).execute(agent);
  }

  if (agent->world().ball().posCount() <= 1)
  {
    agent->setNeckAction(new Neck_ScanField());
  }
  else
  {
    agent->setNeckAction(new Neck_TurnToBallOrScan());
  }

  return true;
}

  今天算是把基本移动的函数认真看了一下,总的来说,相比第一次认识到了很多新的东西,包括以前根本不会去看的各种计算和判断,现在部分可以进行模拟尝试着理解,但疑问依然不少,还需要后面进一步理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值