zoukankan      html  css  js  c++  java
  • Robcup2D足球学习记录【2020.01.10】

    对于代码的理解与存在的疑问(用注释标出)

    注释格式如下:
    /*
    问题:
    xxxx

    理解:
    xxxx
    By ChenYanTing
    */

    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif
    
    #include "bhv_chain_action.h"
    
    #include "action_chain_holder.h"
    #include "action_chain_graph.h"
    #include "action_state_pair.h"
    #include "field_analyzer.h"
    
    #include "bhv_pass_kick_find_receiver.h"
    #include "bhv_normal_dribble.h"
    #include "body_force_shoot.h"
    
    #include "neck_turn_to_receiver.h"
    
    #include <rcsc/action/bhv_scan_field.h>
    #include <rcsc/action/body_clear_ball.h>
    #include <rcsc/action/body_go_to_point.h>
    #include <rcsc/action/body_smart_kick.h>
    #include <rcsc/action/body_hold_ball.h>
    #include <rcsc/action/body_turn_to_point.h>
    #include <rcsc/action/neck_scan_field.h>
    #include <rcsc/action/neck_turn_to_goalie_or_scan.h>
    
    #include <rcsc/action/kick_table.h>
    
    #include <rcsc/player/intercept_table.h>
    #include <rcsc/player/soccer_intention.h>
    #include <rcsc/player/player_agent.h>
    #include <rcsc/common/server_param.h>
    #include <rcsc/common/logger.h>
    
    using namespace rcsc;
    
    namespace {
    
    class IntentionTurnTo
        : public SoccerIntention {
    private:
        int M_step;
        Vector2D M_target_point;
    
    public:
    
        IntentionTurnTo( const Vector2D & target_point )
            : M_step( 0 ),
              M_target_point( target_point )
          { }
    
        bool finished( const PlayerAgent * agent );
    
        bool execute( PlayerAgent * agent );
    
    private:
    
    };
    
    /*-------------------------------------------------------------------*/
    /*!
    
     */
        
    
    /*
     问题:
     wm.interceptTable()中的一些属性分别有什么,可以在哪里查看?
         
     理解:
     此函数为每次球员移动结束后的提示函数,其主要功能为:每次球员完成了移动动作后,输出移动完成时的球员状态或者其他状态
     此函数的内容如下:
     记录步数的变量自加,然后输出移动的步数
     如果移动的步数大于二,则输出时间溢出,并且返回true
     如果自己是不可踢球状态,则输出(finished) no kickable并且返回true
     如果存在可踢球的敌人,则输出(finished) exist kickable opponent
     如果拦截表中,敌人的可达半径小于1,则输出(finished) opponent may be kickable
     如果自己下一步距离球的距离大于可以踢球的距离,输出 (finished) unkickable at next cycle
     
     By ChenYanTing
    */
    bool
    IntentionTurnTo::finished( const PlayerAgent * agent )
    {
        ++M_step;
        dlog.addText( Logger::TEAM,
                      __FILE__": (finished) step=%d",
                      M_step );
    
        if ( M_step >= 2 )
        {
            dlog.addText( Logger::TEAM,
                          __FILE__": (finished) time over" );
            return true;
        }
    
        const WorldModel & wm = agent->world();
    
        //
        // check kickable
        //
    
        if ( ! wm.self().isKickable() )
        {
            dlog.addText( Logger::TEAM,
                          __FILE__": (finished) no kickable" );
            return true;
        }
    
        //
        // check opponent
        //
    
        if ( wm.existKickableOpponent() )
        {
            dlog.addText( Logger::TEAM,
                          __FILE__": (finished) exist kickable opponent" );
            return true;
        }
    
        if ( wm.interceptTable()->opponentReachCycle() <= 1 )
        {
            dlog.addText( Logger::TEAM,
                          __FILE__": (finished) opponent may be kickable" );
            return true;
        }
    
        //
        // check next kickable
        //
    
        double kickable2 = std::pow( wm.self().playerType().kickableArea()
                                     - wm.self().vel().r() * ServerParam::i().playerRand()
                                     - wm.ball().vel().r() * ServerParam::i().ballRand()
                                     - 0.15,
                                     2 );
        Vector2D self_next = wm.self().pos() + wm.self().vel();
        Vector2D ball_next = wm.ball().pos() + wm.ball().vel();
    
        if ( self_next.dist2( ball_next ) > kickable2 )
        {
            // unkickable if turn is performed.
            dlog.addText( Logger::TEAM,
                          __FILE__": (finished) unkickable at next cycle" );
            return true;
        }
    
        return false;
    }
    
    /*-------------------------------------------------------------------*/
    
    
    
        
    /*
     问题:
     agent->setNeckAction( new Neck_ScanField() ),这个设置颈部动作是不是在那个agent代码里面,属于后面看的代码?
         
     理解:
     这是球员移动到目标点的执行函数
     函数内容如下:
     首先输出目标点的x,y坐标
     然后执行Body_TurnToPoint( M_target_point ).execute( agent )函数,执行移动到目标点的函数
     最后设置颈部动作,环顾四周
     By ChenYanTing
    */
    bool
    IntentionTurnTo::execute( PlayerAgent * agent )
    {
        dlog.addText( Logger::TEAM,
                      __FILE__": (intention) facePoint=(%.1f %.1f)",
                      M_target_point.x, M_target_point.y );
        agent->debugClient().addMessage( "IntentionTurnToForward" );
    
        Body_TurnToPoint( M_target_point ).execute( agent );
        agent->setNeckAction( new Neck_ScanField() );
    
        return true;
    }
    
    }
    
    /*-------------------------------------------------------------------*/
    /*!
    
     */
    Bhv_ChainAction::Bhv_ChainAction( const ActionChainGraph & chain_graph )
        : M_chain_graph( chain_graph )
    {
    
    }
    
    /*-------------------------------------------------------------------*/
    /*!
    
     */
    Bhv_ChainAction::Bhv_ChainAction()
        : M_chain_graph( ActionChainHolder::i().graph() )
    {
    
    }
    
    /*-------------------------------------------------------------------*/
    
    /*
     问题:
     ServerParam::i()代表什么?ServerParam这个类有必要看源代码吗?
     M_chain_graph.getFirstAction(),这里获得的第一个动作指的什么?
     agent->setNeckAction( new Neck_TurnToReceiver( M_chain_graph ) )这个设置的颈部动作是什么意思?
     wm.gameMode().type(),不理解,vm的源代码需要看吗?
     整个球场的中心坐标在哪里,球场的长和宽是多少?如果需要自己了解这些,可以在哪里查看数据?
     Body_ClearBall(),这是指的什么意思?
     
     
     理解:
     这个函数为动作链的执行函数,简单通俗的讲,就是判断链式动作里面的第一个动作属于什么动作(射门、运球、持球等等),然后通过switch语句,根据不同的判断结果,给出不同的执行过程。
     函数的内容如下:
     首先输出Bhv_ChainAction
     判断是否正在执行doTurnToForward( agent ),如果是则返回true
     获得动作链式图里面的第一个动作,然后进行进入switch语句,判断第一个动作属于什么,根据不同的判断结果执行不同的过程。
     如果当前比赛暂停或者处于不是正在比赛的过程中,则返回false。其他球员正在执行动作的情况,返回true。
     */
    bool
    Bhv_ChainAction::execute( PlayerAgent * agent )
    {
        dlog.addText( Logger::TEAM,
                      __FILE__": Bhv_ChainAction" );
    
        if ( doTurnToForward( agent ) )
        {
            return true;
        }
    
        const ServerParam & SP = ServerParam::i();
        const WorldModel & wm = agent->world();
    
        const CooperativeAction & first_action = M_chain_graph.getFirstAction();
    
        ActionChainGraph::debug_send_chain( agent, M_chain_graph.getAllChain() );
    
        const Vector2D goal_pos = SP.theirTeamGoalPos();
        agent->setNeckAction( new Neck_TurnToReceiver( M_chain_graph ) );
    
        switch ( first_action.category() ) {
        case CooperativeAction::Shoot:
            {
                dlog.addText( Logger::TEAM,
                              __FILE__" (Bhv_ChainAction) shoot" );
                if ( Body_ForceShoot().execute( agent ) )
                {
                    agent->setNeckAction( new Neck_TurnToGoalieOrScan() );
                    #ifdef DEBUG2014
                    std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": (Bhv_ChainAction) shoot...
    ";
                    #endif // DEBUG2014
    
                    return true;
                }
                #ifdef DEBUG2014
                std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": (Bhv_ChainAction) shoot failed...
    ";
                #endif // DEBUG2014
    
    
                break;
            }
    
        case CooperativeAction::Dribble:
            {
                if ( wm.gameMode().type() != GameMode::PlayOn
                     && ! wm.gameMode().isPenaltyKickMode() )
                {
                    agent->debugClient().addMessage( "CancelChainDribble" );
                    dlog.addText( Logger::TEAM,
                                  __FILE__" (Bhv_ChainAction) cancel dribble" );
                    return false;
                }
    
                const Vector2D & dribble_target = first_action.targetPoint();
    
                dlog.addText( Logger::TEAM,
                              __FILE__" (Bhv_ChainAction) dribble target=(%.1f %.1f)",
                              dribble_target.x, dribble_target.y );
    
                NeckAction::Ptr neck;
                double goal_dist = goal_pos.dist( dribble_target );
                if ( goal_dist < 18.0 )
                {
                    int count_thr = 0;
                    if ( goal_dist < 13.0 )
                    {
                        count_thr = -1;
                    }
                    agent->debugClient().addMessage( "ChainDribble:LookGoalie" );
                    neck = NeckAction::Ptr( new Neck_TurnToGoalieOrScan( count_thr ) );
                }
    
                if ( Bhv_NormalDribble( first_action, neck ).execute( agent ) )
                {
                    #ifdef DEBUG2014
                    std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": (Bhv_ChainAction) Dribble...
    ";
                    #endif // DEBUG2014
    
                    return true;
                }
                break;
            }
    
        case CooperativeAction::Hold:
            {
                if ( wm.gameMode().type() != GameMode::PlayOn )
                {
                    agent->debugClient().addMessage( "CancelChainHold" );
                    dlog.addText( Logger::TEAM,
                                  __FILE__" (Bhv_ChainAction) cancel hold" );
                    return false;
                }
    
                if ( wm.ball().pos().x < -SP.pitchHalfLength() + 8.0
                     && wm.ball().pos().absY() < SP.goalHalfWidth() + 1.0 )
                {
                    agent->debugClient().addMessage( "ChainHold:Clear" );
                    dlog.addText( Logger::TEAM,
                                  __FILE__" (Bhv_ChainAction) cancel hold. clear ball" );
                    Body_ClearBall().execute( agent );
                    agent->setNeckAction( new Neck_ScanField() );
                    return true;
                }
    
                agent->debugClient().addMessage( "hold" );
                dlog.addText( Logger::TEAM,
                              __FILE__" (Bhv_ChainAction) hold" );
    
                if ( Body_HoldBall().execute( agent ) )
                {
                    agent->setNeckAction( new Neck_ScanField() );
                    #ifdef DEBUG2014
                    std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": (Bhv_ChainAction) Hold ball...
    ";
                    #endif // DEBUG2014
    
                    return true;
                }
    
                break;
            }
    
        case CooperativeAction::Pass:
            {
                dlog.addText( Logger::TEAM,
                              __FILE__" (Bhv_ChainAction) pass" );
                if ( first_action.targetPlayerUnum() == 1 )
                {
                    #ifdef DEBUG2014
                    std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": DO NOT PASS TO OUR GOALIE!!!
    
    ";
                    #endif // DEBUG2014
    
                    break;
                }
                if ( Bhv_PassKickFindReceiver( M_chain_graph ).execute( agent ) )
                {
                    if ( wm.self().pos().x < -42.0 )
                    {
                        #ifdef DEBUG2014
                        std::cerr << "wm.gameMode().type() = " << wm.gameMode().type() << std::endl;
                        std::cerr << "targetPoint = " << '(' << first_action.targetPoint().x << first_action.targetPoint().y << ')'
                                  << std::endl;
                        std::cerr << "targetPlayerUnum = " << first_action.targetPlayerUnum() << std::endl;
                        #endif // DEBUG2014
    
                    }
                    #ifdef DEBUG2014
                    std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": (Bhv_ChainAction) Pass...
    
    ";
                    #endif // DEBUG2014
    
                    return true;
                }
    
                break;
            }
    
        case CooperativeAction::Move:
            {
                dlog.addText( Logger::TEAM,
                              __FILE__" (Bhv_ChainAction) move" );
    
                if ( Body_GoToPoint( first_action.targetPoint(),
                                     1.0,
                                     SP.maxDashPower() ).execute( agent ) )
                {
                    agent->setNeckAction( new Neck_ScanField() );
                    #ifdef DEBUG2014
                    std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum()
                                << ": (Bhv_ChainAction) Move to "
                                << first_action.targetPoint().x << ',' << first_action.targetPoint().y << std::endl;
                    #endif // DEBUG2014
    
                    return true;
                }
    
                break;
            }
    
        case CooperativeAction::Clear:
            {
                dlog.addText( Logger::TEAM,
                              __FILE__" (Bhv_ChainAction) clear" );
    
                if ( Body_SmartKick( first_action.targetPoint(),
                                    first_action.firstBallSpeed(),
                                    first_action.firstBallSpeed() * 0.99,
                                    first_action.kickCount() ).execute( agent ) )
    
                {
                    agent->setNeckAction( new Neck_ScanField() );
                    #ifdef DEBUG2014
                    std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": (Bhv_ChainAction) Clear...
    ";
                    #endif // DEBUG2014
    
                    return true;
                }
                #ifdef DEBUG2014
                std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": (Bhv_ChainAction) Clear failed...
    ";
                #endif // DEBUG2014
    
    
                break;
            }
    
        case CooperativeAction::NoAction:
            {
                dlog.addText( Logger::TEAM,
                              __FILE__" (Bhv_ChainAction) no action" );
    
                return true;
                break;
            }
    
        default:
            dlog.addText( Logger::TEAM,
                          __FILE__" (Bhv_ChainAction) invalid category" );
            break;
        }
    
        return false;
    }
    
    
    /*-------------------------------------------------------------------*/
    /*
     问题:
     ( face_point - wm.self().pos() ).th(),face_point是指的面向的坐标吗?.th是指的什么?我又忘记这个了
     opponent_dist_thr的意义?
     (*o)->posCount(),地方的位置数代表的意义是?
     getKeepBallVel( agent->world() ),获得的是球的什么速度?
     
     
     理解:
     这个函数为执行转向的函数。
     函数的内容如下:
     首先判断游戏是否正在进行,如果游戏不是正在进行,则返回false
     获取身体面向与脸面向的角度差
     如果角度差在110以内,则认为不需要转向,返回false
     否则,尝试转向
     判断地方的每个敌人距离自己的距离,如果距离小于某一临界值,则返回false,不执行转向
     如果自己接下来距离球接下来的距离小于kikable2的距离,则执行转向函数,并且返回true
     
    
     */
    bool
    Bhv_ChainAction::doTurnToForward( PlayerAgent * agent )
    {
        const WorldModel & wm = agent->world();
    
        if ( wm.gameMode().type() != GameMode::PlayOn )
        {
            return false;
        }
    
        Vector2D face_point( 42.0, 0.0 );
    
        const double body_angle_diff = ( ( face_point - wm.self().pos() ).th() - wm.self().body() ).abs();
        if ( body_angle_diff < 110.0 )
        {
            dlog.addText( Logger::TEAM,
                          __FILE__" (doTurnToForward) already facing the forward direction. angle_diff=%.1f",
                          body_angle_diff );
            return false;
        }
    
        dlog.addText( Logger::TEAM,
                      __FILE__" (doTurnToForward) angle_diff=%.1f. try turn",
                      body_angle_diff );
    
        // const double opponent_dist_thr = ( wm.self().pos().x > ServerParam::i().theirPenaltyAreaLineX() - 2.0
        //                                    && wm.self().pos().absY() > ServerParam::i().goalHalfWidth()
        //                                    ? 2.7
        //                                    : 4.0 );
        const double opponent_dist_thr = 4.0;
    
        const PlayerPtrCont::const_iterator o_end = wm.opponentsFromSelf().end();
        for ( PlayerPtrCont::const_iterator o = wm.opponentsFromSelf().begin();
              o != o_end;
              ++o )
        {
            double dist = (*o)->distFromSelf();
            dist -= bound( 0, (*o)->posCount(), 3 ) * (*o)->playerTypePtr()->realSpeedMax();
    
            if ( dist < opponent_dist_thr )
            {
                dlog.addText( Logger::TEAM,
                          __FILE__" (doTurnToForward) exist opponent" );
                return false;
            }
    
            if ( dist > 10.0 )
            {
                break;
            }
        }
    
        // TODO: find the best scan target angle
        face_point.y = wm.self().pos().y * 0.5;
    
    
        double kickable2 = std::pow( wm.self().playerType().kickableArea()
                                     - wm.self().vel().r() * ServerParam::i().playerRand()
                                     - wm.ball().vel().r() * ServerParam::i().ballRand()
                                     - 0.2,
                                     2 );
        Vector2D self_next = wm.self().pos() + wm.self().vel();
        Vector2D ball_next = wm.ball().pos() + wm.ball().vel();
    
        if ( self_next.dist2( ball_next ) < kickable2 )
        {
            Body_TurnToPoint( face_point ).execute( agent );
            agent->setNeckAction( new Neck_ScanField() );
            return true;
        }
    
    
        Vector2D ball_vel = getKeepBallVel( agent->world() );
    
        if ( ! ball_vel.isValid() )
        {
            dlog.addText( Logger::TEAM,
                          __FILE__": (doKeepBall) no candidate." );
    
            return false;
        }
    
        //
        // perform first kick
        //
    
        Vector2D kick_accel = ball_vel - wm.ball().vel();
        double kick_power = kick_accel.r() / wm.self().kickRate();
        AngleDeg kick_angle = kick_accel.th() - wm.self().body();
    
        dlog.addText( Logger::TEAM,
                      __FILE__": (doTurnToForward) "
                      " ballVel=(%.2f %.2f)"
                      " kickPower=%.1f kickAngle=%.1f",
                      ball_vel.x, ball_vel.y,
                      kick_power,
                      kick_angle.degree() );
    
        if ( kick_power > ServerParam::i().maxPower() )
        {
            dlog.addText( Logger::TEAM,
                          __FILE__": (doTurnToForward) over kick power" );
            Body_HoldBall( true,
                           face_point ).execute( agent );
            agent->setNeckAction( new Neck_ScanField() );
            #ifdef DEBUG2014
    std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": (Bhv_ChainAction) doTurnToForward: Hold???
    ";
            #endif // DEBUG2014
    
    
        }
        else
        {
            agent->doKick( kick_power, kick_angle );
            agent->setNeckAction( new Neck_ScanField() );
            #ifdef DEBUG2014
    std::cerr << wm.time().cycle() << __FILE__ << wm.self().unum() << ": (Bhv_ChainAction) doTurnToForward: Kick???n";
            #endif // DEBUG2014
    
        }
    
        agent->debugClient().addMessage( "Chain:Turn:Keep" );
        agent->debugClient().setTarget( face_point );
    
        //
        // set turn intention
        //
    
        dlog.addText( Logger::TEAM,
                      __FILE__": (doTurnToFoward) register intention" );
        agent->setIntention( new IntentionTurnTo( face_point ) );
    
        return true;
    }
    
    /*-------------------------------------------------------------------*/
    
    /*
     问题:
     keep_pos代表什么?
     std::pow( ptype.playerSize()+ SP.ballSize(),2 ),这个pow代表什么?是代表的指数运算吗?还是和power有关的函数?
     playerSize和ballSize,这个size是指的什么size?
     ptype.kickableMargin(),球员类型的可踢边境?这个代表着每个球员类型都有自己的可踢边境的划分吗?
     keep_dist的含义代表什么?
     keep_pos的含义代表什么?
     Vector2D::INVALIDATED代表什么数据?这个可以从哪里看到?
     Vector2D::from_polar()函数的作用是什么?如果不懂可以从哪里找到?
     Vector2D.r()是指的向量的大小吗?那Vector2D.r2()又是什么?
     
     
     理解:
     说实话这个函数,我看不太懂。。。
     我的所有理解都写成注释,写在函数里面了,但是因为这个函数里面太多调用我都不明白原理,所以我理解起来很困难。
     看了几遍,还是不能把这些东西串起来,先放放吧。。。看看以后再看是不是就能看懂了。。。
     
     */
    Vector2D
    Bhv_ChainAction::getKeepBallVel( const WorldModel & wm )
    {
        //初始化s_update_time时间为0
        static GameTime s_update_time( 0, 0 );
        
        //初始化s_best_ball_vel,横向速度和纵向速度都为零
        static Vector2D s_best_ball_vel( 0.0, 0.0 );
    
        //如果wm.time()与s_update_time相等,即wm.time()等于零,那么返回s_best_ball_vel
        if ( s_update_time == wm.time() )
        {
            return s_best_ball_vel;
        }
        //设置s_update_time为wm.time()
        s_update_time = wm.time();
    
        //ANGLE_DIVS代表将360度分割成了十二份
        const int ANGLE_DIVS = 12;
    
        //获得SP参数对象、ptype球员类型对象
        const ServerParam & SP = ServerParam::i();
        const PlayerType & ptype = wm.self().playerType();
        //定义collide_dist2(碰撞距离),但是pow具体是指什么?
        const double collide_dist2 = std::pow( ptype.playerSize()
                                               + SP.ballSize(),
                                               2 );
        
        //keep_dist的含义代表什么?
        const double keep_dist = ptype.playerSize()
            + ptype.kickableMargin() * 0.5
            + ServerParam::i().ballSize();
    
        //获得自己下一个与下下个自己所处的位置
        const Vector2D next_self_pos
            = wm.self().pos() + wm.self().vel();
        const Vector2D next2_self_pos
            = next_self_pos
            + wm.self().vel() * ptype.playerDecay();
    
        //
        // create keep target point
        //
    
        // 初始化几个变量
        int best_angle = -1;
        Vector2D best_ball_vel = Vector2D::INVALIDATED;
        int best_opponent_step = 0;
        double best_ball_speed = 1000.0;
    
        /*
         将三百六十度分成十二份,每次转三十度。每次线获取keep_pos,如果keep_pos符合某个条件则不进行处理
         否则,则进行如下处理(看下面的注释)。
         */
        for ( int a = 0; a < ANGLE_DIVS; ++a )
        {
            Vector2D keep_pos
                = next2_self_pos
                + Vector2D::from_polar( keep_dist,
                                        360.0/ANGLE_DIVS * a );
            if ( keep_pos.absX() > SP.pitchHalfLength() - 0.2
                 || keep_pos.absY() > SP.pitchHalfWidth() - 0.2 )
            {
                continue;
            }
            
            //初始化ball_move、ball_speed,这里的ball_move是一个向量
            Vector2D ball_move = keep_pos - wm.ball().pos();
            double ball_speed = ball_move.r() / ( 1.0 + SP.ballDecay() );
    
            
            Vector2D max_vel
                = KickTable::calc_max_velocity( ball_move.th(),
                                                wm.self().kickRate(),
                                                wm.ball().vel() );
            //这个临界条件的设定不是很明白
            if ( max_vel.r2() < std::pow( ball_speed, 2 ) )
            {
                continue;
            }
    
            
            Vector2D ball_next_next = keep_pos;
    
            Vector2D ball_vel = ball_move.setLengthVector( ball_speed );
            Vector2D ball_next = wm.ball().pos() + ball_vel;
    
            if ( next_self_pos.dist2( ball_next ) < collide_dist2 )
            {
                ball_next_next = ball_next;
                ball_next_next += ball_vel * ( SP.ballDecay() * -0.1 );
            }
    
    #ifdef DEBUG_PRINT
            dlog.addText( Logger::TEAM,
                          __FILE__": (getKeepBallVel) %d: ball_move th=%.1f speed=%.2f max=%.2f",
                          a,
                          ball_move.th().degree(),
                          ball_speed,
                          max_vel.r() );
            dlog.addText( Logger::TEAM,
                          __FILE__": __ ball_next=(%.2f %.2f) ball_next2=(%.2f %.2f)",
                          ball_next.x, ball_next.y,
                          ball_next_next.x, ball_next_next.y );
    #endif
    
            //
            // check opponent
            //
    
            
            int min_step = 1000;
            for ( PlayerPtrCont::const_iterator o = wm.opponentsFromSelf().begin();
                  o != wm.opponentsFromSelf().end();
                  ++o )
            {
                if ( (*o)->distFromSelf() > 10.0 )
                {
                    break;
                }
    
                int o_step = FieldAnalyzer::predict_player_reach_cycle( *o,
                                                                        ball_next_next,
                                                                        (*o)->playerTypePtr()->kickableArea(),
                                                                        0.0, // penalty distance
                                                                        1, // body count thr
                                                                        1, // default turn step
                                                                        0, // wait cycle
                                                                        true );
    
                if ( o_step <= 0 )
                {
                    break;
                }
    
                if ( o_step < min_step )
                {
                    min_step = o_step;
                }
            }
    #ifdef DEBUG_PRINT
            dlog.addText( Logger::TEAM,
                          __FILE__": (getKeepBallVel) %d: keepPos=(%.2f %.2f)"
                          " ballNext2=(%.2f %.2f) ballVel=(%.2f %.2f) speed=%.2f o_step=%d",
                          a,
                          keep_pos.x, keep_pos.y,
                          ball_next_next.x, ball_next_next.y,
                          ball_vel.x, ball_vel.y,
                          ball_speed,
                          min_step );
    #endif
            if ( min_step > best_opponent_step )
            {
                best_angle = a;
                best_ball_vel = ball_vel;
                best_opponent_step = min_step;
                best_ball_speed = ball_speed;
            }
            else if ( min_step == best_opponent_step )
            {
                if ( best_ball_speed > ball_speed )
                {
                    best_angle = a;
                    best_ball_vel = ball_vel;
                    best_opponent_step = min_step;
                    best_ball_speed = ball_speed;
                }
            }
        }
    
        s_best_ball_vel = best_ball_vel;
        return s_best_ball_vel;
    }
    
    

    学习心得与体会

    这一次只看了一个cpp文件,感觉进度比较,我认为原因有以下几点吧。第一点就是自己没有安排好学习计划,经常会被其他的事情占用了我的学习robcup的时间,导致我花费在robcup上面的时间比我预计的要少。第二点就是,许多的函数里面调用了很多底层的东西,这些东西如何自己去查找?或者这个东西值不值得去理解原理,我把握不好这个度。
    所以,这一次的学习过程,最大的收获的其实不是robcup的函数又掌握了多少,而是我明白了学习过程中让我成长缓慢的痛点,而这个痛点越早察觉到,对我以后的学习过程的帮助越大。希望自己能够有所改进!

  • 相关阅读:
    iOS设计模式之观察者模式
    iOS设计模式之装饰者模式
    【Dart学习】--之Iterable相关方法总结
    【Dart学习】--之Duration相关方法总结
    【Flutter学习】基本组件之弹窗和提示(SnackBar、BottomSheet、Dialog)
    【Dart学习】--Dart之超级父类之Object
    从零开始实现ASP.NET Core MVC的插件式开发(五)
    从零开始实现ASP.NET Core MVC的插件式开发(四)
    从零开始实现ASP.NET Core MVC的插件式开发(三)
    从零开始实现ASP.NET Core MVC的插件式开发(二)
  • 原文地址:https://www.cnblogs.com/782687539-nanfu/p/12707603.html
Copyright © 2011-2022 走看看