00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00047 #include <stdio.h>
00048 #include "WorldModel.h"
00049
00050
00051
00052
00053
00066 bool WorldModel::predictStateAfterCommand( SoccerCommand com,
00067 VecPosition *pos, VecPosition *vel, AngDeg *angGlobalBody,
00068 AngDeg *angGlobalNeck, ObjectT obj, Stamina *sta )
00069 {
00070 switch( com.commandType )
00071 {
00072 case CMD_DASH:
00073 predictStateAfterDash( com.dPower, pos, vel, sta, *angGlobalBody, obj );
00074 break;
00075 case CMD_TURN:
00076 predictStateAfterTurn( com.dAngle, pos, vel,
00077 angGlobalBody, angGlobalNeck, obj, sta);
00078 break;
00079 case CMD_TURNNECK:
00080 *angGlobalNeck = VecPosition::normalizeAngle(*angGlobalNeck+com.dAngle);
00081 break;
00082 case CMD_KICK:
00083 case CMD_CATCH:
00084 case CMD_TACKLE:
00085 predictStateAfterDash( 0.0, pos, vel, sta, *angGlobalBody, obj );
00086 break;
00087 case CMD_MOVE:
00088 pos->setVecPosition( com.dX, com.dY );
00089 vel->setMagnitude( 0.0 );
00090 break;
00091 case CMD_ILLEGAL:
00092 predictStateAfterDash( 0.01, pos, vel, sta, *angGlobalBody, obj );
00093 break;
00094 default:
00095 return false;
00096 }
00097 return true;
00098 }
00099
00110 bool WorldModel::predictAgentStateAfterCommand( SoccerCommand com,
00111 VecPosition *pos, VecPosition *vel, AngDeg *angGlobalBody,
00112 AngDeg *angGlobalNeck, Stamina *sta )
00113 {
00114 *pos = getAgentGlobalPosition();
00115 *vel = getAgentGlobalVelocity();
00116 *angGlobalBody = getAgentGlobalBodyAngle();
00117 *angGlobalNeck = getAgentGlobalNeckAngle();
00118 *sta = getAgentStamina();
00119 predictStateAfterCommand( com, pos, vel, angGlobalBody, angGlobalNeck,
00120 getAgentObjectType(), sta );
00121
00122 return true;
00123 }
00124
00135 bool WorldModel::predictObjectStateAfterCommand( ObjectT obj,SoccerCommand com,
00136 VecPosition *pos, VecPosition *vel, AngDeg *angGlobalBody,
00137 AngDeg *angGlobalNeck, Stamina *sta )
00138 {
00139 if( obj == getAgentObjectType() )
00140 return predictAgentStateAfterCommand(
00141 com, pos, vel, angGlobalBody, angGlobalNeck, sta );
00142 *pos = getGlobalPosition( obj );
00143 *vel = getGlobalVelocity( obj );
00144 *angGlobalBody = getGlobalBodyAngle( obj );
00145 *angGlobalNeck = getGlobalNeckAngle(obj );
00146 predictStateAfterCommand( com, pos, vel, angGlobalBody, angGlobalNeck, obj );
00147
00148 return true;
00149 }
00150
00156 VecPosition WorldModel::predictAgentPosAfterCommand( SoccerCommand com )
00157 {
00158 VecPosition p1, p2;
00159 AngDeg a1, a2;
00160 Stamina sta;
00161 predictAgentStateAfterCommand( com, &p1, &p2, &a1, &a2, &sta );
00162 return p1;
00163 }
00164
00173 void WorldModel::predictStateAfterDash( double dActualPower, VecPosition *pos,
00174 VecPosition *vel, Stamina *sta, double dDirection, ObjectT obj )
00175 {
00176
00177 double dEffort = ( sta != NULL ) ? sta->getEffort() : getEffortMax( obj );
00178 double dAcc = dActualPower * getDashPowerRate( obj ) * dEffort;
00179
00180
00181 if( dAcc > 0 )
00182 *vel += VecPosition::getVecPositionFromPolar( dAcc, dDirection );
00183 else
00184 *vel += VecPosition::getVecPositionFromPolar( fabs(dAcc),
00185 VecPosition::normalizeAngle(dDirection+180));
00186
00187
00188 if( vel->getMagnitude() > SS->getPlayerSpeedMax() )
00189 vel->setMagnitude( SS->getPlayerSpeedMax() );
00190
00191
00192 *pos += *vel;
00193 *vel *= getPlayerDecay(obj);
00194 if( sta != NULL )
00195 predictStaminaAfterDash( dActualPower, sta );
00196 }
00197
00209 void WorldModel::predictStateAfterTurn( AngDeg dSendAngle, VecPosition *pos,
00210 VecPosition *vel, AngDeg *angBody, AngDeg *angNeck, ObjectT obj,
00211 Stamina *sta )
00212 {
00213
00214 double dEffectiveAngle;
00215 dEffectiveAngle = getActualTurnAngle( dSendAngle, vel->getMagnitude(), obj );
00216 *angBody = VecPosition::normalizeAngle( *angBody + dEffectiveAngle );
00217 *angNeck = VecPosition::normalizeAngle( *angNeck + dEffectiveAngle );
00218
00219
00220 predictStateAfterDash( 0.0, pos, vel, sta, *angBody, obj );
00221 return;
00222 }
00223
00224 void WorldModel::predictBallInfoAfterCommand( SoccerCommand soc,
00225 VecPosition *pos, VecPosition *vel )
00226 {
00227 VecPosition posBall = getGlobalPosition( OBJECT_BALL ) ;
00228 VecPosition velBall = getGlobalVelocity( OBJECT_BALL );
00229
00230 if( soc.commandType == CMD_KICK )
00231 {
00232 int iAng = (int)soc.dAngle;
00233 int iPower = (int)soc.dPower;
00234
00235
00236
00237 AngDeg ang = VecPosition::normalizeAngle(iAng+getAgentGlobalBodyAngle());
00238 velBall += VecPosition( getActualKickPowerRate()*iPower, ang, POLAR ) ;
00239 if( velBall.getMagnitude() > SS->getBallSpeedMax() )
00240 velBall.setMagnitude( SS->getBallSpeedMax() );
00241 Log.log( 600, "ang: %f kick_rate %f", ang, getActualKickPowerRate() );
00242 Log.log( 600, "update for kick: %f %f", soc.dPower, soc.dAngle );
00243 }
00244
00245 posBall += velBall;
00246 velBall *= SS->getBallDecay();
00247
00248 if( pos != NULL )
00249 *pos = posBall;
00250 if( vel != NULL )
00251 *vel = velBall;
00252 }
00253
00263 VecPosition WorldModel::predictPosAfterNrCycles( ObjectT o, double dCycles,
00264 int iDashPower, VecPosition *posIn, VecPosition *velIn, bool bUpdate )
00265 {
00266 VecPosition vel = ( velIn == NULL ) ? getGlobalVelocity( o ) : *velIn ;
00267 VecPosition pos = ( posIn == NULL ) ? getGlobalPosition( o ) : *posIn ;
00268
00269 if( o == OBJECT_BALL )
00270 {
00271
00272
00273
00274 double dDist = Geometry::getSumGeomSeries( vel.getMagnitude(),
00275 SS->getBallDecay(),
00276 dCycles);
00277 pos += VecPosition( dDist, vel.getDirection(), POLAR );
00278 vel *= pow( SS->getBallDecay(), dCycles );
00279 }
00280 else if( SoccerTypes::isKnownPlayer( o ) )
00281 {
00282 double dDirection = 0.0;
00283 Stamina stamina;
00284
00285 if( getAgentObjectType() == o )
00286 {
00287 dDirection = getAgentGlobalBodyAngle();
00288 stamina = getAgentStamina();
00289 }
00290 else if( getTimeGlobalAngles(o) > getCurrentTime() - 2 )
00291 dDirection = getGlobalBodyAngle(o);
00292
00293 for( int i = 0; i < (int)dCycles ; i ++ )
00294 predictStateAfterDash( iDashPower, &pos, &vel, &stamina, dDirection, o );
00295 }
00296
00297 if( posIn != NULL && bUpdate )
00298 *posIn = pos;
00299 if( velIn != NULL && bUpdate )
00300 *velIn = vel;
00301
00302 return pos;
00303 }
00304
00311 VecPosition WorldModel::predictAgentPos( int iCycles, int iDashPower )
00312 {
00313 return predictPosAfterNrCycles( getAgentObjectType(), iCycles, iDashPower);
00314 }
00315
00319 VecPosition WorldModel::predictFinalAgentPos(VecPosition *pos,VecPosition *vel)
00320 {
00321 VecPosition velAgent = (vel==NULL) ? getAgentGlobalVelocity (): *vel;
00322 VecPosition posAgent = (pos==NULL) ? getAgentGlobalPosition (): *pos;
00323 double dDistExtra =
00324 Geometry::getSumInfGeomSeries(velAgent.getMagnitude(),SS->getPlayerDecay());
00325 return posAgent + VecPosition(dDistExtra,velAgent.getDirection(), POLAR );
00326
00327 }
00328
00331 int WorldModel::predictNrCyclesForDistance ( ObjectT o, double dDist,
00332 double dSpeed )
00333 {
00334 double dSpeedPrev = -1.0;
00335 int iCycles = 0;
00336 double dDecay = getPlayerDecay( o );
00337 double dDashRate = getDashPowerRate( o );
00338 double dMinDist = getMaximalKickDist( o );
00339
00340
00341 while( dDist > dMinDist &&
00342 (fabs(dSpeed - dSpeedPrev) > EPSILON || dSpeed < 0.3 ) &&
00343 iCycles < 40 )
00344 {
00345 dSpeedPrev = dSpeed;
00346 dSpeed += SS->getMaxPower()*dDashRate;
00347 if( dSpeed > SS->getPlayerSpeedMax() )
00348 dSpeed = SS->getPlayerSpeedMax();
00349 dDist = max( 0, dDist - dSpeed );
00350 dSpeed *= dDecay;
00351 iCycles++;
00352 }
00353 dSpeed /= dDecay;
00354
00355
00356
00357 if( dDist > dMinDist )
00358 iCycles += (int)ceil(( dDist - dMinDist )/dSpeed);
00359 return max(0, iCycles ) ;
00360 }
00361
00362
00371 int WorldModel::predictNrCyclesToPoint( ObjectT o, VecPosition posTo )
00372 {
00373 char strBuf[128];
00374 VecPosition posGlobal = getGlobalPositionLastSee( o ), posPred;
00375 VecPosition vel;
00376 int iCycles;
00377 AngDeg angBody, angNeck = 0, ang;
00378 AngDeg angDes = (posTo-posGlobal).getDirection();
00379 SoccerCommand soc;
00380
00381 Log.log( 460, "predict steps for %s with dist %f (time %d) and body %f (%d)",
00382 SoccerTypes::getObjectStr( strBuf, o ),
00383 posTo.getDistanceTo( posGlobal ),
00384 getTimeGlobalPositionLastSee( o ).getTime(),
00385 getGlobalBodyAngle(o), getTimeChangeInformation(o).getTime() );
00386
00387
00388 if( posTo.getDistanceTo( posGlobal ) < getMaximalKickDist( o) )
00389 {
00390 Log.log( 460, "already close: 0" );
00391 return 0;
00392 }
00393
00394
00395
00396
00397 iCycles = getTimeChangeInformation(o).getTime() - getCurrentCycle();
00398 if( o == getAgentObjectType() )
00399 {
00400 angBody = getAgentGlobalBodyAngle();
00401 vel = getAgentGlobalVelocity( );
00402 posPred = getAgentGlobalPosition( );
00403 iCycles = 0;
00404 }
00405 else if( iCycles < -3 )
00406 {
00407 angBody = angDes;
00408 vel.setVecPosition( 0.3, angDes, POLAR );
00409 if( SoccerTypes::isOpponent( o ) )
00410 iCycles = -2;
00411 else
00412 iCycles = 0;
00413 posPred = getGlobalPositionLastSee( o );
00414 }
00415 else
00416 {
00417 angBody = getGlobalBodyAngleLastSee( o );
00418 vel = getGlobalVelocityLastSee( o );
00419 posPred = getGlobalPositionLastSee( o );
00420 }
00421
00422 Log.log( 460, "rel. time angle info (des %f,now %f,speed %f): %d (%d-%d)",
00423 angDes, angBody, vel.getMagnitude(), iCycles,
00424 getTimeChangeInformation(o).getTime(), getCurrentCycle() );
00425
00426 if( o != getAgentObjectType() &&
00427 getTimeGlobalPositionLastSee( o ) > getTimeChangeInformation(o) )
00428 {
00429 Log.log( 460, "update cycles to global pos. time: %d",
00430 getTimeGlobalPositionLastSee( o ).getTime() );
00431 iCycles = max(iCycles,
00432 getTimeGlobalPositionLastSee(o).getTime()-getCurrentCycle());
00433 }
00434
00435 soc = predictCommandToMoveToPos(o,posTo,1,2.5,false,&posPred,&vel,&angBody );
00436 ang = VecPosition::normalizeAngle( angBody - angDes );
00437
00438
00439 while( soc.commandType == CMD_TURN ||
00440 ( fabs( ang ) > 20 && soc.commandType == CMD_DASH && soc.dPower < 0 ))
00441 {
00442 iCycles++;
00443 predictStateAfterCommand( soc, &posPred, &vel, &angBody, &angNeck, o );
00444 if( posTo.getDistanceTo( posPred ) < getMaximalKickDist( o ) )
00445 {
00446 Log.log( 460, "reached point during turning, vel %f: %d",
00447 vel.getMagnitude(), iCycles );
00448 return iCycles;
00449 }
00450 soc=predictCommandToMoveToPos(o,posTo,1,2.5,false,&posPred,&vel,&angBody );
00451 ang = VecPosition::normalizeAngle( angBody - angDes );
00452 }
00453 Log.log( 460, "cycles after turning: %d (ang %f, %f) vel %f",
00454 iCycles, ang, angDes, vel.getMagnitude() );
00455
00456 if( o != getAgentObjectType() )
00457 {
00458
00459 double dVel = vel.rotate(-angBody).getX();
00460 iCycles += predictNrCyclesForDistance(o,posPred.getDistanceTo(posTo),dVel);
00461 }
00462 else
00463 {
00464 while( posPred.getDistanceTo( posTo ) > getMaximalKickDist( o ) )
00465 {
00466 soc=predictCommandToMoveToPos(o,posTo,1,2.5,0,&posPred,&vel,&angBody);
00467 predictStateAfterCommand( soc, &posPred, &vel, &angBody, &angNeck, o );
00468 iCycles++;
00469 }
00470 }
00471
00472 Log.log( 460, "total cycles: %d", iCycles );
00473 return iCycles;
00474 }
00475
00481 int WorldModel::predictNrCyclesToObject( ObjectT objFrom, ObjectT objTo )
00482 {
00483 VecPosition posPrev(UnknownDoubleValue,UnknownDoubleValue);
00484
00485 if( objFrom == OBJECT_ILLEGAL || objTo == OBJECT_ILLEGAL ||
00486 getGlobalPosition( objFrom ).getDistanceTo( getGlobalPosition( objTo )
00487 ) > 40 )
00488 return 101;
00489
00490
00491 if( objFrom == getAgentObjectType() && objTo == OBJECT_BALL )
00492 {
00493 FeatureT feature_type = FEATURE_INTERCEPT_CYCLES_ME;
00494 if( isFeatureRelevant( feature_type ) )
00495 {
00496 return max(0,
00497 ((int)getFeature( feature_type ).getInfo() - getCurrentCycle() ));
00498 }
00499 else
00500 {
00501 Log.log( 460, "create intercept features" );
00502 createInterceptFeatures( );
00503 Log.log( 460, "call predict again" );
00504 return predictNrCyclesToObject( objFrom, objTo );
00505 }
00506 }
00507
00508
00509 if( objTo == OBJECT_BALL && getBallSpeed() < 0.01 )
00510 return predictNrCyclesToPoint( objFrom, getBallPos() );
00511
00512 int iCycles = 0;
00513 int iCyclesToObj = 100;
00514 VecPosition posObj(0,0);
00515
00516
00517
00518
00519 while( iCycles <= iCyclesToObj && iCycles < PS->getPlayerWhenToIntercept() &&
00520 posObj.getDistanceTo( posPrev ) > EPSILON )
00521 {
00522 iCycles = iCycles + 1 ;
00523 posPrev = posObj;
00524 posObj = predictPosAfterNrCycles( objTo, iCycles );
00525
00526 if(getGlobalPosition(objFrom).getDistanceTo(posObj)/SS->getPlayerSpeedMax()
00527 < iCycles + 1 )
00528 {
00529 Log.log( 460, "predictNrCyclesToPoint after %d cycles", iCycles );
00530 iCyclesToObj = predictNrCyclesToPoint ( objFrom, posObj );
00531 }
00532 }
00533
00534 return iCyclesToObj;
00535 }
00536
00543 void WorldModel::predictStaminaAfterDash( double dPower, Stamina *stamina )
00544 {
00545 double sta = stamina->getStamina();
00546 double eff = stamina->getEffort();
00547 double rec = stamina->getRecovery();
00548
00549
00550 sta -= ( dPower > 0.0 ) ? dPower : -2*dPower ;
00551 if( sta < 0 ) sta = 0;
00552
00553
00554 if( sta <= SS->getRecoverDecThr()*SS->getStaminaMax() &&
00555 rec > SS->getRecoverMin() )
00556 rec -= SS->getRecoverDec();
00557
00558
00559 if( sta <= SS->getEffortDecThr()*SS->getStaminaMax() &&
00560 eff > SS->getEffortMin() )
00561 eff -= SS->getEffortDec();
00562
00563
00564 if( sta >= SS->getEffortIncThr() * SS->getStaminaMax() &&
00565 eff < 1.0)
00566 {
00567 eff += SS->getEffortInc();
00568 if ( eff > 1.0 )
00569 eff = 1.0;
00570 }
00571
00572
00573 sta += rec*SS->getStaminaIncMax();
00574 if ( sta > SS->getStaminaMax() )
00575 sta = SS->getStaminaMax();
00576
00577 stamina->setStamina ( sta );
00578 stamina->setEffort ( eff );
00579 stamina->setRecovery( rec );
00580 }
00581
00588 SoccerCommand WorldModel::predictCommandTurnTowards( ObjectT obj, VecPosition
00589 posTo, int iCycles, double dDistBack, bool bMoveBack,
00590 VecPosition *posIn, VecPosition *velIn, AngDeg *angBodyIn )
00591 {
00592 SoccerCommand soc, socFirst;
00593 VecPosition pos, vel;
00594 AngDeg angBody, ang, angNeck, angTo;
00595 Stamina sta;
00596 bool bFirst = true;
00597
00598
00599 angBody = ( angBodyIn == NULL ) ? getGlobalBodyAngle( obj ) : *angBodyIn;
00600 pos = ( posIn == NULL ) ? getGlobalPosition ( obj ) : *posIn;
00601 vel = ( velIn == NULL ) ? getGlobalVelocity ( obj ) : *velIn;
00602 angNeck = getGlobalNeckAngle( obj );
00603
00604
00605
00606 VecPosition posPred=predictPosAfterNrCycles( obj, min(iCycles,4),
00607 0, &pos, &vel, false );
00608 Line line =Line::makeLineFromPositionAndAngle( posPred, angBody );
00609 double dDist =line.getDistanceWithPoint( posTo );
00610
00611
00612 angTo = (posTo - posPred).getDirection();
00613 angTo = VecPosition::normalizeAngle( angTo - angBody );
00614
00615
00616 double dRatioTurn;
00617 if( pos.getDistanceTo(posTo) > 30.0 )
00618 dRatioTurn = 4.0;
00619 if( pos.getDistanceTo(posTo) > 20.0 )
00620 dRatioTurn = 3.0;
00621 else if( pos.getDistanceTo(posTo) > 10 )
00622 dRatioTurn = 2.0;
00623 else
00624 dRatioTurn = 0.90 ;
00625
00626 AngDeg angTmp = angTo + (bMoveBack) ? 180 : 0;
00627 angTmp = VecPosition::normalizeAngle( angTmp );
00628
00629
00630
00631
00632
00633 int turn = 0;
00634 while( ( dDist > dRatioTurn*getMaximalKickDist( obj ) ||
00635 ( posPred.getDistanceTo( posTo ) > dDistBack &&
00636 ( ( fabs( angTo ) > 90 && bMoveBack == false ) ||
00637 ( fabs( angTo ) < 90 && bMoveBack == true ) ) ) )
00638 && turn < 5 && fabs( angTmp ) > PS->getPlayerWhenToTurnAngle() )
00639 {
00640
00641 ang = (posTo - posPred).getDirection() + (( bMoveBack == true )?180:0);
00642 ang = VecPosition::normalizeAngle( ang - angBody );
00643 soc = SoccerCommand(CMD_TURN,getAngleForTurn(ang,vel.getMagnitude(),obj));
00644 Log.log( 468, "angTo %f, dDist %f, ang %f %d angBody %f soc %f vel %f %f",
00645 angTo, dDist, ang, obj, angBody, soc.dAngle, vel.getMagnitude(),
00646 getInertiaMoment( obj ));
00647 if( bFirst == true )
00648 socFirst = soc;
00649 bFirst = false;
00650 predictStateAfterTurn(soc.dAngle, &pos, &vel, &angBody,&angNeck,obj,&sta);
00651 line = Line::makeLineFromPositionAndAngle( posPred, angBody );
00652 dDist = line.getDistanceWithPoint( posTo );
00653 angTo = (posTo - posPred).getDirection();
00654 angTo = VecPosition::normalizeAngle( angTo - angBody );
00655 turn++;
00656 }
00657
00658
00659
00660 if( turn > 1 && iCycles < 4 && posPred.getDistanceTo( posTo ) < dDistBack &&
00661 bMoveBack == false)
00662 {
00663 angBody = ( angBodyIn == NULL ) ? getGlobalBodyAngle( obj ) : *angBodyIn;
00664 pos = ( posIn == NULL ) ? getGlobalPosition ( obj ) : *posIn;
00665 vel = ( velIn == NULL ) ? getGlobalVelocity ( obj ) : *velIn;
00666 ang = (posTo - posPred).getDirection() + 180;
00667 ang = VecPosition::normalizeAngle( ang - angBody );
00668 soc = SoccerCommand(CMD_TURN,getAngleForTurn(ang,vel.getMagnitude(),obj));
00669 predictStateAfterTurn( soc.dAngle,&pos,&vel,&angBody,&angNeck,obj,&sta);
00670 line = Line::makeLineFromPositionAndAngle( posPred, angBody );
00671 dDist = line.getDistanceWithPoint( posTo );
00672 if( dDist < 0.9*getMaximalKickDist( obj ) )
00673 {
00674 Log.log( 463, "turn around and intercept with back" );
00675 return soc;
00676 }
00677 }
00678
00679 return socFirst;
00680 }
00681
00686 SoccerCommand WorldModel::predictCommandToMoveToPos( ObjectT obj,
00687 VecPosition posTo, int iCycles, double dDistBack,
00688 bool bMoveBack,VecPosition *posIn, VecPosition *velIn, AngDeg *angBodyIn)
00689 {
00690 VecPosition pos, vel;
00691 AngDeg angBody;
00692 SoccerCommand soc;
00693 double dPower;
00694
00695
00696 angBody = ( angBodyIn == NULL ) ? getGlobalBodyAngle( obj ) : *angBodyIn;
00697 pos = ( posIn == NULL ) ? getGlobalPosition ( obj ) : *posIn;
00698 vel = ( velIn == NULL ) ? getGlobalVelocity ( obj ) : *velIn;
00699
00700 soc = predictCommandTurnTowards(obj, posTo, iCycles, dDistBack, bMoveBack,
00701 posIn, velIn, angBodyIn);
00702 if( ! soc.isIllegal() )
00703 return soc;
00704
00705 dPower = getPowerForDash( posTo-pos, angBody, vel,getAgentEffort(),iCycles );
00706 return SoccerCommand( CMD_DASH, dPower );
00707 }
00708
00715 SoccerCommand WorldModel::predictCommandToInterceptBall( ObjectT obj,
00716 SoccerCommand socClose, int *iCycles, VecPosition *posIntercept,
00717 VecPosition *posIn, VecPosition *velIn, AngDeg *angBodyIn )
00718 {
00719 FeatureT feature_type = FEATURE_INTERCEPTION_POINT_BALL;
00720
00721
00722 if( isFeatureRelevant( feature_type ) )
00723 {
00724 int i = max(0,((int)getFeature(feature_type).getInfo()-getCurrentCycle()));
00725 if( iCycles != NULL )
00726 *iCycles = i;
00727 if( posIntercept != NULL )
00728 *posIntercept = predictPosAfterNrCycles( OBJECT_BALL, i );
00729
00730 Log.log( 463, "intercept, use old info, feature %d: %d", feature_type,
00731 max(0,((int)getFeature( feature_type ).getInfo()-getCurrentCycle())));
00732 return getFeature( feature_type ).getCommand();
00733 }
00734
00735
00736 SoccerCommand soc;
00737 VecPosition pos, vel, posPred, posBall(0,0), posBallTmp, velBall, posAgent;
00738 AngDeg angBody, angNeck;
00739 int iMinCyclesBall=100, iFirstBall=100;
00740 double dMaxDist = getMaximalKickDist( obj );
00741 double dBestX = UnknownDoubleValue;
00742 Stamina sta;
00743 double dMinOldIntercept = 100, dDistanceOfIntercept = 10.0;
00744 int iOldIntercept = UnknownIntValue;
00745 static Time timeLastIntercepted(-1,0);
00746 static VecPosition posOldIntercept;
00747
00748
00749 if( (getCurrentTime() - timeLastIntercepted) > 2 )
00750 posOldIntercept.setVecPosition( UnknownDoubleValue, UnknownDoubleValue);
00751 timeLastIntercepted = getCurrentTime();
00752
00753 int iCyclesBall = 0;
00754
00755 Log.log( 468, "old interception point: (%f,%f)", posOldIntercept.getX(),
00756 posOldIntercept.getY() );
00757
00758
00759
00760 while( iCyclesBall <= PS->getPlayerWhenToIntercept() &&
00761 iCyclesBall <= iFirstBall + 20 &&
00762 isInField( posBall ) == true )
00763 {
00764
00765 angBody = ( angBodyIn == NULL ) ? getGlobalBodyAngle( obj ) : *angBodyIn;
00766 angNeck = getGlobalNeckAngle( obj );
00767 pos = ( posIn == NULL ) ? getGlobalPosition ( obj ) : *posIn;
00768 vel = ( velIn == NULL ) ? getGlobalVelocity ( obj ) : *velIn;
00769 sta = getAgentStamina();
00770 soc.commandType = CMD_ILLEGAL;
00771
00772
00773 posBallTmp = predictPosAfterNrCycles( OBJECT_BALL, iCyclesBall );
00774 if( iCyclesBall == 0 )
00775 velBall = getGlobalVelocity( OBJECT_BALL );
00776 else
00777 velBall = posBallTmp - posBall;
00778 posBall = posBallTmp;
00779
00780
00781 posPred = predictPosAfterNrCycles( obj, min(iCyclesBall,4), 0 );
00782 posAgent = getGlobalPosition( obj );
00783
00784
00785 if( posPred.getDistanceTo(posBall)/getPlayerSpeedMax( obj )
00786 > iCyclesBall + dMaxDist || isInField( posBall ) == false )
00787 {
00788 iCyclesBall++;
00789 continue;
00790 }
00791
00792
00793 for( int i = 0; i < iCyclesBall; i++ )
00794 {
00795 soc = predictCommandToMoveToPos( obj, posBall, iCyclesBall - i ,
00796 2.5, false, &pos, &vel, &angBody );
00797 predictStateAfterCommand( soc, &pos, &vel, &angBody, &angNeck, obj );
00798 }
00799
00800
00801 if (pos.getDistanceTo( posBall ) < dMaxDist )
00802 {
00803 Log.log( 468, "can intercept ball in %d cycles, dist %f, old %f obj %d",
00804 iCyclesBall, pos.getDistanceTo( posBall ),
00805 posBall.getDistanceTo( posOldIntercept ), obj );
00806
00807 if( iMinCyclesBall == 100 )
00808 iFirstBall = iMinCyclesBall = iCyclesBall;
00809
00810
00811
00812
00813
00814
00815
00816
00817 if( posBall.getDistanceTo( posOldIntercept ) <
00818 min( 1.0, dMinOldIntercept ) &&
00819 pos.getDistanceTo( posBall ) < 0.70*getMaximalKickDist( obj ) &&
00820 velBall.getMagnitude() > 0.6 )
00821 {
00822 Log.log( 468, "update old interception point %d", iCyclesBall );
00823 dBestX = posBall.getX();
00824 iOldIntercept = iCyclesBall;
00825 dDistanceOfIntercept = pos.getDistanceTo( posBall );
00826 dMinOldIntercept = posBall.getDistanceTo( posOldIntercept );
00827 }
00828
00829
00830
00831
00832 else if( pos.getDistanceTo( posBall ) < dDistanceOfIntercept &&
00833 dDistanceOfIntercept > 0.50*getMaximalKickDist( obj ) &&
00834 ( iCyclesBall <= iMinCyclesBall + 3 ||
00835 iCyclesBall <= iOldIntercept + 3 ) &&
00836 fabs( posBall.getY() ) < 32.0 &&
00837 fabs( posBall.getX() ) < 50.0 )
00838 {
00839 iMinCyclesBall = iCyclesBall;
00840 dDistanceOfIntercept = pos.getDistanceTo( posBall );
00841 Log.log( 468, "safer interception at %d", iMinCyclesBall );
00842 if( iOldIntercept == iMinCyclesBall - 1 )
00843 {
00844 Log.log( 468, "old interception point -> safer" );
00845 iOldIntercept = iMinCyclesBall;
00846 }
00847 }
00848 }
00849 else
00850 Log.log( 468, "cannot intercept ball in %d cycles, dist %f, %f and %f",
00851 iCyclesBall, pos.getDistanceTo(posBall), pos.getDistanceTo( posAgent ),
00852 posBall.getDistanceTo( posAgent ) - dMaxDist);;
00853
00854 iCyclesBall++;
00855 }
00856
00857 Log.log( 463, "first interception point: %d cycles", iFirstBall );
00858 Log.log( 463, "best interception point: %d cycles", iMinCyclesBall );
00859 Log.log( 463, "old interception point %d cycles", iOldIntercept );
00860
00861
00862 if( !( iMinCyclesBall > iOldIntercept + 2 ) &&
00863 iOldIntercept != UnknownIntValue )
00864 {
00865 Log.log( 463, "move to old interception point." );
00866 iMinCyclesBall = iOldIntercept;
00867 }
00868 else
00869 {
00870 Log.log( 463, "move to first intercept" );
00871 iMinCyclesBall = iFirstBall;
00872 }
00873
00874 posBall = predictPosAfterNrCycles( OBJECT_BALL, iMinCyclesBall );
00875 Log.log( 463, "choose %d cycles", iMinCyclesBall );
00876 logCircle( 463, posBall, 1.0 );
00877 if( iCycles != NULL )
00878 *iCycles = iMinCyclesBall;
00879
00880 posOldIntercept = posBall;
00881 posPred = predictPosAfterNrCycles( obj, min(iMinCyclesBall,4), 0 );
00882 if( posIntercept != NULL )
00883 *posIntercept = posBall;
00884
00885 if( iMinCyclesBall < 3 && ! socClose.isIllegal() )
00886 {
00887 Log.log( 463, "do close intercept" );
00888 iMinCyclesBall = 1;
00889 soc = socClose;
00890 }
00891 else if( posPred.getDistanceTo( posBall ) < 0.5 )
00892 {
00893 Log.log( 463, "intercept: do not move already close" );
00894 soc = SoccerCommand( CMD_ILLEGAL );
00895 }
00896 else
00897 {
00898 Log.log( 463, "intercept: move to (%f,%f)", posBall.getX(),posBall.getY());
00899 Log.log( 560, "intercept: move to (%f,%f) in %d cycles",
00900 posBall.getX(),posBall.getY(), iMinCyclesBall);
00901 if( isDeadBallUs() && !isGoalKickUs())
00902 soc = predictCommandToMoveToPos( obj, posBall, iMinCyclesBall, 0 );
00903 else
00904 soc = predictCommandToMoveToPos( obj, posBall, iMinCyclesBall );
00905 }
00906
00907
00908 if( obj == getAgentObjectType() )
00909 setFeature( feature_type,
00910 Feature( getTimeLastSeeMessage(),
00911 getTimeLastSenseMessage(),
00912 getTimeLastHearMessage(),
00913 OBJECT_ILLEGAL,
00914 getTimeLastSeeMessage().getTime() + iMinCyclesBall,
00915 soc ) );
00916 return soc;
00917 }
00918
00929 bool WorldModel::isCollisionAfterCommand( SoccerCommand soc )
00930 {
00931 VecPosition posPred, velPred;
00932 AngDeg ang1, ang2;
00933 Stamina sta;
00934
00935 predictAgentStateAfterCommand( soc, &posPred, &velPred, &ang1,&ang2,&sta );
00936 velPred /= SS->getPlayerDecay();
00937 VecPosition posBall = predictPosAfterNrCycles( OBJECT_BALL, 1 );
00938 if( soc.commandType == CMD_KICK )
00939 predictBallInfoAfterCommand( soc, &posBall );
00940 double dDist = posPred.getDistanceTo( posBall ) -
00941 SS->getPlayerSize() - SS->getBallSize();
00942 Log.log( 510, "check collision dist %f, noise_ball %f noise_me %f",
00943 dDist, getBallSpeed()*SS->getBallRand(),
00944 velPred.getMagnitude()*SS->getPlayerRand() );
00945
00946
00947
00948 if( dDist < getBallSpeed()*SS->getBallRand() )
00949 return true;
00950
00951 return false;
00952 }
00953