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

📄 worldmodelpredict.cpp

📁 2003年RoboCup仿真组世界冠军源代码 足球机器人 仿真组 的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
VecPosition WorldModel::predictFinalAgentPos(VecPosition *pos,VecPosition *vel){  VecPosition velAgent   = (vel==NULL) ? getAgentGlobalVelocity (): *vel;  VecPosition posAgent   = (pos==NULL) ? getAgentGlobalPosition (): *pos;  double      dDistExtra =   Geometry::getSumInfGeomSeries(velAgent.getMagnitude(),SS->getPlayerDecay());  return posAgent + VecPosition(dDistExtra,velAgent.getDirection(), POLAR );}/*! This method check how many cycles are needed for object 'o' to travel    a distance 'dDist' when it currently has a speed 'dSpeed'. */int WorldModel::predictNrCyclesForDistance ( ObjectT o, double dDist,                                             double dSpeed ){  double dSpeedPrev = -1.0;  int    iCycles    = 0;  double dDecay     = getPlayerDecay( o );  double dDashRate  = getDashPowerRate( o );  double dMinDist   = getMaximalKickDist( o );  // stop this loop when max speed is reached or the distance is traveled.  while( dDist > dMinDist &&         (fabs(dSpeed - dSpeedPrev) > EPSILON || dSpeed < 0.3 ) &&         iCycles < 40 ) // ignore standing still and turning  {    dSpeedPrev = dSpeed;    dSpeed    += SS->getMaxPower()*dDashRate;    if( dSpeed > SS->getPlayerSpeedMax() )      dSpeed = SS->getPlayerSpeedMax();    dDist = max( 0, dDist - dSpeed );    dSpeed *= dDecay;    iCycles++;  }  dSpeed /= dDecay;    // if distance not completely traveled yet, count the number of cycles to   // travel the remaining distance with this speed.  if( dDist > dMinDist  )   iCycles += (int)ceil(( dDist - dMinDist )/dSpeed);  return max(0, iCycles ) ;}/*! This method gives an estimate for the number of cycles a player needs to    reach a specific position. A position is reached when the player is located    in the maximal kick distance of this position. When this is not the case    a dash (or turn) is performed until the player is in the kickable distance.    \param o objectT which wants to reach posTo    \param posTo global position which has to be reached    \param angToTurn angle to 'posTo' when is turned (instead of dashed)    \return predicted nr of cycles for o to reach posTo  */int WorldModel::predictNrCyclesToPoint( ObjectT o, VecPosition posTo ){  char          strBuf[128];  VecPosition   posGlobal = getGlobalPositionLastSee( o ), posPred;  VecPosition   vel;  int           iCycles;  AngDeg        angBody, angNeck = 0, ang;  AngDeg        angDes = (posTo-posGlobal).getDirection();  SoccerCommand soc;  Log.log( 460, "predict steps for %s with dist %f (time %d) and body %f (%d)",              SoccerTypes::getObjectStr( strBuf, o ),              posTo.getDistanceTo( posGlobal ),              getTimeGlobalPositionLastSee( o ).getTime(),              getGlobalBodyAngle(o), getTimeChangeInformation(o).getTime() );  // if already in kickable distance, return 0  if( posTo.getDistanceTo( posGlobal ) < getMaximalKickDist( o) )  {    Log.log( 460, "already close: 0" );    return 0;  }  // first check how old the change info (and thus body and vel.) info is  // if too old, assume information is perfect and set time to position info  // otherwise update all information with stored information  iCycles = getTimeChangeInformation(o).getTime() - getCurrentCycle();  if( o == getAgentObjectType() )  {    angBody = getAgentGlobalBodyAngle();    vel     = getAgentGlobalVelocity( );    posPred = getAgentGlobalPosition( );    iCycles = 0;  }  else if( iCycles < -3 )  {    angBody = angDes;    vel.setVecPosition( 0.3, angDes, POLAR );    if( SoccerTypes::isOpponent( o ) )      iCycles = -2; // otherwise too optimistic    else      iCycles = 0;    posPred = getGlobalPositionLastSee( o );  }  else  {    angBody = getGlobalBodyAngleLastSee( o );    vel     = getGlobalVelocityLastSee( o );    posPred = getGlobalPositionLastSee( o );  }  Log.log( 460, "rel. time angle info (des %f,now %f,speed %f): %d (%d-%d)",       angDes, angBody, vel.getMagnitude(), iCycles,       getTimeChangeInformation(o).getTime(), getCurrentCycle() );  if( o != getAgentObjectType() &&      getTimeGlobalPositionLastSee( o ) > getTimeChangeInformation(o) )  {    Log.log( 460, "update cycles to global pos. time: %d",                  getTimeGlobalPositionLastSee( o ).getTime() );    iCycles = max(iCycles,                  getTimeGlobalPositionLastSee(o).getTime()-getCurrentCycle());  }  soc = predictCommandToMoveToPos(o,posTo,1,2.5,false,&posPred,&vel,&angBody );  ang = VecPosition::normalizeAngle( angBody - angDes );  // sometimes we dash to stand still and turn then  while( soc.commandType == CMD_TURN ||         ( fabs( ang ) > 20 && soc.commandType == CMD_DASH && soc.dPower < 0 ))  {    iCycles++;    predictStateAfterCommand( soc, &posPred, &vel, &angBody, &angNeck, o );    if( posTo.getDistanceTo( posPred ) < getMaximalKickDist( o ) )    {      Log.log( 460, "reached point during turning, vel %f: %d",                        vel.getMagnitude(), iCycles );      return iCycles;    }    soc=predictCommandToMoveToPos(o,posTo,1,2.5,false,&posPred,&vel,&angBody );    ang = VecPosition::normalizeAngle( angBody - angDes );  }  Log.log( 460, "cycles after turning: %d (ang %f, %f) vel %f",            iCycles, ang, angDes, vel.getMagnitude() );  if( o != getAgentObjectType() )  {    // iCycles++; // do not count last dash -> predictState not called    double dVel = vel.rotate(-angBody).getX(); // get distance in direction    iCycles += predictNrCyclesForDistance(o,posPred.getDistanceTo(posTo),dVel);  }  else  {    while( posPred.getDistanceTo( posTo ) > getMaximalKickDist( o ) )    {      soc=predictCommandToMoveToPos(o,posTo,1,2.5,0,&posPred,&vel,&angBody);      predictStateAfterCommand( soc, &posPred, &vel, &angBody, &angNeck, o );        iCycles++;    }  }  Log.log( 460, "total cycles: %d", iCycles );  return iCycles;}/*! This method returns the number of cycles it will take the object 'objFrom'    to reach the object 'objTo' (usually respectively the player and the ball).    \param objFrom ObjectT that is the object that wants to move    \param objTo ObjectT to which is moved    \return number of cycles it will take objFrom to move to objTo */int WorldModel::predictNrCyclesToObject( ObjectT objFrom, ObjectT objTo ){  VecPosition posPrev(UnknownDoubleValue,UnknownDoubleValue);  if( objFrom == OBJECT_ILLEGAL || objTo == OBJECT_ILLEGAL ||      getGlobalPosition( objFrom ).getDistanceTo( getGlobalPosition( objTo )      ) > 40 )    return 101;  // this is part of the intercept  if( objFrom == getAgentObjectType() && objTo == OBJECT_BALL )  {     FeatureT  feature_type = FEATURE_INTERCEPT_CYCLES_ME;       if( isFeatureRelevant( feature_type ) )     {       return max(0,             ((int)getFeature( feature_type ).getInfo() - getCurrentCycle() ));     }     else     {       Log.log( 460, "create intercept features" );       createInterceptFeatures( );       Log.log( 460, "call predict again" );       return predictNrCyclesToObject( objFrom, objTo );     }  }  // in case of ball with no velocity, calculate cycles to point  if( objTo == OBJECT_BALL && getBallSpeed() < 0.01 )    return predictNrCyclesToPoint( objFrom, getBallPos() );  int         iCycles      = 0;  int         iCyclesToObj = 100;  VecPosition posObj(0,0);  // continue calculating number of cycles to position until or we can get  // earlier at object position, are past maximum allowed number of cycles or  // the object does not move anymore.  while( iCycles <= iCyclesToObj && iCycles < PS->getPlayerWhenToIntercept() &&         posObj.getDistanceTo( posPrev ) > EPSILON )  {    iCycles      = iCycles + 1  ;    posPrev      = posObj;    posObj       = predictPosAfterNrCycles( objTo,   iCycles );    if(getGlobalPosition(objFrom).getDistanceTo(posObj)/SS->getPlayerSpeedMax()              < iCycles + 1 )    {      Log.log( 460, "predictNrCyclesToPoint after %d cycles", iCycles );      iCyclesToObj = predictNrCyclesToPoint ( objFrom, posObj );    }  }  return iCyclesToObj;}/*! This method updates all the stamina variables using the calculations from    the soccer manual. It is not really important since stamina is read from    sense_body every cycle. That information is more up to date.    \param power of last dash command    \param stamina pointer to all stamina values, will change to new value    \return stamina class will be updated to new stamina values */void WorldModel::predictStaminaAfterDash( double dPower, Stamina *stamina ){  double sta = stamina->getStamina();  double eff = stamina->getEffort();  double rec = stamina->getRecovery();  // double negative value when dashed backwards  sta -= ( dPower > 0.0 ) ? dPower : -2*dPower ;  if( sta < 0 ) sta = 0;  // stamina below recovery threshold, lower recovery  if( sta <= SS->getRecoverDecThr()*SS->getStaminaMax() &&                         rec > SS->getRecoverMin() )      rec -= SS->getRecoverDec();  // stamina below effort decrease threshold, lower effort  if( sta <= SS->getEffortDecThr()*SS->getStaminaMax() &&                   eff > SS->getEffortMin() )      eff -= SS->getEffortDec();  // stamina higher than effort incr threshold, raise effort and check maximum  if( sta >= SS->getEffortIncThr() * SS->getStaminaMax() &&      eff < 1.0)  {    eff += SS->getEffortInc();    if ( eff > 1.0 )       eff = 1.0;  }  // increase stamina with (new) recovery value and check for maximum  sta += rec*SS->getStaminaIncMax();  if ( sta > SS->getStaminaMax() )    sta = SS->getStaminaMax();  stamina->setStamina ( sta );  stamina->setEffort  ( eff );  stamina->setRecovery( rec );}/*! This method returns the command for object 'obj' to turn towards a point    'posTo' on the field when it has 'iCycles' to reach that point. If    the point is within 'dDistBack' behind the object it will try to dash    backwards. In the case that 'bMoveBack' is true, it will always try to    move backwards. When posIn, velIn and angBodyIn are equal to NULL, the    current agent information is used. */SoccerCommand WorldModel::predictCommandTurnTowards( ObjectT obj, VecPosition  posTo, int iCycles, double dDistBack, bool bMoveBack,  VecPosition *posIn, VecPosition *velIn, AngDeg *angBodyIn ){  SoccerCommand soc, socFirst;  VecPosition   pos, vel;  AngDeg        angBody, ang, angNeck, angTo;  Stamina       sta;  bool          bFirst = true;  // fill in all values  angBody = ( angBodyIn == NULL ) ? getGlobalBodyAngle( obj ) : *angBodyIn;  pos     = ( posIn     == NULL ) ? getGlobalPosition ( obj ) : *posIn;  vel     = ( velIn     == NULL ) ? getGlobalVelocity ( obj ) : *velIn;  angNeck = getGlobalNeckAngle( obj );  // predict where we will finally stand when our current vel is propogated  // and then check the orthogonal distance w.r.t. our body direction  VecPosition posPred=predictPosAfterNrCycles( obj, min(iCycles,4),                                               0, &pos, &vel, false );  Line        line   =Line::makeLineFromPositionAndAngle( posPred, angBody );  double      dDist  =line.getDistanceWithPoint( posTo );  // get the angle to this point  angTo = (posTo - posPred).getDirection();  angTo = VecPosition::normalizeAngle( angTo - angBody );  // determine whether we want to turn based on orthogonal distance   double dRatioTurn;  if( pos.getDistanceTo(posTo) > 30.0 )     dRatioTurn = 4.0;    if( pos.getDistanceTo(posTo) > 20.0 )     dRatioTurn = 3.0;    else if( pos.getDistanceTo(posTo) > 10 )     dRatioTurn = 2.0;  else    dRatioTurn = 0.90 ;  AngDeg angTmp = angTo + (bMoveBack) ? 180 : 0;  angTmp = VecPosition::normalizeAngle( angTmp );    // turn when:   //  1. point lies outside our body range (forward and backwards)  //  2. point lies outside distBack and behind us (forward move)   //  3. point lies outside distBack and in front of us backwards move)  int    turn = 0;  while( ( dDist > dRatioTurn*getMaximalKickDist( obj ) ||          ( posPred.getDistanceTo( posTo ) > dDistBack &&               ( ( fabs( angTo ) > 90 && bMoveBack == false  ) ||

⌨️ 快捷键说明

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