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
00048 #include "WorldModel.h"
00049 #include "Parse.h"
00050 #include <stdio.h>
00051 #include <list>
00052
00053 #include <sys/times.h>
00054 #include <sys/time.h>
00055 #include <sys/resource.h>
00056 #include <unistd.h>
00057
00058
00059
00060
00061
00062
00063
00075 void WorldModel::processSeeGlobalInfo( ObjectT o, Time time,
00076 VecPosition pos, VecPosition vel, AngDeg angBody, AngDeg angNeck)
00077 {
00078 DynamicObject * dobj;
00079 PlayerObject * pobj;
00080
00081 if( o == OBJECT_ILLEGAL )
00082 return;
00083 if( SoccerTypes::isPlayer( o ) )
00084 {
00085 pobj = (PlayerObject*)getObjectPtrFromType( o );
00086 pobj->setTimeLastSeen( time );
00087 pobj->setGlobalPositionLastSee( pos, time );
00088 pobj->setTimeChangeInformation( time );
00089 pobj->setGlobalPosition( pos, time );
00090 pobj->setGlobalVelocity( vel, time );
00091 pobj->setGlobalBodyAngle( angBody, time );
00092 pobj->setGlobalNeckAngle( VecPosition::normalizeAngle(angBody+angNeck),
00093 time );
00094 pobj->setIsKnownPlayer( true );
00095
00096 }
00097 else if( SoccerTypes::isBall( o ) )
00098 {
00099 dobj = (DynamicObject*)getObjectPtrFromType( o );
00100 dobj->setTimeLastSeen( time );
00101 dobj->setGlobalPosition( pos, time );
00102 dobj->setGlobalVelocity( vel, time );
00103 }
00104 }
00105
00121 bool WorldModel::processNewAgentInfo( ViewQualityT vq, ViewAngleT va,
00122 double dStamina, double dEffort, double dSpeed, AngDeg angSpeed,
00123 AngDeg angHeadAngle, int iTackleExpires, int iArmMovable,
00124 int iArmExpires, VecPosition posArm )
00125 {
00126 Stamina sta = agentObject.getStamina();
00127
00128 sta.setStamina ( dStamina );
00129 sta.setEffort ( dEffort );
00130 agentObject.setStamina ( sta );
00131
00132
00133 if( vq == VQ_ILLEGAL )
00134 agentObject.setViewQuality ( vq );
00135 if( va == VA_ILLEGAL )
00136 agentObject.setViewAngle ( va );
00137 agentObject.setSpeedRelToNeck ( VecPosition( dSpeed, angSpeed, POLAR) );
00138 agentObject.setBodyAngleRelToNeck( angHeadAngle );
00139 agentObject.setTackleExpires ( iTackleExpires );
00140 agentObject.setArmMovable ( iArmMovable == 0 );
00141 agentObject.setArmExpires ( iArmExpires );
00142 agentObject.setGlobalArmPosition ( getAgentGlobalPosition() + posArm );
00143
00144 return true;
00145 }
00146
00170 void WorldModel::processNewObjectInfo( ObjectT o, Time time,
00171 double dDist, int iDir, double dDistChange, double dDirChange,
00172 AngDeg angRelBodyAng, AngDeg angRelNeckAng, bool isGoalie,
00173 ObjectT objMin, ObjectT objMax, double dPointDir, bool isTackling )
00174 {
00175 if( dDist == UnknownDoubleValue || o == OBJECT_ILLEGAL )
00176 return;
00177
00178 if( SoccerTypes::isFlag( o ) )
00179 {
00180
00181 Flags[SoccerTypes::getIndex(o)].setRelativePosition(
00182 dDist,(double)iDir,time);
00183 Flags[SoccerTypes::getIndex(o)].setTimeLastSeen ( time );
00184 Flags[SoccerTypes::getIndex(o)].setType ( o );
00185 }
00186 else if( SoccerTypes::isPlayer( o ) || SoccerTypes::isBall( o ) )
00187 {
00188 DynamicObject *d ;
00189
00190
00191 if( !( SoccerTypes::isKnownPlayer( o ) || SoccerTypes::isBall( o ) ) )
00192 {
00193 UnknownPlayers[iNrUnknownPlayers].setIsKnownPlayer( false );
00194 UnknownPlayers[iNrUnknownPlayers].setPossibleRange( objMin, objMax );
00195 d = &UnknownPlayers[iNrUnknownPlayers];
00196 iNrUnknownPlayers++;
00197 }
00198 else
00199 {
00200 d = (DynamicObject*)getObjectPtrFromType( o );
00201 if( SoccerTypes::isPlayer( o ) )
00202 ((PlayerObject*)d)->setIsKnownPlayer( true );
00203 }
00204
00205 if( d != NULL )
00206 {
00207
00208 d->setRelativePosition( dDist, (double)iDir, time );
00209 if( dDistChange != UnknownDoubleValue )
00210 d->setRelativeDistanceChange( dDistChange, time );
00211 if( dDirChange != UnknownDoubleValue )
00212 d->setRelativeAngleChange( dDirChange, time );
00213 if( angRelBodyAng != UnknownAngleValue )
00214 ((PlayerObject*)d)->setRelativeBodyAngle( angRelBodyAng, time );
00215 if( angRelNeckAng != UnknownAngleValue )
00216 ((PlayerObject*)d)->setRelativeNeckAngle( angRelNeckAng, time );
00217 if( isGoalie == true && SoccerTypes::isPlayer( o ))
00218 ((PlayerObject*)d)->setIsGoalie( true );
00219 else if( SoccerTypes::isPlayer( o ))
00220 ((PlayerObject*)d)->setIsGoalie( false );
00221 d->setType( o );
00222 d->setTimeLastSeen( time );
00223
00224 if( isTackling )
00225 {
00226
00227 if( ((PlayerObject*)d)->getTimeTackle() + SS->getTackleCycles()
00228 < getCurrentTime() )
00229 ((PlayerObject*)d)->setTimeTackle( getCurrentTime() - 1 );
00230 }
00231 else
00232 ((PlayerObject*)d)->setTimeTackle( Time(-1,0) );
00233
00234 if( dPointDir != UnknownDoubleValue )
00235 ((PlayerObject*)d)->setGlobalArm( dPointDir, getCurrentTime() );
00236
00237
00238
00239 if( SoccerTypes::isPlayer( o ) && SoccerTypes::isKnownPlayer( o ) )
00240 {
00241 int iIndex;
00242 ObjectT objMin = OBJECT_ILLEGAL;
00243 double dMinDist = 1000.0, dTmp;
00244 ObjectSetT set = SoccerTypes::isOpponent( o )
00245 ? OBJECT_SET_OPPONENTS
00246 : OBJECT_SET_TEAMMATES;
00247
00248 for( ObjectT obj = iterateObjectStart( iIndex, set );
00249 obj != OBJECT_ILLEGAL;
00250 obj = iterateObjectNext ( iIndex, set ) )
00251 {
00252 if( obj != getAgentObjectType() && isKnownPlayer( obj ) == false )
00253 {
00254 dTmp=(getRelativePosition(obj)-d->getRelativePosition()
00255 ).getMagnitude();
00256 if( dTmp < dMinDist )
00257 {
00258 objMin = obj;
00259 dMinDist = dTmp;
00260 }
00261 }
00262 }
00263 iterateObjectDone( iIndex );
00264 if( objMin != OBJECT_ILLEGAL &&
00265 dMinDist < PS->getPlayerDistTolerance() &&
00266 dMinDist < getMaxTraveledDistance( objMin ) )
00267 {
00268 PlayerObject *pob = (PlayerObject*) getObjectPtrFromType( objMin );
00269 pob->setTimeLastSeen( -1 );
00270 Log.log( 464, "set time objMin %d to -1 mapped to player %d %f %f",
00271 objMin, o, dMinDist, getMaxTraveledDistance( objMin ) );
00272 }
00273 else
00274 Log.log( 464, "don't set time objMin %d to -1 player %d dist %f",
00275 objMin, o, dMinDist );
00276
00277 }
00278 }
00279 }
00280 else if( SoccerTypes::isLine( o ) )
00281 {
00282
00283
00284 iDir = ( iDir < 0 ) ? (90 + iDir ) : - (90 - iDir );
00285
00286 Lines[SoccerTypes::getIndex(o)].setRelativePosition(
00287 dDist,(double)iDir,time);
00288 Lines[SoccerTypes::getIndex(o)].setTimeLastSeen( time );
00289 Lines[SoccerTypes::getIndex(o)].setType( o );
00290 }
00291 }
00292
00300 bool WorldModel::storePlayerMessage( int iPlayer, char *strMsg, int iCycle )
00301 {
00302 strcpy( m_strPlayerMsg, strMsg );
00303 m_iCycleInMsg = iCycle;
00304 m_timePlayerMsg = getCurrentTime();
00305 m_iMessageSender = iPlayer;
00306 return true;
00307 }
00308
00310 bool WorldModel::processPlayerMessage( )
00311 {
00312 static char strMessage[MAX_MSG];
00313 int iDiff = getCurrentCycle() - m_iCycleInMsg;
00314 double dDiff = (double)iDiff/100.0;
00315 char *strMsg;
00316 strcpy( strMessage, m_strPlayerMsg );
00317 strMsg = strMessage;
00318
00319 char cOffside = strMsg[1];
00320 if( cOffside >= 'a' && cOffside <= 'z' )
00321 {
00322 m_dCommOffsideX = (double)(cOffside - 'a');
00323 m_timeCommOffsideX = getCurrentTime() - 1;
00324 }
00325 else if( cOffside >= 'A' && cOffside <= 'Z' )
00326 {
00327 m_dCommOffsideX = 26 + (double)(cOffside - 'A');
00328 m_timeCommOffsideX = getCurrentTime() - 1;
00329 }
00330 else
00331 return false;
00332
00333 if( strMsg[2] >= '0' && strMsg[2] <= '9' &&
00334 strlen( strMessage ) == 12)
00335 {
00336
00337 double dBallX = (int)(strMsg[2]-'0')*10 +(int)(strMsg[3] - '0' ) - 48.0;
00338 double dBallY = (int)(strMsg[4]-'0')*10 +(int)(strMsg[5] - '0' ) - 34.0;
00339 double dBallVelX = (int)(strMsg[6]-'0') + (int)(strMsg[7] - '0' )/10.0-2.7;
00340 double dBallVelY = (int)(strMsg[8]-'0') + (int)(strMsg[9] - '0' )/10.0-2.7;
00341
00342 VecPosition pos( dBallX, dBallY );
00343 VecPosition vel( dBallVelX, dBallVelY );
00344 for( int i = 0; i < iDiff ; i ++ )
00345 {
00346 pos += vel;
00347 vel *= SS->getBallDecay();
00348 }
00349
00350
00351 if( getTimeLastSeen( OBJECT_BALL ) == -1 ||
00352 (
00353 getTimeChangeInformation( OBJECT_BALL ) < getCurrentTime() - 3 &&
00354 getRelativeDistance( OBJECT_BALL ) > SS->getVisibleDistance()
00355 ) ||
00356 (
00357 getTimeChangeInformation( OBJECT_BALL ) < getCurrentTime() - iDiff &&
00358 vel.getDistanceTo( getGlobalVelocity(OBJECT_BALL) ) > 0.3 &&
00359 getRelativeDistance( OBJECT_BALL ) > SS->getVisibleDistance()
00360 )
00361 )
00362 {
00363 Log.log( 600,
00364 "update ball comm. (%1.2f,%1.2f)(%1.2f,%1.2f) diff %d, last %d",
00365 pos.getX(), pos.getY(), vel.getX(), vel.getY(), iDiff,
00366 getTimeLastSeen( OBJECT_BALL ).getTime() );
00367 Log.log( 601, "update ball from comm (%1.2f,%1.2f)(%1.2f,%1.2f) diff %d",
00368 pos.getX(), pos.getY(), vel.getX(), vel.getY(), iDiff );
00369 processPerfectHearInfoBall( pos, vel, 1.00 - dDiff - 0.01 ) ;
00370 }
00371 else
00372 Log.log( 600, "do not update ball time_change %d, now %d, diff %d, d %f",
00373 getTimeChangeInformation( OBJECT_BALL ).getTime(),
00374 getCurrentCycle(),
00375 iDiff,
00376 vel.getDistanceTo( getGlobalVelocity(OBJECT_BALL) ) );
00377 }
00378 else if( strlen( strMessage ) == 12 &&
00379 strMsg[2] >= 'a' && strMsg[2] <= 'a' + 10 &&
00380 strMsg[6] == ' ' )
00381 {
00382 ObjectT objOpp
00383 = SoccerTypes::getOpponentObjectFromIndex((int)(strMsg[2]-'a'));
00384 char *str = &strMsg[3];
00385 double dOppX = -1*Parse::parseFirstInt( &str );
00386 dOppX /= 10.0;
00387 double dOppY = Parse::parseFirstInt( &str );
00388 dOppY /= 10.0;
00389 VecPosition posOpp( dOppX, dOppY );
00390 processPerfectHearInfo( objOpp, posOpp, 0.99, false ) ;
00391 }
00392
00393 return true;
00394 }
00395
00396 bool WorldModel::processRecvThink( bool b )
00397 {
00398 m_bRecvThink = b;
00399 if( b == true && SS->getSynchMode() == true )
00400 {
00401 #ifdef WIN32
00402
00403 bNewInfo = true;
00404 SetEvent ( event_newInfo );
00405
00406 #else
00407 pthread_mutex_lock ( &mutex_newInfo );
00408 bNewInfo = true;
00409 pthread_cond_signal ( &cond_newInfo );
00410 pthread_mutex_unlock( &mutex_newInfo );
00411 #endif
00412 }
00413 return true;
00414 }
00415
00423 bool WorldModel::processPerfectHearInfoBall( VecPosition posGlobal,
00424 VecPosition vel, double dConf )
00425 {
00426 Log.log( 501, "ball conf: %f %d", getConfidence( OBJECT_BALL ),
00427 getTimeLastSeen( OBJECT_BALL ).getTime() );
00428 if( Ball.getConfidence( getCurrentTime() ) < dConf ||
00429 vel.getDistanceTo( getGlobalVelocity(OBJECT_BALL) ) > 0.3 )
00430 {
00431 Time time = getTimeFromConfidence( dConf );
00432 Ball.setGlobalPosition( posGlobal, time );
00433 Ball.setGlobalVelocity( vel, time );
00434 Ball.setTimeLastSeen ( time );
00435 updateObjectRelativeFromGlobal( OBJECT_BALL );
00436 setTimeLastHearMessage( getCurrentTime() );
00437 return true;
00438 }
00439 return false;
00440 }
00441
00453 bool WorldModel::processPerfectHearInfo( ObjectT o, VecPosition posGlobal,
00454 double dConf, bool bIsGoalie )
00455 {
00456 if( SoccerTypes::isBall( o ) || o == getAgentObjectType() )
00457 return false;
00458 else if( !SoccerTypes::isKnownPlayer( o ) )
00459 return processUnsureHearInfo( o, posGlobal, dConf );
00460
00461 PlayerObject *object = (PlayerObject *)getObjectPtrFromType( o );
00462 if( object == NULL )
00463 return false;
00464
00465 Time time = getTimeFromConfidence( dConf ) ;
00466
00467
00468
00469
00470
00471
00472 if( object->getConfidence( getCurrentTime() ) < dConf ||
00473 object->getIsKnownPlayer() == false )
00474 {
00475 object->setGlobalPosition ( posGlobal , time );
00476 object->setTimeLastSeen ( time );
00477 object->setGlobalVelocity ( VecPosition( 0, 0), time );
00478 object->setIsKnownPlayer ( true );
00479 object->setIsGoalie ( bIsGoalie );
00480 updateObjectRelativeFromGlobal( o );
00481 setTimeLastHearMessage( getCurrentTime() );
00482 return true;
00483 }
00484 return false;
00485 }
00486
00498 bool WorldModel::processUnsureHearInfo( ObjectT o, VecPosition pos,
00499 double dConf )
00500 {
00501 double dMinDist;
00502 ObjectT objInitial = o;
00503
00504 if( o != OBJECT_TEAMMATE_UNKNOWN && o != OBJECT_OPPONENT_UNKNOWN )
00505 return false;
00506
00507
00508 if( SoccerTypes::isTeammate( o ) )
00509 o = getClosestInSetTo( OBJECT_SET_TEAMMATES, pos, &dMinDist);
00510 else if( SoccerTypes::isOpponent( o ) )
00511 o = getClosestInSetTo( OBJECT_SET_OPPONENTS, pos, &dMinDist);
00512
00513 if( o == getAgentObjectType() &&
00514 pos.getDistanceTo(getAgentGlobalPosition())<PS->getPlayerDistTolerance())
00515 return false;
00516
00517
00518
00519
00520
00521 else if( SoccerTypes::isKnownPlayer(o) &&
00522 dMinDist < PS->getPlayerDistTolerance())
00523 {
00524 processPerfectHearInfo( o, pos, dConf );
00525 return true;
00526 }
00527
00528 if( objInitial == OBJECT_TEAMMATE_UNKNOWN )
00529 o = getFirstEmptySpotInSet( OBJECT_SET_TEAMMATES );
00530 else if( objInitial == OBJECT_OPPONENT_UNKNOWN )
00531 o = getFirstEmptySpotInSet( OBJECT_SET_OPPONENTS );
00532 else
00533 return false ;
00534
00535 if( o != OBJECT_ILLEGAL )
00536 {
00537 processPerfectHearInfo( o, pos, dConf );
00538 setIsKnownPlayer( o, false );
00539 }
00540 return true;
00541 }
00542
00563 bool WorldModel::processNewHeteroPlayer( int iIndex, double dPlayerSpeedMax,
00564 double dStaminaIncMax, double dPlayerDecay, double dInertiaMoment,
00565 double dDashPowerRate, double dPlayerSize, double dKickableMargin,
00566 double dKickRand, double dExtraStamina,double dEffortMax,
00567 double dEffortMin )
00568 {
00569 pt[iIndex].dPlayerSpeedMax = dPlayerSpeedMax;
00570 pt[iIndex].dStaminaIncMax = dStaminaIncMax;
00571 pt[iIndex].dPlayerDecay = dPlayerDecay;
00572 pt[iIndex].dInertiaMoment = dInertiaMoment;
00573 pt[iIndex].dDashPowerRate = dDashPowerRate;
00574 pt[iIndex].dPlayerSize = dPlayerSize;
00575 pt[iIndex].dKickableMargin = dKickableMargin;
00576 pt[iIndex].dKickRand = dKickRand;
00577 pt[iIndex].dExtraStamina = dExtraStamina;
00578 pt[iIndex].dEffortMax = dEffortMax;
00579 pt[iIndex].dEffortMin = dEffortMin;
00580 pt[iIndex].dMaximalKickDist = dKickableMargin +
00581 dPlayerSize +
00582 SS->getBallSize();
00583
00584 return true;
00585 }
00586
00596 void WorldModel::processCatchedBall( RefereeMessageT rm, Time time )
00597 {
00598 if( rm == REFC_GOALIE_CATCH_BALL_LEFT && sideSide == SIDE_LEFT )
00599 timeLastCatch = time;
00600 else if( rm == REFC_GOALIE_CATCH_BALL_RIGHT && sideSide == SIDE_RIGHT )
00601 timeLastCatch = time;
00602 Ball.setGlobalVelocity( VecPosition(0,0), getCurrentTime() );
00603 }
00604
00613 void WorldModel::processQueuedCommands( SoccerCommand commands[],
00614 int iCommands )
00615 {
00616 if( iCommands > CMD_MAX_COMMANDS )
00617 {
00618 cerr << "(WorldModel::setQueuedCommands) queuedCommands array cannot "
00619 << "contain so many commands!\n";
00620 return;
00621 }
00622
00623
00624 for( int i = 0 ; i < iCommands ; i ++ )
00625 {
00626 commands[i].time = getCurrentTime();
00627 queuedCommands[(int)commands[i].commandType] = commands[i];
00628 }
00629 }
00630
00638 bool WorldModel::updateAll( )
00639 {
00640 static Timing timer;
00641 double dTimeSense = 0.0, dTimeSee = 0.0, dTimeComm=0.0, dTimeFastest = 0.0;
00642 static struct tms times1, times2;
00643
00644 bool bReturn = false, bUpdateAfterSee = false;
00645 bool bUpdateAfterSense = false, bDebug = false;
00646 static Time timeLastHoleRecorded;
00647 static Time timeBeginInterval;
00648 static Time timePlayersCounted;
00649 static int iNrHolesLastTime = 0;
00650 static Time timeLastSenseUpdate;
00651 static Time timeLastSeeUpdate;
00652 static Time timeLastSayUpdate;
00653 if( bDebug )
00654 {
00655 timer.restartTime();
00656 times( ×1 );
00657 }
00658
00659
00660 if( agentObject.getTimeGlobalPosition() < getCurrentTime() - 1 )
00661 Log.log( 3, "(WorldModel::updateAll) missed a sense??" );
00662
00663
00664 if( isFullStateOn( ) == true )
00665 {
00666 Log.log( 4, "full state is on" );
00667 updateRelativeFromGlobal();
00668 timeLastSenseMessage = timeLastRecvSeeMessage;
00669 timeLastSeeMessage = timeLastRecvSeeMessage;
00670 bUpdateAfterSee = bUpdateAfterSense = false;
00671 bReturn = true;
00672 }
00673 else
00674 {
00675 Log.log( 4, "full state is off" );
00676 if( getTimeLastRecvSeeMessage() > timeLastSeeUpdate )
00677 bUpdateAfterSee = true;
00678 if( getTimeLastRecvSenseMessage() > timeLastSenseUpdate )
00679 bUpdateAfterSense = true;
00680 }
00681
00682
00683
00684 if( bUpdateAfterSee && bUpdateAfterSense )
00685 {
00686 Log.log( 3, "!!! Two updates !!! " );
00687 Log.log( 3, "see: %d sense: %d", getTimeLastRecvSeeMessage().getTime(),
00688 getTimeLastRecvSenseMessage().getTime() );
00689 if( getTimeLastRecvSeeMessage( ) == getTimeLastRecvSenseMessage() )
00690 {
00691 Log.log( 3, "update sense" );
00692 timeLastSenseMessage = timeLastRecvSenseMessage;
00693 bReturn = updateAfterSenseMessage( );
00694 if( bDebug ) dTimeSense = timer.getElapsedTime(1000);
00695 updateRelativeFromGlobal();
00696 Log.log( 3, "update see" );
00697 timeLastSeeMessage = timeLastRecvSeeMessage;
00698 bReturn &= updateAfterSeeMessage( );
00699 if( bDebug ) dTimeSee = timer.getElapsedTime(1000) - dTimeSense;
00700 }
00701 else if( getTimeLastRecvSeeMessage( ) < getTimeLastRecvSenseMessage() )
00702 {
00703 Log.log( 3, "update see" );
00704 timeLastSeeMessage = timeLastRecvSeeMessage;
00705 bReturn = updateAfterSeeMessage( );
00706 if( bDebug ) dTimeSee = timer.getElapsedTime(1000);
00707 Log.log( 3, "update sense" );
00708 timeLastSenseMessage = timeLastRecvSenseMessage;
00709 bReturn &= updateAfterSenseMessage( );
00710 updateRelativeFromGlobal();
00711 if( bDebug ) dTimeSense = timer.getElapsedTime(1000) - dTimeSee;
00712 }
00713 timeLastSenseUpdate = getTimeLastSenseMessage();
00714 timeLastSeeUpdate = getTimeLastSeeMessage();
00715 }
00716 else if( bUpdateAfterSee )
00717 {
00718 Log.log( 3, "update see" );
00719 timeLastSeeMessage = timeLastRecvSeeMessage;
00720 bReturn = updateAfterSeeMessage( );
00721 timeLastSeeUpdate = getTimeLastSeeMessage();
00722 if( bDebug ) dTimeSee = timer.getElapsedTime(1000);
00723 }
00724 else if( bUpdateAfterSense )
00725 {
00726 Log.log( 3, "update sense" );
00727 timeLastSenseMessage = timeLastRecvSenseMessage;
00728 bReturn = updateAfterSenseMessage( );
00729 timeLastSenseUpdate = getTimeLastSenseMessage();
00730 updateRelativeFromGlobal();
00731 if( bDebug ) dTimeSense = timer.getElapsedTime(1000);
00732 }
00733
00734 if( timeLastSayUpdate != m_timePlayerMsg &&
00735 isFullStateOn() == false )
00736 {
00737 Log.log( 3, "update hear" );
00738 if( bDebug ) dTimeComm = timer.getElapsedTime(1000);
00739 timeLastSayUpdate = m_timePlayerMsg;
00740 processPlayerMessage();
00741 if( bDebug ) dTimeComm = timer.getElapsedTime(1000) - dTimeComm;
00742 }
00743
00744 SoccerCommand soc = getChangeViewCommand( );
00745 if( ! soc.isIllegal() )
00746 {
00747 setAgentViewAngle( soc.va );
00748 setAgentViewQuality( soc.vq );
00749 }
00750
00751
00752 if( isQueuedActionPerformed() == false &&
00753 timeLastHoleRecorded != getCurrentTime() &&
00754 isFullStateOn() == false )
00755 {
00756 Log.log( 2, "HOLE recorded" );
00757 timeLastHoleRecorded = getCurrentTime();
00758 iNrHoles++;
00759 }
00760
00761
00762 int iTimeDiff = getCurrentTime() - timeBeginInterval;
00763 double dHolePerc = (double)(iNrHoles - iNrHolesLastTime)/iTimeDiff*100;
00764 if( ! isLastMessageSee( ) && iTimeDiff % 400 == 0 && dHolePerc > 1.0 &&
00765 PS->getFractionWaitSeeEnd() > 0.70 )
00766 {
00767 PS->setFractionWaitSeeEnd( PS->getFractionWaitSeeEnd() - 0.05 );
00768 timeBeginInterval = getCurrentTime();
00769 cerr << getCurrentCycle() << ": lowered send time to " <<
00770 PS->getFractionWaitSeeEnd() << " for player number " <<
00771 getPlayerNumber() <<
00772 "; nr of holes is "<< dHolePerc << "%" << "( " << iNrHoles << ", "
00773 << iNrHolesLastTime << ")" << endl;
00774 iNrHolesLastTime = iNrHoles;
00775 }
00776
00777
00778 if( bUpdateAfterSense == true && ! isTimeStopped() &&
00779 getCurrentTime() != timePlayersCounted )
00780 {
00781 iNrTeammatesSeen += getNrInSetInRectangle( OBJECT_SET_TEAMMATES );
00782 iNrOpponentsSeen += getNrInSetInRectangle( OBJECT_SET_OPPONENTS );
00783 timePlayersCounted = getCurrentTime();
00784 }
00785
00786
00787 if( Log.isInLogLevel( 456 ) )
00788 logObjectInformation( 456, getAgentObjectType() );
00789
00790 if( bUpdateAfterSee == true )
00791 Log.logWithTime(3, " finished update_all see; start determining action" );
00792 if( bUpdateAfterSense == true )
00793 Log.logWithTime(3, " finished update_all sense;start determining action");
00794
00795 if( Log.isInLogLevel( 459 ) )
00796 {
00797 Log.log( 459, "%s%s", strLastSeeMessage, strLastSenseMessage );
00798 show( OBJECT_BALL, Log.getOutputStream() );
00799 show( OBJECT_SET_PLAYERS, Log.getOutputStream() );
00800 }
00801 if( ( Log.isInLogLevel( 101 ) && getRelativeDistance( OBJECT_BALL ) < 2.0 ) )
00802 show( OBJECT_BALL, Log.getOutputStream() );
00803 if( Log.isInLogLevel( 556 ) &&
00804 getRelativeDistance( OBJECT_BALL ) < SS->getVisibleDistance() )
00805 {
00806 Log.log( 556, "%s", strLastSeeMessage );
00807 show( OBJECT_SET_PLAYERS, Log.getOutputStream() );
00808 show( OBJECT_BALL, Log.getOutputStream() );
00809 }
00810 if( LogDraw.isInLogLevel( 460 ) )
00811 {
00812 int iCycles;
00813 dTimeFastest = timer.getElapsedTime( 1000 );
00814 ObjectT obj = getFastestInSetTo(OBJECT_SET_OPPONENTS,OBJECT_BALL,&iCycles);
00815 logCircle( 460, getGlobalPosition( obj ), 1.5 );
00816 logCircle( 460, predictPosAfterNrCycles( OBJECT_BALL, iCycles ), 0.5 );
00817 obj=getFastestInSetTo(OBJECT_SET_TEAMMATES_NO_GOALIE,OBJECT_BALL,&iCycles);
00818 logCircle( 460, getGlobalPosition( obj ), 1.5 );
00819 logCircle( 460, predictPosAfterNrCycles( OBJECT_BALL, iCycles ), 0.75 );
00820 dTimeFastest = timer.getElapsedTime( 1000 ) - dTimeFastest;
00821 }
00822
00823 if( LogDraw.isInLogLevel( 701 ) )
00824 drawCoordinationGraph( );
00825
00826 logLine( 602, VecPosition( getOffsideX(), -PITCH_WIDTH/2.0),
00827 VecPosition( getOffsideX(), PITCH_WIDTH/2.0) );
00828 if( bDebug )
00829 {
00830 Log.logWithTime( 461, "time update all: %f\n time comm: %1.5f\n\
00831 time see: %1.5f\n time sense: %1.5f\n time fastest: %1.5f\n\
00832 time rest: %1.5f\n utime: %1.5f",
00833 timer.getElapsedTime()*1000, dTimeComm, dTimeSee, dTimeSense,dTimeFastest,
00834 timer.getElapsedTime()*1000-(dTimeComm+dTimeSee+dTimeSense+dTimeFastest ),
00835 times2.tms_utime - times1.tms_utime );
00836 }
00837 return bReturn;
00838 }
00839
00840
00841
00842
00843
00844 void WorldModel::processLastSeeMessage( )
00845 {
00846 ObjectT o;
00847 double dDist, dDistChange, dDirChange, dPointDir, dTemp;
00848 int iDir;
00849 AngDeg angBodyFacingDir, angHeadFacingDir;
00850 Time time = getTimeLastSeeMessage();
00851 bool isGoalie, isTackling;
00852 static char strTmp[MAX_MSG];
00853 char *strMsg = strLastSeeMessage ;
00854 Parse::parseFirstInt( &strMsg );
00855
00856 ObjectT objMin = OBJECT_ILLEGAL;
00857 ObjectT objMax = OBJECT_ILLEGAL;
00858
00859 while( *strMsg != ')' )
00860 {
00861 dDist = dDistChange = dDirChange = dTemp = dPointDir = UnknownDoubleValue;
00862 angBodyFacingDir = angHeadFacingDir = UnknownAngleValue;
00863 strMsg += 2;
00864 isTackling = false;
00865
00866
00867
00868 o = SoccerTypes::getObjectFromStr( &strMsg, &isGoalie, getTeamName() );
00869
00870 if( o == OBJECT_ILLEGAL )
00871 {
00872 Log.log( 4, "Illegal object in: %s", strLastSeeMessage );
00873 Log.log( 4, "rest of message: %s", strMsg );
00874 }
00875 else if( SoccerTypes::isKnownPlayer( o ) )
00876 objMin = o;
00877 else if( SoccerTypes::isPlayer( o ) )
00878 {
00879 if( SoccerTypes::isTeammate( o ) &&
00880 ( objMin == OBJECT_ILLEGAL || SoccerTypes::isOpponent( objMin ) ) )
00881 objMin = OBJECT_TEAMMATE_1 ;
00882 else if( SoccerTypes::isOpponent( o ) &&
00883 ( objMin == OBJECT_ILLEGAL || SoccerTypes::isTeammate( objMin ) ) )
00884 objMin = OBJECT_OPPONENT_1 ;
00885 else if( objMin == OBJECT_ILLEGAL )
00886 objMin = (getSide() == SIDE_LEFT ) ? OBJECT_TEAMMATE_1
00887 : OBJECT_OPPONENT_1 ;
00888 else if( objMin == OBJECT_TEAMMATE_11 )
00889 objMin = OBJECT_OPPONENT_1;
00890 else if( objMin == OBJECT_OPPONENT_11 )
00891 objMin = OBJECT_TEAMMATE_1;
00892 else
00893 objMin = (ObjectT)((int)objMin + 1);
00894
00895 if( objMin == getAgentObjectType() )
00896 {
00897 if( objMin == OBJECT_TEAMMATE_11 )
00898 objMin = OBJECT_OPPONENT_1;
00899 else if( objMin == OBJECT_OPPONENT_11 )
00900 objMin = OBJECT_TEAMMATE_1;
00901 else
00902 objMin = (ObjectT)((int)objMin + 1);
00903 }
00904 strcpy( strTmp, strMsg );
00905 objMax = getMaxRangeUnknownPlayer( objMin, strTmp );
00906 }
00907
00908 dTemp = Parse::parseFirstDouble( &strMsg );
00909 if ( *strMsg == ')' )
00910 iDir = (int)dTemp;
00911 else
00912 {
00913 dDist = dTemp;
00914 iDir = Parse::parseFirstInt( &strMsg );
00915
00916 double dValues[7];
00917 int i = 0;
00918 if( *strMsg == ' ' )
00919 {
00920 while( *strMsg != ')' && *(strMsg+1) != 't' && i < 7 )
00921 {
00922 dValues[i] = Parse::parseFirstDouble( &strMsg );
00923 i++;
00924 }
00925 }
00926
00927 switch( i )
00928 {
00929 case 0:
00930 break;
00931 case 1:
00932 dPointDir = dValues[0];
00933 break;
00934 case 5:
00935 dPointDir = dValues[4];
00936 case 4:
00937 angBodyFacingDir = dValues[2];
00938 angHeadFacingDir = dValues[3];
00939 case 2:
00940 dDistChange = dValues[0];
00941 dDirChange = dValues[1];
00942 break;
00943 default:
00944 cerr << "(WorldModelUpdate::analyzeSee) wrong param nr " << i <<endl;
00945
00946 }
00947
00948 if( *(strMsg+1) == 't')
00949 isTackling = true;
00950 }
00951
00952
00953
00954 Parse::gotoFirstOccurenceOf( ')', &strMsg );
00955 strMsg++;
00956
00957 if( SoccerTypes::isPlayer( o ) && !SoccerTypes::isKnownPlayer( o ) )
00958 {
00959 if( objMin != OBJECT_ILLEGAL )
00960 {
00961 if( objMin == objMax )
00962 {
00963 Log.log( 459, "range, only %d left", objMin );
00964 o = objMin;
00965 }
00966 else if( SoccerTypes::isTeammate( objMin ) &&
00967 SoccerTypes::isTeammate( objMax ) )
00968 o = OBJECT_TEAMMATE_UNKNOWN;
00969 else if( SoccerTypes::isOpponent( objMin ) &&
00970 SoccerTypes::isOpponent( objMax ) )
00971 o = OBJECT_OPPONENT_UNKNOWN;
00972 }
00973 }
00974
00975
00976 processNewObjectInfo( o, time, dDist, iDir, dDistChange,
00977 dDirChange, angBodyFacingDir, angHeadFacingDir,
00978 isGoalie, objMin, objMax, dPointDir, isTackling );
00979 }
00980 }
00981
00987 bool WorldModel::updateAfterSeeMessage( )
00988 {
00989 processLastSeeMessage( );
00990
00991
00992 if( getCurrentTime().getTime() != -1 )
00993 updateAgentObjectAfterSee( );
00994
00995 mapUnknownPlayers( getTimeLastSeeMessage() );
00996
00997
00998
00999
01000
01001 double dConfThr = PS->getPlayerConfThr();
01002 int iIndex;
01003
01004 for( ObjectT o = iterateObjectStart( iIndex, OBJECT_SET_PLAYERS, dConfThr );
01005 o != OBJECT_ILLEGAL;
01006 o = iterateObjectNext ( iIndex, OBJECT_SET_PLAYERS, dConfThr ) )
01007 {
01008 if( getTimeLastSeen( o ) == getTimeLastSeeMessage() &&
01009 o != getAgentObjectType() )
01010 updateDynamicObjectAfterSee ( o );
01011 else
01012 updateObjectRelativeFromGlobal( o );
01013 }
01014 iterateObjectDone( iIndex );
01015
01016
01017 if( getTimeLastSeen( OBJECT_BALL ) == getTimeLastSeeMessage() )
01018 updateDynamicObjectAfterSee ( OBJECT_BALL );
01019 else
01020 updateObjectRelativeFromGlobal( OBJECT_BALL );
01021
01022
01023 if( Log.isInLogLevel( 2 ) )
01024 show( OBJECT_BALL, Log.getOutputStream() );
01025 removeGhosts();
01026 if( Log.isInLogLevel( 2 ) )
01027 show( OBJECT_BALL, Log.getOutputStream() );
01028
01029
01030 return true;
01031 }
01032
01037 bool WorldModel::updateAgentObjectAfterSee( )
01038 {
01039 VecPosition posGlobal, velGlobal;
01040 AngDeg angGlobal;
01041
01042
01043 calculateStateAgent( &posGlobal, &velGlobal, &angGlobal );
01044
01045
01046 agentObject.setTimeLastSeen ( getTimeLastSeeMessage() );
01047
01048
01049 agentObject.setPositionDifference(posGlobal-agentObject.getGlobalPosition());
01050 agentObject.setGlobalPosition ( posGlobal, getTimeLastSeeMessage() );
01051 agentObject.setGlobalPositionLastSee( posGlobal, getTimeLastSeeMessage() );
01052 agentObject.setGlobalNeckAngle ( angGlobal );
01053 agentObject.setGlobalVelocity ( velGlobal, getTimeLastSeeMessage() );
01054
01055 return true;
01056 }
01057
01058
01064 bool WorldModel::updateDynamicObjectAfterSee( ObjectT o )
01065 {
01066 VecPosition posGlobal, velGlobal;
01067
01068 if( o == OBJECT_BALL )
01069 {
01070 calculateStateBall ( &posGlobal, &velGlobal );
01071 Ball.setGlobalVelocity ( velGlobal, getTimeLastSeeMessage() );
01072 Ball.setGlobalPosition ( posGlobal, getTimeLastSeeMessage() );
01073 Ball.setGlobalPositionLastSee( posGlobal, getTimeLastSeeMessage() );
01074 return true;
01075 }
01076 else if( SoccerTypes::isKnownPlayer( o ) )
01077 {
01078 calculateStatePlayer( o, &posGlobal, &velGlobal );
01079
01080 PlayerObject *pob = (PlayerObject*) getObjectPtrFromType( o );
01081
01082
01083
01084 pob->setGlobalVelocity ( velGlobal, getTimeLastSeeMessage() );
01085 pob->setGlobalPosition ( posGlobal, getTimeLastSeeMessage() );
01086 pob->setGlobalPositionLastSee( posGlobal, getTimeLastSeeMessage() );
01087
01088 if( pob->getTimeRelativeAngles() == getTimeLastSeeMessage() )
01089 {
01090 AngDeg ang = getAgentGlobalNeckAngle() + pob->getRelativeBodyAngle();
01091 ang = VecPosition::normalizeAngle( ang );
01092 pob->setGlobalBodyAngle( ang, getTimeLastSeeMessage() );
01093 pob->setGlobalBodyAngleLastSee( ang );
01094 ang = getAgentGlobalNeckAngle() + pob->getRelativeNeckAngle();
01095 ang = VecPosition::normalizeAngle( ang );
01096 pob->setGlobalNeckAngle( ang, getTimeLastSeeMessage() );
01097 pob->setGlobalVelocityLastSee( velGlobal );
01098 }
01099 return true;
01100 }
01101
01102 return false;
01103 }
01104
01105
01106
01107
01108
01109
01110 void WorldModel::processLastSenseMessage( )
01111 {
01112 char *strMsg = strLastSenseMessage ;
01113
01114 Parse::parseFirstInt( &strMsg );
01115 strMsg++;
01116
01117 Parse::gotoFirstOccurenceOf( ' ', &strMsg );
01118 strMsg++;
01119
01120 ViewQualityT vq = SoccerTypes::getViewQualityFromStr( strMsg );
01121 Parse::gotoFirstOccurenceOf( ' ', &strMsg );
01122 strMsg++;
01123 ViewAngleT va = SoccerTypes::getViewAngleFromStr( strMsg );
01124 double dStamina = Parse::parseFirstDouble( &strMsg );
01125 double dEffort = Parse::parseFirstDouble( &strMsg );
01126
01127 double dSpeed = Parse::parseFirstDouble( &strMsg );
01128 AngDeg angSpeed = Parse::parseFirstDouble( &strMsg );
01129
01130
01131 int iHeadAngle = - Parse::parseFirstInt( &strMsg );
01132
01133
01134 setNrOfCommands( CMD_KICK , Parse::parseFirstInt( &strMsg ) );
01135 setNrOfCommands( CMD_DASH , Parse::parseFirstInt( &strMsg ) );
01136 setNrOfCommands( CMD_TURN , Parse::parseFirstInt( &strMsg ) );
01137 setNrOfCommands( CMD_SAY , Parse::parseFirstInt( &strMsg ) );
01138 setNrOfCommands( CMD_TURNNECK , Parse::parseFirstInt( &strMsg ) );
01139 setNrOfCommands( CMD_CATCH , Parse::parseFirstInt( &strMsg ) );
01140 setNrOfCommands( CMD_MOVE , Parse::parseFirstInt( &strMsg ) );
01141 setNrOfCommands( CMD_CHANGEVIEW , Parse::parseFirstInt( &strMsg ) );
01142 int iArmMovable = Parse::parseFirstInt( &strMsg );
01143 int iArmExpires = Parse::parseFirstInt( &strMsg );
01144 double dArmDist = Parse::parseFirstDouble( &strMsg );
01145 AngDeg angArm = Parse::parseFirstDouble( &strMsg );
01146
01147 setNrOfCommands( CMD_POINTTO , Parse::parseFirstInt( &strMsg ) );
01148
01149
01150 int i = Parse::parseFirstInt( &strMsg );
01151 char c = (i >= 10 ) ? *(strMsg-4) : *(strMsg-3);
01152 Log.log( 602, "focus %d |%c|", i, c );
01153 if( c == 'l' || c == 'r' )
01154 {
01155 Log.log( 602, "set focus: %d",
01156 SoccerTypes::getTeammateObjectFromIndex( -1 + i ) );
01157 setObjectFocus( SoccerTypes::getTeammateObjectFromIndex( -1 + i ) );
01158 i = Parse::parseFirstInt( &strMsg );
01159 }
01160 setNrOfCommands( CMD_ATTENTIONTO , i );
01161
01162 int iTackleExpires = Parse::parseFirstInt( &strMsg );
01163 setNrOfCommands( CMD_TACKLE , Parse::parseFirstInt( &strMsg ) );
01164
01165 angArm = VecPosition::normalizeAngle( angArm );
01166 processNewAgentInfo( vq, va, dStamina, dEffort, dSpeed,
01167 (AngDeg) angSpeed, (AngDeg)iHeadAngle, iTackleExpires,
01168 iArmMovable, iArmExpires, VecPosition( dArmDist, angArm, POLAR ));
01169 }
01170
01179 bool WorldModel::updateAfterSenseMessage( )
01180 {
01181 processLastSenseMessage( );
01182
01183
01184 updateAgentAndBallAfterSense( );
01185
01186
01187 double dConfThr = PS->getPlayerConfThr();
01188 int iIndex;
01189
01190 for( ObjectT o = iterateObjectStart( iIndex, OBJECT_SET_PLAYERS, dConfThr );
01191 o != OBJECT_ILLEGAL;
01192 o = iterateObjectNext ( iIndex, OBJECT_SET_PLAYERS, dConfThr ) )
01193 {
01194 if( o != getAgentObjectType() && getTimeGlobalPosition(o) > 0 &&
01195 ! isBeforeKickOff() )
01196 {
01197 updateDynamicObjectForNextCycle( o,
01198 getCurrentTime() - getTimeGlobalPosition(o) );
01199 }
01200 }
01201 iterateObjectDone( iIndex);
01202
01203
01204 if( isBeforeKickOff() )
01205 {
01206 for( ObjectT o = iterateObjectStart( iIndex, OBJECT_SET_TEAMMATES, -2000 );
01207 o != OBJECT_ILLEGAL;
01208 o = iterateObjectNext ( iIndex, OBJECT_SET_TEAMMATES, -2000 ) )
01209 {
01210 if( o == getAgentObjectType() )
01211 continue;
01212 PlayerObject *pob = (PlayerObject*) getObjectPtrFromType( o );
01213
01214 VecPosition pos = getStrategicPosition( SoccerTypes::getIndex( o ) ) ;
01215 VecPosition vel( 0, 0 );
01216
01217 pob->setGlobalVelocity ( vel, getTimeLastSenseMessage() );
01218 pob->setGlobalPosition ( pos, getTimeLastSenseMessage() );
01219 pob->setGlobalPositionLastSee( pos, getTimeLastSenseMessage() );
01220 pob->setTimeLastSeen ( getTimeLastSenseMessage() - 2 );
01221 updateObjectRelativeFromGlobal( o );
01222 Log.log( 459, "set info %d (%f,%f)", SoccerTypes::getIndex( o ),
01223 pos.getX(), pos.getY() );
01224 }
01225 Ball.setGlobalPosition( VecPosition(0,0), getTimeLastSenseMessage() );
01226 Ball.setGlobalVelocity( VecPosition(0,0), getTimeLastSenseMessage() );
01227 }
01228
01229 iterateObjectDone( iIndex);
01230
01231 return true;
01232 }
01233
01239 bool WorldModel::updateAgentAndBallAfterSense( )
01240 {
01241
01242 bool bBallUpdated = false;
01243 VecPosition pos = getAgentGlobalPosition();
01244 AngDeg angGlobalNeck = getAgentGlobalNeckAngle();
01245 AngDeg angGlobalBody = getAgentGlobalBodyAngle();
01246 Stamina sta = getAgentStamina();
01247 VecPosition velNeck = agentObject.getSpeedRelToNeck();
01248 VecPosition vel = getAgentGlobalVelocity();
01249 Time time = getCurrentTime() - 1 ;
01250
01251
01252
01253 for( int i = 0; i < CMD_MAX_COMMANDS; i ++ )
01254 {
01255 if( performedCommands[i] == true &&
01256 ( queuedCommands[i].time.getTime() == time.getTime() ||
01257 queuedCommands[i].time.getTime() == time.getTime() - 1 ) )
01258 {
01259 switch( queuedCommands[i].commandType )
01260 {
01261 case CMD_TURN:
01262 case CMD_TURNNECK:
01263 case CMD_DASH:
01264 case CMD_TACKLE:
01265
01266 predictStateAfterCommand( queuedCommands[i], &pos, &vel,
01267 &angGlobalBody, &angGlobalNeck,
01268 getAgentObjectType(), &sta );
01269 break;
01270 case CMD_KICK:
01271 updateBallAfterKick( queuedCommands[i] );
01272 bBallUpdated = true;
01273 queuedCommands[i].time.updateTime( -1 );
01274 break;
01275 case CMD_MOVE:
01276 pos.setVecPosition( queuedCommands[i].dX, queuedCommands[i].dY );
01277 initParticlesAgent( pos );
01278 break;
01279 default:
01280 break;
01281 }
01282 }
01283 }
01284
01285
01286 if( !bBallUpdated )
01287 {
01288 m_bPerformedKick = false;
01289 updateDynamicObjectForNextCycle( OBJECT_BALL, 1 );
01290 }
01291 else
01292 m_bPerformedKick = true;
01293
01294
01295 velNeck.rotate( angGlobalNeck );
01296 double dDistBall = pos.getDistanceTo( getBallPos() );
01297
01298 if( velNeck.getMagnitude() < EPSILON &&
01299 vel.getMagnitude() > 0.01 &&
01300 dDistBall < 0.6 )
01301 Log.log( 102, "I assume collision after kick" );
01302
01303 if( (
01304 velNeck.getMagnitude() < EPSILON &&
01305 vel.getMagnitude() > 0.01 &&
01306 dDistBall < 0.8
01307 )
01308 ||
01309 ( dDistBall<SS->getPlayerSize()+SS->getBallSize() &&
01310 velNeck.getMagnitude( ) < EPSILON
01311 )
01312 ||
01313 ( dDistBall < SS->getMaximalKickDist() + 0.5 &&
01314 velNeck.getMagnitude( ) > EPSILON &&
01315 ( sign( vel.getX() ) != sign( velNeck.getX() ) ||
01316 fabs( vel.getX() ) < 0.08 ) &&
01317 ( sign( vel.getY() ) != sign( velNeck.getY() ) ||
01318 fabs( vel.getY() ) < 0.08 ) &&
01319 velNeck.getMagnitude() < 0.25 * vel.getMagnitude() ) )
01320 {
01321 m_bWasCollision = true;
01322 m_timeLastCollision = getCurrentTime();
01323 double dDistPlayer;
01324 getClosestInSetTo(
01325 OBJECT_SET_PLAYERS, getAgentObjectType(), &dDistPlayer );
01326 if( dDistBall < dDistPlayer )
01327 {
01328 updateBallForCollision( pos );
01329 Log.log( 102, "COLLISION WITH BALL %f, vel(%f,%f) velNeck(%f,%f)",
01330 dDistBall, vel.getX(), vel.getY(), velNeck.getX(), velNeck.getY() );
01331 }
01332 else
01333 Log.log( 102, "COLLISION WITH PLAYER vel(%f,%f) velNeck(%f,%f)",
01334 vel.getX(), vel.getY(), velNeck.getX(), velNeck.getY() );
01335
01336
01337 vel = velNeck;
01338 }
01339 else
01340 {
01341 if( dDistBall < SS->getVisibleDistance() )
01342 Log.log( 102, "No collision: dist: %f, velNeck (%f,%f), vel (%f,%f)",
01343 dDistBall, velNeck.getX(), velNeck.getY(), vel.getX(), vel.getY() );
01344 m_bWasCollision = false;
01345
01346 pos = getAgentGlobalPosition();
01347 angGlobalNeck = getAgentGlobalNeckAngle();
01348 angGlobalBody = getAgentGlobalBodyAngle();
01349 sta = getAgentStamina();
01350 vel = agentObject.getSpeedRelToNeck();
01351
01352
01353
01354
01355
01356
01357
01358 vel.setMagnitude( vel.getMagnitude()/SS->getPlayerDecay() );
01359
01360 for( int i = 0; i < CMD_MAX_COMMANDS; i ++ )
01361 {
01362 if( performedCommands[i] == true &&
01363 ( queuedCommands[i].time.getTime() == time.getTime() ||
01364 queuedCommands[i].time.getTime() == time.getTime() - 1 ) )
01365 {
01366 switch( queuedCommands[i].commandType )
01367 {
01368 case CMD_TURN:
01369 case CMD_TURNNECK:
01370 predictStateAfterCommand( queuedCommands[i], &pos, &vel,
01371 &angGlobalBody, &angGlobalNeck,
01372 getAgentObjectType(), &sta );
01373 break;
01374 case CMD_MOVE:
01375 pos.setVecPosition( queuedCommands[i].dX, queuedCommands[i].dY );
01376 initParticlesAgent( pos );
01377 break;
01378 case CMD_DASH:
01379
01380
01381 break;
01382 case CMD_TACKLE:
01383
01384 break;
01385 default:
01386 break;
01387 }
01388 }
01389 queuedCommands[i].time.updateTime( -1 );
01390 }
01391
01392
01393 vel = agentObject.getSpeedRelToNeck();
01394 pos = getAgentGlobalPosition();
01395 vel.setMagnitude( vel.getMagnitude()/SS->getPlayerDecay() );
01396 vel.rotate( angGlobalNeck );
01397
01398
01399
01400
01401
01402 predictStateAfterDash( 0.0, &pos, &vel, &sta, 0, getAgentObjectType() );
01403 }
01404
01405
01406 updateParticlesAgent( vel, true );
01407
01408
01409
01410 agentObject.setGlobalPosition ( pos, getCurrentTime() );
01411 agentObject.setGlobalVelocity ( vel, getCurrentTime() );
01412 agentObject.setGlobalNeckAngle( angGlobalNeck );
01413
01414 return true;
01415 }
01416
01424 bool WorldModel::updateBallAfterKick( SoccerCommand soc )
01425 {
01426 if( getRelativeDistance( OBJECT_BALL ) < SS->getMaximalKickDist() )
01427 {
01428 VecPosition posBall, velBall;
01429 predictBallInfoAfterCommand( soc, &posBall, &velBall );
01430 Ball.setGlobalPosition( posBall, getCurrentTime() );
01431 Ball.setGlobalVelocity( velBall, getCurrentTime() );
01432
01433
01434 }
01435 else
01436 {
01437 updateDynamicObjectForNextCycle( OBJECT_BALL, 1 );
01438
01439
01440 #ifdef WIN32
01441 Log.log( 21, "(WorldModel::%s) KICK command, but ball not kickable (%f)",
01442 "updateBallAfterKick", getRelativeDistance( OBJECT_BALL ) );
01443 #else
01444 Log.log( 21, "(WorldModel::%s) KICK command, but ball not kickable (%f)",
01445 __FUNCTION__, getRelativeDistance( OBJECT_BALL ) );
01446 #endif
01447 }
01448 return true;
01449 }
01450
01457 bool WorldModel::updateDynamicObjectForNextCycle( ObjectT obj, int iCycles)
01458 {
01459 DynamicObject *o = (DynamicObject*) getObjectPtrFromType( obj );
01460 if( o == NULL )
01461 return false;
01462
01463
01464 VecPosition vel = getGlobalVelocity( obj );
01465 VecPosition pos = getGlobalPosition( obj );
01466 VecPosition posBall = getBallPos();
01467
01468
01469 if( SoccerTypes::isBall( obj ) )
01470 {
01471 for( int i = 0; i < iCycles ; i++ )
01472 {
01473 pos += vel;
01474 vel *= SS->getBallDecay();
01475 }
01476 double dDist;
01477 ObjectT objOpp =
01478 getClosestInSetTo( OBJECT_SET_OPPONENTS, OBJECT_BALL, &dDist );
01479 if( objOpp != OBJECT_ILLEGAL &&
01480 pos.getDistanceTo( getGlobalPosition( objOpp ) )
01481 < getMaximalKickDist( objOpp ) )
01482 {
01483 Log.log( 556, "update dyn. obj; set ball velocity to 0, opp has it" );
01484 vel.setVecPosition(0,0);
01485 }
01486 }
01487 else if( SoccerTypes::isTeammate( obj ) &&
01488 obj != OBJECT_TEAMMATE_1 && getPlayMode() == PM_PLAY_ON )
01489 {
01490 for( int i = 0; i < iCycles ; i++ )
01491 {
01492
01493 pos += vel;
01494 vel *= SS->getPlayerDecay();
01495 }
01496 }
01497 else if( SoccerTypes::isOpponent( obj ) )
01498 {
01499 VecPosition velBall = getGlobalVelocity( OBJECT_BALL );
01500 for( int i = 0; i < iCycles ; i++ )
01501 {
01502
01503 if( obj == getOppGoalieType() )
01504 ;
01505
01506 else if( obj == getFastestInSetTo( OBJECT_SET_OPPONENTS, OBJECT_BALL ) )
01507 {
01508 AngDeg ang = (getBallPos()-getGlobalPosition( obj )).getDirection();
01509 pos += VecPosition( 0.3, ang, POLAR );
01510 vel *= SS->getPlayerDecay();
01511 Log.log( 556, "update fastest opp to (%f,%f) cyc %d",
01512 pos.getX(), pos.getY(), iCycles );
01513 }
01514 else if( velBall.getX() > 0 && ! ( isDeadBallUs() || isDeadBallThem() )
01515 && ! ( fabs( pos.getX() ) > PENALTY_X + 5 ) )
01516 {
01517 pos += VecPosition( (velBall.getX() > 1.0) ? 0.5 : 0.25, 0 );
01518 vel *= SS->getPlayerDecay();
01519 }
01520 else if( ! ( isDeadBallUs() || isDeadBallThem() )
01521 && ! ( fabs( pos.getX() ) > PENALTY_X + 5 ) )
01522 {
01523
01524 pos -= VecPosition( (velBall.getX() < -1.0 ) ? 0.5 : 0.25, 0 );
01525 vel *= SS->getPlayerDecay();
01526 }
01527 }
01528 }
01529
01530 o->setGlobalVelocity ( vel, getCurrentTime() );
01531 o->setGlobalPosition ( pos, getCurrentTime() );
01532
01533 return true;
01534 }
01535
01536
01541 bool WorldModel::updateBallForCollision( VecPosition posAgent )
01542 {
01543 VecPosition posBall = getGlobalPosition( OBJECT_BALL );
01544 VecPosition velBall = getGlobalVelocity( OBJECT_BALL );
01545
01546
01547
01548 AngDeg ang = (posBall - posAgent).getDirection();
01549 Ball.setGlobalPosition( posAgent + VecPosition( 0.2, ang, POLAR ),
01550 getCurrentTime() );
01551 Ball.setGlobalVelocity( velBall*-0.1, getCurrentTime() );
01552 Log.log( 102, "updateBallForCollision; vel from (%f,%f) to (%f,%f)",
01553 velBall.getX(), velBall.getY(), getGlobalVelocity(OBJECT_BALL).getX(),
01554 getGlobalVelocity(OBJECT_BALL).getY() );
01555 return true;
01556 }
01557
01563 bool WorldModel::updateRelativeFromGlobal()
01564 {
01565 double dConfThr = PS->getPlayerConfThr();
01566 int iIndex;
01567
01568
01569 for( ObjectT o = iterateObjectStart( iIndex, OBJECT_SET_PLAYERS, dConfThr );
01570 o != OBJECT_ILLEGAL;
01571 o = iterateObjectNext ( iIndex, OBJECT_SET_PLAYERS, dConfThr ) )
01572 {
01573 if( o != getAgentObjectType() )
01574 updateObjectRelativeFromGlobal( o );
01575 }
01576 iterateObjectDone( iIndex);
01577
01578
01579 if( isConfidenceGood( OBJECT_BALL ) )
01580 updateObjectRelativeFromGlobal( OBJECT_BALL );
01581
01582
01583
01584 return true;
01585 }
01586
01592 bool WorldModel::updateObjectRelativeFromGlobal( ObjectT o )
01593 {
01594 Object *obj = (Object*) getObjectPtrFromType( o );
01595 if( obj == NULL )
01596 return false;
01597
01598
01599 VecPosition rel = obj->getGlobalPosition();
01600 rel.globalToRelative( getAgentGlobalPosition(), getAgentGlobalNeckAngle() );
01601 obj->setRelativePosition( rel, obj->getTimeGlobalPosition() );
01602 return true;
01603 }
01604
01613 bool WorldModel::calculateStateAgent( VecPosition *posGlobal,
01614 VecPosition *velGlobal, AngDeg *angGlobal )
01615 {
01616 int iNrLeft;
01617
01618
01619 ObjectT objLine = getFurthestRelativeInSet( OBJECT_SET_LINES );
01620 if( objLine != OBJECT_ILLEGAL )
01621 {
01622 double angGlobalLine = getGlobalAngle ( objLine );
01623 AngDeg angRelLine = getRelativeAngle( objLine );
01624 *angGlobal = angGlobalLine - angRelLine;
01625 *angGlobal = VecPosition::normalizeAngle( *angGlobal );
01626 }
01627 else
01628 {
01629 Log.log( 21,
01630 "(WorldModel::calculateStateAgent) no line in last see message" );
01631 *angGlobal = getAgentGlobalNeckAngle();
01632 }
01633
01634
01635
01636
01637
01638
01639
01640
01641 *velGlobal = agentObject.getSpeedRelToNeck().rotate( *angGlobal );
01642 velGlobal->setMagnitude( velGlobal->getMagnitude()/SS->getPlayerDecay() );
01643
01644 updateParticlesAgent ( *velGlobal, false );
01645 iNrLeft = checkParticlesAgent ( *angGlobal );
01646
01647 if( iNrLeft == 0 )
01648 {
01649
01650
01651 initParticlesAgent ( *angGlobal );
01652 iNrLeft = checkParticlesAgent( *angGlobal );
01653 if( iNrLeft == 0 )
01654 {
01655
01656
01657 calculateStateAgent2( posGlobal, velGlobal, angGlobal );
01658 initParticlesAgent( *posGlobal );
01659 return false;
01660 }
01661 }
01662
01663
01664
01665 *posGlobal = averageParticles( particlesPosAgent, iNrLeft );
01666 resampleParticlesAgent( iNrLeft );
01667
01668
01669
01670 AngDeg ang = calculateAngleAgentWithPos( *posGlobal );
01671 if( ang != UnknownAngleValue )
01672 *angGlobal = ang;
01673
01674 *velGlobal = agentObject.getSpeedRelToNeck().rotate(*angGlobal);
01675 return true;
01676 }
01677
01685 void WorldModel::initParticlesAgent( AngDeg angGlobal )
01686 {
01687 double dDist, dMaxRadius, dMinRadius, dInput;
01688 AngDeg ang;
01689
01690
01691 ObjectT objFlag = getClosestRelativeInSet( OBJECT_SET_FLAGS );
01692
01693 if( objFlag == OBJECT_ILLEGAL )
01694 {
01695 Log.log( 21, "(WorldModel::%s) no flag in last see message",
01696 "initParticlesAgent" );
01697 return;
01698 }
01699
01700
01701 dInput = getRelativeDistance( objFlag );
01702 getMinMaxDistQuantizeValue( dInput, &dMinRadius, &dMaxRadius,
01703 SS->getQuantizeStepL(), 0.1 ) ;
01704
01705
01706
01707 AngDeg angFlag = getRelativeAngle( objFlag ) + 180 + angGlobal ;
01708
01709 for( int i = 0 ; i < iNrParticlesAgent ; i++ )
01710 {
01711
01712
01713
01714
01715 dDist = dMinRadius + drand48()*(dMaxRadius-dMinRadius);
01716 ang = VecPosition::normalizeAngle( angFlag - 1.0 + 2*drand48() );
01717
01718
01719 particlesPosAgent[i] = getGlobalPosition( objFlag ) +
01720 VecPosition( dDist, ang, POLAR );
01721 }
01722 }
01723
01729 void WorldModel::initParticlesAgent( VecPosition posInitial )
01730 {
01731 for( int i = 0 ; i < iNrParticlesAgent ; i++ )
01732 particlesPosAgent[i] = posInitial;
01733 }
01734
01744 int WorldModel::checkParticlesAgent( AngDeg angGlobalNeck )
01745 {
01746 double dMaxRadius, dMinRadius, dInput, dDist;
01747 AngDeg ang;
01748 int iIndex, iNrLeft = iNrParticlesAgent, iLength = iNrParticlesAgent;
01749
01750
01751 for( ObjectT o = iterateObjectStart( iIndex, OBJECT_SET_FLAGS, 1.0 );
01752 o != OBJECT_ILLEGAL;
01753 o = iterateObjectNext ( iIndex, OBJECT_SET_FLAGS, 1.0 ) )
01754 {
01755 iNrLeft = 0;
01756 dInput = getRelativeDistance( o );
01757 getMinMaxDistQuantizeValue( dInput, &dMinRadius, &dMaxRadius,
01758 SS->getQuantizeStepL(), 0.1 ) ;
01759
01760
01761 for( int i = 0; i < iLength; i ++ )
01762 {
01763
01764
01765
01766 dDist = particlesPosAgent[i].getDistanceTo( getGlobalPosition( o ) );
01767 ang = (getGlobalPosition(o) - particlesPosAgent[i]).getDirection();
01768 ang = ang - ( getRelativeAngle( o ) + angGlobalNeck );
01769
01770
01771
01772 if( dDist > dMinRadius && dDist < dMaxRadius &&
01773 fabs(VecPosition::normalizeAngle( ang )) <= 1.0 )
01774 particlesPosAgent[iNrLeft++] = particlesPosAgent[i];
01775 }
01776
01777 iLength = iNrLeft;
01778 }
01779 return iNrLeft;
01780 }
01781
01792 void WorldModel::updateParticlesAgent( VecPosition vel, bool bAfterSense )
01793 {
01794
01795 static VecPosition prev_vel;
01796
01797 for( int i = 0; i < iNrParticlesAgent ; i ++ )
01798 {
01799 if( bAfterSense == false )
01800 {
01801 particlesPosAgent[i].setX( particlesPosAgent[i].getX()-prev_vel.getX());
01802 particlesPosAgent[i].setY( particlesPosAgent[i].getY()-prev_vel.getY());
01803 }
01804
01805 particlesPosAgent[i].setX( particlesPosAgent[i].getX( ) + vel.getX() );
01806 particlesPosAgent[i].setY( particlesPosAgent[i].getY( ) + vel.getY() );
01807 }
01808 prev_vel = vel;
01809 }
01810
01811
01816 VecPosition WorldModel::averageParticles( VecPosition posArray[], int iLength )
01817 {
01818 if( iLength == 0 )
01819 return VecPosition( UnknownDoubleValue, UnknownDoubleValue );
01820
01821
01822 double x = 0, y = 0;
01823 for( int i = 0; i < iLength ; i ++ )
01824 {
01825 x += posArray[ i ].getX( );
01826 y += posArray[ i ].getY( );
01827 }
01828
01829 return VecPosition( x/iLength, y/iLength );
01830 }
01831
01838 void WorldModel::resampleParticlesAgent( int iLeft )
01839 {
01840 for ( int i = iLeft; i < iNrParticlesAgent; i ++ )
01841 particlesPosAgent[ i ] = particlesPosAgent[ (int)(drand48()*iLeft) ];
01842 }
01843
01852 bool WorldModel::calculateStateAgent2( VecPosition *posGlobal,
01853 VecPosition *velGlobal, AngDeg *angGlobal)
01854 {
01855 double x=0.0, y=0.0, dMinRadius1, dMaxRadius1, dMinRadius2, dMaxRadius2;
01856 double dTotalVar = UnknownDoubleValue, dVar, K;
01857 int iIndex1, iIndex2;
01858 ObjectT obj2;
01859 VecPosition pos;
01860
01861
01862 for( ObjectT obj1 = iterateObjectStart( iIndex1, OBJECT_SET_FLAGS, 1.0 );
01863 obj1 != OBJECT_ILLEGAL;
01864 obj1 = iterateObjectNext ( iIndex1, OBJECT_SET_FLAGS, 1.0 ) )
01865 {
01866
01867 iIndex2 = iIndex1;
01868 for( obj2 = iterateObjectNext ( iIndex2, OBJECT_SET_FLAGS, 1.0 ) ;
01869 obj2 != OBJECT_ILLEGAL;
01870 obj2 = iterateObjectNext ( iIndex2, OBJECT_SET_FLAGS, 1.0 ) )
01871 {
01872
01873 pos = calculatePosAgentWith2Flags( obj1, obj2 );
01874
01875
01876
01877
01878
01879
01880
01881 getMinMaxDistQuantizeValue(getRelativeDistance(obj1),
01882 &dMinRadius1, &dMaxRadius1, SS->getQuantizeStepL(), 0.1 ) ;
01883 getMinMaxDistQuantizeValue(getRelativeDistance(obj2),
01884 &dMinRadius2, &dMaxRadius2, SS->getQuantizeStepL(), 0.1 ) ;
01885 dVar = (dMaxRadius1-dMinRadius1)*(dMaxRadius1-dMinRadius1)/12;
01886 dVar += (dMaxRadius2-dMinRadius2)*(dMaxRadius2-dMinRadius2)/12;
01887
01888 if( pos.getX() != UnknownDoubleValue &&
01889 dTotalVar == UnknownDoubleValue )
01890 {
01891 dTotalVar = dVar;
01892 x = pos.getX();
01893 y = pos.getY();
01894 }
01895 else if( pos.getX() != UnknownDoubleValue )
01896 {
01897 K = dTotalVar / ( dVar + dTotalVar );
01898 x += K*( pos.getX() - x );
01899 y += K*( pos.getY() - y );
01900 dTotalVar -= K*dTotalVar;
01901 }
01902 }
01903 iterateObjectDone( iIndex2 );
01904 }
01905 iterateObjectDone( iIndex1 );
01906 posGlobal->setVecPosition( x, y );
01907
01908
01909
01910 *angGlobal = calculateAngleAgentWithPos( *posGlobal );
01911
01912
01913 *velGlobal = agentObject.getSpeedRelToNeck().rotate(*angGlobal);
01914
01915 return true;
01916 }
01917
01927 bool WorldModel::calculateStateAgent3( VecPosition *posGlobal,
01928 VecPosition *velGlobal, AngDeg *angGlobal )
01929 {
01930
01931 ObjectT objFlag1 = getClosestRelativeInSet( OBJECT_SET_FLAGS );
01932 ObjectT objFlag2 = getSecondClosestRelativeInSet( OBJECT_SET_FLAGS );
01933 ObjectT objLine = getFurthestRelativeInSet( OBJECT_SET_LINES );
01934
01935
01936 if( objLine != OBJECT_ILLEGAL )
01937 {
01938 double angGlobalLine = getGlobalAngle ( objLine );
01939 AngDeg angRelLine = getRelativeAngle( objLine );
01940 *angGlobal = angGlobalLine - angRelLine;
01941 *angGlobal = VecPosition::normalizeAngle( *angGlobal );
01942 }
01943
01944
01945
01946
01947
01948 if( objFlag1 != OBJECT_ILLEGAL && objFlag2 != OBJECT_ILLEGAL &&
01949 (
01950 fabs(getRelativeAngle(objFlag1) - getRelativeAngle(objFlag2)) > 8.0
01951 || objLine == OBJECT_ILLEGAL
01952 ) )
01953 {
01954 *posGlobal = calculatePosAgentWith2Flags( objFlag1, objFlag2 );
01955 }
01956 else if( objFlag1 != OBJECT_ILLEGAL && objLine != OBJECT_ILLEGAL )
01957 {
01958
01959
01960
01961
01962
01963 VecPosition posGlobalFlag = getGlobalPosition( objFlag1 );
01964 VecPosition relPosFlag = VecPosition::getVecPositionFromPolar(
01965 getRelativeDistance( objFlag1 ),
01966 *angGlobal + getRelativeAngle( objFlag1 ) );
01967 *posGlobal = posGlobalFlag - relPosFlag;
01968 }
01969 else
01970 {
01971 cout << "(WorldModel::calculateStateAgent3) cannot determine pos in cycle "
01972 << getCurrentCycle() << endl;
01973 return false;
01974 }
01975
01976
01977 *velGlobal = agentObject.getSpeedRelToNeck().rotate(*angGlobal);
01978
01979 return true;
01980 }
01981
01993 VecPosition WorldModel::calculatePosAgentWith2Flags( ObjectT objFlag1,
01994 ObjectT objFlag2 )
01995 {
01996 double xA, yA, xB, yB, rA, rB;
01997 AngDeg aA, aB;
01998
01999
02000 xA = getGlobalPosition ( objFlag1 ).getX();
02001 yA = getGlobalPosition ( objFlag1 ).getY();
02002 rA = getRelativeDistance( objFlag1 );
02003 aA = getRelativeAngle ( objFlag1 );
02004 xB = getGlobalPosition ( objFlag2 ).getX();
02005 yB = getGlobalPosition ( objFlag2 ).getY();
02006 rB = getRelativeDistance( objFlag2 );
02007 aB = getRelativeAngle ( objFlag2 );
02008
02009 double L, dx, dy, d_par, d_orth;
02010 double x, y;
02011
02012 double sign = ((aB - aA) > 0.0) ? 1.0 : -1.0;
02013
02014
02015
02016
02017
02018
02019
02020
02021 dx = xB - xA;
02022 dy = yB - yA;
02023 L = sqrt(dx*dx + dy*dy);
02024
02025 dx /= L; dy /= L;
02026
02027 d_par = (L*L + rA*rA - rB*rB) / (2.0 * L);
02028 double arg = rA*rA - d_par*d_par;
02029 d_orth = (arg > 0.0) ? sqrt(arg) : 0.0;
02030
02031 x = xA + d_par * dx - sign * d_orth * dy;
02032 y = yA + d_par * dy + sign * d_orth * dx;
02033
02034 return VecPosition( x, y );
02035 }
02036
02048 AngDeg WorldModel::calculateAngleAgentWithPos( VecPosition pos )
02049 {
02050 int iNrFlags = 0, iIndex;
02051 double dCosX=0, dSinX=0 ,dAngleNow, xA, yA, aA;
02052
02053 for( ObjectT obj = iterateObjectStart( iIndex, OBJECT_SET_FLAGS, 1.0 );
02054 obj != OBJECT_ILLEGAL;
02055 obj = iterateObjectNext ( iIndex, OBJECT_SET_FLAGS, 1.0 ) )
02056 {
02057 xA = getGlobalPosition( obj ).getX();
02058 yA = getGlobalPosition( obj ).getY();
02059 aA = getRelativeAngle( obj );
02060
02061
02062
02063 dAngleNow = atan2Deg( yA - pos.getY(), xA - pos.getX() );
02064 dAngleNow = VecPosition::normalizeAngle( dAngleNow - aA );
02065
02066
02067
02068
02069 dCosX += cosDeg( dAngleNow );
02070 dSinX += sinDeg( dAngleNow );
02071 iNrFlags++;
02072
02073 }
02074 iterateObjectDone( iIndex );
02075
02076
02077 dCosX /= (double)iNrFlags;
02078 dSinX /= (double)iNrFlags;
02079 if( iNrFlags == 0 )
02080 return UnknownAngleValue;
02081
02082 return VecPosition::normalizeAngle( atan2Deg( dSinX, dCosX ) ) ;
02083 }
02084
02085
02091 VecPosition WorldModel::calculateVelocityDynamicObject( ObjectT o )
02092 {
02093 DynamicObject * dobj = (DynamicObject*) getObjectPtrFromType( o );
02094 if( dobj == NULL )
02095 return VecPosition( UnknownDoubleValue, UnknownDoubleValue );
02096 double dDistCh = dobj->getRelativeDistanceChange( );
02097 double angCh = dobj->getRelativeAngleChange ( );
02098 double dDist = getRelativeDistance ( o );
02099 double ang = getRelativeAngle ( o );
02100
02101 double velx = dDistCh * cosDeg(ang) - Deg2Rad(angCh) * dDist * sinDeg( ang );
02102 double vely = dDistCh * sinDeg(ang) + Deg2Rad(angCh) * dDist * cosDeg( ang );
02103
02104 VecPosition vel( velx, vely );
02105 return vel.relativeToGlobal( getAgentGlobalVelocity(),
02106 getAgentGlobalNeckAngle() );
02107 }
02108
02109
02115 bool WorldModel::calculateStateBall( VecPosition *posGlobal,
02116 VecPosition *velGlobal )
02117 {
02118
02119
02120
02121 VecPosition posRelWorld =
02122 VecPosition( getRelativeDistance( OBJECT_BALL ),
02123 getRelativeAngle( OBJECT_BALL ) + getAgentGlobalNeckAngle(),
02124 POLAR );
02125 *posGlobal = getAgentGlobalPosition() + posRelWorld;
02126
02127 if( isBeforeKickOff() )
02128 {
02129 posGlobal->setVecPosition( 0, 0 );
02130 velGlobal->setVecPosition( 0, 0 );
02131 return true;
02132 }
02133
02134 *velGlobal = getGlobalVelocity(OBJECT_BALL);
02135 if( Ball.getTimeChangeInformation( ) == getTimeLastSeen( OBJECT_BALL ) )
02136 {
02137 *velGlobal = calculateVelocityDynamicObject( OBJECT_BALL );;
02138 Log.log( 458, "vel based on change info: (%f,%f)", velGlobal->getX(),
02139 velGlobal->getY() );
02140
02141
02142
02143 if( fabs(velGlobal->getX() - getGlobalVelocity(OBJECT_BALL).getX())
02144 <= 2*SS->getBallRand()*getBallSpeed() &&
02145 fabs(velGlobal->getY() - getGlobalVelocity(OBJECT_BALL).getY())
02146 <= 2*SS->getBallRand()*getBallSpeed() )
02147 {
02148 *velGlobal = (*velGlobal + getGlobalVelocity(OBJECT_BALL))/2.0;
02149 Log.log( 458, "average ball vel to (%f,%f)", velGlobal->getX(),
02150 velGlobal->getY() );
02151 }
02152 }
02153 else if( getRelativeDistance(OBJECT_BALL) < SS->getVisibleDistance() &&
02154 getTimeLastSeeMessage() - Ball.getTimeGlobalPosDerivedFromSee() < 3)
02155 {
02156
02157
02158
02159
02160
02161
02162
02163 VecPosition posGlobalDiff = *posGlobal - Ball.getGlobalPositionLastSee()
02164 - agentObject.getPositionDifference();
02165 Log.log( 101, "2 pos: ball(%f,%f), ball_prev(%f,%f), agentdiff(%f,%f)",
02166 posGlobal->getX(), posGlobal->getY(),
02167 Ball.getGlobalPositionLastSee().getX(),
02168 Ball.getGlobalPositionLastSee().getY(),
02169 agentObject.getPositionDifference().getX(),
02170 agentObject.getPositionDifference().getY() );
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181 if( getTimeLastSeeMessage() - Ball.getTimeGlobalPosDerivedFromSee() == 1 &&
02182 m_bWasCollision == false )
02183 {
02184 *velGlobal = posGlobalDiff*SS->getBallDecay();
02185 Log.log( 458, "vel based on 2 pos: (%f,%f)", velGlobal->getX(),
02186 velGlobal->getY() );
02187 Log.log( 101, "vel based on 2 pos: (%f,%f)", velGlobal->getX(),
02188 velGlobal->getY() );
02189 }
02190 else if(getTimeLastSeeMessage()-Ball.getTimeGlobalPosDerivedFromSee()==2 &&
02191 m_bWasCollision == false )
02192 {
02193 VecPosition velTmp, posTmp;
02194 double dDist;
02195
02196
02197
02198
02199
02200
02201
02202 velTmp = (posGlobalDiff/(1+SS->getBallDecay()))*SS->getBallDecay();
02203 posTmp = *posGlobal - velTmp;
02204 getClosestInSetTo( OBJECT_SET_PLAYERS, posTmp, &dDist );
02205 if( dDist > SS->getMaximalKickDist() &&
02206 m_bPerformedKick == false &&
02207 (getCurrentTime() - m_timeLastCollision) > 3 )
02208 {
02209 *velGlobal = velTmp * SS->getBallDecay();
02210 Log.log( 458, "vel based on 3 pos: (%f,%f)", velGlobal->getX(),
02211 velGlobal->getY() );
02212 }
02213 }
02214 else if( getTimeLastSeeMessage()-Ball.getTimeGlobalPosDerivedFromSee() > 2)
02215 {
02216 #ifdef WIN32
02217 Log.log( 20, "(WorldModel:%s) time difference too large" ,
02218 "calculateStateBall" );
02219 #else
02220 Log.log( 20, "(WorldModel:%s) time difference too large" ,__FUNCTION__ );
02221 #endif
02222
02223 }
02224 }
02225 else
02226 Log.log( 458, "vel ball not updated", velGlobal->getX(),velGlobal->getY());
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236 if( getTimeSinceLastCatch() < 2 ||
02237 (getPlayMode() != PM_PLAY_ON && !isGoalKickUs() && !isGoalKickThem() &&
02238 !isPenaltyUs() && !isPenaltyThem() ))
02239 velGlobal->setMagnitude( 0.0 );
02240 else if( getNrInSetInCircle( OBJECT_SET_OPPONENTS,
02241 Circle(*posGlobal,SS->getMaximalKickDist())) > 0
02242 && getRelativeDistance( OBJECT_BALL ) > SS->getMaximalKickDist() )
02243 velGlobal->setMagnitude( 0.0 );
02244 else if( velGlobal->getMagnitude() >
02245 ( 1.0 + SS->getBallRand() )*SS->getBallSpeedMax() )
02246 velGlobal->setMagnitude( SS->getBallSpeedMax() );
02247
02248 if( isKickInUs() || isKickInThem() )
02249 posGlobal->setY( sign( posGlobal->getY() ) * PITCH_WIDTH/2.0 );
02250 else if( isBackPassUs() )
02251 posGlobal->setVecPosition( - PENALTY_X,
02252 sign(posGlobal->getY())*PENALTY_AREA_WIDTH/2.0);
02253 else if( isBackPassThem() )
02254 posGlobal->setVecPosition( + PENALTY_X,
02255 sign(posGlobal->getY())*PENALTY_AREA_WIDTH/2.0);
02256
02257 Log.log( 458, "final ball vel: (%f,%f)",velGlobal->getX(),velGlobal->getY());
02258 if( getRelativeDistance(OBJECT_BALL) < SS->getVisibleDistance() )
02259 Log.log( 101, "direction old: %f, new: %f",
02260 ( getGlobalPosition( OBJECT_BALL ) -
02261 getAgentGlobalPosition()).getDirection(),
02262 ( *posGlobal - getAgentGlobalPosition()).getDirection() );
02263 return true;
02264 }
02265
02266
02267
02274 bool WorldModel::calculateStatePlayer( ObjectT o, VecPosition *posGlobal,
02275 VecPosition *velGlobal )
02276 {
02277 PlayerObject *pob = (PlayerObject*) getObjectPtrFromType( o );
02278 if( pob == NULL )
02279 return false;
02280
02281
02282
02283
02284 VecPosition posRelWorld =
02285 VecPosition( getRelativeDistance( o ),
02286 getRelativeAngle( o ) + agentObject.getGlobalNeckAngle(),
02287 POLAR );
02288 *posGlobal = getAgentGlobalPosition() + posRelWorld;
02289
02290 *velGlobal = getGlobalVelocity( o ) ;
02291 if( pob->getTimeChangeInformation( ) == getTimeLastSeen( o ) )
02292 {
02293
02294
02295 *velGlobal = calculateVelocityDynamicObject( o );
02296 }
02297 else
02298 ;
02299
02300
02301 if( velGlobal->getMagnitude() >=
02302 ( 1.0 + SS->getPlayerRand())*SS->getPlayerSpeedMax() )
02303 velGlobal->setMagnitude( SS->getPlayerSpeedMax() );
02304
02305 return true;
02306 }
02307
02308
02322 bool WorldModel::getMinMaxDistQuantizeValue( double dOutput, double *dMin,
02323 double *dMax, double x1, double x2 )
02324 {
02325
02326
02327
02328
02329
02330
02331
02332 dOutput -= 1.0e-10;
02333 if( dOutput < 0 )
02334 *dMin = 0.0;
02335 else
02336 *dMin = exp( invQuantizeMin( log( invQuantizeMin(dOutput,x2) ), x1 ) );
02337 dOutput += 2.0e-10;
02338 *dMax = exp( invQuantizeMax( log( invQuantizeMax(dOutput,x2) ), x1 ) );
02339 return true;
02340 }
02341
02351 bool WorldModel::getMinMaxDirChange( double dOutput, double *dMin,
02352 double *dMax, double x1 )
02353 {
02354 *dMin = invQuantizeMin( dOutput, x1 ) ;
02355 *dMax = invQuantizeMax( dOutput, x1 ) ;
02356 return true;
02357 }
02358
02373 bool WorldModel::getMinMaxDistChange( double dOutput, double dDist,
02374 double *dMin, double *dMax, double x1, double xDist1, double xDist2)
02375 {
02376
02377
02378
02379
02380
02381 double dMinDist, dMaxDist;
02382 getMinMaxDistQuantizeValue( dDist, &dMinDist, &dMaxDist, xDist1, xDist2 );
02383 dOutput = dOutput/dDist;
02384 double dMinCh = invQuantizeMin( dOutput, x1 ) ;
02385 double dMaxCh = invQuantizeMax( dOutput, x1 ) ;
02386 *dMin = min( dMinDist*dMinCh, dMaxDist*dMinCh );
02387 *dMax = max( dMinDist*dMaxCh, dMaxDist*dMaxCh );
02388 return true;
02389 }
02390
02396 double WorldModel::invQuantizeMin( double dOutput, double dQuantizeStep )
02397 {
02398
02399
02400 return max(1.0e-10,(rint( dOutput / dQuantizeStep )-0.5 )*dQuantizeStep);
02401 }
02402
02408 double WorldModel::invQuantizeMax( double dOutput, double dQuantizeStep )
02409 {
02410
02411
02412 return (rint( dOutput/dQuantizeStep) + 0.5 )*dQuantizeStep;
02413 }
02414
02426 void WorldModel::mapUnknownPlayers( Time time)
02427 {
02428 double dDist, dMinDist;
02429 VecPosition pos, posAgent = getAgentGlobalPosition();
02430 ObjectT o, o_new, objTmp;
02431 int index;
02432
02433
02434 for( int j = 0; j < iNrUnknownPlayers; j ++ )
02435 {
02436 pos = posAgent + VecPosition( UnknownPlayers[j].getRelativeDistance(),
02437 VecPosition::normalizeAngle( getAgentGlobalNeckAngle() +
02438 UnknownPlayers[j].getRelativeAngle() ),
02439 POLAR );
02440 dMinDist = 1000.0;
02441 o = UnknownPlayers[j].getType();
02442 o_new = OBJECT_ILLEGAL;
02443 Log.log( 464, "map unknown player: %d %f %f (%f,%f) neck %f",
02444 o,
02445 UnknownPlayers[j].getRelativeDistance(),
02446 UnknownPlayers[j].getRelativeAngle(),
02447 pos.getX(), pos.getY(),
02448 getAgentGlobalNeckAngle() );
02449 if( ! SoccerTypes::isOpponent( o ) )
02450 {
02451 for( int i = 0 ; i < MAX_TEAMMATES ; i++ )
02452 {
02453 objTmp = Teammates[i].getType();
02454 if( isConfidenceGood( objTmp ) && getTimeLastSeen( objTmp ) != time &&
02455 objTmp != getAgentObjectType() )
02456 {
02457 dDist = pos.getDistanceTo( Teammates[i].getGlobalPosition( ) );
02458 Log.log( 464, "distance with %d %f (%f,%f)", objTmp, dDist,
02459 Teammates[i].getRelativeDistance(),
02460 Teammates[i].getRelativeAngle() );
02461 if( dDist < dMinDist )
02462 {
02463 o_new = objTmp;
02464 dMinDist = dDist;
02465 }
02466 }
02467 else
02468 Log.log( 464, "not possible: distance with %d (%f,%f) conf %d \
02469 last_seen (%d,%d), now (%d,%d)",
02470 objTmp,
02471 Teammates[i].getRelativeDistance(),
02472 Teammates[i].getRelativeAngle(),
02473 isConfidenceGood( objTmp ),
02474 getTimeLastSeen( objTmp ).getTime(),
02475 getTimeLastSeen( objTmp ).getTimeStopped(),
02476 time.getTime(),
02477 time.getTimeStopped());
02478
02479 }
02480 }
02481 if( ! SoccerTypes::isTeammate( o ) )
02482 {
02483 for( int i = 0 ; i < MAX_OPPONENTS ; i++ )
02484 {
02485 objTmp = Opponents[i].getType();
02486 if( isConfidenceGood( objTmp ) && getTimeLastSeen( objTmp ) != time )
02487 {
02488 dDist = pos.getDistanceTo( Opponents[i].getGlobalPosition( ) );
02489 Log.log( 464, "distance with %d %f (%f,%f)", objTmp, dDist,
02490 Opponents[i].getRelativeDistance(),
02491 Opponents[i].getRelativeAngle() );
02492 if( dDist < dMinDist )
02493 {
02494 o_new = objTmp;
02495 dMinDist = dDist;
02496 }
02497 }
02498 else
02499 Log.log( 464, "not possible: distance with %d (%f,%f) conf %d \
02500 last_seen (%d,%d), now (%d,%d)",
02501 objTmp,
02502 Opponents[i].getRelativeDistance(),
02503 Opponents[i].getRelativeAngle(),
02504 isConfidenceGood( objTmp ),
02505 getTimeLastSeen( objTmp ).getTime(),
02506 getTimeLastSeen( objTmp ).getTimeStopped(),
02507 time.getTime(),
02508 time.getTimeStopped());
02509 }
02510 }
02511
02512 Log.log( 464, "closest obj %d, found %f, max_move %f rel_dist %f type %d",
02513 o_new, dMinDist, getMaxTraveledDistance( o_new ),
02514 UnknownPlayers[j].getRelativeDistance(),
02515 UnknownPlayers[j].getType() );
02516
02517
02518
02519
02520
02521
02522
02523 if( SoccerTypes::isKnownPlayer(o_new)
02524 && dMinDist < PS->getPlayerDistTolerance()
02525 && dMinDist < getMaxTraveledDistance( o_new ) + 2 )
02526 {
02527 UnknownPlayers[j].setType( o_new );
02528 if( SoccerTypes::isTeammate( o_new ) )
02529 {
02530 index = SoccerTypes::getIndex(o_new);
02531 UnknownPlayers[j].setHeteroPlayerType(
02532 Teammates[index].getHeteroPlayerType( ) );
02533 Teammates[index] = UnknownPlayers[j];
02534 Log.log( 464, "map to known teammate %d (%f,%f) conf %f", index + 1,
02535 Teammates[index].getGlobalPosition().getX(),
02536 Teammates[index].getGlobalPosition().getY(),
02537 Teammates[index].getConfidence( getCurrentTime() ) );
02538 }
02539 else if( SoccerTypes::isOpponent( o_new ) )
02540 {
02541 index = SoccerTypes::getIndex(o_new );
02542 UnknownPlayers[j].setHeteroPlayerType(
02543 Opponents[index].getHeteroPlayerType( ) );
02544 Opponents[index] = UnknownPlayers[j];
02545 Log.log( 464, "map to known opponent %d (time %d)",
02546 index + 1, UnknownPlayers[j].getTimeLastSeen().getTime() );
02547 }
02548 }
02549 else if( UnknownPlayers[j].getType() == OBJECT_TEAMMATE_UNKNOWN )
02550 {
02551 o_new = getFirstEmptySpotInSet( OBJECT_SET_TEAMMATES, j );
02552
02553 if( o_new != OBJECT_ILLEGAL )
02554 {
02555 index = SoccerTypes::getIndex(o_new);
02556 UnknownPlayers[j].setHeteroPlayerType(
02557 Teammates[index].getHeteroPlayerType( ) );
02558 UnknownPlayers[j].setType( o_new );
02559 Teammates[index] = UnknownPlayers[j];
02560 Log.log( 464, "map to unknown teammate %d", index + 1 );
02561 }
02562 }
02563 else if( UnknownPlayers[j].getType() == OBJECT_OPPONENT_UNKNOWN )
02564 {
02565 o_new = getFirstEmptySpotInSet( OBJECT_SET_OPPONENTS, j );
02566 Log.log( 464, "map unkown opponent to %d", o_new );
02567 if( o_new != OBJECT_ILLEGAL )
02568 {
02569 index = SoccerTypes::getIndex(o_new);
02570 UnknownPlayers[j].setHeteroPlayerType(
02571 Opponents[index].getHeteroPlayerType( ) );
02572 UnknownPlayers[j].setType( o_new );
02573 Opponents[index] = UnknownPlayers[j];
02574 Log.log( 464, "map to unknown opponent %d", index + 1 );
02575 }
02576 else
02577 {
02578 Log.log( 464, "couldn't find empty spot for unk. opponent" );
02579 if( Log.isInLogLevel( 464 ) )
02580 show( OBJECT_SET_PLAYERS, Log.getOutputStream() );
02581
02582
02583
02584 }
02585 }
02586 else if( UnknownPlayers[j].getType() == OBJECT_PLAYER_UNKNOWN &&
02587 ( UnknownPlayers[j].getRelativeDistance() < SS->getVisibleDistance()
02588 || ( dMinDist - getMaxTraveledDistance( o_new ) ) > 10 ) )
02589 {
02590 o_new = getFirstEmptySpotInSet( OBJECT_SET_OPPONENTS );
02591 Log.log( 464, "map unkown player to %d", o_new );
02592 if( o_new != OBJECT_ILLEGAL )
02593 {
02594 index = SoccerTypes::getIndex(o_new);
02595 UnknownPlayers[j].setHeteroPlayerType(
02596 Opponents[index].getHeteroPlayerType( ) );
02597 UnknownPlayers[j].setType( o_new );
02598 Opponents[index] = UnknownPlayers[j];
02599 Log.log( 464, "map to unknown close opponent %d", index + 1 );
02600 }
02601 }
02602 }
02603 Log.log( 464, "end map unknown player" );
02604
02605 iNrUnknownPlayers = 0;
02606 }
02607
02615 bool WorldModel::updateSSToHeteroPlayerType( int iIndex )
02616 {
02617 SS->setPlayerSpeedMax( pt[iIndex].dPlayerSpeedMax );
02618 SS->setStaminaIncMax ( pt[iIndex].dStaminaIncMax );
02619 SS->setPlayerDecay ( pt[iIndex].dPlayerDecay );
02620 SS->setInertiaMoment ( pt[iIndex].dInertiaMoment );
02621 SS->setDashPowerRate ( pt[iIndex].dDashPowerRate );
02622 SS->setPlayerSize ( pt[iIndex].dPlayerSize );
02623 SS->setKickableMargin( pt[iIndex].dKickableMargin );
02624 SS->setKickRand ( pt[iIndex].dKickRand );
02625 SS->setExtraStamina ( pt[iIndex].dExtraStamina );
02626 SS->setEffortMax ( pt[iIndex].dEffortMax );
02627 SS->setEffortMin ( pt[iIndex].dEffortMin );
02628
02629 return true;
02630 }
02631
02635 bool WorldModel::resetTimeObjects( )
02636 {
02637 Ball.setTimeLastSeen ( Time( -1, 0) );
02638 for( int i = 0 ; i < MAX_TEAMMATES ; i ++ )
02639 Teammates[i].setTimeLastSeen ( Time( -1, 0) );
02640 for( int i = 0 ; i < MAX_OPPONENTS ; i ++ )
02641 Opponents[i].setTimeLastSeen ( Time( -1, 0) );
02642 for( int i = 0 ; i < MAX_FLAGS ; i ++ )
02643 Flags[i].setTimeLastSeen ( Time( -1, 0) );
02644 for( int i = 0 ; i < MAX_LINES ; i ++ )
02645 Lines[i].setTimeLastSeen ( Time( -1, 0) );
02646 agentObject.setTimeLastSeen ( Time( -1, 0) );
02647 return true;
02648 }
02649
02653 void WorldModel::removeGhosts( )
02654 {
02655 AngDeg dAngle=SoccerTypes::getHalfViewAngleValue(agentObject.getViewAngle());
02656 dAngle -= 0.35*dAngle;
02657 VecPosition posAgent = getAgentGlobalPosition();
02658
02659 if( fabs( getRelativeAngle( OBJECT_BALL ) ) < dAngle
02660 && getTimeLastSeen( OBJECT_BALL ) != getTimeLastSeeMessage() )
02661 {
02662 double dDist;
02663 ObjectT objOpp=getClosestInSetTo(OBJECT_SET_OPPONENTS,OBJECT_BALL,&dDist);
02664
02665
02666 if( dDist < 2.0 &&
02667 posAgent.getDistanceTo( getGlobalPosition( objOpp ) ) < 4.5 &&
02668 getTimeLastSeen( objOpp ) != getTimeLastSeeMessage() )
02669 {
02670 Log.log( 556, "ball not seen, but opp close, set ball to that pos" );
02671 Ball.setGlobalPosition( getGlobalPosition( objOpp ),
02672 Ball.getTimeGlobalPosition() );
02673 }
02674 else
02675 {
02676 Log.log( 556, "ball not in cone: set time ball at -1 %f %f",
02677 fabs( getRelativeAngle( OBJECT_BALL ) ), dAngle );
02678 Ball.setTimeLastSeen( Time( -1, 0 ) );
02679 }
02680 }
02681
02682
02683 if( fabs( getRelativeDistance( OBJECT_BALL ) ) < 0.9*SS->getVisibleDistance()
02684 && getTimeLastSeen( OBJECT_BALL ) != getTimeLastSeeMessage() )
02685 {
02686 double dDist;
02687 ObjectT objOpp=getClosestInSetTo(OBJECT_SET_OPPONENTS,OBJECT_BALL,&dDist);
02688 if( dDist < 2.0 )
02689 {
02690 Log.log( 556, "ball not seen, but opp close, set ball to that pos" );
02691 Ball.setGlobalPosition( getGlobalPosition( objOpp ),
02692 Ball.getTimeGlobalPosition() );
02693 }
02694 else
02695 {
02696 Log.log( 556, "ball not in vis. dist: set time ball at -1 %f %f",
02697 fabs( getRelativeAngle( OBJECT_BALL ) ), dAngle );
02698 Ball.setTimeLastSeen( Time( -1, 0 ) );
02699 }
02700 }
02701
02702
02703
02704
02705
02706 int iIndex;
02707 for( ObjectT o = iterateObjectStart( iIndex, OBJECT_SET_OPPONENTS );
02708 o != OBJECT_ILLEGAL;
02709 o = iterateObjectNext ( iIndex, OBJECT_SET_OPPONENTS ) )
02710 {
02711 if( fabs( getRelativeAngle( o ) ) < dAngle
02712
02713 && getTimeLastSeen( o ) != getTimeLastSeeMessage() &&
02714 o != getOppGoalieType() )
02715 {
02716 Log.log( 556, "opponent %d not in cone: (angle %f>%f) see (%d,%d)",
02717 SoccerTypes::getIndex( o ) + 1,
02718 fabs( getRelativeAngle( o ) ), dAngle,
02719 getTimeLastSeeMessage().getTime(),getTimeLastSeen(o).getTime());
02720
02721 AngDeg ang =
02722 SoccerTypes::getHalfViewAngleValue(agentObject.getViewAngle());
02723 AngDeg angOpp = (getGlobalPosition(o)-posAgent).getDirection();
02724 AngDeg angNeck = getAgentGlobalNeckAngle();
02725
02726 if( fabs(VecPosition::normalizeAngle( angOpp - angNeck )) < 10 &&
02727 getCurrentTime() - getTimeGlobalAngles(o) < 4 )
02728 angOpp = (getGlobalPosition(o)+
02729 VecPosition(2.0, getGlobalBodyAngle(o), POLAR )-posAgent)
02730 .getDirection();
02731 if( VecPosition::normalizeAngle( angOpp - angNeck ) > 0 )
02732 angOpp = angNeck + ang;
02733 else
02734 angOpp = angNeck - ang;
02735 angOpp = VecPosition::normalizeAngle( angOpp );
02736 DynamicObject *obj = (DynamicObject*) getObjectPtrFromType( o );
02737
02738
02739 if( fabs( getRelativeAngle( o ) ) + 20 > dAngle )
02740 {
02741 VecPosition posNew = posAgent+
02742 VecPosition(getRelativeDistance(o),angOpp, POLAR);
02743 if( posNew.getDistanceTo( getGlobalPosition( o ) ) <
02744 getMaxTraveledDistance( o ) )
02745 {
02746 obj->setGlobalPosition( posNew, getCurrentTime());
02747
02748 Log.log( 556, "set opp at angle %f", angOpp );
02749 updateObjectRelativeFromGlobal( o );
02750 }
02751 else
02752 Log.log( 556, "do not reposition opp too far dist %f",
02753 posNew.getDistanceTo( getGlobalPosition( o ) ));
02754 }
02755 else
02756 {
02757 setTimeLastSeen( o, Time( -1, 0 ) );
02758 Log.log( 556, "remove opponent not in cone at angle %f %f %f", angOpp,
02759 fabs(getRelativeAngle(o)), dAngle );
02760 }
02761 }
02762 if( getRelativeDistance(o) < SS->getVisibleDistance( )
02763 && getTimeLastSeen( o ) != getTimeLastSeeMessage() )
02764 {
02765 Log.log( 556, "opp %d not felt, place him outside vis. dist", o );
02766 DynamicObject *obj = (DynamicObject*) getObjectPtrFromType( o );
02767 VecPosition posNew = posAgent + VecPosition( SS->getVisibleDistance(),
02768 (getGlobalPosition( o ) - getAgentGlobalPosition()).
02769 getDirection(), POLAR );
02770 obj->setGlobalPosition( posNew, getCurrentTime( ));
02771
02772 updateObjectRelativeFromGlobal( o );
02773 }
02774 }
02775 iterateObjectDone( iIndex );
02776
02777
02778
02779
02780
02781 for( ObjectT o = iterateObjectStart( iIndex, OBJECT_SET_TEAMMATES );
02782 o != OBJECT_ILLEGAL;
02783 o = iterateObjectNext ( iIndex, OBJECT_SET_TEAMMATES ) )
02784 {
02785 if( fabs( getRelativeAngle( o ) ) < dAngle
02786
02787 && getTimeLastSeen( o ) != getTimeLastSeeMessage() )
02788 {
02789 Log.log( 556, "teammate %d not in cone: (angle %f>%f) see (%d,%d)",
02790 SoccerTypes::getIndex( o ) + 1,
02791 fabs( getRelativeAngle( o ) ), dAngle,
02792 getTimeLastSeeMessage().getTime(), getTimeLastSeen( o ).getTime() );
02793 setTimeLastSeen( o, Time( -1, 0 ) );
02794 }
02795 }
02796 iterateObjectDone( iIndex );
02797
02798 }
02799
02809 void WorldModel::initParticlesBall( VecPosition posArray[],
02810 VecPosition velArray[], int iLength )
02811 {
02812
02813 double dDistBall, dDistChange = UnknownDoubleValue;
02814 AngDeg angBall, angChange = UnknownAngleValue;
02815 double dMinDist, dMaxDist, dMinCh, dMaxCh, dDistTmp, dDistChTmp, dVelX,dVelY;
02816 AngDeg angChMin, angChMax, angTmp, angChTmp;
02817
02818
02819 if( Ball.getTimeRelativePosition() != getTimeLastSeeMessage() )
02820 return;
02821
02822
02823 dDistBall = getRelativeDistance( OBJECT_BALL );
02824 angBall = getRelativeAngle( OBJECT_BALL );
02825
02826
02827 if( Ball.getTimeChangeInformation( ) == getTimeLastSeeMessage() )
02828 {
02829 dDistChange = Ball.getRelativeDistanceChange();
02830 angChange = Ball.getRelativeAngleChange();
02831 }
02832
02833
02834 getMinMaxDistQuantizeValue( dDistBall, &dMinDist, &dMaxDist, 0.1, 0.1 );
02835 getMinMaxDistChange( dDistChange, dDistBall, &dMinCh, &dMaxCh, 0.02, 0.1,0.1);
02836 getMinMaxDirChange ( angChange, &angChMin, &angChMax, 0.1 );
02837
02838 for( int i = 0; i < iLength; i ++ )
02839 {
02840
02841
02842 dDistTmp = dMinDist + drand48()*fabs(dMaxDist - dMinDist);
02843 angTmp = angBall + drand48() - 0.5;
02844
02845 posArray[i].setVecPosition( dDistTmp, angTmp, POLAR );
02846 posArray[i].relativeToGlobal( getAgentGlobalPosition(),
02847 getAgentGlobalNeckAngle() );
02848
02849 if( dDistChange != UnknownDoubleValue )
02850 {
02851
02852 angChTmp = angChMin + drand48()*(angChMax-angChMin);
02853 dDistChTmp = dMinCh + drand48()*(dMaxCh-dMinCh);
02854
02855 dVelX=dDistChTmp*
02856 cosDeg(angTmp)-Deg2Rad(angChTmp)*dDistTmp*sinDeg(angTmp);
02857 dVelY=dDistChTmp*
02858 sinDeg(angTmp)+Deg2Rad(angChTmp)*dDistTmp*cosDeg(angTmp);
02859
02860 velArray[i].setVecPosition( dVelX, dVelY );
02861 velArray[i].relativeToGlobal( getAgentGlobalVelocity(),
02862 getAgentGlobalNeckAngle() );
02863 }
02864 else
02865 velArray[i].setVecPosition( 0, 0 );
02866 }
02867 }
02868
02879 void WorldModel::checkParticlesBall( VecPosition posArray[],
02880 VecPosition velArray[], int iLength, int *iNrParticlesLeft )
02881 {
02882 bool bIllegal;
02883 double dMinDist, dMaxDist, dMinCh, dMaxCh, dMag;
02884 double dDistBall, dDistChange = UnknownDoubleValue;
02885 AngDeg angBall, angChange;
02886 double dDistChTmp;
02887 AngDeg angChTmp, angChMin, angChMax;
02888 VecPosition pos_rel, vel_rel;
02889
02890
02891 if( getTimeLastSeen( OBJECT_BALL ) != getTimeLastSeeMessage() )
02892 return;
02893
02894
02895
02896 dDistBall = getRelativeDistance( OBJECT_BALL );
02897 angBall = getRelativeAngle( OBJECT_BALL );
02898 getMinMaxDistQuantizeValue( dDistBall, &dMinDist, &dMaxDist, 0.1, 0.1 );
02899
02900 if( getTimeLastSeen( OBJECT_BALL ) == Ball.getTimeChangeInformation( ) )
02901 {
02902 dDistChange = Ball.getRelativeDistanceChange();
02903 angChange = Ball.getRelativeAngleChange();
02904 getMinMaxDirChange ( angChange, &angChMin, &angChMax, 0.1);
02905 getMinMaxDistChange( dDistChange,dDistBall, &dMinCh, &dMaxCh,0.02,0.1,0.1);
02906
02907 }
02908
02909 *iNrParticlesLeft = 0;
02910 for( int i = 0; i < iLength; i ++ )
02911 {
02912
02913 pos_rel = posArray[i];
02914 vel_rel = velArray[i];
02915 pos_rel.globalToRelative( getAgentGlobalPosition(),
02916 getAgentGlobalNeckAngle() );
02917 vel_rel.globalToRelative( getAgentGlobalVelocity(),
02918 getAgentGlobalNeckAngle() );
02919
02920 bIllegal = false;
02921
02922 dMag = pos_rel.getMagnitude();
02923 if( dMag < dMinDist || dMag > dMaxDist )
02924 {
02925 bIllegal = true;
02926 }
02927 if( fabs( VecPosition::normalizeAngle(pos_rel.getDirection() - angBall) )
02928 > 0.5 )
02929 {
02930 bIllegal = true;
02931 }
02932
02933 if( dDistChange != UnknownDoubleValue )
02934 {
02935 dDistChTmp = (vel_rel.getX()*(pos_rel.getX()/dMag)) +
02936 (vel_rel.getY()*(pos_rel.getY()/dMag));
02937 angChTmp = Rad2Deg( ((vel_rel.getY()*pos_rel.getX()/dMag) -
02938 (vel_rel.getX()*pos_rel.getY()/dMag)))/dMag ;
02939
02940 if( angChTmp < angChMin || angChTmp > angChMax )
02941 {
02942 bIllegal = true;
02943 }
02944 if( dDistChTmp < dMinCh || dDistChTmp > dMaxCh )
02945 {
02946 bIllegal = true;
02947 }
02948 }
02949
02950
02951 if( bIllegal == false )
02952 {
02953 posArray[*iNrParticlesLeft] = posArray[i];
02954 velArray[(*iNrParticlesLeft)++] = velArray[i];
02955 }
02956 }
02957 }
02958
02967 void WorldModel::updateParticlesBall( VecPosition posArray[],
02968 VecPosition velArray[], int iLength, double dPower, AngDeg ang )
02969 {
02970 double dRand = SS->getBallRand();
02971 double dMaxRand;
02972
02973 for( int i = 0; i < iLength; i ++ )
02974 {
02975
02976 if( dPower > EPSILON )
02977 {
02978 ang = VecPosition::normalizeAngle(ang + getAgentGlobalBodyAngle() );
02979 velArray[i] += VecPosition(getActualKickPowerRate()*dPower, ang, POLAR) ;
02980 if( velArray[i].getMagnitude() > SS->getBallSpeedMax() )
02981 velArray[i].setMagnitude( SS->getBallSpeedMax() );
02982 }
02983
02984
02985 dMaxRand = dRand * velArray[i].getMagnitude();
02986 velArray[i] += VecPosition(
02987 (-1 + 2*drand48())*dMaxRand,
02988 (-1 + 2*drand48())*dMaxRand );
02989 posArray[i] += velArray[i];
02990 velArray[i] *= SS->getBallDecay();
02991 }
02992 }
02993
02994
03004 void WorldModel::resampleParticlesBall( VecPosition posArray[],
03005 VecPosition velArray[], int iLength, int iLeft )
03006 {
03007 int iRand ;
03008 for ( int i = iLeft; i < iLength; i ++ )
03009 {
03010 iRand = (int)(drand48()*iLeft);
03011 posArray[ i ] = posArray[ iRand ];
03012 velArray[ i ] = velArray[ iRand ];
03013 }
03014 }
03015
03016 ObjectT WorldModel::getMaxRangeUnknownPlayer( ObjectT obj, char* strMsg )
03017 {
03018 list<ObjectT> l;
03019 ObjectT o;
03020 bool isGoalie, bCont = true;
03021 int i, loop;
03022
03023 ObjectT objMax = (getSide()==SIDE_LEFT) ? OBJECT_OPPONENT_11
03024 : OBJECT_TEAMMATE_11 ;
03025
03026 while( bCont == true )
03027 {
03028 i = Parse::gotoFirstOccurenceOf( '(', &strMsg );
03029 if( i == -1 )
03030 bCont = false;
03031 else
03032 {
03033 strMsg++;
03034 o = SoccerTypes::getObjectFromStr(&strMsg,&isGoalie,getTeamName());
03035 if( SoccerTypes::isPlayer( o ) )
03036 l.push_back( o );
03037 }
03038 }
03039 Log.log( 459, "list size %d", l.size() );
03040 while( ! l.empty() )
03041 {
03042 o = l.back();
03043 l.pop_back();
03044 if( SoccerTypes::isKnownPlayer( o ) )
03045 objMax = o;
03046 else if( SoccerTypes::isOpponent( o ) &&
03047 SoccerTypes::isTeammate( objMax ) )
03048 objMax = OBJECT_OPPONENT_11;
03049 else if( SoccerTypes::isTeammate( o ) &&
03050 SoccerTypes::isOpponent( objMax ) )
03051 objMax = OBJECT_TEAMMATE_11;
03052
03053 if( objMax == getAgentObjectType() )
03054 loop = 2;
03055 else
03056 loop = 1;
03057
03058 for( int j = 0; j < loop; j ++ )
03059 {
03060 i = SoccerTypes::getIndex( objMax );
03061 if( objMax == OBJECT_TEAMMATE_1 )
03062 objMax = OBJECT_OPPONENT_11;
03063 else if( objMax == OBJECT_OPPONENT_1 )
03064 objMax = OBJECT_TEAMMATE_11;
03065 else if( SoccerTypes::isTeammate( objMax ) )
03066 objMax = SoccerTypes::getTeammateObjectFromIndex( i - 1 );
03067 else if( SoccerTypes::isOpponent( objMax ) )
03068 objMax = SoccerTypes::getOpponentObjectFromIndex( i - 1 );
03069 }
03070 Log.log( 459, "processs %d new obj_max: %d", o, objMax );
03071
03072 }
03073
03074 return objMax;
03075 }