实验三 doprocess的基本动作
1.实验目的
1.了解 doPreprocess 的工作原理
2.会对 doPreprocess 进行简单的修改
能通过底层动作的简单组合控制场上队员做出一些复杂动作,掌握控球带球传球等操作
2、实验设备
硬件环境:PC机
软件环境:操作系统Linux
3.实验内容及步骤
1..『传球』 传球用到的函数主要有Body_Pass(),以及Pass::get best pass()
Body_Pass();
//向我方队员传球。在搜索过程中,会自动选择评价最高的传球路径。
//当未搜索到传球路径的时候,不执行任何动作,body_pass()::execute()将返回false。
//调用这一动作之前,调用静态成员函数Body Pass::get best pass()以确认是否存在适合的传球路径,以下是详细参数
Body_Pass::get_best_pass( const WorldModel & world,
Vector2D * target_point,
double*first_speed,
int * receiver )
传球示例:
#include<rcsc/action/body_pass.h>
if ( wm.self().isKickable() ){
rcsc::Vector2D target_point;
double pass_speed = 0.0;
int recever = 11;
rcsc::Body_Pass::get_best_pass( this->world(), &target_point, &pass_speed, &recever );
// target_point为找到的适合传球的目标
// pass_speed为传球过去的速度
rcsc::Body_KickOneStep( target_point,pass_speed ).execute( this );
// KickOneStep函数在实验二中有过介绍,此时为向合适方向踢球
this->setNeckAction( new rcsc::Neck_ScanField() );
return true;
}
2.『控球』 自行编写实现控球函数 控球方式大致如下: 需要函数Body_HoldBall:
#include<rcsc/action/body_hold_ball.h>
Body_HoldBall(const bool do_turn=false,
const Vector2D&face_target=Vector2D(0.0,0.0));
//在当前场地位置控球,防止被对方得球。
//在do_turn=TRUE的情况下,若有转身余地,则身体旋转朝向face_target方向
示例实现:
if ( wm.self().isKickable() )
{
dlog.addText( Logger::DRIBBLE,
__FILE__": doAvoidKick. power over. hold" );
Vector2D face_point= wm.self().pos();
Body_HoldBall( true, face_point );
return true;
}
3.『带球』 带球动作 设计为跑动至禁区,在禁区射门 Body_GoToPoint参数解释如下
#include<rcsc/action/body_go_to_point.h> //头文件
Body_GoToPoint(const Vector2D&target_point,
const double&dist_thr,
const double&dash_power,
const int cycle=100,
const bool back_mode=false,
const bool save_recovery=true,
const double&dir_thr=12.0);
//朝target_point位置方向,以dash_power力量强度,在达到dist_thr距离之前一直带球奔跑。为了在周期后到达制定位置,dash_power会自动调整;
//如果back_mode=true,就执行向后冲刺;如果save recovery=true,dash_power也会自动调整以保证单位时间体力恢复值不至于减少。在所述主体的方向和移动的目点的方向(target_point)误差小于dir_thr
本示例将使用实验二Body_Dribble示例以及判断禁区示例进行演示
if ( wm.self().isKickable() ){
Vector2D goal_pos( ServerParam::i().pitchHalfLength() - 5, 0.0 );
Body_Dribble( goal_pos,
1.0,
ServerParam::i().maxDashPower(),
2
).execute(this);
if(wm.penaltyKickState())
{
Body_KickOneStep( Vector2D(0,0),
ServerParam::i().ballSpeedMax()
).execute(this));
}
return true;
}
实验任务: 编译程序,观察球员行为,包括对带球,传球,控球以及实验二等动作进行检验
根据以下描述完成练习:通过基本动作的组合实现球员的以下行为(更多基本动作请查阅运动类成员函数,或其他有关书籍,也希望大家能做出更多的动作来)
1.如果在对方禁区内就射门,否则,如果是7,8,9号队员就朝前带球,其他队员将球传给9号
// 参考worldmodel中判断禁区位置函数,以及踢球,传球函数:
WorldModel::penaltyKickState() const
{
//assert( M_penalty_kick_state );
return M_penalty_kick_state;
}
2.如果队员的位置在自己半场就将球朝对方球门踢去,否者就朝前方带球
// 参考函数:
GlobalWorldModel::getBallStatus() const
3.当有人来抢球时(离自己很近),就将球传给离自己最近的队员,否则就自己带球
// 参考函数:
GlobalWorldModel::getPlayerNearestTo( const Vector2D & point ) const