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

📄 worldmodelhighlevel.c

📁 机器足球2D比赛程序 对trlen_base_2002的改进
💻 C
📖 第 1 页 / 共 5 页
字号:
  return getGlobalPosition (obj).getX () < getOffsideX () - 0.5;}/*! This method determines whether there stands an opponent in the global  direction of the specified angle and in distance 'dDist'. An opponent is  considered to stand in the global direction when the angle difference with  the specified angle is smaller than 60 degrees.  \param ang angle of the global direction in which to check opponents  \param dDist distance in which opponents should be checked  \return bool indicating wheter an opponent was found. */boolWorldModel::isOpponentAtAngle (AngDeg ang, double dDist){  VecPosition posAgent = getAgentGlobalPosition ();  VecPosition posOpp;  AngDeg angOpp;  int iIndex;  for (ObjectT o = iterateObjectStart (iIndex, OBJECT_SET_OPPONENTS);       o != OBJECT_ILLEGAL;       o = iterateObjectNext (iIndex, OBJECT_SET_OPPONENTS))    {      posOpp = getGlobalPosition (o);      angOpp = (posOpp - posAgent).getDirection ();      if (fabs (angOpp - ang) < 60 && posAgent.getDistanceTo (posOpp) < dDist)	return true;      else if (fabs (angOpp - ang) < 120 &&	       posAgent.getDistanceTo (posOpp) < dDist / 2.0)	return true;    }  iterateObjectDone (iIndex);  return false;}/*! This method returns the inverse confidence, i.e. the time that belongs  to the specified confidence. This can be used to determine  the time the object was last seen when the confidence is given. Herefore  the current time is used.  \param dConf confidence  \return server cycle the object was last seen. */TimeWorldModel::getTimeFromConfidence (double dConf){  return getCurrentTime () - (int) ((1.00 - dConf) * 100);}/*! This method returns the x coordinate of the offside line using the known  information in the WorldModel. If a player moves beyond this line, he  stands offside. First the opponent with the second highest x coordinate is  located, then the maximum of this x coordinate and the ball x coordinate  is returned.  \param bIncludeComm boolean indicating whether communicated offside line  should also be included.   \return x coordinate of the offside line. */doubleWorldModel::getOffsideX (bool bIncludeComm){  double dHighestX = 0.0;  double dSecondX = 0.0;  double x;  ObjectT o;  for (int i = 0; i < MAX_OPPONENTS; i++)    {      o = Opponents[i].getType ();      if (isConfidenceVeryGood (o))	{	  x = Opponents[i].getGlobalPosition ().getX ();	  if (x > dHighestX)	// if larger x than highest	    {	      dSecondX = dHighestX;	// make second the previous highest	      dHighestX = x;	// and this the new one	    }	  else if (x > dSecondX)	// if smaller than highest and larger than 2nd	    dSecondX = x;	// make it the second	}    }  // if highest x is outside pen_area, it cannot be the goalie (unless playing  // Portugal ;-) ), so assume goalie is just not seen  if (dHighestX < PENALTY_X && getOppGoalieType () == OBJECT_ILLEGAL)    dSecondX = dHighestX;  x = getBallPos ().getX ();  x = max (x, dSecondX);  return x;}/*! This method returns the outer position on the field given a position 'pos'  and a global angle 'ang'. The outer position is defined as the point on  the field where the line created from this position and angle crosses  either a side line, goal line or penalty line. To be on the safe side a  small value is specified, which denotes the distance from the side line  that should be returned.  \param pos position on the field from which outer position should be  calculated  \param ang global angle which denotes the global direction in pos  \param dDist distance from line  \param bWithPenalty boolean denoting whether penalty area should be taken  into account (if false only goal line and side line  are used.  \return position denoting the outer position on the field */VecPositionWorldModel::getOuterPositionInField (VecPosition pos, AngDeg ang,				     double dDist, bool bWithPenalty){  VecPosition posShoot;  // make shooting line using position and desired direction  Line lineObj = Line::makeLineFromPositionAndAngle (pos, ang);  // get intersection point between the created line and goal line  Line lineLength =    Line::    makeLineFromPositionAndAngle (VecPosition				  (PITCH_LENGTH / 2.0 - dDist, 0.0), 90);  posShoot = lineObj.getIntersection (lineLength);  // check whether it first crosses the penalty line  Line linePenalty =    Line::makeLineFromPositionAndAngle (VecPosition (PENALTY_X - dDist, 0.0),					90.0);  double dPenaltyY = lineObj.getIntersection (linePenalty).getY ();  if (bWithPenalty && fabs (dPenaltyY) < PENALTY_AREA_WIDTH / 2.0)    {      if (fabs (dPenaltyY) < PENALTY_AREA_WIDTH / 2.0 - 5.0 ||	// crosses inside	  fabs (posShoot.getY ()) < PENALTY_AREA_WIDTH / 2.0)	// or ends inside	posShoot = lineObj.getIntersection (linePenalty);    }  // check where it crosses the side line  Line lineSide = (ang < 0)    ? Line::    makeLineFromPositionAndAngle (VecPosition				  (0.0, -PITCH_WIDTH / 2.0 + dDist),				  0.0) : Line::    makeLineFromPositionAndAngle (VecPosition				  (0.0, +PITCH_WIDTH / 2.0 - dDist), 0.0);  if (fabs (posShoot.getY ()) > PITCH_WIDTH / 2.0 - dDist)    posShoot = lineObj.getIntersection (lineSide);  return posShoot;}/*! This method determines the (global) direction which has the largest  angle between the opponents and is located in the interval angMin..  angMax.  \param origin of which the angles angMin and angMax are based on.  \param angMin minimal global direction that should be returned  \param angMax maximal global direction that should be returned  \param angLargest will contain the size of the largest angle of the  direction that is returned  \param dDist only opponents with relative distance smaller than this value  will be taken into account.  \return global direction with the largest angle between opponents */AngDegWorldModel::getDirectionOfWidestAngle (VecPosition posOrg, AngDeg angMin,				       AngDeg angMax, AngDeg * angLargest,				       double dDist){  list < double >v;  list < double >v2;  double temp;  int iIndex;  double dConf = PS->getPlayerConfThr ();  // add all angles of all the opponents to the list v  for (ObjectT o = iterateObjectStart (iIndex, OBJECT_SET_OPPONENTS, dConf);       o != OBJECT_ILLEGAL;       o = iterateObjectNext (iIndex, OBJECT_SET_OPPONENTS, dConf))    {      if (getRelativeDistance (o) < dDist)	v.push_back ((getGlobalPosition (o) - posOrg).getDirection ());    }  iterateObjectDone (iIndex);  v.sort ();  // if goalkeeper is spotted and he is located within the range that we want  // to shoot at, make sure the angle with the goalkeeper is large enough, since  // he has better intercepting capabilities than the normal players  ObjectT objGoalie = getOppGoalieType ();  VecPosition posGoalie = getGlobalPosition (objGoalie);  AngDeg angGoalie;  if (objGoalie != OBJECT_ILLEGAL && posOrg.getX () > PITCH_LENGTH / 4.0 &&      posOrg.getDistanceTo (posGoalie) < dDist)    {      angGoalie = (posGoalie - posOrg).getDirection ();      Log.log (560, "direction_widest_angle: min %f max %f angGoalie %f",	       angMin, angMax, angGoalie);      if (posOrg.getY () > 0)	// right side of the field	{	  angGoalie = VecPosition::normalizeAngle (angGoalie - 33);	  angMax = max (angMin, min (angGoalie, angMax));	}      else	{	  angGoalie = VecPosition::normalizeAngle (angGoalie + 33);	  angMin = min (angMax, max (angMin, angGoalie));	}      Log.log (560, "direction_widest_angle after: %f %f", angMin, angMax);    }  // Create new list with only opponents from interval [angMin..angMax].  // Note that opponents outside angMin and angMax can have an influence  // on the largest angle between the opponents, so they should be accounted  // for. To this end, a projection is defined in both angMin and angMax.  // The opponent with the smallest global angle difference a to angMin  // (either inside or outside the interval [angMin..angMax]) is determined  // and an extra angle angMin - a is added to the list. The situation for  // angMax is analogous.  double absMin = 1000;  double absMax = 1000;  double angProjMin = angMin;  double angProjMax = angMax;  double array[MAX_OPPONENTS + 2];  while (v.size () > 0)    {      if (fabs (v.front () - angMin) < absMin)	// opp near angMin	{	  absMin = fabs (v.front () - angMin);	// make angMin wider	  angProjMin = angMin - absMin;	// to take him into account	}      if (fabs (v.front () - angMax) < absMax)	// opp near angMax	{	  absMax = fabs (v.front () - angMax);	// make angMax wider	  angProjMax = angMax + absMax;	// to take him into account	}      if (v.front () > angMin && v.front () < angMax)	// opp in range	v2.push_back (v.front ());	// add him      v.pop_front ();    }  // make all angles relative to angProjMin which has angle 0 and set them in  // the range 0..360, where the range -180..0 is moved to 180..360. Do this by  // adding 360 and then subtracting 360 if value is larger than 360.  v.push_back (0);  while (v2.size () > 0)	// for all the opponents    {      temp = VecPosition::normalizeAngle (v2.front () - angProjMin) + 360.0;      if (temp > 360)	temp -= 360;      v.push_back (temp);      v2.pop_front ();    }  // add max projection.  temp = VecPosition::normalizeAngle (angProjMax - angProjMin) + 360.0;  if (temp > 360)    temp -= 360;  v.push_back (temp);  // sort the list  v.sort ();  // put all the values in an array  int i = 0;  while (v.size () > 0)    {      array[i++] = v.front ();      v.pop_front ();    }  // find the largest angle and determine the associated midpoint direction  double dLargest = -1000;  double d;  double ang = UnknownAngleValue;  for (int j = 0; j < i - 1; j++)    {      d = VecPosition::normalizeAngle ((array[j + 1] - array[j]) / 2.0);      if (d > dLargest)	{	  ang = angProjMin + array[j] + d;	  ang = VecPosition::normalizeAngle (ang);	  dLargest = d;	}    }  if (ang == UnknownAngleValue)	// no angle found -> get angle in between    {      ang = getBisectorTwoAngles (angMin, angMax);      if (angLargest != NULL)	*angLargest = 360;    }  else if (angLargest != NULL)    *angLargest = dLargest;  return ang;}/*! This method determine the strategic position for the specified player. This   is done using the Formations class. In this class all information  about the current formation, player number in formation and otheic  values are stored. The strategic position is based on the position of  the ball. If the confidence in the position of the ball is lower than the  threshold defined in PlayerSettings, it is assumed that the ball is at  position (0,0).  \param iPlayer role in formation for which strategic position should be   returnd. With default value is -1 it is assumed that the strategic  position of the agent itself should be returned.   \return VecPosition strategic position for player 'iPlayer' */VecPositionWorldModel::getStrategicPosition (int iPlayer){  VecPosition pos;  // -1 is default -> get player number in formation  if (iPlayer == -1)    iPlayer = formations->getPlayerInFormation ();  // get maximal allowed x coordinate, this is offside x coordinate  double dMaxX = getOffsideX () - 3.0;  // after standing offside we are not allowed to move for ball  // with a goal kick of them we are not allowed to move into penalty area  if (isOffsideUs ())    dMaxX = min (dMaxX, getBallPos ().getX () - 1.0);  if (isGoalKickThem ())    dMaxX = min (dMaxX, PENALTY_X - 1.0);  if (isBeforeKickOff ())    dMaxX = min (dMaxX, -2.0);  // change the ball position on which strategic position is based depending on  // the different deadball situation and thus the expected movement of the ball  VecPosition posBall = getBallPos ();  if (isGoalKickUs () ||      getTimeSinceLastCatch () < PS->getCyclesCatchWait () + 5)    posBall.setX (-PITCH_LENGTH / 4 - 5.0);  else if (getConfidence (OBJECT_BALL) < PS->getBallConfThr ())    posBall.setVecPosition (0.0, 0.0);  else if (isGoalKickThem () ||	   (isFreeKickThem () && posBall.getX () > PENALTY_X))    posBall.setX (PENALTY_X - 10.0);  // get the strategic position  pos = formations->getStrategicPosition (iPlayer, posBall, dMaxX);  return pos;}/*! The actual power with which the ball is kicked depends on the  relative location of the ball to the player. The kick is more  powerful when the ball is very close to and in front of the player.  The actual kickpowerrate with which the power of the kick command  is multiplied is equal to<BR>  KickPowerRate*(1 - 0.25*DirDiff / 180 -  0.25*(DistBall-PlayerSize-BallSize)/KickableMargin)<BR>  with DirDiff = global angle of the ball rel to the body dir agent<BR>  DistBall = the distance from the center of the player to the ball<BR>  See soccermanual  \return the actual kick power rate with which power is multiplied  */doubleWorldModel::getActualKickPowerRate (){  // true indicates that relative angle to body should be returned  double dir_diff = fabs (getRelativeAngle (OBJECT_BALL, true));  double dist = getRelativeDistance (OBJECT_BALL) -    SS->getPlayerSize () - SS->getBallSize ();  return SS->getKickPowerRate () *    (1 - 0.25 * dir_diff / 180.0 - 0.25 * dist / SS->getKickableMargin ());}/*! The actual power with which the ball must be kicked depends on the  relative location of the ball to the player. The kick is more  powerful when the ball is very close to and in front of the player.  The actual power with which the ball must be kicked is equal to<BR>  Speed / KickPowerRate*(1 - 0.25*DirDiff / 180 -  0.25*(DistBall-PlayerSize-BallSize)/KickableMargin)<BR>  with DirDiff = global angle of the ball rel to the body dir agent<BR>  DistBall = the distance from the center of the player to the ball<BR>  See soccermanual for further information.  This method receives a speed vector which the ball should have after the  kick command and calculates the power for the kick command to reach this.  This value can be higher than is possible to shoot!  \param dDesiredSpeed the desired speed after the kick command  \return the actual power for kick command to get dDesiredSpeed */doubleWorldModel::getKickPowerForSpeed (double dDesiredSpeed){  // acceleration after kick is calculated by power * eff_kick_power_rate  // so actual kick power is acceleration / eff_kick_power_rate  return dDesiredSpeed / getActualKickPowerRate ();}

⌨️ 快捷键说明

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