进攻方向是X轴的正方向,顺时针旋转90°后就是Y轴正方向,球场内的X的取值范围是[-52.5, 52.5],Y的取值范围是[-34, 34]。
球场中的各个位置分布着flag,用于球员定位自己、己方球员、对方球员、球的位置。
由 SoccerServer 控制的比赛流程分为以下步骤
(1) 裁判启动仿真平台。(可以利用 rcsoccersim 同时启动 SoccerServer 和 SoccerMonitor)
(2) 双方启动各自的 12 个 Client 程序(一般为 11 个球员智能体和 1 个教练智能体)与
平台连接。
(3) 准备完成后,裁判按下 Kick_off 按钮开始上半场 3000 周期的比赛(为实际时间的 5 分钟)。
(4) 上半场结束,SoccerServer 暂停比赛。
(5) 在下半场比赛开始之前,每个 Client 使用 reconnect 命令重新连接 SoccerServer。
(6) 下半场结束,比赛自动停止。
(7) 若比赛为平局,则进入上下半场各位 1000 周期的加时赛,当加时赛仍未平局时,则进入双方互射单刀球形式的“点球大战”决出最后胜利者
在比赛过程中不同的比赛阶段存在不同的比赛模式GameMode,在Agent 2D的底层代码中的util文件夹下的game_mode文件中对各类比赛模式做了枚举。(ps:在world model中可以获得场上的比赛模式以及side,game_mode定义在rcsc命名空间中)
enum Type {
BeforeKickOff, //开球前
TimeOver, //
PlayOn, //正常踢球
KickOff_, // Left | Right开球
KickIn_, // Left | Right界外球
FreeKick_, // Left | Right任意球
CornerKick_, // Left | Right角球
GoalKick_, // Left | Right球门球
AfterGoal_, // Left | Right进球
//Drop_Ball, // Left | Right
OffSide_, // Left | Right越位
PenaltyKick_, // Left | Right点球
FirstHalfOver, //上半场结束
Pause, //暂停
Human,
FoulCharge_, // Left | Right违规撞人
FoulPush_, // Left | Right违规推人
FoulMultipleAttacker_, // Left | Right
FoulBallOut_, // Left | Right
BackPass_, // Left | Right回传
FreeKickFault_, // Left | Right任意球违规
CatchFault_, // Left | Right扑球违规
IndFreeKick_, // Left | Right非直接任意球
PenaltySetup_, // Left | Right
PenaltyReady_, // Left | Right
PenaltyTaken_, // Left | Right
PenaltyMiss_, // Left | Right
PenaltyScore_, // Left | Right
// these are not a real playmode
PenaltyOnfield_, // next real playmode is PenaltySetup_
PenaltyFoul_, // next real playmode is PenaltyMiss_ or PenaltyScore_
//PenaltyWinner_, // next real playmode is TimeOver
//PenaltyDraw, // next real playmode is TimeOver
GoalieCatch_, // Left | Right
ExtendHalf,
MODE_MAX
};
比赛平台分为server、client(每队12client=11球员+1*在线教练)、monitor。
先开server端并打开monitor将球场画面呈现出来,随后每队初始化12 个client进程并通过UDP/IP连接到server上。
每个球员程序都是独立的进程,通过一个特定的端口和比赛平台连接。当一个球员程序和比赛平台建立好连接后,所有通讯信息都通过这个端口传输。这些球员程序向比赛平台发送请求执行相应行为,平台分析处理这些请求,相应的更新场上比赛状态。另一方面,比赛平台给所有队员提供他们可以感知到的信息(教练可以获得比普通球员更多的信息),如球员可以看到的视觉信息、球员自身的状态信息等。由于比赛平台实际上是一种以离散时间片/周期(为cycle)为时间单位工作的实时系统,球员程序必须在每个指定仿真周期内及时做出决策并及时将请求发送给比赛平台,否则将错过执行动作的机会。
WorldModel类(世界模型)
世界模型实例化了大量其他的类(比如SelfObject、BallObject、PlayerCont等),通过实现获取这些示例的共有方法(如ball()、self()等等)来获取这些实例。
通过这些示例可以获取球场上的各种信息(例如:wm.ball().pos()球的位置以及速度,球员的位置以及速度(包括我方球员以及对方球员),球员的体力值之类的,所有的基本信息都可以从世界模型里面获取)
这些基本信息包括:?
action
动作类底层代码,通过调用更底层的基本动作代码和相互调用,实现各类更高级的动作。
同时这些action中的底层动作代码被更高层的动作代码调用,在与决策结合之后组成复杂的球员行为。
常见的有bhv_scan_field、body_pass、body_intercept2009、bhv_go_to_point_look_all等等
ann
全程为artificial neural network,即人工神经网络类,其中内容不是特别丰富。基于RBF作为激活函数的神经网络。
coach
包含在线教练类
common
包含一些公共的类,如BasicClient、PlayParam、SoccerAgent、StaminaModel等等
formation
包含一些阵型类,阵形如bpn、cdt、dt、knn、ngnet(与ann有关)、rbf(与ann有关)等等
geom
全称是geometry即几何,包含一些几何类。
其中用的比较多的有:Vector2D(二维向量)、Ray2D(线)、Rect2D(矩形)、Circle2D(圆)等等
gz
不知道
monitor
包含显示器命令类
net
包含一些基本的、TCP、UDP的套接字socket类,用于通信。
param
包含一些参数类。
player
包含球员类,包含WorldModel、PlayerAgent、DebugClient等等
rcg
time
包含一些时间类
tariner
包含一些离线教练的类
util
包含一些多功能类和工具。如GameModel、version
chain_action
动作链
bhv
动作类
main
各个主程序
intention
意图类
role
角色类
sample
样例类
/*进攻球员跑位文件*/
bool execute(rcsc::PlayerAgent* agent){return false;}
// 为什么直接返回false?
bool Bhv_AttackersMove::AttackersMove(PlayerAgent * agent)
//进攻球员跑位
//调用Bhv_BasicTackle(0.75, 90.0).execute(agent),能铲球则铲球,否则
//如果自己有充足体力,且对方球员截球条件好于自己和队友,且球靠近自己的位置和home_pos
//则尝试调用Body_ForestallBlock(agent),进行拦截,拦截成功则设置视角方向,否则
//如果intercept
//
void Bhv_AttackersMove::doGoToCrossPoint( rcsc::PlayerAgent * agent)
//cross 传中,有时候泛指横传,所以是去传中点或者长传点?
bool Bhv_AttackersMove::Body_ForestallBlock(PlayerAgent * agent)
//forestallblock先手拦截?
bool Bhv_AttackersMove::doCheckCrossPoint( rcsc::PlayerAgent * agent )
//私有方法,check 阻挡,检查,所以是阻挡传中点或者检查传中点?
double Bhv_AttackersMove::getDashPower(const PlayerAgent * agent, const Vector2D & target_point)
//私有方法,返回球员沿身体方向加速,Power 表示加速使用的力量大小,取值为-100~100。
//详情见体力模型
/*基本跑位文件*/
bool Bhv_BasicMove::execute( PlayerAgent * agent )
//实现基本跑位,套路是:能铲球则铲球,不能则跑位
double getDashPower( const rcsc::PlayerAgent * agent );
//该方法没有实现
铲球模型1
/*基本的进攻型踢球/
bool execute( rcsc::PlayerAgent * agent );
//实现offensive的踢球,里面涉及踢球的安全性以及传球的操作
//一般过程详见踢球模型
//里面涉及Body_Pass类的方法
bool execute_side_cross( rcsc::PlayerAgent * agent );
//side cross 是边锋的意思
//可能是针对side cross的踢球
//该方法相较于excute方法只是在判断条件处修改了参数
/*基本的铲球动作*/
bool execute( rcsc::PlayerAgent * agent );
//不同版本的execute(old v12 v14)
//基本的铲球动作
Bhv_BasicTackle( const double & min_prob, const double & body_thr ): M_min_probability( min_prob ), M_body_thr( body_thr ){ }
//构造函数
铲球模型1
explicit Bhv_CustomBeforeKickOff( const rcsc::Vector2D & point ): M_move_point( point ){ }
//构造函数
//C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式).
bool execute( rcsc::PlayerAgent * agent );
//根据场上时间、开球模式等信息做动作?可能做一些转向之类。
/*危险区铲球动作*/
Bhv_DangerAreaTackle( const double & min_prob = 0.85 ) : M_min_probability( min_prob ) { }
//构造函数
bool execute( rcsc::PlayerAgent * agent );
// 如果有铲球对手、铲球概率大于某值,则根据场上情况,调整参数后铲球
铲球模型1
/*移动到静止的球*/
Bhv_GoToStaticBall( const rcsc::AngleDeg & ball_place_angle ): M_ball_place_angle( ball_place_angle ){ }
//构造函数
bool execute( rcsc::PlayerAgent * agent );
//根据球的角度、自己的位置、身体的朝向修改dash_power等dash到静止的球?
/*守门员的基本跑位动作*/
Bhv_GoalieBasicMove(){ }
//构造函数
bool execute( rcsc::PlayerAgent * agent );
//能铲球则铲球
//execute调用下面的私有方法
rcsc::Vector2D getTargetPoint( rcsc::PlayerAgent * agent );
//主要是根据球的轨迹、敌人的位置等因素,来计算出守门员应该处于的目标点并且返回该值。
double getBasicDashPower( rcsc::PlayerAgent * agent, const rcsc::Vector2D & move_point );
//主要是根据球的x坐标,进行危险度划分,然后再结合自身的体力值等因素来得到最合适的DashPower并且返回。
bool doPrepareDeepCross( rcsc::PlayerAgent * agent, const rcsc::Vector2D & move_point );
//做准备?
bool doStopAtMovePoint( rcsc::PlayerAgent * agent, const rcsc::Vector2D & move_point );
//主要作用是结合自己的位置、速度还有目标点的位置,来判断自己是否应该终止跑向目标点的行动。
bool doMoveForDangerousState( rcsc::PlayerAgent * agent, const rcsc::Vector2D & move_point );
//主要作用是结合自身的位置、球的位置、敌人距离球的距离等因素,来判断自己是否应该前往危险区域。
bool doCorrectX( rcsc::PlayerAgent * agent, const rcsc::Vector2D & move_point );
//主要作用是j考虑球与地方球员的危险程度,来校准当前守门员的x值。
bool doCorrectBodyDir( rcsc::PlayerAgent * agent, const rcsc::Vector2D & move_point, const bool consider_opp );
//主要作用是根据自身与球的角度差、地方球员的威胁程度等因素来调节守门员的身体朝向。
bool doGoToMovePoint( rcsc::PlayerAgent * agent, const rcsc::Vector2D & move_point );
//主要作用是根据身体的朝向、目标点与自身的位置等因素来执行移动到目标点的动作。
void doGoToPointLookBall( rcsc::PlayerAgent * agent,
const rcsc::Vector2D & target_point,
const rcsc::AngleDeg & body_angle,
const double & dist_thr,
const double & dash_power,
const double & back_power_rate = 0.7 );
//只是在doGoToPoint函数的基础上加了一个Look的动作
/*守门员追球动作*/
bool execute( rcsc::PlayerAgent * agent );
//能铲球则铲球
//
//里面有Body_Intercept的execute方法抢断球
bool is_ball_chase_situation( const rcsc::PlayerAgent * agent );
// 根据球、队友、对手的相对位置信息得到球的信息并转发队友
bool is_ball_shoot_moving( const rcsc::PlayerAgent * agent );
//球是否被被踢射门
void doGoToCatchPoint( rcsc::PlayerAgent * agent,
const rcsc::Vector2D & target_point );
//私有方法,跑到扑球点,其中包括各种角度的dash。
/*守门员踢任意球动作*/
bool execute( rcsc::PlayerAgent * agent );
//不在GoalieCatch_或者ourSide()模式下,且球不能踢,则守门员执行基本跑位
//开始计时,进行第一次移动(地点确定),随后检查自身体力值
//第二次移动,调用getKickPoint获得踢球点并移动到此,转动身体,随后wait see info
//调用doKick
rcsc::Vector2D getKickPoint( const rcsc::PlayerAgent * agent );
//没怎么看懂?
//获得最好的踢球点吗
void doKick( rcsc::PlayerAgent * agent );
//调用Body_Pass中get_best_past方法获得最优的传球点和传球速度
//根据对方球员到传球目标点的距离判断传球点安全后,调用Body_KickOneStep中的execute方法踢球
//否则调用Body_ClearBall中的execute方法
void doWait( rcsc::PlayerAgent * agent );
//根据罚球区范围、球员位置和大小、球大小调整朝向,调用Body_TurnToPoint中的execute方法
任意球2
/*点球动作*/
bool execute( rcsc::PlayerAgent * agent );
//根据场上模式和罚球方做不同的动作
//
bool doKickerWait( rcsc::PlayerAgent * agent );
//如果已经到wait point,则转身体;否则跑到wait_position
bool doKickerSetup( rcsc::PlayerAgent * agent );
//跑到静止的球,如果已经到了;则转向对方守门员
bool doKickerReady( rcsc::PlayerAgent * agent );
//如果体力太少或者球踢不了,则调用doKickerSetup;否则调用doKicker踢球
bool doKicker( rcsc::PlayerAgent * agent );
//分单踢还是多踢两种情况
//单踢调用doOneKickShoot
//多踢调用doShoot
// used only for one kick PK
bool doOneKickShoot( rcsc::PlayerAgent * agent );
//根据守门员位置、球我的角度调整角度后调用Body_KickOneStep的execute方法
// used only for multi kick PK
bool doShoot( rcsc::PlayerAgent * agent );
//没时间了直接调用doOneKickShoot单踢,有时间调用Body_SmartKickexecute方法
bool getShootTarget( const rcsc::PlayerAgent * agent,
rcsc::Vector2D * point,
double * first_speed );
//获得射球的点
bool doDribble( rcsc::PlayerAgent * agent );
//带球到可以射门的点
//当带球点太远时,啥事不干
//否则:根据敌手守门员位置、距离和调整带球点位置,并调整dribble的dashpower
//守门员
bool doGoalieWait( rcsc::PlayerAgent * agent );
//跑到等球位置,并面向球。
bool doGoalieSetup( rcsc::PlayerAgent * agent );
//跑到固定位置
bool doGoalie( rcsc::PlayerAgent * agent );
//尝试扑球,并向对方方向无人能控球的地方将球踢出。
//判断是否能多踢
//如果可以,则调用doGoalieBasicMove
//否则,根据情况选择doGoalieSetup或者doGoalieSlideChase
bool doGoalieBasicMove( rcsc::PlayerAgent * agent );
//获得inertiaPoint,并判断能否截球,能则调用Body_Intercept的execute方法
//否则根据场上是否有敌手控球来调整跑位
rcsc::Vector2D getGoalieMovePos( const rcsc::Vector2D & ball_pos,
const rcsc::Vector2D & my_pos );
bool isGoalieBallChaseSituation();
bool doGoalieSlideChase( rcsc::PlayerAgent * agent );
//调用Body_StopDash的execute方法
//调用doDash方法
//调用Body_Intercept的execute方法
bool doTurnNeckToShootPoint( rcsc::PlayerAgent * agent,
const rcsc::Vector2D & shoot_point );//add jelly
set_play3
/*团队配合前的准备*/
Bhv_PrepareSetPlayKick( const rcsc::AngleDeg & ball_place_angle,
const int wait_cycle )
: M_ball_place_angle( ball_place_angle )
, M_wait_cycle( wait_cycle )
{ }
//构造函数
bool execute( rcsc::PlayerAgent * agent );
//调用Bhv_GoToStaticBall的execute方法,并等周期cycle
bool doGoToStaticBall( rcsc::PlayerAgent * agent );
/*在不同模式下团队配合的不同调用*/
Bhv_SetPlay()
{ }
//构造函数
bool execute( rcsc::PlayerAgent * agent );
//如果自己是守门员,根据踢球模式选择Bhv_GoalieFreeKick的execute方法或者Bhv_SetPlayIndirectFreeKick的execute方法
//否则:根据场上模式以及gamemode.side()执行不同的动作
//KickOff_开球:Bhv_SetPlayKickOff().execute()(己方)或者doBasicTheirSetPlayMove()(对方)
//CornerKick_角球:Bhv_SetPlayKickIn().execute( );(己方)或者doCornerKickmove()(对方)
//FreeKick_任意球:Bhv_SetPlayFreeKick().execute();(己方)或者doBasicTheirSetPlayMove()(对方)
//GoalKick_球门球:Bhv_SetPlayGoalKick().execute( );(己方)或者Bhv_TheirGoalKickMove().execute()
//FoulPush_犯规:Bhv_SetPlayIndirectFreeKick().execute( agent );不分敌我方应该是该方法都包含了解决方案
//isOurSetPlay:Bhv_SetPlayFreeKick().execute( agent );(我方)或者doBasicTheirSetPlayMove( agent );(对方)
static rcsc::Vector2D get_avoid_circle_point( const rcsc::WorldModel & world, const rcsc::Vector2D & target_point );
//获取避开原点?
//用到了can_go_to方法?
static double get_set_play_dash_power( const rcsc::PlayerAgent * agent );
//根据球、球员、targetPoint位置选择返回getSafetyDashPower或者其他值
static bool is_kicker( const rcsc::PlayerAgent * agent );
//如果我们队的守门员catch到球且自己不是守门员,则返回false
//否则找到离球最近的球员号码
static bool is_delaying_tactics_situation( const rcsc::PlayerAgent * agent );
//根据对方和我方得分和场上周期数来判断采取delaying策略
void doBasicTheirSetPlayMove( rcsc::PlayerAgent * agent );
//在敌手发定点球时的跑位
//没仔细看
void doCornerKickmove( rcsc::PlayerAgent * agent );
//在敌手发角球的跑位
//没仔细看
/*团队配合的任意球*/
Bhv_SetPlayFreeKick()
{ }
//构造函数
bool execute( rcsc::PlayerAgent * agent );
//调用 Bhv_SetPlay::is_kicker( agent )判断自己是不是kicker
//是则调用doKick()
//否则调用doMove()
void doKick( rcsc::PlayerAgent * agent );
//先调用doKickWait
//随后调用ChainAction(连锁动作、联合进攻)
bool doKickWait( rcsc::PlayerAgent * agent );
//判断是否为delaying战术,是则调整视角方向返回true
//根据自身体力和setplayCount大小决定返回true还是false
//setplayCount是周期?代表什么?
void doMove( rcsc::PlayerAgent * agent );
//如果setplayCount大于0、体力充足、且敌手球员存在且离我足够近
//则根据场上时间周期调整targetPoint,根据get_set_play_dash_power获得dashPower
//由targetPoint和dashPower和与球到自身距离相关的阈值跑到目标点
//是要做拦截封走位?
/*团队配合的球门球*/
Bhv_SetPlayGoalKick()
{ }
//构造函数
bool execute( rcsc::PlayerAgent * agent );
//调用 Bhv_SetPlay::is_kicker( agent )判断自己是不是kicker
//是则调用doKick()
//否则调用doMove()
void doKick( rcsc::PlayerAgent * agent );
//调用Bhv_GoToStaticBall( 0.0 ).execute( agent )跑到球边
//调用doKickWait
//调用doPass
//调用doKickToFarSide
//调用Body_ClearBall().execute( agent );踢解围球
bool doSecondKick( rcsc::PlayerAgent * agent );
//先根据球在场上位置判断是否要踢第二次
//如果自己可踢,则先考虑调用doPass()传球
//其次考虑Body_ClearBall().execute( agent );踢解围球
//然后考虑调用doIntercept()截球
//最后根据wm.ball().inertiaFinalPoint(); 考虑Body_GoToPoint()追球
bool doKickWait( rcsc::PlayerAgent * agent );
//判断是否为delaying战术,是则调整视角方向返回true
//根据自身体力和setplayCount大小调整视角方向并决定返回true还是false
bool doPass( rcsc::PlayerAgent * agent );
//看方法名应该是传球的意思
//调用Bhv_ChainAction().execute( agent )联合动作链
bool doKickToFarSide( rcsc::PlayerAgent * agent );
//没仔细看,应该是将球很远,可能配合长传、解围球
bool doIntercept( rcsc::PlayerAgent * agent );
//先根据球在球场的位置判断能否截球
//如果自己带球则返回false
//如果队友截球距离小于我,则返回false,让队友截球
//根据球的interiaPoint在场上的位置选择是否调用Body_Intercept().execute( agent );截球
void doMove( rcsc::PlayerAgent * agent );
//先调用doIntercept看能否截球
//如果setplayCount大于0、体力充足、且敌手球员存在且离我足够近
//则根据场上时间周期调整targetPoint,根据get_set_play_dash_power获得dashPower
//由targetPoint和dashPower和与球到自身距离相关的阈值跑到目标点
goal kick4
/*团队配合的非直接任意球*/
Bhv_SetPlayIndirectFreeKick()
{ }
//构造函数
bool execute( rcsc::PlayerAgent * agent );
//判断:对方BackPass回传 或者 我方IndFreeKick非直接任意球 或者 对方FoulCharge 或者 对方FoulPush是否为真
//是则:调用Bhv_SetPlay::is_kicker( agent )判断是否为踢球者,是则调用doKicker()踢球,否则调用doOffenseMove( agent );带进攻性跑位
//否则:调用doDefenseMove( agent );带防守性质的跑位
void doKicker( rcsc::PlayerAgent * agent );
//试图调用Bhv_GoToStaticBall( 0.0 ).execute( agent )跑向球
//否则试图调用doKickWait( agent )等待
//否则试图调用doKickToShooter( agent )将球踢向射门球员
//否则试图Bhv_ChainAction().execute( agent )动作链IntentionWaitAfterSetPlayKick()
//否则判断周围是否有队友,无队友调用Body_KickOneStep( target_point, ball_speed ).execute( agent );踢球,有队友则传球给最近队友
bool doKickWait( rcsc::PlayerAgent * agent );
//调整Body_TurnToPoint( face_point ).execute( agent );和agent->setNeckAction( new Neck_ScanField() );
bool doKickToShooter( rcsc::PlayerAgent * agent );
//遍历从近到远所有球员,找出shooter没有则返回false
//根据receiver位置信息设置踢球参量,调用Body_KickOneStep( target_point, ball_speed ).execute( agent );
void doOffenseMove( rcsc::PlayerAgent * agent );
//带进攻性的跑位
//调用wm.self().getSafetyDashPower( ServerParam::i().maxDashPower() );获得dashPower
//设置阈值、targetPoint参数之后,调用Body_GoToPoint
void doDefenseMove( rcsc::PlayerAgent * agent );
//带防守性质的跑位
//调用wm.self().getSafetyDashPower( ServerParam::i().maxDashPower() );获得dashPower
//设置阈值、targetPoint参数之后,调用Body_GoToPoint
//细节地方没看懂,与带进攻性质跑位的区别
/*团队配合的界外球*/
Bhv_SetPlayKickIn()
{ }
//构造函数
bool execute( rcsc::PlayerAgent * agent );
//调用Bhv_SetPlay::is_kicker( agent)判断是否为踢球者
//是则调用doKick( agent );
//否则调用doMove( agent );
void doKick( rcsc::PlayerAgent * agent );
//调用Bhv_GoToStaticBall( ball_place_angle ).execute( agent )跑向球
//否则调用doKickWait( agent )等待
//否则调用Bhv_ChainAction().execute( agent )动作链,setIntention( new IntentionWaitAfterSetPlayKick() );是干啥?
//否则根据球位置,离球最近的我方和对方球员位置修改参数,最终调用Body_KickOneStep(target_point, ball_speed).execute( agent );
//否则调用Body_TurnToBall().execute( agent );面向球
//否则调用Body_AdvanceBall().execute( agent );啥意思?
//否则设置参数后,调用 Body_KickOneStep( target_point, ServerParam::i().ballSpeedMax()).execute( agent );踢到the opponent side corner
bool doKickWait( rcsc::PlayerAgent * agent );
//判断是否为delaying战术,是则调整视角方向返回true
//根据自身体力和setplayCount大小调整视角方向并决定返回true还是false
void doMove( rcsc::PlayerAgent * agent );
//如果体力充足、且敌手球员存在且离我足够近
//则根据场上时间周期调整targetPoint,根据get_set_play_dash_power获得dashPower
//由targetPoint和dashPower和与球到自身距离相关的阈值,调用Body_GoToPoint( target_point, dist_thr, dash_power ).execute( agent )跑到目标点
界外球5
/*团队配合的开球*/
Bhv_SetPlayKickOff()
{ }
//构造函数
bool execute( rcsc::PlayerAgent * agent );
//没有队友或者队友到球的距离比我远,则调用doKick( agent );,否则调用doMove( agent );
void doKick( rcsc::PlayerAgent * agent );
//调用Bhv_GoToStaticBall( 0.0 ).execute( agent )
//否则调用doKickWait( agent )
//否则判断是否有队友:
//无队友则:根据场上周期和球场长度和球门长度获得一个targetPoint
//有队友但是距离太远:同样获得一个targetPoint
//有队友距离不远:targetPoint设为inertiaFinalPoint();,并发送targetPoint、ball_speed等信息
//调整参数后,调用Body_SmartKick( target_point, ball_speed, ball_speed * 0.96,1 ).execute( agent );
bool doKickWait( rcsc::PlayerAgent * agent );
//判断是否为delaying战术,是则调整视角方向返回true
//判断周围是否有队友或者距离(size?)很近,无队友则调整视角方向返回true
//判断体力<0.9max则调整视角方向并决定返回true
void doMove( rcsc::PlayerAgent * agent );
//调用Bhv_SetPlay::get_set_play_dash_power( agent );获得dashPower
//调用Strategy::i().getPosition( wm.self().unum() );获得自己位置并修改为targetPoint
//设置好阈值dis_thr后,调用Body_GoToPoint( target_point, dist_thr, dash_power).execute( agent ) )
/*对方球门球的跑位*/
Bhv_TheirGoalKickMove()
{ }
//构造函数
bool execute( rcsc::PlayerAgent * agent );
//调用doChaseBall( agent )追球
//否则
//intersection
//expand_their_penalty.contains( wm.ball().pos()啥意思?expand_their_penalty.intersection啥意思?
void doNormal( rcsc::PlayerAgent * agent );
//根据球的位置和禁区位置修改targetPoint
//调用Bhv_SetPlay::get_set_play_dash_power( agent );获得dashPower
//调用Body_GoToPoint( target_point, dist_thr, dash_power ).execute( agent )跑到目标点
//设置setNeckAction( new Neck_TurnToBallOrScan() )
bool doChaseBall( rcsc::PlayerAgent * agent );
//根据对方罚球区/禁区位置、自己位置判断是否能追球
//不能追球则返回false
//能追球则调用Body_Intercept().execute( agent );,返回true
高层代码中bhv开头的cpp文件通过调用底层类的方法实现较为高级的动作,其中大致做如下分类:
1、basic类6
2、goalie类7
3、set_play类8
4、gameMode类9
5、其他类10
/*后卫 2号 3号行为动作*/
virtual
bool execute( rcsc::PlayerAgent * agent );
void doDefMidFieldMove(rcsc::PlayerAgent * agent);
void doKick( rcsc::PlayerAgent * agent );
void doMove( rcsc::PlayerAgent * agent );
void doOffensiveMove(rcsc::PlayerAgent * agent);
void doDefensiveMove(rcsc::PlayerAgent * agent);
void doDribbleBlockMove(rcsc::PlayerAgent* agent);
void doCrossAreaMove(rcsc::PlayerAgent * agent);
/*中后卫 2号 3号跑位*/
rolecenterbackmove()
{}
//构造函数
double get_dash_power(const rcsc::PlayerAgent * agent, const rcsc::Vector2D & home_pos);
//
void doBasicMove(rcsc::PlayerAgent * agent, const rcsc::Vector2D & home_pos);
//基本跑位
//能铲球则铲球,调用Bhv_BasicTackle(0.87, 70.0).execute(agent)
//如果队友没带球,根据队友、我、对手的截球距离将截球状态分为(初始级别为0)1-5、9、10、12、13个等级
//只要存在截球的可能,即级别intercept_state不为0,就去追球Body_Intercept2009().execute(agent);
//并如果对方球员离球很近,则头转向球,如果不存在对方球员则头转向球或者四处扫描。
//调用getBasicMoveTarget获得targetPoint,调用get_dash_power获得dashPower
//根据球的位置和自身体力选择调用Bhv_GoToPointLookBall(target_point, dist_thr, dash_power).execute(agent);或者doGoToPoint(agent, target_point, dist_thr, dash_power, 15.0); // dir_thr
//根据对手截球距离选择Neck_TurnToBall或者Neck_TurnToBallOrScan
rcsc::Vector2D getBasicMoveTarget(rcsc::PlayerAgent * agent, const rcsc::Vector2D & home_pos, double * dist_thr);
// 获得基本跑位的目标点
//遍历所有的对方球员,在防守线、特定范围内获得离home_pos最近的对方球员
//如果上述球员存在
//则设置自己y位置与nearest_attacker一致,x根据对方是否突破我的站位来调整?达到阻拦的目的
//此处体现中后卫的人盯人,战术紧贴住对方的攻击球员的策略
//疑问:home_pos代表什么?是每个球员在阵型中的职责点吗?
// unique action for each area
void doCrossBlockAreaMove(rcsc::PlayerAgent * agent, const rcsc::Vector2D & home_pos);
//穿越对方禁区的移动?
//能铲则铲,先调用危险区铲球Bhv_DangerAreaTackle(0.9).execute(agent)否则
//对手持球并且快进入我们的禁区时,调用roleoffensivehalfmove().markCloseOpp(agent),否则
//找对方跑的最快的球员,修改targetPoint为fastest_opp->pos() + wm.ball().pos() ;,并且用最大的dashPower调用doGoToPoint();表示全力以赴防守。否则
//如果对方没带球且我截球距离最小,则调用Body_GoToPoint2010( wm.ball().pos() + wm.ball().vel(), 0.1, ServerParam::i().maxDashPower()).execute( agent )*1.5) //power*1.5否则
//调用doMarkMove,盯人的跑位
//blockArea是什么意思?禁区?所以是表示对方要进入我方禁区的跑位吗?
//roleoffensivehalfmove().markCloseOpp(agent)啥意思?
//wm.existOpponentIn(our_penalty_plus, 1, NULL)啥意思?
//! wm.interceptTable()->isOurTeamBallPossessor()啥意思?
void doStopperMove(rcsc::PlayerAgent * agent, const rcsc::Vector2D & home_pos);
//拦截对方的跑位
//根据球的位置和自身的位置选择是否进行:固定点移动,根据对方最快球员以及对方球员的截球距离选择视角方向,否则
//根据球位置和自身阵型位置选择:doBasicMove基本跑位(无危险)
//或者doMarkMove(有危险)盯人跑位,以及doDangerGetBall,如果non-gettable,则调用Bhv_BasicMove().execute(agent);
void doDangerAreaMove(rcsc::PlayerAgent * agent, const rcsc::Vector2D & home_pos);
//危险区的跑位
//能Bhv_DangerAreaTackle().execute(agent)则tackle,否则
//如果球的位置很危险或者球突破了防线,则选择Body_ClearBall().execute(agent);踢解围球,并扫视
//后面做的动作包括setNeckAction、doGoToPoint、Body_Intercept2009().execute( agent );、markCloseOpp、doDangerGetBall
//选择的条件是:如果球进球概率不大,则选择盯人,截球距离不错就截球,对方截球条件好且或者控球,则做doGotoPoint,自己截球条件好则doDangerGetBall否则盯人。
//ball_line啥意思
//doDangerGetBall里面的策略是什么样的?与intercept有啥区别
void doDefMidMove(rcsc::PlayerAgent * agent, const rcsc::Vector2D & home_pos);
//防守中场的跑位
rcsc::Vector2D getDefMidMoveTarget(rcsc::PlayerAgent * agent, const rcsc::Vector2D & home_pos);
//防守中场的targetPoint
// support action
void doMarkMove(rcsc::PlayerAgent * agent, const rcsc::Vector2D & home_pos);
//盯人的跑位
//能铲球则铲球,Bhv_DangerAreaTackle().execute(agent),否则
//队友没控球且我的截球条件优于队友和对方球员,则调用Body_Intercept2009().execute(agent);
//如果找到对手最快的球员,并且其截球条件不错,则看球和对方球员,否则看球或者扫视。否则
//调用doDangerGetBall,否则
//如果没有离很近的对方球员或者其他条件则调用doBasicMove(agent, home_pos);否则
//
bool markCloseOpp(rcsc::PlayerAgent * agent);
//盯最近的对方球员
bool doDangerGetBall(rcsc::PlayerAgent * agent, const rcsc::Vector2D & home_pos);
//危险区抢球
void doGoToPoint(rcsc::PlayerAgent * agent, const rcsc::Vector2D & target_point,
const double & dist_thr, const double & dash_power,
const double & dir_thr);
//根据dir_thr、dashPower、targetPoint跑到某点
bool Bhv_BlockDribble(rcsc::PlayerAgent * agent);
//
bool execute(rcsc::PlayerAgent *= agent) {return false;}
//执行函数直接返回false
//yily adds this
void doOffensiveMove(rcsc::PlayerAgent * agent);
void doDefensiveMove(rcsc::PlayerAgent * agent);
void doDribbleBlockMove(rcsc::PlayerAgent* agent);
void doCrossAreaMove(rcsc::PlayerAgent * agent);
/*前锋 11号行为动作*/
/* 前卫 6号行为动作*/
/*前卫 6号跑位*/
/*前卫 7号 8号的行为动作*/
/*前卫 7号 8号的跑位*/
/*边后卫 4号 5号的行为动作*/
/*边后卫 4号 5号的跑位*/
/*边前卫 9号 10号的行为动作*/
/*守门员的行为动作*/
中科大robocup教材
markchalse博主博文
Li_Yikai博主博文
南孚先生博主博文
mgkede博主的博文
体力模型11
铲球模型1
踢球模型12
扑球模型13
中后卫center back14
防守15
任意球是一种在足球(或手球) [1] 比赛中发生犯规后重新开始比赛的方法。任意球分两种:直接任意球(踢球队员可将球直接射入犯规队球门得分)及间接任意球(踢球队员不得直接射门得分,球在进入球门前必须被其他队员踢或触及)。 ↩︎
Set offenses start in a predefined formation, or set. From the starting set, plays, options, and apatterns anc be run.进攻开始前的一个固定阵型,然后开始各种跑位带球等。 ↩︎
球门球是足球比赛中重新开始比赛的一种方法。球门球应由守方球员在球门区,直接向球场中踢出。球门球一般由守门员开出。 ↩︎
界外球顾名思义就是出了赛场边界的球。外球是足球比赛中重新开始比赛的一种方式。当足球完全离开足球场边线的时候(在地面或是在空中),一个界外球就判罚给最后触球方的对手。 ↩︎
basic类包括:bhv_basic_move、bhv_basic_offensice_kick、bhv_basic_tackle ↩︎
goalie类包括:bhv_goalie_basic_move、bhv_goalie_chase_ball、bhv_goalie_free_kick ↩︎
set_play类包括:bhv_prepareset_play_kick、bhvset_play、bhv_set_play_free_kick、bhv_set_play_goal_kick、bhv_set_play_indirect_free_kick、bhv_set_play_kick_in、bhv_set_play_kick_off ↩︎
gameMode类包括:bhv_custombefore_kick_off、bhvpenalty_kick ↩︎
其他类包括:bhv_attackers_move、bhv_dangerAreaTackle、bhv_go_to_static_ball、bhv_their_goal_kick_move ↩︎
体力模型:使用dash命令使球员按照他的身体方向进行加速,参数power位于[minpower,maxpower]之间,大于0则向前加速,小于0则反向加速。
↩︎
中后卫(Center Back),足球运动术语,位置处于守门员的前方及左右后卫之间,活动范围在于中后场,属于全队防守力量的核心,主要职责是阻止对方球员策动攻势并同时封锁在对方控球之下进入本方的禁区位置。
最常用的四后卫阵型中多数球队使用两名球员作为中后卫(也有三中卫战术)驻守在守门员前面。中后卫的两个主要职责是要以“人盯人”战术紧贴著对方的攻击球员,并负责弥补防守线出现的漏洞。 ↩︎