实验四 复杂的动作决策(含WorldModel)

1.实验目的

1.了解 doPreprocess 的工作原理
2.会对 doPreprocess 进行简单的修改 ,能通过底层动作的简单组合控制场上队员做出一些复杂动作决策
3.对WorldModel有初步的认识

2.实验设备

硬件环境:PC机
软件环境:操作系统Linux

3.实验内容

1.截球

截球用到的函数主要有Body_Intercept(),以及Body_Intercept::getBestIntercept();

Body_Intercept( const bool save_recovery = true,
const Vector2D & face_point = Vector2D::INVALIDATED )//设置朝向位置 
//如果save recovery=true,dash_power也会自动调整以保证单位时间体力恢复值不至于减少。  

//截球。在搜索过程中,会自动选择评价最高的截球路径。
//当未搜索到截球路径的时候,不执行任何动作,body_pass()::execute()将返回false。
//调用这一动作之前,调用静态成员函数Body Pass::get best pass()以确认是否存在适合的截球路径,以下是详细参数

Body_Intercept::getBestIntercept( const WorldModel & wm,
                                    const InterceptTable * table ) //初始化预测信息

截球示例:

#include <rcsc/action/body_intercept.h>
const WorldModel & wm = this->world();
int self_min = wm.interceptTable()->selfReachCycle();
//获取预测的球员捕获到球的最小周期数
Vector2D intercept_pos = wm.ball().inertiaPoint( self_min );    
//获取在经过该最小周期数后球的位置

if ( ! wm.existKickableTeammate()//不存在可踢球的成员
    && wm.ball().posCount() <= 1//球位置满足的条件
    && wm.ball().velCount() <= 1//球速度满足的条件
    && self_min < 20            //捕获球时间满足的条件
    )//满足截球条件
{
    Body_Intercept().execute( this );//执行截球动作
    this->setNeckAction( new Neck_TurnToBall() );//调整视角对准球
}

2.在Sample_player里添加状态函数

①打开Sample_player.cpp,在里面写入 bool isOpponentAtAngleEx( AngleDeg angA , AngleDeg angB ,double dDist );
该函数用来 判断当前球员角度在angA~angB之间距离小于dDist的范围内是否有对方队员

填加一个新函数


bool isOpponentAtAngleEx(const WorldModel & wm, AngleDeg angA , AngleDeg angB ,double dDist )
{
    Vector2D selfpos=wm.self().pos();
    Sector2D sector(selfpos, 0, dDist, wm.self().body()+angA,wm.self().body()+angB);
    const PlayerPtrCont & players=wm.opponentsFromSelf();
    const PlayerPtrCont::const_iterator end = players.end();
    for ( PlayerPtrCont::const_iterator it = players.begin();it != end;++it )
        if ( sector.contains( (*it)->pos() ) )
            return true;
    return false
}

③在doReprocess中添加:

if( wm.self().isKickable())
{
    double ang = (Vector2D(52.5,0)-wm.self().pos()).th().degree();
    if ( isOpponentAtAngleEx(wm, ang-45, ang, 6) )
        ang+=45;
    else if ( isOpponentAtAngleEx(wm, ang,ang+45,6) )
        ang-=45;
    Body_KickToRelative( 12,ang,true );
}

然后编译运行程序,观察球员的行为,试分析球员的行为。

附:指定方向踢球

#include <rcsc/action/body_kick_to_relative.h>
Body_KickToRelative( const double & target_dist, 
const AngleDeg & target_angle_rel, 
const bool stop ); 
//向与身体朝向target_angle_rel角度的方向,将球踢出target_dist距离。
//根据需要进行多步踢法的规划。但是,因为踢球动作不能被持续执行,在下个周期内,必须要重新进行踢球设计。
//如果stop = true,则需要调整踢球规划,以便能够在设定位置处停住球。

到此为止,doReprocess的基本内容已经向大家介绍完毕,希望大家能够熟练的应用doReprocess 函数。

根据以上描述完成练习:通过基本动作的组合实现球员的以下行为(要求至少做出1~2 个题目,更多基本动作请查询BodyAction的各个派生类,或其他有关书籍,也希望大家能做出更多的动 作来)

  • 判断守门员的位置,朝球门空隙较大的一方射门,(通过在WorldModel里建立新状态来判断,球门哪一方空隙较大,守门员的位置为Vector2D posGoalie = wm->getOpponentGoalie().pos();
    球门位置坐标为(52.5,0), 可尝试朝(52.5,6.5)(52.5,-6.5)两点射门)

  • 在 SamplePlayer里填加一个带球函数,要求如果无人阻挡(带球将要经过的路线附近 没有对方球员)就朝球门方向带球,否则想办法避开对方球员带球前进(要求只要 作出闪避的动作即可,不要求效果)。

  • 尝试修改视觉函数使得球员能更多的获得场上信息(要求不影响球员的动作)。

Copyright@Njupt-Apollo-2d-2021 all right reserved,powered by Gitbook该文件最新修订时间: 2022-02-26 09:05:41

results matching ""

    No results matching ""