📄 basicplayer.cpp
字号:
/*Copyright (c) 2000-2003, Jelle Kok, University of AmsterdamAll rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions are met:1. Redistributions of source code must retain the above copyright notice, thislist of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice,this list of conditions and the following disclaimer in the documentationand/or other materials provided with the distribution.3. Neither the name of the University of Amsterdam nor the names of itscontributors may be used to endorse or promote products derived from thissoftware without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLEFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIALDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ORSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVERCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USEOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*//*这个Basic Player模块记录了所有的球员基本技能,它仅仅负责指定生成动作用于记录到命令队列,而不会进行高层的决策判断。有些关键动作一个周期只允许发送一次,但是一些动作是允许在一个一个周期内执行多个的,比如转动脖子指令。注释修改:05计算机2 席浩洋*//*! \file BasicPlayer.cpp<pre><b>File:</b> BasicPlayer.cpp<b>Project:</b> Robocup Soccer Simulation Team: UvA Trilearn<b>Authors:</b> Jelle Kok<b>Created:</b> 10/12/2000<b>Last Revision:</b> $ID$<b>Contents:</b> This file contains the class declaration for the BasicPlayer. The BasicPlayer is the class where the available skills for the agent are defined.<hr size=2><h2><b>Changes</b></h2><b>Date</b> <b>Author</b> <b>Comment</b>:10/12/2000 Jelle Kok Initial version created</pre>*/#include "BasicPlayer.h"#include "Parse.h" // parseFirstInt/********************** LOW-LEVEL SKILLS *************************************//********************** 低层次技术动作 *************************************//*! This skill enables an agent to align his neck with his body. It returns a turn neck command that takes the angle of the agent's body relative to his neck as its only argument. \return SoccerCommand turn_neck command that aligns neck with body *//* 这个命令用于让球员将脖子转向身体前方(于Body同向) 返回一个让球员脖子转向和身体同向的命令 */SoccerCommand BasicPlayer::alignNeckWithBody( ){ return SoccerCommand( CMD_TURNNECK, WM->getAgentBodyAngleRelToNeck( ) );//取得脖子和身体的相对角度}/*! This skill enables an agent to turn his body towards a given point. It receives a global position 'pos' on the field and returns a turn command that will turn the agent's body towards this point. To this end the agent's global position in the next cycle is predicted based on his current velocity. This is done to compensate for the fact that the remaining velocity will move the agent to another position in the next cycle. The global angle between the given position and the predicted position is then determined after which the agent's global body direction is subtracted from this angle in order to make it relative to the agent's body. Finally, the resulting angle is normalized and adjusted to compensate for the inertia moment and speed of the agent. If it is impossible to turn towards the given position in a single cycle then the agent turns as far as possible. \param pos position to which body should be turned \param iCycles denotes the number of cycles that are used to update the the agent position. The resulting position is compared with 'pos' to determine the desired turning angle. \return SoccerCommand turn command to turn body to the desired point *//* 这个函数用于将身体转向一个绝对点,当无法进行那么大角度的转动,则尽力的转动最大角度 pos : 参数指定绝对点 iCycles = 1 : 预测当前球员于几个周期后的位置,然后会以那个点为基点进行转身,默认计算一个周期之后的位置 返回一个转体指令 (之后的所有返回,因为和功能类似所以不再赘述)*/SoccerCommand BasicPlayer::turnBodyToPoint( VecPosition pos, int iCycles ){ VecPosition posGlobal = WM->predictAgentPos(iCycles, 0);//预测iCycles周期后当前球员的位置 AngDeg angTurn = (pos - posGlobal).getDirection();//取得需要转到的方向 angTurn -= WM->getAgentGlobalBodyAngle();//取得需要转到的方向和球员的向对角度 angTurn = VecPosition::normalizeAngle( angTurn );//将角度标准化 angTurn = WM->getAngleForTurn( angTurn, WM->getAgentSpeed(), WM->getAgentObjectType() );//取得转向速度等参数 return SoccerCommand( CMD_TURN, angTurn );//生成命令}/*! This skill enables an agent to turn his back towards a given point 'pos'. The only difference between this skill and turnBodyToPoint is that the angle between the given position and the predicted position of the agent in the next cycle is now made relative to the back of the agent by subtracting the agent's global back direction. This skill can for example be used by the goalkeeper in case he wants to move back to his goal while keeping sight of the rest of the field. \param pos position to which the agent's back should be turned \param iCycles denotes the number of cycles that are used to update the the agent position. The resulting position is compared with 'pos' to determine the desired turning angle. \return SoccerCommand command to turn agent's back to the desired point *//* 这个函数的功能类似上一个函数,不同的是它将身体背对一个点,主要用于看着球后退 */SoccerCommand BasicPlayer::turnBackToPoint( VecPosition pos, int iCycles ){ VecPosition posGlobal = WM->predictAgentPos(iCycles, 0); AngDeg angTurn = (pos - posGlobal).getDirection(); angTurn -= (WM->getAgentGlobalBodyAngle() + 180); angTurn = VecPosition::normalizeAngle( angTurn ); angTurn = WM->getAngleForTurn( angTurn, WM->getAgentSpeed(), WM->getAgentObjectType() ); return SoccerCommand( CMD_TURN, angTurn );}/*! This skill enables an agent to turn his neck towards a given point. It receives a global position 'pos' on the field as well as a primary action command 'soc' that will be executed by the agent at the end of the current cycle and returns a turn neck command that will turn the agent's neck towards 'pos'. To this end the agent's global position and neck direction after executing the cmd command are predicted using methods from the world model. The global angle between the given position and the predicted position is then determined after which the predicted neck direction is subtracted from this angle in order to make it relative to the agent's neck. Finally, the resulting angle is normalized and directly passed as an argument to the turn neck command since the actual angle with which a player turns his neck is by definition equal to this argument. If the resulting turn angle causes the absolute angle between the agent's neck and body to exceed the maximum value, then the agent turns his neck as far as possible. Note that it is necessary to supply the selected primary command as an argument to this skill, since a turn neck command can be executed in the same cycle as a kick, dash, turn , move or catch command. \param pos position to which neck should be turned \param soc SoccerCommand that is executed in the same cycle \return SoccerCommand turn command to turn neck to the desired point *//* 这个函数用于将脖子转向一个绝对点,此外可以传入一个主要动作伴随着这个转脖子动作一起进行。 pos : 同上 soc : 在同一个周期内将要进行的主要动作 */SoccerCommand BasicPlayer::turnNeckToPoint(VecPosition pos, SoccerCommand soc){ VecPosition posMe, velMe; AngDeg angBody, angNeck, angActual; Stamina sta; // predict agent information after command 'soc' is performed // 估计执行主要指令“soc”之后的球员状态 // calculate the desired global angle of the neck // calculate the desired angle of the neck relative to the body // 计算所希望的球员状态 WM->predictAgentStateAfterCommand(soc,&posMe,&velMe,&angBody,&angNeck,&sta); AngDeg angDesGlobNeck = (pos - posMe).getDirection(); AngDeg angNeckRelToBody= VecPosition::normalizeAngle(angDesGlobNeck-angBody); // calculate the current angle of the body relative to the neck // 取得当前球员脖子和身体的相对角度 // check if the desired neck angle relative to the body is possible: // 判断希望的角度可否达到? // if angle is smaller than the minimum or larger than the maximum neck angle // turn neck to the minimum or maximum neck angle + the current neck angle // else calculate the desired angle relative to the body // 根据不同的情况转动脖子 AngDeg angBodyRelToNeck = VecPosition::normalizeAngle(angBody-angNeck); if( angNeckRelToBody < SS->getMinNeckAng() ) angActual = SS->getMinNeckAng() + angBodyRelToNeck; else if( angNeckRelToBody > SS->getMaxNeckAng() ) angActual = SS->getMaxNeckAng() + angBodyRelToNeck; else angActual = angNeckRelToBody + angBodyRelToNeck; return SoccerCommand( CMD_TURNNECK, angActual );}/*! lookAround技能用于使球员左右环顾用以查看四周的状况。适用于开球前的信息收集。 lookRight/lookLeft指定球员将脖子向右/左转动一个角度,主要用于战术配合。 \param angTurn 每次转动脖子的角度,角度越大转动的越快,角度必须为正,而且建议<60 \param com 伴随着转动脖子指令一起进行的主要动作 \return 返回一个伴随着主要动作的转脖子指令 */SoccerCommand BasicPlayer::lookAround(AngDeg angTurn,SoccerCommand com ){ static int iFlag = 1; if(WM->getAgentBodyAngleRelToNeck()>80.0) iFlag=1; else if(WM->getAgentBodyAngleRelToNeck()<-80.0) iFlag=-1; angTurn=VecPosition::normalizeAngle(WM->getAgentGlobalNeckAngle() + angTurn*iFlag); VecPosition posLook(10.0, angTurn, POLAR ); posLook += WM->getAgentGlobalPosition(); return turnNeckToPoint(posLook,com);}SoccerCommand BasicPlayer::lookRight(AngDeg angTurn,SoccerCommand com ){ angTurn=VecPosition::normalizeAngle(WM->getAgentGlobalNeckAngle() + angTurn*(-1)); VecPosition posLook(10.0, angTurn, POLAR ); posLook += WM->getAgentGlobalPosition(); return turnNeckToPoint(posLook,com);}SoccerCommand BasicPlayer::lookLeft(AngDeg angTurn,SoccerCommand com ){ angTurn=VecPosition::normalizeAngle(WM->getAgentGlobalNeckAngle() + angTurn); VecPosition posLook(10.0, angTurn, POLAR ); posLook += WM->getAgentGlobalPosition(); return turnNeckToPoint(posLook,com);}/*! This skill enables an agent to search for the ball when he cannot see it. It returns a turn command that causes the agent to turn his body by an angle that equals the width of his current view cone (denoted by the ViewAngle attribute in the AgentObject class). In this way the agent will see an entirely different part of the field after the turn which maximizes the chance that he will see the ball in the next cycle. Note that the agent turns towards the direction in which the ball was last observed to avoid turning back and forth without ever seeing the ball. Furthermore the inertia moment of the agent is taken into account to compensate for the current speed of the agent. \return SoccerCommand that searches for the ball. *//* 在看不见球的时候寻找球的位置,转动的角度将会等于球员当前的视觉范围(圆锥)角度 球员将会自动向最后一次看见球的方向转动,尽量保证不会作多余的转向 */SoccerCommand BasicPlayer::searchBall(){ //定义了三个静态变量用于一直寻找球的位置 static Time timeLastSearch; static SoccerCommand soc; static int iSign = 1; //取得在最后一次看到球的时候,球的位置 VecPosition posBall =WM->getBallPos(); //取得自己的当前位置 VecPosition posAgent=WM->getAgentGlobalPosition(); //取得它们之间的相对角度 AngDeg angBall =(posBall-WM->getAgentGlobalPosition()).getDirection(); //取得球员当前的身体方向 AngDeg angBody =WM->getAgentGlobalBodyAngle(); //如果取得的当前时间等于最后一次寻找的时间,返回寻找指令 if( WM->getCurrentTime().getTime() == timeLastSearch.getTime() ) return soc; //如果已经找了三个周期了,或者说根本还没有开始寻找 if( WM->getCurrentTime() - timeLastSearch > 3 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -