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
00049 #include<list>
00050 #include<stdio.h>
00051 #include "WorldModel.h"
00052
00058 int WorldModel::getNrInSetInCircle( ObjectSetT set, Circle c )
00059 {
00060 double dConfThr = PS->getPlayerConfThr();
00061 int iNr = 0;
00062 int iIndex;
00063
00064 for( ObjectT o = iterateObjectStart( iIndex, set, dConfThr );
00065 o != OBJECT_ILLEGAL;
00066 o = iterateObjectNext ( iIndex, set, dConfThr ) )
00067 {
00068 if( c.isInside( getGlobalPosition( o ) ) )
00069 iNr++;
00070 }
00071 iterateObjectDone( iIndex );
00072
00073 return iNr;
00074 }
00075
00085 int WorldModel::getNrInSetInRectangle( ObjectSetT set, Rect *rect )
00086 {
00087 double dConfThr = PS->getPlayerConfThr();
00088 int iNr = 0;
00089 int iIndex;
00090
00091 for( ObjectT o = iterateObjectStart( iIndex, set, dConfThr );
00092 o != OBJECT_ILLEGAL;
00093 o = iterateObjectNext ( iIndex, set, dConfThr ) )
00094 {
00095 if( rect == NULL || rect->isInside( getGlobalPosition( o ) ) )
00096 iNr++;
00097 }
00098 iterateObjectDone( iIndex );
00099 return iNr;
00100 }
00101
00113 int WorldModel::getNrInSetInCone( ObjectSetT set, double dWidth,
00114 VecPosition start , VecPosition end )
00115 {
00116 double dConfThr = PS->getPlayerConfThr();
00117 int iNr = 0;
00118 int iIndex;
00119 Line line = Line::makeLineFromTwoPoints( start, end );
00120 VecPosition posOnLine;
00121 VecPosition posObj;
00122
00123 for( ObjectT o = iterateObjectStart( iIndex, set, dConfThr );
00124 o != OBJECT_ILLEGAL;
00125 o = iterateObjectNext ( iIndex, set, dConfThr ) )
00126 {
00127 posObj = getGlobalPosition( o );
00128 posOnLine = line.getPointOnLineClosestTo( posObj );
00129
00130
00131
00132
00133 if(posOnLine.getDistanceTo(posObj) < dWidth*posOnLine.getDistanceTo(start)
00134 && line.isInBetween( posOnLine, start, end )
00135 && start.getDistanceTo( posObj ) < start.getDistanceTo( end ) )
00136 iNr++;
00137 }
00138 iterateObjectDone( iIndex );
00139 return iNr;
00140 }
00141
00142
00145 bool WorldModel::isEmptySpace( ObjectT obj, AngDeg ang, double dDist )
00146 {
00147 if( obj == OBJECT_ILLEGAL )
00148 return false;
00149
00150 VecPosition pos = getGlobalPosition( obj );
00151 pos += VecPosition( dDist, ang, POLAR );
00152
00153 if( getNrInSetInCircle( OBJECT_SET_OPPONENTS, Circle( pos, dDist ) ) == 0 )
00154 return true;
00155
00156 return false;
00157 }
00158
00159
00160 bool WorldModel::coordinateWith( ObjectT obj )
00161 {
00162 VecPosition pos = getGlobalPosition( obj );
00163 if( pos.getDistanceTo( getBallPos() ) < 30.0 &&
00164 pos.getX() > getBallPos().getX() - 5.0 )
00165 {
00166
00167 if( getFastestInSetTo( OBJECT_SET_TEAMMATES, OBJECT_BALL ) ==
00168 getAgentObjectType() )
00169 {
00170 logCircle( 700, pos, 2.5 );
00171 }
00172 Log.log( 700, "coordinate with %d %f %f (%f %f)",
00173 obj, pos.getDistanceTo( getBallPos() ),
00174 pos.getX(), getBallPos().getX(), getBallPos().getY() );
00175 return true;
00176 }
00177
00178 return false;
00179 }
00180
00196 ObjectT WorldModel::getClosestInSetTo( ObjectSetT set, ObjectT objTarget,
00197 double *dDist, double dConfThr )
00198 {
00199 if( dConfThr == -1.0 ) dConfThr = PS->getPlayerConfThr();
00200 ObjectT closestObject = OBJECT_ILLEGAL;
00201 double dMinMag = 1000.0;
00202 VecPosition v;
00203 int iIndex;
00204
00205 for( ObjectT o = iterateObjectStart( iIndex, set, dConfThr );
00206 o != OBJECT_ILLEGAL;
00207 o = iterateObjectNext ( iIndex, set, dConfThr ) )
00208 {
00209 if( o != objTarget )
00210 {
00211 v = getGlobalPosition( objTarget ) - getGlobalPosition( o );
00212 if( v.getMagnitude() < dMinMag )
00213 {
00214 dMinMag = v.getMagnitude();
00215 closestObject = o;
00216 }
00217 }
00218 }
00219
00220 iterateObjectDone( iIndex );
00221 if( dDist != NULL )
00222 *dDist = dMinMag;
00223 return closestObject;
00224 }
00225
00240 ObjectT WorldModel::getClosestInSetTo( ObjectSetT set, VecPosition pos,
00241 double *dDist, double dConfThr )
00242 {
00243 ObjectT closestObject = OBJECT_ILLEGAL;
00244 double dMinMag = 1000.0;
00245 VecPosition v;
00246 int iIndex;
00247
00248 if( dConfThr == -1.0 ) dConfThr = PS->getPlayerConfThr();
00249 for( ObjectT o = iterateObjectStart( iIndex, set, dConfThr );
00250 o != OBJECT_ILLEGAL;
00251 o = iterateObjectNext ( iIndex, set, dConfThr ) )
00252 {
00253 v = pos - getGlobalPosition( o );
00254 if( v.getMagnitude() < dMinMag )
00255 {
00256 dMinMag = v.getMagnitude();
00257 closestObject = o;
00258 }
00259 }
00260 iterateObjectDone( iIndex );
00261 if( dDist != NULL )
00262 *dDist = dMinMag;
00263 return closestObject;
00264 }
00265
00281 ObjectT WorldModel::getClosestInSetTo( ObjectSetT set, Line l,
00282 VecPosition pos1, VecPosition pos2,
00283 double *dDistObjToLine, double *dDistPos1ToPoint)
00284 {
00285 VecPosition posObj;
00286 VecPosition posOnLine;
00287 double dConfThr = PS->getPlayerConfThr();
00288 ObjectT obj = OBJECT_ILLEGAL;
00289 double dDist ;
00290 double dMinDist = 1000.0;
00291 double dDistPos1 = 1000.0;
00292 int iIndex;
00293
00294 for( ObjectT o = iterateObjectStart( iIndex, set, dConfThr );
00295 o != OBJECT_ILLEGAL;
00296 o = iterateObjectNext ( iIndex, set, dConfThr ) )
00297 {
00298 posObj = getGlobalPosition( o );
00299 posOnLine = l.getPointOnLineClosestTo( posObj );
00300 dDist = posObj.getDistanceTo( posOnLine );
00301 if( l.isInBetween( posOnLine, pos1, pos2 ) && dDist < dMinDist )
00302 {
00303 dMinDist = dDist;
00304 obj = o;
00305 dDistPos1 = pos1.getDistanceTo( posOnLine );
00306 }
00307 }
00308 iterateObjectDone( iIndex );
00309 if( dDistObjToLine != NULL )
00310 *dDistObjToLine = dMinDist;
00311 if( dDistPos1ToPoint != NULL )
00312 *dDistPos1ToPoint = dDistPos1;
00313
00314 return obj;
00315 }
00316
00323 ObjectT WorldModel::getClosestRelativeInSet( ObjectSetT set, double *dDist )
00324 {
00325 ObjectT closestObject = OBJECT_ILLEGAL;
00326 double dMinMag = 1000.0;
00327 int iIndex;
00328
00329 for( ObjectT o = iterateObjectStart( iIndex, set, 1.0 );
00330 o != OBJECT_ILLEGAL;
00331 o = iterateObjectNext ( iIndex, set, 1.0 ) )
00332 {
00333 if( getRelativeDistance( o ) < dMinMag )
00334 {
00335 dMinMag = getRelativeDistance( o );
00336 closestObject = o;
00337 }
00338 }
00339
00340 iterateObjectDone( iIndex );
00341 if( dDist != NULL )
00342 *dDist = dMinMag;
00343 return closestObject;
00344 }
00345
00356 ObjectT WorldModel::getSecondClosestInSetTo ( ObjectSetT set, ObjectT obj,
00357 double *dDist, double dConfThr )
00358 {
00359 VecPosition v;
00360 ObjectT closestObject = OBJECT_ILLEGAL;
00361 ObjectT secondClosestObject = OBJECT_ILLEGAL;
00362 double dMinMag = 1000.0;
00363 double dSecondMinMag = 1000.0;
00364 int iIndex;
00365
00366 if( dConfThr == -1.0 ) dConfThr = PS->getPlayerConfThr();
00367
00368 for( ObjectT o = iterateObjectStart( iIndex, set, dConfThr );
00369 o != OBJECT_ILLEGAL;
00370 o = iterateObjectNext ( iIndex, set, dConfThr ) )
00371 {
00372 if( o != obj )
00373 {
00374 v = getGlobalPosition( obj ) - getGlobalPosition( o );
00375 if( v.getMagnitude() < dMinMag )
00376 {
00377 dSecondMinMag = dMinMag;
00378 secondClosestObject = closestObject;
00379 dMinMag = v.getMagnitude();
00380 closestObject = o;
00381 }
00382 else if( v.getMagnitude() < dSecondMinMag )
00383 {
00384 dSecondMinMag = v.getMagnitude();
00385 secondClosestObject = o;
00386 }
00387 }
00388 }
00389 iterateObjectDone( iIndex );
00390 if( dDist != NULL )
00391 *dDist = dSecondMinMag;
00392 return secondClosestObject;
00393 }
00394
00401 ObjectT WorldModel::getSecondClosestRelativeInSet( ObjectSetT set,
00402 double *dDist )
00403 {
00404 ObjectT closestObject = OBJECT_ILLEGAL;
00405 ObjectT secondClosestObject = OBJECT_ILLEGAL;
00406 double dMinMag = 1000.0;
00407 double dSecondMinMag = 1000.0;
00408 double d;
00409 int iIndex;
00410
00411 for( ObjectT o = iterateObjectStart( iIndex, set, 1.0 );
00412 o != OBJECT_ILLEGAL;
00413 o = iterateObjectNext ( iIndex, set, 1.0 ) )
00414 {
00415 d = getRelativeDistance( o );
00416 if( d < dMinMag )
00417 {
00418 dSecondMinMag = dMinMag;
00419 secondClosestObject = closestObject;
00420 dMinMag = d;
00421 closestObject = o;
00422 }
00423 else if( d < dSecondMinMag )
00424 {
00425 dSecondMinMag = d;
00426 secondClosestObject = o;
00427 }
00428 }
00429 iterateObjectDone( iIndex );
00430 if( dDist != NULL )
00431 *dDist = dSecondMinMag;
00432 return secondClosestObject;
00433 }
00434
00435
00447 ObjectT WorldModel::getFurthestInSetTo( ObjectSetT set, ObjectT objTarget,
00448 double *dDist, double dConfThr )
00449 {
00450 if( dConfThr == -1.0 ) dConfThr = PS->getPlayerConfThr();
00451
00452 ObjectT furthestObject = OBJECT_ILLEGAL;
00453 double dMaxMag = -1000.0;
00454 VecPosition v;
00455 int iIndex;
00456
00457 for( ObjectT o = iterateObjectStart( iIndex, set, dConfThr );
00458 o != OBJECT_ILLEGAL;
00459 o = iterateObjectNext ( iIndex, set, dConfThr ) )
00460 {
00461 if( o != objTarget )
00462 {
00463 v = getGlobalPosition( objTarget ) - getGlobalPosition( o );
00464 if( v.getMagnitude() > dMaxMag )
00465 {
00466 dMaxMag = v.getMagnitude();
00467 furthestObject = o;
00468 }
00469 }
00470 }
00471 iterateObjectDone( iIndex );
00472 if( dDist != NULL )
00473 *dDist = dMaxMag;
00474 return furthestObject;
00475 }
00476
00483 ObjectT WorldModel::getFurthestRelativeInSet( ObjectSetT set, double *dDist )
00484 {
00485 ObjectT furthestObject = OBJECT_ILLEGAL;
00486 double dMaxMag = -1000.0;
00487 int iIndex;
00488
00489 for( ObjectT o = iterateObjectStart( iIndex, set, 1.0 );
00490 o != OBJECT_ILLEGAL;
00491 o = iterateObjectNext ( iIndex, set, 1.0 ) )
00492 {
00493 if( getRelativeDistance( o ) > dMaxMag )
00494 {
00495 dMaxMag = getRelativeDistance( o );
00496 furthestObject = o;
00497 }
00498 }
00499 iterateObjectDone( iIndex );
00500 if( dDist != NULL )
00501 *dDist = dMaxMag;
00502 return furthestObject;
00503 }
00504
00505
00506 VecPosition WorldModel::getPosClosestOpponentTo( double *dDist, ObjectT o )
00507 {
00508 if( o == OBJECT_ILLEGAL )
00509 o = getAgentObjectType();
00510 ObjectT objOpp = getClosestInSetTo( OBJECT_SET_OPPONENTS, o, dDist );
00511 if( objOpp == OBJECT_ILLEGAL )
00512 return VecPosition( UnknownDoubleValue, UnknownDoubleValue );
00513
00514 return getGlobalPosition( objOpp );
00515 }
00516
00517 double WorldModel::getMaxTraveledDistance( ObjectT o )
00518 {
00519 return (getCurrentTime() - getTimeLastSeen( o ) )*SS->getPlayerSpeedMax();
00520 }
00521
00522
00523 void WorldModel::createInterceptFeatures( )
00524 {
00525 static int count = 0;
00526 static Time timeLastCalled(0,0);
00527
00528 if( timeLastCalled == getTimeLastSenseMessage() )
00529 count++;
00530 else
00531 count = 0;
00532
00533 if( count > 4 )
00534 cerr << getPlayerNumber() << " called createIntercept too often: " <<
00535 count << endl;
00536
00537
00538
00539
00540 ObjectSetT set = OBJECT_SET_PLAYERS;
00541 int iCycles = -1;
00542 int iMinCyclesTeam = 100;
00543 int iMinCyclesOpp = 100;
00544 bool bOnlyMe = false;
00545
00546 VecPosition posObj;
00547 int iIndex;
00548 int iCyclesToObj ;
00549
00550
00551 ObjectT objFastestTeam = OBJECT_ILLEGAL;
00552 ObjectT objFastestTeamNoGoalie = OBJECT_ILLEGAL;
00553 ObjectT objFastestOpp = OBJECT_ILLEGAL;
00554 ObjectT objFastestPlayer = OBJECT_ILLEGAL;
00555
00556 int iCyclesFastestPlayer = -1;
00557 int iCyclesFastestTeam = -1;
00558 int iCyclesFastestTeamNoGoalie = -1;
00559 int iCyclesFastestOpp = -1;
00560 int iCyclesFastestMe = -1;
00561
00562 bool bFinishedPlayer = false;
00563 bool bFinishedTeammates = false;
00564 bool bFinishedTeammatesNoGoalie = false;
00565 bool bFinishedOpponents = false;
00566 bool bFinishedMe = false;
00567 bool bFinished = false;
00568
00569 ObjectT objLog = OBJECT_ILLEGAL;
00570 int iCyclesLog = -1;
00571 FeatureT featLog = FEATURE_ILLEGAL;
00572
00573
00574 while( bFinished == false && iCycles <= PS->getPlayerWhenToIntercept() )
00575 {
00576 iCycles++;
00577 iMinCyclesTeam = 100;
00578 iMinCyclesOpp = 100;
00579 Log.log( 460, "fastest loop: %d", iCycles );
00580
00581
00582
00583 posObj = predictPosAfterNrCycles( OBJECT_BALL, iCycles );
00584 for( ObjectT o = iterateObjectStart( iIndex, set );
00585 o != OBJECT_ILLEGAL;
00586 o = iterateObjectNext ( iIndex, set ) )
00587 {
00588 if( getGlobalPosition(o).getDistanceTo(posObj)/SS->getPlayerSpeedMax()
00589 < iCycles + 1 && (bOnlyMe == false || SoccerTypes::isOpponent( o )
00590 || o == getAgentObjectType() ) )
00591 {
00592 Log.log( 460, "call predictNrCyclesToPoint %d %d %d",
00593 iCycles, iMinCyclesTeam, iMinCyclesOpp );
00594 iCyclesToObj = predictNrCyclesToPoint( o, posObj );
00595
00596 if( iCyclesToObj < iMinCyclesOpp && SoccerTypes::isOpponent( o ) )
00597 {
00598 iMinCyclesOpp = iCyclesToObj;
00599 objFastestOpp = o;
00600 }
00601 if( iCyclesToObj < iMinCyclesTeam && SoccerTypes::isTeammate( o ) )
00602 {
00603 iMinCyclesTeam = iCyclesToObj;
00604 objFastestTeam = o;
00605 }
00606 }
00607 }
00608 iterateObjectDone( iIndex );
00609
00610 bool bContinue = true;
00611 bool bLastCall = ( iCycles == PS->getPlayerWhenToIntercept() );
00612
00613 while( bContinue )
00614 {
00615 featLog = FEATURE_ILLEGAL;
00616 if( bLastCall )
00617 iCycles = 100;
00618
00619
00620
00621 if( bFinishedPlayer == false &&
00622 ( min( iMinCyclesTeam, iMinCyclesOpp ) <= iCycles
00623 ||
00624 bLastCall == true ) )
00625 {
00626 featLog = FEATURE_FASTEST_PLAYER_TO_BALL;
00627 iCyclesLog = iCycles;
00628 iCyclesFastestPlayer = iCycles;
00629 objLog = (iMinCyclesTeam<=iMinCyclesOpp) ?
00630 objFastestTeam : objFastestOpp;
00631 objFastestPlayer = objLog;
00632 bFinishedPlayer = true;
00633 }
00634
00635 else if( bFinishedTeammates == false &&
00636 (iMinCyclesTeam <= iCycles || bFinishedOpponents == true
00637 || bLastCall))
00638 {
00639 if( bFinishedOpponents == true )
00640 objFastestTeam = getFastestInSetTo( OBJECT_SET_TEAMMATES, posObj,
00641 VecPosition(0,0), 0, &iCycles );
00642 featLog = FEATURE_FASTEST_TEAMMATE_TO_BALL;
00643 iCyclesLog = iCycles;
00644 iCyclesFastestTeam = iCycles;
00645 objLog = objFastestTeam;
00646 bFinishedTeammates = true;
00647 }
00648 else if( bFinishedTeammatesNoGoalie == false &&
00649 ( ( iMinCyclesTeam <= iCycles && objFastestTeam != getOwnGoalieType())
00650 || bFinishedOpponents == true || bLastCall ) )
00651 {
00652 if( bFinishedOpponents == true && objFastestTeam == getOwnGoalieType())
00653 objFastestTeam=getFastestInSetTo( OBJECT_SET_TEAMMATES_NO_GOALIE,
00654 posObj, VecPosition(0,0), 0, &iCycles );
00655 featLog = FEATURE_FASTEST_TEAMMATE_TO_BALL_NO_GOALIE;
00656 iCyclesLog = iCycles;
00657 iCyclesFastestTeamNoGoalie = iCycles;
00658 objLog = objFastestTeam;
00659 objFastestTeamNoGoalie = objFastestTeam;
00660 bFinishedTeammatesNoGoalie = true;
00661 }
00662 else if( bFinishedMe == false &&
00663 ((iMinCyclesTeam <= iCycles && objFastestTeam == getAgentObjectType())
00664 || bFinishedOpponents == true || bLastCall ) )
00665 {
00666 if( bFinishedOpponents == true &&
00667 objFastestTeam != getAgentObjectType())
00668 iCycles = predictNrCyclesToPoint( getAgentObjectType(), posObj );
00669 featLog = FEATURE_INTERCEPT_CYCLES_ME;
00670 iCyclesLog = iCycles;
00671 iCyclesFastestMe = iCycles;
00672 objLog = getAgentObjectType();
00673 bFinishedMe = true;
00674 }
00675 else if( bFinishedOpponents == false &&
00676 ( iMinCyclesOpp <= iCycles || bLastCall ) )
00677 {
00678 featLog = FEATURE_FASTEST_OPPONENT_TO_BALL;
00679 iCyclesLog = iCycles;
00680 iCyclesFastestOpp = iCycles;
00681 objLog = objFastestOpp;
00682 bFinishedOpponents = true;
00683
00684 }
00685 else
00686 bContinue = false;
00687
00688 if( featLog != FEATURE_ILLEGAL )
00689 {
00690 Log.log( 460, "log feature %d object %d in %d cycles sense %d see %d",
00691 featLog, objLog, iCyclesLog,getTimeLastSenseMessage().getTime(),
00692 getTimeLastSeeMessage().getTime() );
00693 setFeature( featLog,
00694 Feature( getTimeLastSeeMessage(),
00695 getTimeLastSenseMessage(),
00696 getTimeLastHearMessage(), objLog,
00697 getTimeLastSeeMessage().getTime() + iCyclesLog));
00698 }
00699 }
00700 bFinished = bFinishedTeammates && bFinishedTeammatesNoGoalie;
00701 if( bFinished == true )
00702 bOnlyMe = true;
00703 bFinished &= bFinishedMe ;
00704 if( bFinished == true )
00705 set = OBJECT_SET_OPPONENTS;
00706 bFinished &= bFinishedOpponents;
00707 }
00708 Log.log( 460, "creatIntercept: team %d me %d opp %d",
00709 iCyclesFastestTeamNoGoalie, iCyclesFastestMe, iCyclesFastestOpp );
00710 }
00711
00712
00722 ObjectT WorldModel::getFastestInSetTo( ObjectSetT set, ObjectT obj,
00723 int *iCyclesToIntercept )
00724 {
00725 ObjectT objFastestOpp = OBJECT_ILLEGAL, objFastestTeam = OBJECT_ILLEGAL;
00726 int iCyclesFastestOpp = 30;
00727 int iCyclesFastestTeam;
00728 bool bSkip = false;
00729
00730 FeatureT feature_type = FEATURE_ILLEGAL;
00731 ObjectT fastestObject = OBJECT_ILLEGAL;
00732 int iCycles = -1;
00733
00734 if( obj == OBJECT_BALL )
00735 {
00736 switch( set )
00737 {
00738 case OBJECT_SET_OPPONENTS:
00739 feature_type = FEATURE_FASTEST_OPPONENT_TO_BALL;
00740 break;
00741 case OBJECT_SET_TEAMMATES:
00742 feature_type = FEATURE_FASTEST_TEAMMATE_TO_BALL;
00743 break;
00744 case OBJECT_SET_TEAMMATES_NO_GOALIE:
00745 feature_type = FEATURE_FASTEST_TEAMMATE_TO_BALL_NO_GOALIE;
00746 break;
00747 case OBJECT_SET_PLAYERS:
00748 objFastestOpp =
00749 getFastestInSetTo( OBJECT_SET_OPPONENTS, obj, &iCyclesFastestOpp);
00750 objFastestTeam =
00751 getFastestInSetTo( OBJECT_SET_TEAMMATES, obj, &iCyclesFastestTeam);
00752 if( iCyclesFastestOpp < iCyclesFastestTeam )
00753 {
00754 fastestObject = objFastestOpp;
00755 iCycles = iCyclesFastestOpp;
00756 }
00757 else
00758 {
00759 fastestObject = objFastestTeam;
00760 iCycles = iCyclesFastestTeam;
00761 }
00762 bSkip = true;
00763 feature_type = FEATURE_FASTEST_PLAYER_TO_BALL;
00764 break;
00765 default:
00766 cerr << "WorldModel::getFastestInSetTo unknown set: " << set << endl;
00767 return OBJECT_ILLEGAL;
00768 }
00769 if( isFeatureRelevant( feature_type ) )
00770 {
00771 int i = max(0,
00772 ((int)getFeature( feature_type ).getInfo() - getCurrentCycle() ));
00773 if( iCyclesToIntercept != NULL )
00774 *iCyclesToIntercept = i;
00775 return getFeature( feature_type ).getObject();
00776 }
00777
00778 Log.log( 460, "create intercept features" );
00779 createInterceptFeatures( );
00780 Log.log( 460, "call fastest again" );
00781 return getFastestInSetTo( set, obj, iCyclesToIntercept );
00782 if( set == OBJECT_SET_TEAMMATES || set == OBJECT_SET_TEAMMATES_NO_GOALIE )
00783 objFastestOpp =
00784 getFastestInSetTo( OBJECT_SET_OPPONENTS, obj, &iCyclesFastestOpp);
00785 }
00786
00787
00788 double dConfThr = PS->getPlayerConfThr();
00789 int iCyclesToObj ;
00790 int iMinCycles = 100;
00791 int iIndex;
00792 VecPosition posObj;
00793
00794
00795 while( bSkip == false &&
00796 iCycles < iMinCycles &&
00797 iCycles <= iCyclesFastestOpp )
00798 {
00799 iCycles++;
00800 iMinCycles = 100;
00801 posObj = predictPosAfterNrCycles( obj, iCycles );
00802 Log.log( 460, "fastest loop: %d fastest_opp %d",
00803 iCycles, iCyclesFastestOpp );
00804 for( ObjectT o = iterateObjectStart( iIndex, set, dConfThr );
00805 o != OBJECT_ILLEGAL;
00806 o = iterateObjectNext ( iIndex, set, dConfThr ) )
00807 {
00808 if( getGlobalPosition(o).getDistanceTo(posObj)/SS->getPlayerSpeedMax()
00809 < iMinCycles &&
00810 getGlobalPosition(o).getDistanceTo(posObj)/SS->getPlayerSpeedMax()
00811 < iCycles + 1 )
00812 {
00813 Log.log( 460, "call predictNrCyclesToPoint %d %d",
00814 iCycles,iMinCycles );
00815 iCyclesToObj = predictNrCyclesToPoint( o, posObj );
00816 if( iCyclesToObj < iMinCycles )
00817 {
00818 iMinCycles = iCyclesToObj;
00819 fastestObject = o;
00820 }
00821 }
00822 }
00823 iterateObjectDone( iIndex );
00824 }
00825
00826
00827
00828 if( fastestObject == OBJECT_ILLEGAL )
00829 fastestObject = getFastestInSetTo(set,posObj,VecPosition(0,0),0, &iCycles);
00830
00831 if( iCyclesToIntercept != NULL )
00832 *iCyclesToIntercept = iCycles;
00833
00834 if( feature_type != FEATURE_ILLEGAL )
00835 {
00836 Log.log( 460, "log feature %d object %d in %d cycles sense %d see %d",
00837 feature_type, fastestObject, iCycles,getTimeLastSenseMessage().
00838 getTime(), getTimeLastSeeMessage().getTime() );
00839 setFeature( feature_type,
00840 Feature( getTimeLastSeeMessage(),
00841 getTimeLastSenseMessage(),
00842 getTimeLastHearMessage(), fastestObject,
00843 getTimeLastSeeMessage().getTime() + iCycles ) );
00844 }
00845
00846 return fastestObject;
00847 }
00848
00859 ObjectT WorldModel::getFastestInSetTo( ObjectSetT set, VecPosition pos,
00860 VecPosition vel, double dDecay, int *iCyclesToIntercept)
00861 {
00862 double dConfThr = PS->getPlayerConfThr();
00863 ObjectT fastestObject = OBJECT_ILLEGAL;
00864 int iCycles = 0;
00865 int iCyclesToObj ;
00866 int iMinCycles = 100;
00867 int iIndex;
00868
00869 while( iCycles <= iMinCycles && iCycles < 100)
00870 {
00871 iCycles = iCycles + 1 ;
00872 iMinCycles = 100;
00873 Log.log( 460, "fastest to point: %d", iCycles );
00874 for( ObjectT o = iterateObjectStart( iIndex, set, dConfThr );
00875 o != OBJECT_ILLEGAL;
00876 o = iterateObjectNext ( iIndex, set, dConfThr ) )
00877 {
00878 if( getGlobalPosition(o).getDistanceTo(pos)/SS->getPlayerSpeedMax()
00879 < iMinCycles )
00880 {
00881 iCyclesToObj = predictNrCyclesToPoint( o, pos );
00882 if( iCyclesToObj < iMinCycles )
00883 {
00884 iMinCycles = iCyclesToObj;
00885 fastestObject = o;
00886 }
00887 }
00888 }
00889 iterateObjectDone( iIndex );
00890 pos += vel;
00891 vel *= dDecay;
00892 if( vel.getMagnitude( ) < EPSILON )
00893 {
00894 iCycles = iMinCycles;
00895 iMinCycles--;
00896 }
00897 }
00898
00899 if( iCyclesToIntercept != NULL )
00900 *iCyclesToIntercept = iCycles;
00901 return fastestObject;
00902 }
00903
00918 ObjectT WorldModel::getFirstEmptySpotInSet( ObjectSetT set, int iUnknownPlayer)
00919 {
00920 int iIndex;
00921
00922 for( ObjectT o = iterateObjectStart( iIndex, set, 0.0, true );
00923 o != OBJECT_ILLEGAL;
00924 o = iterateObjectNext ( iIndex, set, 0.0, true ) )
00925 {
00926 if( getConfidence( o ) <= PS->getPlayerConfThr() &&
00927 o != getAgentObjectType() )
00928 return o;
00929 }
00930 return OBJECT_ILLEGAL;
00931 }
00932
00933
00940 bool WorldModel::isVisible( ObjectT o )
00941 {
00942 Object *object = getObjectPtrFromType( o );
00943
00944 if( object != NULL &&
00945 object->getTimeLastSeen() == getTimeLastSeeMessage() )
00946 return true;
00947
00948 return false;
00949 }
00950
00957 bool WorldModel::isBallKickable()
00958 {
00959 return getRelativeDistance( OBJECT_BALL ) < SS->getMaximalKickDist();
00960 }
00961
00971 bool WorldModel::isBallCatchable()
00972 {
00973 return getTimeSinceLastCatch() > SS->getCatchBanCycle() &&
00974 getRelativeDistance( OBJECT_BALL ) <= SS->getCatchableAreaL() &&
00975 isInOwnPenaltyArea( getBallPos() );
00976 }
00977
00987 bool WorldModel::isBallHeadingToGoal( )
00988 {
00989 int iSide = 1;
00990
00991 if( isPenaltyUs() || isPenaltyThem() )
00992 iSide = ( getSide() == getSidePenalty() ) ? 1 : -1;
00993
00994 if( !isConfidenceGood( OBJECT_BALL ) ||
00995 fabs( getBallPos().getX() ) < PENALTY_X - 5.0 )
00996 {
00997 Log.log( 553, "ball not towards goal: confidence too low" );
00998 return false;
00999 }
01000
01001
01002 Line l = Line::makeLineFromPositionAndAngle(getBallPos(),getBallDirection());
01003 Line l2= Line::makeLineFromTwoPoints( getPosOwnGoal(), getPosOwnGoal() +
01004 VecPosition( 0, 10 ));
01005
01006
01007 VecPosition posIntersect = l.getIntersection( l2 );
01008 if( fabs(posIntersect.getY()) > SS->getGoalWidth()/2.0 + 3.0)
01009 {
01010 Log.log( 553, "ball not towards goal: outside goal %f",
01011 posIntersect.getY());
01012 return false;
01013 }
01014
01015
01016 VecPosition pos = getBallPos();
01017 int iCycle = 1;
01018 while( fabs( pos.getX() ) < PITCH_LENGTH/2.0 && iCycle < 20)
01019 {
01020 pos = predictPosAfterNrCycles( OBJECT_BALL, iCycle );
01021 Log.log( 553, "predicted pos %d cycles: (%f,%f)" ,
01022 iCycle, pos.getX(), pos.getY() );
01023 iCycle ++;
01024 }
01025
01026 return ( iCycle == 20 ) ? false : true;
01027 }
01028
01033 bool WorldModel::isBallInOurPossesion( )
01034 {
01035 int iCyc;
01036 ObjectT o = getFastestInSetTo( OBJECT_SET_PLAYERS, OBJECT_BALL, &iCyc );
01037
01038 if( o == OBJECT_ILLEGAL )
01039 return false;
01040 if( SoccerTypes::isTeammate( o ) )
01041 return true;
01042 else
01043 return false;
01044 }
01045
01048 bool WorldModel::isBallInOwnPenaltyArea( )
01049 {
01050 return isInOwnPenaltyArea( getBallPos() );
01051 }
01052
01057 bool WorldModel::isInOwnPenaltyArea( VecPosition pos )
01058 {
01059 ObjectT objFlag = ( getSide() == SIDE_LEFT )
01060 ? OBJECT_FLAG_P_L_C
01061 : OBJECT_FLAG_P_R_C ;
01062
01063 if( isPenaltyUs() || isPenaltyThem() )
01064 objFlag = ( getSidePenalty() == SIDE_LEFT ) ? OBJECT_FLAG_P_L_C
01065 : OBJECT_FLAG_P_R_C ;
01066 VecPosition posFlag =SoccerTypes::getGlobalPositionFlag( objFlag, getSide());
01067 if( fabs(pos.getX()) > fabs(posFlag.getX()) &&
01068 fabs( pos.getY() ) < PENALTY_AREA_WIDTH/2.0 )
01069 return true;
01070
01071 return false;
01072 }
01073
01078 bool WorldModel::isInTheirPenaltyArea( VecPosition pos )
01079 {
01080 ObjectT objFlag = ( getSide() == SIDE_LEFT )
01081 ? OBJECT_FLAG_P_R_C
01082 : OBJECT_FLAG_P_L_C ;
01083 VecPosition posFlag = SoccerTypes::getGlobalPositionFlag( objFlag,getSide());
01084
01085 if ( pos.getX() > posFlag.getX() &&
01086 fabs(pos.getY()) < PENALTY_AREA_WIDTH/2.0 )
01087 return true;
01088
01089 return false;
01090 }
01091
01100 bool WorldModel::isConfidenceGood( ObjectT o )
01101 {
01102 return getConfidence( o ) > PS->getPlayerConfThr() &&
01103 o != getAgentObjectType();
01104 }
01105
01114 bool WorldModel::isConfidenceVeryGood( ObjectT o )
01115 {
01116 return getConfidence( o ) > PS->getPlayerHighConfThr() &&
01117 o != getAgentObjectType();
01118 }
01119
01123 bool WorldModel::isOnside( ObjectT obj )
01124 {
01125 return getGlobalPosition( obj ).getX() < getOffsideX() - 0.5 ;
01126 }
01127
01135 bool WorldModel::isOpponentAtAngle( AngDeg ang , double dDist )
01136 {
01137 VecPosition posAgent = getAgentGlobalPosition();
01138 VecPosition posOpp;
01139 AngDeg angOpp;
01140 int iIndex;
01141
01142 for( ObjectT o = iterateObjectStart( iIndex, OBJECT_SET_OPPONENTS );
01143 o != OBJECT_ILLEGAL;
01144 o = iterateObjectNext ( iIndex, OBJECT_SET_OPPONENTS ) )
01145 {
01146 posOpp = getGlobalPosition( o );
01147 angOpp = ( posOpp - posAgent ).getDirection() ;
01148 if( fabs( angOpp - ang ) < 60 &&
01149 posAgent.getDistanceTo( posOpp ) < dDist )
01150 return true;
01151 else if( fabs( angOpp - ang ) < 120 &&
01152 posAgent.getDistanceTo( posOpp ) < dDist/2.0 )
01153 return true;
01154 }
01155 iterateObjectDone( iIndex );
01156 return false;
01157 }
01158
01165 Time WorldModel::getTimeFromConfidence( double dConf )
01166 {
01167 return getCurrentTime()-(int)((1.00-dConf)*100);
01168 }
01169
01174 ObjectT WorldModel::getLastOpponentDefender( double *dX )
01175 {
01176 double dHighestX = 0.0;
01177 double dSecondX = 0.0, x;
01178
01179 ObjectT o, oLast = OBJECT_ILLEGAL, oSecondLast = OBJECT_ILLEGAL;
01180 for( int i = 0; i < MAX_OPPONENTS ; i ++ )
01181 {
01182 o = Opponents[i].getType();
01183 if( isConfidenceGood( o ) )
01184 {
01185 x = Opponents[i].getGlobalPosition().getX();
01186 if( x > dHighestX )
01187 {
01188 dSecondX = dHighestX;
01189 dHighestX = x;
01190 oSecondLast = oLast;
01191 oLast = o;
01192 }
01193 else if( x > dSecondX )
01194 {
01195 dSecondX = x;
01196 oSecondLast = o;
01197 }
01198 }
01199 }
01200
01201
01202
01203 if( dHighestX < PENALTY_X && getOppGoalieType() == OBJECT_ILLEGAL )
01204 {
01205 dSecondX = dHighestX;
01206 oSecondLast = oLast;
01207 }
01208 if( dX != NULL )
01209 *dX = dSecondX ;
01210 return oSecondLast;
01211 }
01212
01221 double WorldModel::getOffsideX( bool bIncludeComm )
01222 {
01223 double x, dAgentX;
01224
01225 getLastOpponentDefender( &dAgentX );
01226 x = getBallPos().getX();
01227 x = max( x, dAgentX );
01228 if( bIncludeComm == true && getCurrentTime() - m_timeCommOffsideX < 3 )
01229 x = max( x, m_dCommOffsideX );
01230 return x ;
01231 }
01232
01247 VecPosition WorldModel::getOuterPositionInField( VecPosition pos, AngDeg ang,
01248 double dDist, bool bWithPenalty )
01249 {
01250 VecPosition posShoot;
01251
01252
01253 Line lineObj = Line::makeLineFromPositionAndAngle( pos, ang );
01254
01255
01256 Line lineLength = Line::makeLineFromPositionAndAngle(
01257 VecPosition( PITCH_LENGTH/2.0 - dDist, 0.0 ), 90 );
01258 posShoot = lineObj.getIntersection( lineLength );
01259
01260
01261 Line linePenalty = Line::makeLineFromPositionAndAngle(
01262 VecPosition( PENALTY_X - dDist, 0.0 ), 90.0 );
01263 double dPenaltyY = lineObj.getIntersection(linePenalty).getY();
01264
01265 if( bWithPenalty && fabs(dPenaltyY) < PENALTY_AREA_WIDTH/2.0 )
01266 {
01267 if( fabs(dPenaltyY) < PENALTY_AREA_WIDTH/2.0 - 5.0 ||
01268 fabs(posShoot.getY()) < PENALTY_AREA_WIDTH/2.0 )
01269 posShoot = lineObj.getIntersection( linePenalty );
01270 }
01271
01272
01273 Line lineSide = ( ang < 0 )
01274 ? Line::makeLineFromPositionAndAngle(
01275 VecPosition( 0.0, - PITCH_WIDTH/2.0 + dDist ),0.0 )
01276 : Line::makeLineFromPositionAndAngle(
01277 VecPosition( 0.0, + PITCH_WIDTH/2.0 - dDist ),0.0 );
01278
01279 if( fabs(posShoot.getY()) > PITCH_WIDTH/2.0 - dDist )
01280 posShoot = lineObj.getIntersection( lineSide );
01281
01282 return posShoot;
01283 }
01284
01296 AngDeg WorldModel::getDirectionOfWidestAngle(VecPosition posOrg, AngDeg angMin,
01297 AngDeg angMax, AngDeg *angLargest, double dDist)
01298 {
01299 list<double> v;
01300 list<double> v2;
01301 double temp;
01302 int iIndex;
01303 double dConf = PS->getPlayerConfThr();
01304
01305
01306 for( ObjectT o = iterateObjectStart( iIndex, OBJECT_SET_OPPONENTS, dConf );
01307 o != OBJECT_ILLEGAL;
01308 o = iterateObjectNext ( iIndex, OBJECT_SET_OPPONENTS, dConf ) )
01309 {
01310 if( getRelativeDistance( o ) < dDist )
01311 v.push_back( (getGlobalPosition(o)-posOrg).getDirection());
01312 }
01313 iterateObjectDone( iIndex );
01314 v.sort();
01315
01316
01317
01318
01319
01320 ObjectT objGoalie = getOppGoalieType();
01321 VecPosition posGoalie = getGlobalPosition( objGoalie );
01322 AngDeg angGoalie;
01323
01324 if( objGoalie != OBJECT_ILLEGAL && posOrg.getX() > PITCH_LENGTH/4.0 &&
01325 posOrg.getDistanceTo( posGoalie ) < dDist )
01326 {
01327 angGoalie = ( posGoalie - posOrg ).getDirection();
01328 Log.log( 560, "direction_widest_angle: min %f max %f angGoalie %f",
01329 angMin, angMax, angGoalie );
01330
01331 if( posOrg.getY() > 0 )
01332 {
01333 angGoalie = VecPosition::normalizeAngle( angGoalie - 33 );
01334 angMax = max( angMin, min( angGoalie, angMax ) );
01335 }
01336 else
01337 {
01338 angGoalie = VecPosition::normalizeAngle( angGoalie + 33 );
01339 angMin = min( angMax, max( angMin, angGoalie ) );
01340 }
01341 Log.log( 560, "direction_widest_angle after: %f %f", angMin, angMax );
01342 }
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354 double absMin = 1000;
01355 double absMax = 1000;
01356 double angProjMin = angMin;
01357 double angProjMax = angMax;
01358 double array[MAX_OPPONENTS+2];
01359
01360 while( v.size() > 0 )
01361 {
01362 if( fabs( v.front() - angMin ) < absMin )
01363 {
01364 absMin = fabs( v.front() - angMin ) ;
01365 angProjMin = angMin - absMin;
01366 }
01367 if( fabs( v.front() - angMax ) < absMax )
01368 {
01369 absMax = fabs( v.front() - angMax ) ;
01370 angProjMax = angMax + absMax;
01371 }
01372 if( v.front() > angMin && v.front() < angMax )
01373 v2.push_back( v.front() );
01374 v.pop_front();
01375 }
01376
01377
01378
01379
01380 v.push_back( 0 );
01381 while( v2.size() > 0 )
01382 {
01383 temp = VecPosition::normalizeAngle(v2.front()-angProjMin)+360.0;
01384 if( temp > 360 )
01385 temp -= 360;
01386 v.push_back( temp );
01387 v2.pop_front();
01388 }
01389
01390 temp = VecPosition::normalizeAngle(angProjMax-angProjMin)+360.0;
01391 if( temp > 360 )
01392 temp -= 360;
01393
01394 v.push_back( temp );
01395
01396
01397 v.sort();
01398
01399
01400 int i = 0;
01401 while( v.size() > 0 )
01402 {
01403 array[i++] = v.front();
01404 v.pop_front();
01405 }
01406
01407
01408 double dLargest = -1000;
01409 double d;
01410 double ang = UnknownAngleValue;
01411 for( int j = 0; j < i - 1 ; j ++ )
01412 {
01413 d = VecPosition::normalizeAngle(( array[j+1] - array[j] )/2.0);
01414 if( d > dLargest )
01415 {
01416 ang = angProjMin + array[j] + d;
01417 ang = VecPosition::normalizeAngle( ang );
01418 dLargest = d;
01419 }
01420 }
01421
01422 if( ang == UnknownAngleValue )
01423 {
01424 ang = getBisectorTwoAngles( angMin, angMax );
01425 if( angLargest != NULL )
01426 *angLargest = 360;
01427 }
01428 else if( angLargest != NULL )
01429 *angLargest = dLargest;
01430
01431 return ang;
01432 }
01433
01435 bool WorldModel::isInField( VecPosition pos, double dMargin )
01436 {
01437 return Rect(
01438 VecPosition( + PITCH_LENGTH/2.0 - dMargin,
01439 - PITCH_WIDTH/2.0 + dMargin ),
01440 VecPosition( - PITCH_LENGTH/2.0 + dMargin,
01441 + PITCH_WIDTH/2.0 - dMargin )
01442 ).isInside( pos );
01443 }
01444
01446 bool WorldModel::isBeforeGoal( VecPosition pos )
01447 {
01448 return Rect(
01449 VecPosition( + PENALTY_X - 2, - ( SS->getGoalWidth()/2.0 + 1)),
01450 VecPosition( + PITCH_LENGTH/2.0, + ( SS->getGoalWidth()/2.0 + 1))
01451 ).isInside( pos );
01452 }
01453
01464 VecPosition WorldModel::getStrategicPosition( ObjectT obj, FormationT ft )
01465 {
01466 return getStrategicPosition( SoccerTypes::getIndex( obj ), ft );
01467 }
01468
01481 VecPosition WorldModel::getStrategicPosition( int iPlayer, FormationT ft )
01482 {
01483 if( iPlayer > MAX_TEAMMATES )
01484 cerr << "WM:getStrategicPosition with player nr " << iPlayer << endl;
01485
01486 VecPosition pos, posBall = getBallPos();
01487 bool bOwnBall = isBallInOurPossesion();
01488
01489
01490 if( iPlayer == -1 )
01491 iPlayer = formations->getPlayerInFormation();
01492
01493
01494 double dMaxX = max( -0.5, getOffsideX() - 1.5 );
01495
01496 if( bOwnBall &&
01497 getGlobalPosition(
01498 SoccerTypes::getTeammateObjectFromIndex(iPlayer)).getX()
01499 < posBall.getX() )
01500 dMaxX = max( dMaxX, posBall.getX() );
01501
01502
01503
01504
01505 if( isGoalKickThem() )
01506 dMaxX = min( dMaxX, PENALTY_X - 1.0 );
01507 else if( isBeforeKickOff() )
01508 dMaxX = min( dMaxX, -2.0 );
01509 else if ( isOffsideUs() )
01510 dMaxX = posBall.getX() - 0.5;
01511
01512
01513
01514
01515 if( isBeforeKickOff() )
01516 posBall.setVecPosition( 0, 0 );
01517 else if( isGoalKickUs() ||
01518 getTimeSinceLastCatch( ) < PS->getCyclesCatchWait() + 5 ||
01519 ( isFreeKickUs() && posBall.getX() < - PENALTY_X ) )
01520 posBall.setX( -PITCH_LENGTH/4 + 5.0 );
01521 else if( getConfidence( OBJECT_BALL ) < PS->getBallConfThr() )
01522 posBall.setVecPosition( 0.0, 0.0 );
01523 else if( isGoalKickThem() ||
01524 ( isFreeKickThem() && posBall.getX() > PENALTY_X ) )
01525 posBall.setX( PENALTY_X - 10.0 );
01526 else if( isFreeKickThem() )
01527 posBall.setX( posBall.getX() - 5.0 );
01528 else if( isBallInOurPossesion() &&
01529 !( isDeadBallUs() || isDeadBallThem() ) )
01530 posBall.setX( posBall.getX() + 5.0 );
01531 else if( posBall.getX() < - PENALTY_X + 5.0 )
01532 posBall = predictPosAfterNrCycles( OBJECT_BALL, 3 );
01533
01534
01535 pos = formations->getStrategicPosition( iPlayer, posBall, dMaxX,
01536 bOwnBall, PS->getMaxYPercentage(),
01537 ft );
01538 return pos;
01539 }
01540
01561 VecPosition WorldModel::getMarkingPosition( VecPosition pos, double dDist,
01562 MarkT mark)
01563 {
01564 VecPosition posBall = getBallPos();
01565
01566 VecPosition posGoal = getPosOwnGoal( );
01567 if( posBall.getX() < - PITCH_LENGTH/2.0 + 10.0 )
01568 posGoal.setX( posBall.getX() + 1 );
01569 else if( posBall.getX() > -PITCH_LENGTH/3.0 )
01570 {
01571 posGoal.setX( -PITCH_LENGTH/2.0 );
01572 double dY = posBall.getY();
01573 if( fabs( dY ) > 12 )
01574 dY += ( sign( dY ) > 0 ) -5 ? : 5 ;
01575 posGoal.setY( dY );
01576 }
01577
01578 VecPosition posAgent = getAgentGlobalPosition();
01579 VecPosition posMark;
01580 AngDeg ang, angToGoal, angToBall;
01581
01582 if( mark == MARK_GOAL )
01583 {
01584 angToGoal = (posGoal-pos).getDirection( );
01585 Line line = Line::makeLineFromTwoPoints( pos, posGoal );
01586
01587
01588
01589
01590
01591 double dCalcDist;
01592 VecPosition posIntersect = line.getPointOnLineClosestTo( posAgent );
01593 double dDistAgent = posIntersect.getDistanceTo( posAgent );
01594 double dDistOpp = posIntersect.getDistanceTo( pos );
01595 dCalcDist = (dDistAgent*dDistAgent-dDistOpp*dDistOpp)/(2*dDistOpp);
01596 double dExtra = 2.0;
01597
01598 if( pos.getDistanceTo(posAgent) < 5 )
01599 dExtra = 0.0;
01600 dCalcDist += dDistOpp + dExtra;
01601 Log.log( 513, "dDistOpp %f dDistAgent %f calc %f min %f",
01602 dDistOpp, dDistAgent, dCalcDist, 0.75*pos.getDistanceTo(posGoal));
01603 dCalcDist = min( dCalcDist, 0.75*pos.getDistanceTo( posGoal ) );
01604 double x = -PITCH_LENGTH/2 + 4;
01605 double y = line.getYGivenX( x);
01606 posMark = pos + VecPosition( dCalcDist, angToGoal, POLAR );
01607 if( posMark.getX() < x )
01608 {
01609 Log.log( 513, "change posmark to (%f,%f)", x, y );
01610 posMark.setVecPosition( x, y );
01611 }
01612
01613
01614 if( ! line.isInBetween( posMark, pos, posGoal ) ||
01615 ( posMark.getDistanceTo( posAgent ) < 1.5 &&
01616 posMark.getDistanceTo( pos ) > 2*dDist ) )
01617 {
01618 Log.log( 513, "set marking position at dDist %f", min(dDistAgent,7.0) );
01619 posMark = pos + VecPosition( min( dDistAgent, 7.0 ), angToGoal, POLAR );
01620 }
01621 Log.log( 513, "marking position calc (%f,%f) pos(%f,%f) calcdist %f",
01622 posMark.getX(), posMark.getY(), pos.getX(), pos.getY(),
01623 dCalcDist );
01624 }
01625 else if( mark == MARK_BALL )
01626 {
01627 angToBall = (posBall-pos).getDirection( );
01628 posMark = pos + VecPosition( dDist, angToBall, POLAR );
01629 }
01630 else if( mark == MARK_BISECTOR )
01631 {
01632 angToBall = (posBall - pos).getDirection( );
01633 angToGoal = (posGoal - pos).getDirection( );
01634 ang = getBisectorTwoAngles( angToBall, angToGoal );
01635 posMark = pos + VecPosition( dDist, ang ,POLAR );
01636 }
01637 if( fabs( posMark.getX() ) > PITCH_LENGTH/2.0 - 2.0 )
01638 posMark.setX( sign(posMark.getX())*(PITCH_LENGTH/2.0 - 2.0) );
01639 return posMark;
01640
01641 }
01642
01643
01655 double WorldModel::getActualKickPowerRate( )
01656 {
01657
01658 double dir_diff = fabs( getRelativeAngle( OBJECT_BALL, true ) );
01659 double dist = getRelativeDistance( OBJECT_BALL ) -
01660 SS->getPlayerSize( ) - SS->getBallSize( );
01661 return SS->getKickPowerRate() *
01662 ( 1 - 0.25 * dir_diff/180.0 - 0.25 * dist / SS->getKickableMargin());
01663 }
01664
01679 double WorldModel::getKickPowerForSpeed( double dDesiredSpeed )
01680 {
01681
01682
01683 return dDesiredSpeed / getActualKickPowerRate( );
01684 }
01685
01686
01693 double WorldModel::getKickSpeedToTravel( double dDistance, double dEndSpeed )
01694 {
01695
01696
01697 if( dEndSpeed < 0.0001 )
01698 return Geometry::getFirstInfGeomSeries(dDistance, SS->getBallDecay() );
01699
01700
01701
01702
01703
01704
01705 double dNrSteps = Geometry::getLengthGeomSeries( dEndSpeed,
01706 1.0/SS->getBallDecay( ), dDistance );
01707 return getFirstSpeedFromEndSpeed( dEndSpeed, (int)rint(dNrSteps) ) ;
01708 }
01709
01710
01718 double WorldModel::getFirstSpeedFromEndSpeed( double dEndSpeed, double dCycles,
01719 double dDecay )
01720 {
01721 if( dDecay < 0 )
01722 dDecay = SS->getBallDecay();
01723
01724
01725
01726
01727 return dEndSpeed * pow( 1 / dDecay, dCycles );
01728 }
01729
01738 double WorldModel::getFirstSpeedFromDist( double dDist, double dCycles, double
01739 dDecay )
01740 {
01741 if( dDecay < 0 )
01742 dDecay = SS->getBallDecay();
01743
01744 return Geometry::getFirstGeomSeries( dDist, dDecay, dCycles);
01745 }
01746
01753 double WorldModel::getEndSpeedFromFirstSpeed(double dFirstSpeed,double dCycles)
01754 {
01755
01756
01757 return dFirstSpeed * pow( SS->getBallDecay(), dCycles );
01758 }
01759
01767 AngDeg WorldModel::getAngleForTurn( AngDeg angDesiredAngle, double dSpeed,
01768 ObjectT obj )
01769 {
01770 AngDeg a = angDesiredAngle * (1.0 + getInertiaMoment( obj ) * dSpeed );
01771 if( a > SS->getMaxMoment() )
01772 return SS->getMaxMoment() ;
01773 else if ( a < SS->getMinMoment() )
01774 return SS->getMinMoment() ;
01775 else
01776 return a;
01777 }
01778
01785 AngDeg WorldModel::getActualTurnAngle( AngDeg angTurn,double dSpeed,ObjectT o )
01786 {
01787 return angTurn / (1.0 + getInertiaMoment( o ) * dSpeed );
01788 }
01789
01801 double WorldModel::getPowerForDash( VecPosition posRelTo, AngDeg angBody,
01802 VecPosition vel, double dEffort, int iCycles )
01803 {
01804
01805
01806
01807
01808 double dDist = posRelTo.rotate(-angBody).getX();
01809 if( iCycles <= 0 ) iCycles = 1;
01810 double dAcc = getFirstSpeedFromDist(dDist,iCycles,SS->getPlayerDecay());
01811
01812 if( dAcc > SS->getPlayerSpeedMax() )
01813 dAcc = SS->getPlayerSpeedMax();
01814 dAcc -= vel.rotate(-angBody).getX();
01815
01816
01817
01818 double dDashPower = dAcc/(SS->getDashPowerRate() * dEffort );
01819 if( dDashPower > SS->getMaxPower() )
01820 return SS->getMaxPower();
01821 else if( dDashPower < SS->getMinPower() )
01822 return SS->getMinPower();
01823 else
01824 return dDashPower;
01825 }
01826
01827
01837 int WorldModel::getClosestPlayerInFormationTo( VecPosition pos,
01838 bool bIncludeGoalie,
01839 ObjectT objWithout,
01840 PlayerSetT ps,
01841 FormationT ft )
01842 {
01843 double dDist = 1000.0;
01844 VecPosition posStrat;
01845 int iPlayer = -1;
01846
01847 for( int i = 0; i < MAX_TEAMMATES; i++ )
01848 {
01849 if( bIncludeGoalie == false && i == 0 )
01850 continue;
01851 else if( objWithout == SoccerTypes::getTeammateObjectFromIndex( i ) )
01852 continue;
01853 else if( !SoccerTypes::isPlayerTypeInSet(
01854 formations->getPlayerType(i,ft), ps ))
01855 continue;
01856
01857 posStrat = getStrategicPosition( i, ft );
01858
01859 if( isDeadBallUs( )&&
01860 getBallPos().getX() < PITCH_LENGTH/3.0 &&
01861 i >= 9 )
01862 ;
01863 else if( posStrat.getDistanceTo( pos ) < dDist )
01864 {
01865 dDist = posStrat.getDistanceTo( pos );
01866 iPlayer = i;
01867 }
01868 }
01869 return iPlayer;
01870 }