⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basicplayer.cpp

📁 2003年RoboCup仿真组世界冠军源代码 足球机器人 仿真组 的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*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.*//*! \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 */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 */SoccerCommand BasicPlayer::turnBodyToPoint( VecPosition pos, int iCycles ){  VecPosition posGlobal = WM->predictAgentPos(iCycles, 0);  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 */SoccerCommand BasicPlayer::turnNeckToPoint(VecPosition pos, SoccerCommand soc){  VecPosition posMe,   velMe;  AngDeg      angBody, angNeck, angActual;  Stamina     sta;  // predict agent information after command 'soc' is performed  // 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 );}/*! 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 )    iSign = ( isAngInInterval( angBall, angBody, 			       VecPosition::normalizeAngle(angBody+180) ) )       ? 1      : -1  ;     //  if( iSign == -1 )  // angBall = VecPosition::normalizeAngle( angBall + 180 );    soc = turnBodyToPoint( posAgent + VecPosition(1.0,		VecPosition::normalizeAngle(angBody+60*iSign), POLAR ) );  Log.log( 556, "search ball: turn to %f s %d t(%d %d) %f", angBall, iSign,           WM->getCurrentTime().getTime(), timeLastSearch.getTime(),	   soc.dAngle );  timeLastSearch = WM->getCurrentTime();  return soc;}/*! This method can be called to create a SoccerCommand that dashes to    a point.  This skill enables an agent to dash to a given point. It    receives a global position 'pos' as its only argument and returns    a dash command that causes the agent to come as close to this    point as possible. Since the agent can only move forwards or    backwards, the closest point to the target position that he can    reach by dashing is the orthogonal projection of 'pos' onto the    line that extends into the direction of his body (forwards and    backwards).  The power that must be supplied to the dash command    is computed using the 'getPowerForDash' method which takes the    position of 'pos' relative to the agent as input and 'iCycles'    which denotes in how many cycles we want to reach that point.    \param pos global position to which the agent wants to dash    \param iCycles desired number of cycles to reach point 'pos'     \return SoccerCommand dash command to move closer to 'pos' */SoccerCommand BasicPlayer::dashToPoint( VecPosition pos, int iCycles ){  double dDashPower = WM->getPowerForDash(                                 pos - WM->getAgentGlobalPosition(),                                 WM->getAgentGlobalBodyAngle(),                                 WM->getAgentGlobalVelocity(),                                 WM->getAgentEffort(),                                 iCycles                              );  return SoccerCommand( CMD_DASH, dDashPower );}/*! This skill enables an agent to freeze a moving ball, i.e. it returns a kick    command that stops the ball dead at its current position. Since ball    movement in the soccer server is implemented as a vector addition, the ball    will stop in the next cycle when it is kicked in such a way that the    resulting acceleration vector has the same length and opposite direction to    the current ball velocity. The desired speed that should be given to the    ball on the kick thus equals the current ball speed. Furthermore, the    direction of the kick should equal the direction of the current ball    velocity plus 180 degrees. Note that this direction must be made relative    to the agent's global body angle before it can be passed as an argument to    the kick command.    \return SoccerCommand to freeze the ball. */SoccerCommand BasicPlayer::freezeBall( ){  // determine power needed to kick the ball to compensate for current speed  // get opposite direction (current direction + 180) relative to body  // and make the kick command.  VecPosition posAgentPred = WM->predictAgentPos( 1, 0 );  double dPower = WM->getKickPowerForSpeed( WM->getBallSpeed() );  if( dPower > SS->getMaxPower() )  {    Log.log( 552, "%d: freeze ball has to much power", WM->getCurrentCycle() );    dPower = (double)SS->getMaxPower();  }  double dAngle = WM->getBallDirection() + 180 - WM->getAgentGlobalBodyAngle();  dAngle        = VecPosition::normalizeAngle( dAngle );  SoccerCommand soc( CMD_KICK, dPower, dAngle );  VecPosition posBall, velBall;  WM->predictBallInfoAfterCommand( soc, &posBall, &velBall );  if( posBall.getDistanceTo( posAgentPred ) < 0.8 * SS->getMaximalKickDist() )    return soc;  Log.log( 101, "freeze ball will end up oustide -> accelerate" );  posBall = WM->getBallPos();  // kick ball to position inside to compensate when agent is moving  VecPosition posTo   = posAgentPred + 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -