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 #ifndef EGRAPH_PLAYER_IF_H
00028 #define EGRAPH_PLAYER_IF_H
00029
00030 #include <libplayerc++/playerc++.h>
00031 #include <vector>
00032 #include <list>
00033 #include <unistd.h>
00034 #include <math.h>
00035 #include <cstdlib>
00036 #include <assert.h>
00037 #include <iostream>
00038 #include <fstream>
00039
00040
00041 #include <R2.h>
00042 #include <Grid.h>
00043 #include <Scan.h>
00044
00045 #include "args.h"
00046 #include "utils.h"
00047
00048 using namespace PlayerCc;
00049 using namespace std;
00050 using namespace boost;
00051 using namespace MipBaselib;
00052
00053 enum BehaviorTypes
00054 {
00055 EXPAND,
00056 GUARD,
00057 FOLLOW,
00058 WANDER,
00059 NO_BEHAVIOR
00060 };
00061
00062 enum KeepColor
00063 {
00064 KEEP_UNKNOWN,
00065 KEEP_ORANGE,
00066 KEEP_PURPLE
00067 };
00068
00069 class PursuitAgent;
00070
00071 typedef uint Identity;
00072 typedef std::vector<Pose > Path;
00073 typedef std::vector<PursuitAgent* > AgentVector;
00074 typedef std::vector<Pose > ViewPoints;
00075
00076 ofstream gLogFile;
00077 Timer gTotalTimer;
00078 int gIterCount;
00079 Grid *gGlobalGrid;
00080 AgentVector gAgentVector;
00081
00082 PlayerClient* gPC;
00083 Graphics2dProxy* gGP = NULL;
00084 MapProxy* gMP = NULL;
00085
00086 int gMapWidth = -1;
00087 int gMapHeight = -1;
00088 double gMapResolution = -1;
00089
00090 int gMinArcSize = 2;
00091 int gMinMergeArcSize = 1;
00092 int gMinRadialArcSize = 3;
00093 double gSafeRangeFrac = 0.92;
00094 double gSafeAngleFrac = 0.92;
00095 double gCoverDistScalar = 1.0;
00096 double gOverlapFactor = 1.08;
00097
00098 Pose adjustViewPoint( Pose initialPose ){
00099
00100
00101
00102
00103
00104
00105
00106 return initialPose;
00107 }
00108
00109 void drawSquare( player_color_t color, Position pos, double border, bool bFill ){
00110 player_point_2d_t square[4], center;
00111
00112 center.px = pos.x();
00113 center.py = pos.y();
00114
00115 square[0].px = center.px - border;
00116 square[0].py = center.py - border;
00117 square[1].px = center.px + border;
00118 square[1].py = center.py - border;
00119 square[2].px = center.px + border;
00120 square[2].py = center.py + border;
00121 square[3].px = center.px - border;
00122 square[3].py = center.py + border;
00123
00124 gGP->Color( color );
00125 gGP->DrawPolygon( square, 4, bFill, color );
00126 }
00127
00128 void drawX( player_color_t color, Position pos, double width ){
00129 player_point_2d_t square[4], center;
00130
00131 center.px = pos.x();
00132 center.py = pos.y();
00133
00134 square[0].px = center.px - width;
00135 square[0].py = center.py - width;
00136 square[2].px = center.px + width;
00137 square[2].py = center.py - width;
00138 square[1].px = center.px + width;
00139 square[1].py = center.py + width;
00140 square[3].px = center.px - width;
00141 square[3].py = center.py + width;
00142
00143 gGP->Color( color );
00144 gGP->DrawPolyline( square, 2 );
00145 gGP->DrawPolyline( &(square[2]), 2 );
00146 }
00147
00148 void drawRedX( Position pos, double width ){
00149 player_color_t color;
00150
00151 color.alpha = 255;
00152 color.red = 255;
00153 color.green = 0;
00154 color.blue = 0;
00155
00156 drawX( color, pos, width);
00157 }
00158
00159
00160 class PursuitAgent{
00161
00162 protected :
00163 Identity m_iID;
00164 PlayerClient* m_pClient;
00165 Position2dProxy* m_pPosProxy;
00166 LaserProxy* m_pLaserProxy;
00167
00168 BehaviorTypes m_eBehavior;
00169 Frontier m_frontier;
00170 Frontier m_freeArcs;
00171 Frontier m_prevFrontier;
00172 Grid m_LSR;
00173 Grid m_prevLSR;
00174 bool m_bFrontierInitialized;
00175 Path m_path;
00176 PursuitAgent* m_pWaitForAgent;
00177 AgentVector m_followers;
00178
00179
00180 void Expand( AgentVector neighbors );
00181 void Guard( AgentVector neighbors );
00182 void processFrontier( AgentVector neighbors );
00183 void Wander( AgentVector neighbors );
00184
00185 void recordLSR();
00186
00187 bool isCellCovered( Pose viewPoint, DubInt iCell, bool bSilent = true );
00188
00189
00190
00191
00192
00193
00194 Pose pickBestViewPoint(int *iNumViewPoints, bool bDebugDisplay = false);
00195
00196
00197
00198 void updateFrontier( AgentVector neighbors, bool bDebugDisplay = false );
00199 void getNeighborFrontiers( AgentVector neighbors, Pose &curPose, vector<Frontier > &ourNeighborFrontiers,
00200 vector<Frontier > &updatedNeighborFrontiers,
00201 vector<DubInt > &neighborObstacleEndpoints,
00202 vector<DubInt > &neighborObstacleBeginpoints );
00203 void classifyOurFrontier( AgentVector neighbors, Pose &curPose, vector<Frontier > &ourNeighborFrontiers,
00204 vector<DubInt > &neighborObstacleEndpoints,
00205 vector<DubInt > &neighborObstacleBeginpoints,
00206 bool bDebugDisplay );
00207 void updateNeighborFrontiers( AgentVector neighbors, Pose &curPose, vector<Frontier > &updatedNeighborFrontiers );
00208 void postProcessOurFrontier( vector<Frontier > &ourNeighborFrontiers, Pose &curPose, bool bDebugDisplay );
00209
00210
00211 public :
00212 PursuitAgent( Identity ID, PlayerClient* client, Position2dProxy* posProxy, LaserProxy* laserProxy );
00213 ~PursuitAgent( );
00214
00215 void clientRead();
00216 Identity getID(){ return m_iID; }
00217 BehaviorTypes getBehavior(){ return m_eBehavior; }
00218 Grid getLSR(){ return ((m_bFrontierInitialized) ? m_LSR : m_prevLSR); }
00219 LRR getLRR(){ return ((m_bFrontierInitialized) ? m_LSR._lrr : m_prevLSR._lrr); }
00220 Frontier getFrontier(){ return ((m_bFrontierInitialized) ? m_frontier : m_prevFrontier); }
00221
00222 int getNumFrontierSegments(){ return ((m_bFrontierInitialized) ? m_frontier.size() : m_prevFrontier.size()); }
00223 int getTotalFrontierCells();
00224 void setFrontier(Frontier frontier, bool bForce = false );
00225 Path getPath(){ return m_path; }
00226 Pose getPose(){ clientRead(); return Pose(m_pPosProxy->GetXPos(), m_pPosProxy->GetYPos(), m_pPosProxy->GetYaw()); }
00227 Position getPosition(){ return getPose().pos(); }
00228 Pose getViewpoint();
00229 Scan getScan();
00230 ExplorationParams getExplParams();
00231
00232 double getSensorRange(){ return m_pLaserProxy->GetMaxRange(); }
00233 double getCoverRange();
00234 double getCoverFieldOfView();
00235 double getWidth(){ return m_pPosProxy->GetSize().sw; }
00236 int getLSRSize(){ return ((m_bFrontierInitialized) ? m_LSR.columns()*m_LSR.rows() : m_prevLSR.columns()*m_prevLSR.rows()); }
00237 vector<Cell* > getRaster( DubInt iCell1, DubInt iCell2 );
00238 double getLSRResolution(){ return ((m_bFrontierInitialized) ? m_LSR.resolution() : m_prevLSR.resolution()); }
00239 Pose getLSRPose();
00240 LSRBound getLSRBound(){ return ((m_bFrontierInitialized) ? m_LSR.lsrBound() : m_prevLSR.lsrBound()); }
00241 Cell* getCell( DubInt indices ){ return ((m_bFrontierInitialized) ? m_LSR.getCell(indices) : m_prevLSR.getCell(indices)); }
00242 Cell* getCell( Position pos ){ return ((m_bFrontierInitialized) ? m_LSR.getCell(pos) : m_prevLSR.getCell(pos)); }
00243 Cell* getCell( int i ){ return ((m_bFrontierInitialized) ? m_LSR.getCell(i) : m_prevLSR.getCell(i)); }
00244 Position getCellPosition( DubInt indices ){ return getCell(indices)->point(); }
00245 int getNumFollowers(){ return m_followers.size(); }
00246 Position getFollowerPosition();
00247
00248
00249 void setToExpand( Path path, bool bClearPrevFrontier, AgentVector neighbors, bool bDoExpand = true );
00250 void setToGuard( AgentVector neighbors );
00251 void setToFollow( AgentVector neighbors );
00252 void setToWander( AgentVector neighbors );
00253 void setToNoBehavior( );
00254
00255 void goTo( Pose pose );
00256 void addFollower( PursuitAgent* newFollower, bool bMove = true );
00257
00258
00259 void doCurrentBehavior( AgentVector neighbors );
00260
00261 bool isLeader();
00262 bool isReady();
00263 bool isWaitingForAnyAgent();
00264 bool isWaitingForAgent(int iID);
00265 void clearWaitingForAgent();
00266 bool isTraveling();
00267
00268 void drawBoundary( Graphics2dProxy &gp );
00269 void drawFrontier( Graphics2dProxy &gp );
00270 void drawLSR( Graphics2dProxy &gp, bool bOnlyLSR );
00271
00272 bool canDetectTargetPosition( Position targetPos );
00273 };
00274
00275
00276 void logData( ){
00277 double time = gTotalTimer.get().dCast();
00278 int iAreaExposed = 0.0;
00279
00280 if( gGlobalGrid != NULL )
00281 {
00282 iAreaExposed = gGlobalGrid->_lsr.size();
00283 }
00284
00285 int iFrontierCount = 0;
00286 int iGuard = 0;
00287 int iExpand = 0;
00288 int iFollow = 0;
00289 int iWander = 0;
00290 for( int i = 0; i < gAgentVector.size(); i++ )
00291 {
00292 switch (gAgentVector[i]->getBehavior())
00293 {
00294 case EXPAND:
00295 iExpand++;
00296 iFrontierCount += gAgentVector[i]->getTotalFrontierCells();
00297 break;
00298 case GUARD:
00299 iGuard++;
00300 iFrontierCount += gAgentVector[i]->getTotalFrontierCells();
00301 break;
00302 case FOLLOW:
00303 iFollow++;
00304 break;
00305 case WANDER:
00306 iWander++;
00307 break;
00308 default:
00309 break;
00310 }
00311 }
00312
00313 gLogFile << gIterCount << ", ";
00314 gLogFile << time << ", ";
00315 gLogFile << iAreaExposed << ", ";
00316 gLogFile << iFrontierCount << ", ";
00317 gLogFile << iExpand << ", ";
00318 gLogFile << iGuard << ", ";
00319 gLogFile << iFollow << ", ";
00320 gLogFile << iWander;
00321
00322 gLogFile << endl;
00323 }
00324
00325 PursuitAgent::PursuitAgent( Identity ID, PlayerClient* client, Position2dProxy* posProxy, LaserProxy* laserProxy ){
00326 m_iID = ID;
00327 m_pClient = client;
00328 m_pPosProxy = posProxy;
00329 m_pLaserProxy = laserProxy;
00330
00331 m_eBehavior = NO_BEHAVIOR;
00332 m_frontier.clear();
00333 m_freeArcs.clear();
00334 m_prevFrontier.clear();
00335 m_LSR = Grid();
00336 m_prevLSR = Grid();
00337 m_bFrontierInitialized = false;
00338 m_path.clear();
00339 m_pWaitForAgent = NULL;
00340 m_followers.clear();
00341
00342
00343 m_pPosProxy->SetMotorEnable(true);
00344 m_pPosProxy->RequestGeom();
00345
00346 while( m_pLaserProxy->GetMaxRange() <= 0.0 || m_pLaserProxy->GetCount() <= 0 )
00347 {
00348
00349 clientRead();
00350 }
00351 }
00352
00353 void PursuitAgent::Expand( AgentVector neighbors ){
00354 if( gDebug > 5 ) cout<< "Agent " << getID() << ": doing EXPAND to " << m_path.back().print() << endl;
00355
00356 if( gDebug > 8 )
00357 {
00358 cout<< " " << getID() << " has followers: ";
00359 for( int i = 0; i < m_followers.size(); i++ )
00360 {
00361 cout<< m_followers[i]->getID() << ", ";
00362 }
00363 cout<< endl;
00364 }
00365
00366 if( isTraveling() )
00367 {
00368 if( gDebug > 5 ) cout<< " " << getID() << ": waiting to reach path pose " << m_path.back().print() << endl;
00369 return;
00370 }
00371
00372 AgentVector::iterator i;
00373 int iCount = 0;
00374 for(i = m_followers.begin(); i != m_followers.end(); i++ )
00375 {
00376 if( getPosition().dist((*i)->getPosition()) > getSensorRange() )
00377 {
00378 if( gDebug > 5 ) cout<< getID() << ": follower " << (*i)->getID() << " still needs to catch up" << endl;
00379 Position followerPosition = getFollowerPosition();
00380 followerPosition *= (Decimal)(iCount+1.0);
00381 (*i)->goTo( Pose(getPosition() - followerPosition, m_path.back().ori()) );
00382 }
00383 iCount++;
00384 }
00385
00386
00387
00388 setToGuard( neighbors );
00389 }
00390
00391 void PursuitAgent::Guard( AgentVector neighbors )
00392 {
00393 if( gDebug > 5 ) cout<< "Agent " << getID() << ": doing GUARD" << endl;
00394 if( gDebug > 8 )
00395 {
00396 cout<< " " << getID() << " has followers: ";
00397 for( int i = 0; i < m_followers.size(); i++ )
00398 {
00399 cout<< m_followers[i]->getID() << ", ";
00400 }
00401 cout<< endl;
00402 }
00403
00404
00405 if( m_bFrontierInitialized && getNumFollowers() > 2 )
00406 {
00407 Position curPos = getLSRPose().pos();
00408 Frontier ourFrontier = m_LSR.frontier();
00409
00410 vector<PursuitAgent* > nearbyLeaders;
00411
00412 for( int i = 0; i < neighbors.size(); i++ )
00413 {
00414 if( neighbors[i]->isLeader() && neighbors[i]->getID() != getID() )
00415 {
00416 if( neighbors[i]->getNumFollowers() < getNumFollowers() / 2 )
00417 {
00418 if( curPos.dist( neighbors[i]->getPosition() ) < 2.0 * getSensorRange() )
00419 {
00420 bool bClose = false;
00421
00422 for( int m = 0; (!bClose && m < ourFrontier.size()); m++ )
00423 {
00424 for( int n = 0; (!bClose && n < ourFrontier[m].size()); n++ )
00425 {
00426 Position cellPos = curPos + m_LSR.getCell(ourFrontier[m][n])->point() - neighbors[i]->getPosition();
00427 Cell* pTheirCell = neighbors[i]->getCell(cellPos);
00428
00429 if( pTheirCell != NULL && pTheirCell->isLSR() )
00430 {
00431 nearbyLeaders.push_back(neighbors[i]);
00432 }
00433 }
00434 }
00435 }
00436 }
00437 }
00438 }
00439
00440 if( nearbyLeaders.size() > 0 )
00441 {
00442 int iFollowersToGive = getNumFollowers() / 2;
00443
00444 while( iFollowersToGive > 0 )
00445 {
00446 for( int i = 0; i < nearbyLeaders.size(); i++ )
00447 {
00448 if( iFollowersToGive > 0 )
00449 {
00450 iFollowersToGive--;
00451
00452 if( gDebug > 2 ) cout<< " " << getID() << " giving " << nearbyLeaders[i]->getID() << " follower " << m_followers.back()->getID() << endl;
00453
00454 nearbyLeaders[i]->addFollower( m_followers.back(), true );
00455 m_followers.pop_back();
00456 }
00457 }
00458 }
00459 }
00460 }
00461 if( m_bFrontierInitialized )
00462 {
00463 Position curPos = getLSRPose().pos();
00464 for( int i = 0; i < m_followers.size(); i++ )
00465 {
00466 Cell* pCell = m_LSR.getCell( m_followers[i]->getPosition() - curPos );
00467
00468 if( pCell == NULL || !(pCell->isLSR()) )
00469 {
00470
00471 m_followers[i]->setToWander( neighbors );
00472 m_followers.erase(m_followers.begin() + i);
00473 i--;
00474 }
00475 }
00476 }
00477
00478
00479 if( isWaitingForAnyAgent() )
00480 {
00481 if( gDebug > 5 ) cout<< " " << getID() << ": is waiting for agent " << m_pWaitForAgent->getID() << endl;
00482 return;
00483 }
00484
00485
00486
00487 updateFrontier( neighbors, (gDebug > 8) );
00488
00489
00490 processFrontier( neighbors );
00491 }
00492
00493 void PursuitAgent::processFrontier( AgentVector neighbors )
00494 {
00495 if( getTotalFrontierCells() < gMinArcSize )
00496 {
00497 if( m_pWaitForAgent != NULL )
00498 {
00499 m_pWaitForAgent->setToWander(neighbors);
00500 }
00501
00502 if( gDebug > 0 ) cout<< getID() << " has only " << getTotalFrontierCells() << " frontier cells, switching to wander" << endl;
00503
00504 m_frontier.clear();
00505 m_prevFrontier.clear();
00506
00507 setToWander(neighbors);
00508 return;
00509 }
00510
00511 int iNumViewPoints;
00512
00513 Pose bestViewPoint = pickBestViewPoint(&iNumViewPoints, (gDebug > 30));
00514
00515 if( bestViewPoint == Pose(0,0,(Angle)0) )
00516 {
00517 if( iNumViewPoints == 1 || m_followers.size() > 0 )
00518 {
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 return;
00530 }
00531 }
00532
00533 bestViewPoint = Pose( bestViewPoint.pos() + getLSRPose().pos(), bestViewPoint.ori() );
00534
00535 bestViewPoint = adjustViewPoint( bestViewPoint );
00536 if( gDebug > 8 ) cout<< " Best view point (" << bestViewPoint.print() << ")" << endl;
00537
00538
00539
00540 Path pathToBestViewPoint;
00541 pathToBestViewPoint.push_back( getPose() );
00542 pathToBestViewPoint.push_back( bestViewPoint );
00543
00544 if( m_pWaitForAgent != NULL )
00545 {
00546
00547
00548 m_pWaitForAgent->setToExpand( pathToBestViewPoint, true, neighbors );
00549 }
00550 else if( iNumViewPoints == 1 )
00551 {
00552 if( gDebug > 8 ) cout<< " Expanding alone" << endl;
00553
00554
00555
00556
00557
00558
00559 if( m_bFrontierInitialized )
00560 {
00561 m_prevFrontier = m_frontier;
00562 m_prevLSR = m_LSR;
00563 }
00564
00565 setToExpand( pathToBestViewPoint, false, neighbors );
00566
00567
00568 }
00569 else
00570 {
00571 if( m_followers.size() > 0 )
00572 {
00573 if( gDebug > 8 ) cout<< " Sending follower " << m_followers.back()->getID() << endl;
00574
00575
00576
00577 PursuitAgent* pExpander = m_followers.front();
00578 m_pWaitForAgent = pExpander;
00579 pExpander->setToExpand( pathToBestViewPoint, true, neighbors );
00580 m_followers.erase(m_followers.begin());
00581
00582 int iMaxNumFollowersToGive = std::min( m_followers.size(), (m_followers.size() + 1)/(iNumViewPoints) );
00583
00584 if( gDebug > 8 ) cout<< " Giving follower " << iMaxNumFollowersToGive << " followers out of " << m_followers.size() << endl;
00585 for( int i = 0; i < iMaxNumFollowersToGive; i++ )
00586 {
00587 pExpander->addFollower( m_followers.back() );
00588 m_followers.pop_back();
00589 }
00590 }
00591 else
00592 {
00593
00594 }
00595
00596
00597 }
00598 }
00599
00600 void PursuitAgent::Wander( AgentVector neighbors )
00601 {
00602 if( gDebug > 5 ) cout<< "Agent " << getID() << " doing WANDER" << endl;
00603 AgentVector leaders;
00604 vector<Pose > leaderPaths;
00605 AgentVector allLeaders;
00606 AgentVector wanderers;
00607
00608 recordLSR();
00609 Frontier ourFrontier = m_LSR.frontier();
00610
00611 Position curPos = getPosition();
00612
00613
00614 for( int i = 0; i < neighbors.size(); i++ )
00615 {
00616 if( neighbors[i]->isLeader() && neighbors[i]->getID() != getID() )
00617 {
00618 allLeaders.push_back(neighbors[i]);
00619
00620 if( curPos.dist( neighbors[i]->getPosition() ) < 2.0*getSensorRange() )
00621 {
00622 bool bClose = false;
00623
00624 for( int m = 0; (!bClose && m < ourFrontier.size()); m++ )
00625 {
00626 for( int n = 0; (!bClose && n < ourFrontier[m].size()); n++ )
00627 {
00628 Position cellPos = curPos + m_LSR.getCell(ourFrontier[m][n])->point() - neighbors[i]->getLSRPose().pos();
00629 Cell* pTheirCell = neighbors[i]->getCell(cellPos);
00630
00631 if( pTheirCell != NULL && pTheirCell->isLSR() )
00632 {
00633 if( gDebug > 8 )
00634 {
00635 drawSquare( gColorBlue, curPos + m_LSR.getCell(ourFrontier[m][n])->point(), 0.05, false );
00636 usleep( 300000 );
00637 }
00638 leaders.push_back(neighbors[i]);
00639 leaderPaths.push_back( Pose(curPos + m_LSR.getCell(ourFrontier[m][n])->point(), Angle(M_PI) + pTheirCell->point().bearing()));
00640 bClose = true;
00641 }
00642 }
00643 }
00644 }
00645 }
00646 else if( neighbors[i]->getBehavior() == WANDER )
00647 {
00648 if( neighbors[i]->getID() != getID() )
00649 {
00650 if( curPos.dist( neighbors[i]->getPosition() ) < getSensorRange() )
00651 {
00652 Cell* pCell = m_LSR.getCell(neighbors[i]->getPosition() - curPos);
00653 if( pCell != NULL && pCell->isLSR() )
00654 {
00655 wanderers.push_back(neighbors[i]);
00656 }
00657 }
00658 }
00659 }
00660 }
00661
00662
00663 if( leaders.size() > 0 )
00664 {
00665 int iNewLeader = -1;
00666 int iMinFollowers = 10;
00667
00668 for( int i = 0; i < leaders.size(); i++ )
00669 {
00670 int iFollowers = leaders[i]->getNumFollowers() + (leaders[i]->isWaitingForAnyAgent() ? 1 : 0);
00671
00672 if( (iFollowers < iMinFollowers) ||
00673 ((iNewLeader >= 0) && (iFollowers == iMinFollowers) && (getPosition().dist(leaders[i]->getPosition()) < getPosition().dist(leaders[iNewLeader]->getPosition()))) )
00674 {
00675 iNewLeader = i;
00676 iMinFollowers = iFollowers;
00677 }
00678 }
00679
00680 if( iNewLeader >= 0 )
00681 {
00682 Cell* pOurCell = m_LSR.getCell( leaders[iNewLeader]->getPosition() - curPos );
00683 Cell* pTheirCell = leaders[iNewLeader]->getCell( curPos - leaders[iNewLeader]->getPosition() );
00684 if( (pOurCell != NULL && pOurCell->isLSR()) || (pTheirCell != NULL && pTheirCell->isLSR()) )
00685 {
00686 for( int j = 0; j < m_followers.size(); j++ )
00687 {
00688 m_followers[j]->setToFollow(neighbors);
00689 leaders[iNewLeader]->addFollower(m_followers[j]);
00690 }
00691
00692 m_followers.clear();
00693
00694 setToFollow(neighbors);
00695 leaders[iNewLeader]->addFollower(this);
00696 return;
00697 }
00698 else
00699 {
00700
00701 if( m_path.size() > 0 && curPos.dist(m_path.back().pos()) > getWidth() )
00702 {
00703 Cell* pTheirCell = leaders[iNewLeader]->getCell( m_path.back().pos() - leaders[iNewLeader]->getLSRPose().pos());
00704 if( pTheirCell != NULL && pTheirCell->isLSR() )
00705 {
00706 goTo( m_path.back() );
00707 return;
00708 }
00709 }
00710
00711 goTo( leaderPaths[iNewLeader] );
00712 return;
00713 }
00714 }
00715 }
00716
00717 if( gDebug > 5 ) cout<< " " << getID() << " no leader to follow" << endl;
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 Frontier frontier = m_LSR.frontier();
00737
00738 if( m_path.size() > 0 )
00739 {
00740 if( curPos.dist( m_path.back().pos() ) > 1.5*getWidth() )
00741 {
00742 if( pickIndexInRange(0,20) != 0 )
00743 {
00744
00745 return;
00746 }
00747 }
00748 }
00749
00750
00751 if( frontier.size() > 0 )
00752 {
00753 Position bestRandPos = curPos;
00754 double bestRandPosValue = -1000.0;
00755
00756 int iFrontierCells = 0;
00757 for( int i = 0; i < frontier.size(); i++ )
00758 {
00759 iFrontierCells += frontier[i].size();
00760 }
00761
00762 for( int i = 0; i < 10; i++ )
00763 {
00764 int iRand = pickIndexInRange( 0, iFrontierCells );
00765 Position randPos = curPos;
00766
00767 for( int j = 0; j < frontier.size(); j++ )
00768 {
00769 if( iRand < frontier[j].size() )
00770 {
00771 randPos += m_LSR.getCell(frontier[j][iRand])->point();
00772 break;
00773 }
00774 else
00775 {
00776 iRand -= frontier[j].size();
00777 }
00778 }
00779
00780 double randPosValue = 10.0*(pickIndexInRange(0, 100))/100.0;
00781
00782 double distDiv = 6.0 * m_pLaserProxy->GetMaxRange();
00783 double closestDistance = distDiv;
00784 for( int j = 0; j < allLeaders.size(); j++ )
00785 {
00786 closestDistance = std::min( closestDistance, randPos.dist( allLeaders[j]->getPosition() ) );
00787 }
00788
00789 randPosValue += 5.0*(distDiv - closestDistance)/distDiv;
00790
00791 randPosValue += 5.0*(M_PI - fabs((randPos - curPos).bearing().alDiff(m_pPosProxy->GetYaw())))/(M_PI);
00792
00793 if( randPosValue > bestRandPosValue )
00794 {
00795 bestRandPos = randPos;
00796 bestRandPosValue = randPosValue;
00797 }
00798 }
00799
00800 Position bestGoToPos = curPos;
00801 double bestGoToDist = curPos.dist( bestRandPos );
00802
00803 for( int i = 0; i < m_LSR._lrr.size(); i++ )
00804 {
00805 Position testPos = curPos + m_LSR.getCell(m_LSR._lrr[i])->point();
00806 double dist = bestRandPos.dist( testPos );
00807 if( dist < bestGoToDist )
00808 {
00809 bestGoToDist = dist;
00810 bestGoToPos = testPos;
00811 }
00812 }
00813
00814 if( gDebug > 8 )
00815 {
00816 drawRedX( bestRandPos, 0.05 );
00817 drawX( gColorGreen, bestGoToPos, 0.05 );
00818 usleep( 100000 );
00819 }
00820
00821 m_path.clear();
00822
00823 m_path.push_back( getPose() );
00824 Position relPos = bestGoToPos - curPos;
00825 m_path.push_back( Pose(bestGoToPos, relPos.bearing()) );
00826
00827 goTo( m_path.back() );
00828 }
00829 }
00830
00831 void PursuitAgent::clientRead()
00832 {
00833
00834 {
00835 m_pClient->ReadIfWaiting();
00836 }
00837 }
00838
00839
00840 void PursuitAgent::getNeighborFrontiers( AgentVector neighbors, Pose &curPose, vector<Frontier > &ourNeighborFrontiers,
00841 vector<Frontier > &updatedNeighborFrontiers,
00842 vector<DubInt > &neighborObstacleEndpoints,
00843 vector<DubInt > &neighborObstacleBeginpoints )
00844 {
00845 player_color_t color;
00846
00848
00849
00850
00852 if( m_prevFrontier.size() > 0 )
00853 {
00854 if( gDebug > 7 ) cout<< " " << getID() << " has " << m_prevFrontier.size() << " prev frontier(s)" << endl;
00855 Pose neighborPose = m_prevLSR.center();
00856 Frontier ourNeighborFrontier;
00857
00858 for( int j = 0; j < m_prevFrontier.size(); j++ )
00859 {
00860 FrontierArc neighborArc = m_prevFrontier[j];
00861 FrontierArc translatedArc;
00862 Cell* pTranslatedCell;
00863
00864 Position translatedPos;
00865
00866 if( m_prevLSR.getCell(neighborArc[0])->isLabelA() )
00867 {
00868 Position arcCellPos = m_prevLSR.getCell(neighborArc[0])->point();
00869 Position globalPos = neighborPose.pos() + arcCellPos;
00870 translatedPos = neighborPose.pos() - curPose.pos() + arcCellPos;
00871
00872 pTranslatedCell = m_LSR.getCell( translatedPos );
00873
00874 if( pTranslatedCell != NULL )
00875 {
00876 neighborObstacleBeginpoints.push_back(pTranslatedCell->indexes());
00877
00878 if( gDebug > 9 ) cout<< " prev obstacle beginpoint at " << neighborObstacleBeginpoints.back().print() << endl;
00879 }
00880 }
00881
00882 if( m_prevLSR.getCell(neighborArc[neighborArc.size()-1])->isLabelB() )
00883 {
00884 if( !(m_prevLSR.getCell(neighborArc[neighborArc.size()-1])->isLabelA()) )
00885 {
00886 Position arcCellPos = m_prevLSR.getCell(neighborArc[neighborArc.size()-1])->point();
00887 Position globalPos = neighborPose.pos() + arcCellPos;
00888 translatedPos = neighborPose.pos() - curPose.pos() + arcCellPos;
00889
00890 pTranslatedCell = m_LSR.getCell( translatedPos );
00891
00892 if( pTranslatedCell != NULL )
00893 {
00894 neighborObstacleEndpoints.push_back(pTranslatedCell->indexes());
00895
00896 if( gDebug > 9 ) cout<< " prev obstacle endpoint at " << neighborObstacleEndpoints.back().print() << endl;
00897 }
00898 }
00899 }
00900
00901
00902
00903 for( int k = 0; k < neighborArc.size(); k++ )
00904 {
00905 Position arcCellPos = m_prevLSR.getCell(neighborArc[k])->point();
00906 Position globalPos = neighborPose.pos() + arcCellPos;
00907 translatedPos = neighborPose.pos() - curPose.pos() + arcCellPos;
00908
00909 pTranslatedCell = m_LSR.getCell( translatedPos );
00910
00911
00912
00913
00914
00915
00916 if( pTranslatedCell == NULL )
00917 {
00918
00919 if( translatedArc.size() >= 0 )
00920 {
00921
00922 ourNeighborFrontier.push_back(translatedArc);
00923 translatedArc = FrontierArc();
00924 }
00925
00926 color.alpha = 0;
00927 color.red = 255;
00928 color.green = 0;
00929 color.blue = 255;
00930 }
00931 else
00932 {
00933
00934 if( (!(pTranslatedCell->isLSR()) || pTranslatedCell->isFrontier()) && !(pTranslatedCell->isObstacle()) )
00935 {
00936
00937 color.alpha = 0;
00938 color.red = 0;
00939 color.green = 0;
00940 color.blue = 255;
00941 }
00942 else
00943 {
00944 color.alpha = 0;
00945 color.red = 255;
00946 color.green = 0;
00947 color.blue = 0;
00948 }
00949
00950 translatedArc.push_back( pTranslatedCell->indexes() );
00951 }
00952
00953
00954 }
00955
00956 if( translatedArc.size() >= 0 )
00957 {
00958 ourNeighborFrontier.push_back(translatedArc);
00959 }
00960 }
00961
00962 if( ourNeighborFrontier.size() > 0 )
00963 {
00964 ourNeighborFrontiers.push_back(ourNeighborFrontier);
00965 }
00966 }
00967
00968
00970
00972 for( int i = 0; i < neighbors.size(); i++ ){
00973 updatedNeighborFrontiers.push_back( Frontier() );
00974
00975 if( neighbors[i]->isLeader() && (neighbors[i]->getID() != getID()) )
00976 {
00977 Pose neighborPose = neighbors[i]->getLSRPose();
00978
00979 if( neighborPose.pos().dist(curPose.pos()) > gOverlapFactor*(getSensorRange() + neighbors[i]->getSensorRange()) )
00980 {
00981 if( gDebug > 7 ) cout<< " " << getID() << " ignoring distant agent " << neighbors[i]->getID() << endl;
00982 continue;
00983 }
00984
00985 if( gDebug > 7 ) cout<< " " << getID() << " updating agent " << neighbors[i]->getID() << " frontiers" << endl;
00986
00987
00988
00989 Frontier neighborFrontier = neighbors[i]->getFrontier();
00990
00991 Frontier updatedNeighborFrontier;
00992 Frontier ourNeighborFrontier;
00993
00994 for( int j = 0; j < neighborFrontier.size(); j++ )
00995 {
00996 FrontierArc neighborArc = neighborFrontier[j];
00997 FrontierArc updatedNeighborArc;
00998
00999
01000
01001
01002 FrontierArc translatedArc;
01003 Cell* pTranslatedCell;
01004
01005 Position translatedPos;
01006
01007 if( neighbors[i]->getCell(neighborArc[0])->isLabelA() )
01008 {
01009 Position arcCellPos = neighbors[i]->getCellPosition(neighborArc[0]);
01010 Position globalPos = neighborPose.pos() + arcCellPos;
01011 translatedPos = neighborPose.pos() - curPose.pos() + arcCellPos;
01012
01013 pTranslatedCell = m_LSR.getCell( translatedPos );
01014
01015 if( pTranslatedCell != NULL )
01016 {
01017 neighborObstacleBeginpoints.push_back(pTranslatedCell->indexes());
01018
01019 if( gDebug > 9 ) cout<< " neighbor obstacle beginpoint at " << neighborObstacleBeginpoints.back().print() << endl;
01020 }
01021 }
01022
01023 if( neighbors[i]->getCell(neighborArc[neighborArc.size()-1])->isLabelB() )
01024 {
01025 if( !(neighbors[i]->getCell(neighborArc[neighborArc.size()-1])->isLabelA()) )
01026 {
01027 Position arcCellPos = neighbors[i]->getCellPosition(neighborArc[neighborArc.size()-1]);
01028 Position globalPos = neighborPose.pos() + arcCellPos;
01029 translatedPos = neighborPose.pos() - curPose.pos() + arcCellPos;
01030
01031 pTranslatedCell = m_LSR.getCell( translatedPos );
01032
01033 if( pTranslatedCell != NULL )
01034 {
01035 neighborObstacleEndpoints.push_back(pTranslatedCell->indexes());
01036
01037 if( gDebug > 9 ) cout<< " neighbor obstacle endpoint at " << neighborObstacleEndpoints.back().print() << endl;
01038 }
01039 }
01040 }
01041
01042 if( gDebug > 7 ) cout<< " " << neighbors[i]->getID() << " had arc of size " << neighborArc.size() << endl;
01043
01044 bool bPrevErased = false;
01045 for( int k = 0; k < neighborArc.size(); k++ )
01046 {
01047 Position arcCellPos = neighbors[i]->getCellPosition(neighborArc[k]);
01048 Position globalPos = neighborPose.pos() + arcCellPos;
01049 translatedPos = neighborPose.pos() - curPose.pos() + arcCellPos;
01050
01051 pTranslatedCell = m_LSR.getCell( translatedPos );
01052
01053
01054
01055
01056
01057
01058 if( pTranslatedCell == NULL )
01059 {
01060
01061
01062
01063 updatedNeighborArc.push_back(neighborArc[k]);
01064
01065 if( translatedArc.size() > 0 )
01066 {
01067
01068 ourNeighborFrontier.push_back(translatedArc);
01069 translatedArc = FrontierArc();
01070 }
01071
01072 color.alpha = 0;
01073 color.red = 255;
01074 color.green = 0;
01075 color.blue = 255;
01076 }
01077 else
01078 {
01079 bool bErase = false;
01080
01081 if( pTranslatedCell->isObstacle() )
01082 {
01083 bErase = true;
01084 }
01085 else if( pTranslatedCell->isFrontier() )
01086 {
01087 bErase = true;
01088 }
01089 else if( pTranslatedCell->isLSR() )
01090 {
01091 bErase = true;
01092 }
01093 else
01094 {
01095
01096
01097 bErase = false;
01098
01099 vector<Cell* > surroundingCells = pTranslatedCell->neighbours();
01100
01101 int iObstacle = 0;
01102 for( int l = 0; l < surroundingCells.size(); l++ )
01103 {
01104 if( surroundingCells[l]->isObstacle() )
01105 {
01106
01107
01108
01109 iObstacle++;
01110
01111 if( iObstacle > 2 )
01112 {
01113 bErase = true;
01114 }
01115 }
01116 else if( surroundingCells[l]->isLSR() )
01117 {
01118 bErase = false;
01119 break;
01120 }
01121 }
01122
01123 if( iObstacle > 0 ) cout<< iObstacle << " out of " << surroundingCells.size() << endl;
01124 }
01125
01126 if( bErase && !bPrevErased && k == neighborArc.size()-1 )
01127 {
01128 if( neighbors[i]->getCell(neighborArc[k])->isLabelB() )
01129 {
01130
01131 bErase = false;
01132 }
01133 }
01134
01135
01136 if( !bErase )
01137 {
01138 if( k == 1 && bPrevErased )
01139 {
01140 if( neighbors[i]->getCell(neighborArc[0])->isLabelA() )
01141 {
01142
01143 updatedNeighborArc.push_back(neighborArc[0]);
01144 }
01145 }
01146 updatedNeighborArc.push_back(neighborArc[k]);
01147
01148 color.alpha = 0;
01149 color.red = 0;
01150 color.green = 0;
01151 color.blue = 255;
01152 }
01153 else
01154 {
01155 if( updatedNeighborArc.size() > 0 )
01156 {
01157 if( updatedNeighborArc.size() >= gMinMergeArcSize )
01158 {
01159 if( gDebug > 7 ) cout<< " adding neighbor arc of size " << (updatedNeighborArc.size()) << endl;
01160 updatedNeighborFrontier.push_back(updatedNeighborArc);
01161 }
01162 else
01163 {
01164 if( gDebug > 7 ) cout<< " clearing temp neighbor arc of size " << (updatedNeighborArc.size()) << endl;
01165 updatedNeighborFrontier.push_back(updatedNeighborArc);
01166 }
01167
01168 updatedNeighborArc = FrontierArc();
01169 }
01170
01171 color.alpha = 0;
01172 color.red = 255;
01173 color.green = 0;
01174 color.blue = 0;
01175 }
01176
01177
01178 translatedArc.push_back( pTranslatedCell->indexes() );
01179
01180 bPrevErased = bErase;
01181 }
01182
01183
01184
01185 }
01186
01187 if( updatedNeighborArc.size() >= gMinMergeArcSize )
01188 {
01189 if( gDebug > 7 ) cout<< " replacing neighbor arc with one of size " << updatedNeighborArc.size() << endl;
01190 updatedNeighborFrontier.push_back(updatedNeighborArc);
01191 }
01192 else
01193 {
01194 if( gDebug > 7 ) cout<< " clearing temp neighbor arc (end) of size " << (updatedNeighborArc.size()) << endl;
01195 }
01196
01197 if( translatedArc.size() > 0 )
01198 {
01199 ourNeighborFrontier.push_back(translatedArc);
01200 }
01201 }
01202
01203 updatedNeighborFrontiers[i] = updatedNeighborFrontier;
01204
01205 if( ourNeighborFrontier.size() > 0 )
01206 {
01207 ourNeighborFrontiers.push_back(ourNeighborFrontier);
01208 }
01209
01210 }
01211 }
01212
01213 }
01214
01215
01216 void PursuitAgent::classifyOurFrontier( AgentVector neighbors, Pose &curPose, vector<Frontier > &ourNeighborFrontiers,
01217 vector<DubInt > &neighborObstacleEndpoints,
01218 vector<DubInt > &neighborObstacleBeginpoints,
01219 bool bDebugDisplay )
01220 {
01221 player_color_t color;
01222
01224
01226 Frontier orangeFrontier;
01227 Frontier purpleFrontier;
01228 FrontierArc tempFrontierArc;
01229 FrontierArc tempFreeArc;
01230 bool bOrange = true;
01231 KeepColor keepColor = KEEP_UNKNOWN;
01232
01233 LSRBound lsrBound = m_LSR.lsrBound();
01234
01235
01236
01237 int iOffset = 0;
01238 for( int l = 0; l < lsrBound.size(); l++ )
01239 {
01240 int iIndex = (l + iOffset)%lsrBound.size();
01241 DubInt iBoundCell = lsrBound[iIndex];
01242 Cell* pBoundCell = m_LSR.getCell(iBoundCell);
01243
01244 if( pBoundCell->isObstacle() &&
01245 m_LSR.getCell(lsrBound[(l + 1 + iOffset)%lsrBound.size()])->isObstacle() &&
01246 m_LSR.getCell(lsrBound[(l - 1 + iOffset)%lsrBound.size()])->isObstacle() )
01247 {
01248 iOffset = l;
01249 break;
01250 }
01251 }
01252
01253
01254
01255
01256 int iCurArc = -1;
01257 for( int l = 0; l < lsrBound.size(); l++ )
01258 {
01259 int iIndex = (l + iOffset)%lsrBound.size();
01260 DubInt iBoundCell = lsrBound[iIndex];
01261 Cell* pBoundCell = m_LSR.getCell(iBoundCell);
01262 Position globalPos = curPose.pos() + pBoundCell->point();
01263 int iThisArc = -1;
01264
01265
01266 bool bFrontierCell = false;
01267 for( int i = 0; (i < m_frontier.size() && !bFrontierCell); i++ )
01268 {
01269 FrontierArc arc = m_frontier[i];
01270 for( int j = 0; (j < arc.size() && !bFrontierCell); j++ )
01271 {
01272 if( iBoundCell == arc[j] )
01273 {
01274 bFrontierCell = true;
01275 iThisArc = i;
01276 break;
01277 }
01278 }
01279 }
01280
01281
01282 bool bBreakArc = false;
01283
01284
01285
01286
01287 if( !bFrontierCell || (bBreakArc) )
01288 {
01289 if( tempFreeArc.size() > 0 )
01290 {
01291 m_freeArcs.push_back(tempFreeArc);
01292 tempFreeArc = FrontierArc();
01293 }
01294 }
01295
01296 if( bFrontierCell )
01297 {
01298 if( tempFreeArc.size() > 0 && tempFreeArc[tempFreeArc.size()-1] == iBoundCell )
01299 {
01300 cerr<< "***Warning***: Free arc: Repeated cell in boundary at " << iBoundCell.print() << ". Ignoring repeat." << endl;
01301 cerr<< " Cell num " << iIndex << " out of " << lsrBound.size() << endl;
01302 }
01303 else
01304 {
01305 tempFreeArc.push_back(iBoundCell);
01306 }
01307 }
01308
01309 if( !bFrontierCell || bBreakArc )
01310 {
01311 if( tempFrontierArc.size() > 0 )
01312 {
01313 if( tempFrontierArc.size() >= gMinMergeArcSize )
01314 {
01315 if( bOrange )
01316 {
01317 if( gDebug > 8 ) cout<< "Pushing temp arc with " << tempFrontierArc.size() << " cells to orange" << endl;
01318 orangeFrontier.push_back(tempFrontierArc);
01319 }
01320 else
01321 {
01322 if( gDebug > 8 ) cout<< "Pushing temp arc with " << tempFrontierArc.size() << " cells to purple" << endl;
01323 purpleFrontier.push_back(tempFrontierArc);
01324 }
01325 }
01326
01327 if( gDebug > 8 ) cout<< "Clearing temp arc with " << tempFrontierArc.size() << " cells" << endl;
01328 tempFrontierArc = FrontierArc();
01329 }
01330 }
01331
01332
01333 if( bFrontierCell )
01334 {
01335
01336 if( tempFrontierArc.size() > 0 && tempFrontierArc[tempFrontierArc.size()-1] == iBoundCell )
01337 {
01338 cerr<< "***Warning***: Frontier Arc: Repeated cell in boundary at " << iBoundCell.print() << ". Ignoring repeat." << endl;
01339 cerr<< " Cell num " << iIndex << " out of " << lsrBound.size() << endl;
01340 }
01341 else
01342 {
01343
01344 tempFrontierArc.push_back(iBoundCell);
01345 }
01346 }
01347
01348 if( iThisArc >= 0 )
01349 {
01350 iCurArc = iThisArc;
01351 }
01352
01353 if( bDebugDisplay )
01354 {
01355 if( bOrange )
01356 {
01357 color.alpha = 0;
01358 color.red = 255;
01359 color.green = 255;
01360 color.blue = 0;
01361
01362 if( pBoundCell->isFrontier() )
01363 {
01364 color.green = 125;
01365 }
01366 }
01367 else
01368 {
01369 color.alpha = 0;
01370 color.red = 255;
01371 color.green = 0;
01372 color.blue = 255;
01373
01374 if( pBoundCell->isFrontier() )
01375 {
01376 color.red = 150;
01377 }
01378 }
01379
01380 drawSquare( color, globalPos, 0.01, true );
01381 }
01382
01383
01384
01385
01386 for( int i = 0; i < ourNeighborFrontiers.size(); i++ )
01387 {
01388 for( int j = 0; j < ourNeighborFrontiers[i].size(); j++ )
01389 {
01390 FrontierArc ourNeighborArc = ourNeighborFrontiers[i][j];
01391
01392 for( int k = 0; k < ourNeighborArc.size(); k++ )
01393 {
01394 bool bChangeIntToExt = false;
01395 bool bChangeExtToInt = false;
01396
01397 bool bObsEndpoint = false;
01398 bool bObsBeginpoint = false;
01399
01400 if( (k == 0) )
01401 {
01402 for( int l = 0; l < neighborObstacleBeginpoints.size(); l++ )
01403 {
01404 if( ourNeighborArc[k] == neighborObstacleBeginpoints[l] )
01405 {
01406 bObsBeginpoint = true;
01407 break;
01408 }
01409 }
01410 }
01411
01412 if( (k == (ourNeighborArc.size() - 1)) )
01413 {
01414 for( int l = 0; l < neighborObstacleEndpoints.size(); l++ )
01415 {
01416 if( ourNeighborArc[k] == neighborObstacleEndpoints[l] )
01417 {
01418 bObsEndpoint = true;
01419 break;
01420 }
01421 }
01422 }
01423
01424 int iPrevLSRFlag = 0;
01425 int iNextLSRFlag = 0;
01426
01427 bool bObsPoint = (bObsBeginpoint && !bObsEndpoint) || (!bObsBeginpoint && bObsEndpoint);
01428
01429 if(bObsPoint || iBoundCell == ourNeighborArc[k])
01430 {
01431
01432
01433
01434
01435
01436
01437 if( k >= 1 )
01438 {
01439 Cell* pPrevArcCell = m_LSR.getCell(ourNeighborArc[k-1]);
01440 if( !(pPrevArcCell->isBoundary()) )
01441 {
01442 if( pPrevArcCell->isLSR() )
01443 {
01444 iPrevLSRFlag = 1;
01445 for( int m = 2; m <= k && m <= gMinMergeArcSize; m++ )
01446 {
01447 pPrevArcCell = m_LSR.getCell(ourNeighborArc[k-m]);
01448 if( (pPrevArcCell->isBoundary()) || !(pPrevArcCell->isLSR()) )
01449 {
01450 iPrevLSRFlag = 0;
01451 break;
01452 }
01453 }
01454 }
01455 else
01456 {
01457 iPrevLSRFlag = -1;
01458 for( int m = 2; m <= k && m <= gMinMergeArcSize; m++ )
01459 {
01460 pPrevArcCell = m_LSR.getCell(ourNeighborArc[k-m]);
01461 if( (pPrevArcCell->isBoundary()) || (pPrevArcCell->isLSR()) )
01462 {
01463 iPrevLSRFlag = 0;
01464 break;
01465 }
01466 }
01467 }
01468 }
01469 }
01470
01471 if( k <= (ourNeighborArc.size() - 2) )
01472 {
01473 Cell* pNextArcCell = m_LSR.getCell(ourNeighborArc[k+1]);
01474 if( !(pNextArcCell->isBoundary()) )
01475 {
01476 if( pNextArcCell->isLSR() )
01477 {
01478 iNextLSRFlag = 1;
01479 for( int m = 2; m <= (ourNeighborArc.size() - 1 - k) && m <= gMinMergeArcSize; m++ )
01480 {
01481 pNextArcCell = m_LSR.getCell(ourNeighborArc[k+m]);
01482 if( (pNextArcCell->isBoundary()) || !(pNextArcCell->isLSR()) )
01483 {
01484 iNextLSRFlag = 0;
01485 break;
01486 }
01487 }
01488 }
01489 else
01490 {
01491 iNextLSRFlag = -1;
01492 for( int m = 2; m <= (ourNeighborArc.size() - 1 - k) && m <= gMinMergeArcSize; m++ )
01493 {
01494 pNextArcCell = m_LSR.getCell(ourNeighborArc[k+m]);
01495 if( (pNextArcCell->isBoundary()) || (pNextArcCell->isLSR()) )
01496 {
01497 iNextLSRFlag = 0;
01498 break;
01499 }
01500 }
01501 }
01502 }
01503 }
01504 }
01505
01506
01507 if(iBoundCell == ourNeighborArc[k])
01508 {
01509 if( bObsPoint && bObsBeginpoint && iNextLSRFlag != -1)
01510 {
01511 pBoundCell->setIsLabelA();
01512 bChangeIntToExt = true;
01513 if( gDebug > 1 ) cout<< " Int to Ext, based on match with obs begin point" << endl;
01514 }
01515 else if( bObsPoint && bObsEndpoint && iPrevLSRFlag != -1)
01516 {
01517 pBoundCell->setIsLabelB();
01518 bChangeExtToInt = true;
01519 if( gDebug > 1) cout<< " Ext to Int, based on match with obst end point" << endl;
01520 }
01521 else if( !bObsPoint )
01522 {
01523
01524 if( iPrevLSRFlag == -1 && iNextLSRFlag == 1 )
01525 {
01526 bChangeIntToExt = true;
01527 if( gDebug > 1 ) cout<< " Int to Ext, based on intersect crossing 1" << endl;
01528 }
01529 else if( iPrevLSRFlag == 1 && iNextLSRFlag == -1 )
01530 {
01531 bChangeExtToInt = true;
01532 if( gDebug > 1 ) cout<< " Ext to Int, based on intersect crossing 2" << endl;
01533 }
01534
01535 else if( iPrevLSRFlag == 1 && iNextLSRFlag == 1 )
01536 {
01537
01538 }
01539 else if( iPrevLSRFlag == -1 && iNextLSRFlag == -1 )
01540 {
01541
01542 }
01543
01544 else if( iPrevLSRFlag == 1 && iNextLSRFlag == 0 )
01545 {
01546
01547 }
01548 else if( iPrevLSRFlag == -1 && iNextLSRFlag == 0 )
01549 {
01550 bChangeIntToExt = true;
01551 if( gDebug > 1 ) cout<< " Int to Ext, based on intersect join 2" << endl;
01552 }
01553 else if( iPrevLSRFlag == 0 && iNextLSRFlag == 1 )
01554 {
01555
01556 }
01557 else if( iPrevLSRFlag == 0 && iNextLSRFlag == -1 )
01558 {
01559 bChangeExtToInt = true;
01560 if( gDebug > 1 ) cout<< " Ext to Int, based on intersect join 4" << endl;
01561 }
01562 }
01563 }
01564 else
01565 {
01566
01567 vector<Cell* > cellNeighbors = m_LSR.getCell(iBoundCell)->neighbours();
01568
01569 for( int n = 0; n < cellNeighbors.size(); n++ )
01570 {
01571
01572 if(cellNeighbors[n]->indexes() == ourNeighborArc[k])
01573 {
01574 if( bObsPoint && bObsBeginpoint && (iNextLSRFlag == 1 || (cellNeighbors[n]->isLSR() && !cellNeighbors[n]->isBoundary())) )
01575 {
01576 bChangeIntToExt = true;
01577 if( gDebug > 1 ) cout<< " Int to Ext, based on first arc cell next to obstacle" << endl;
01578 break;
01579 }
01580 else if( bObsPoint && bObsEndpoint && (iPrevLSRFlag == 1 || (cellNeighbors[n]->isLSR() && !cellNeighbors[n]->isBoundary())) )
01581 {
01582 bChangeExtToInt = true;
01583 if( gDebug > 1) cout<< " Ext to Int, based on last arc cell next to obstacle" << endl;
01584 break;
01585 }
01586 }
01587 }
01588
01589 if( !(bChangeExtToInt || bChangeIntToExt) )
01590 {
01591
01592 bool bCross = false;
01593 if( k < (ourNeighborArc.size() - 1) )
01594 {
01595 int iNextIndex = (l + iOffset + 1)%lsrBound.size();
01596 DubInt iNextBoundCell = lsrBound[iNextIndex];
01597
01598 if( iNextBoundCell.i() != iBoundCell.i() && iNextBoundCell.j() != iBoundCell.j() )
01599 {
01600 if( iBoundCell.i() == ourNeighborArc[k].i() && iNextBoundCell.j() == ourNeighborArc[k].j() )
01601 {
01602 if( iBoundCell.j() == ourNeighborArc[k+1].j() && iNextBoundCell.i() == ourNeighborArc[k+1].i() )
01603 {
01604 bChangeExtToInt = true;
01605 if( gDebug > 1 ) cout<< " Ext to Int, based on crossing" << endl;
01606 }
01607 }
01608 else if( iBoundCell.i() == ourNeighborArc[k+1].i() && iNextBoundCell.j() == ourNeighborArc[k+1].j() )
01609 {
01610 if( iBoundCell.j() == ourNeighborArc[k].j() && iNextBoundCell.i() == ourNeighborArc[k].i() )
01611 {
01612 bChangeIntToExt = true;
01613 if( gDebug > 1 ) cout<< " Int to Ext, based on crossing" << endl;
01614 }
01615 }
01616 }
01617 }
01618 }
01619 }
01620
01621 if(bChangeIntToExt || bChangeExtToInt)
01622 {
01623 if( gDebug > 1 ) cout<< " Transition at cell " << k << " at " << globalPos.print() << endl;
01624
01625 bool bChange = false;
01626
01627 if( bChangeIntToExt )
01628 {
01629
01630 if( keepColor == KEEP_UNKNOWN )
01631 {
01632 keepColor = (bOrange ? KEEP_PURPLE : KEEP_ORANGE);
01633 if( gDebug > 1 ) cout<< " Setting keep color to " << (bOrange ? "KEEP_PURPLE" : "KEEP_ORANGE") << endl;
01634 bOrange = !bOrange;
01635
01636 if( gDebug > 1 ) cout<< " Switched color to " << (bOrange ? "ORANGE" : "PURPLE") << endl;
01637 bChange = true;
01638 }
01639 else
01640 {
01641
01642 if( keepColor == (bOrange ? KEEP_ORANGE : KEEP_PURPLE ) )
01643 {
01644
01645 if( gDebug > 1 ) cout<< " Maintaining current color" << endl;
01646 }
01647 else
01648 {
01649 bOrange = !bOrange;
01650 if( gDebug > 1 ) cout<< " Switched color to " << (bOrange ? "ORANGE" : "PURPLE") << endl;
01651 bChange = true;
01652 }
01653 }
01654
01655 }
01656 else if( bChangeExtToInt )
01657 {
01658
01659 if( keepColor == KEEP_UNKNOWN )
01660 {
01661 keepColor = (bOrange ? KEEP_ORANGE : KEEP_PURPLE);
01662
01663 if( gDebug > 1 ) cout<< " Setting keep color to " << (bOrange ? "KEEP_ORANGE" : "KEEP_PURPLE") << endl;
01664 bOrange = !bOrange;
01665
01666 if( gDebug > 1 ) cout<< " Switched color to " << (bOrange ? "ORANGE" : "PURPLE") << endl;
01667 bChange = true;
01668 }
01669 else
01670 {
01671
01672 if( keepColor == (bOrange ? KEEP_PURPLE : KEEP_ORANGE ) )
01673 {
01674
01675 if( gDebug > 1 ) cout<< " Maintaining current color" << endl;
01676 }
01677 else
01678 {
01679 bOrange = !bOrange;
01680 if( gDebug > 1 ) cout<< " Switched color to " << (bOrange ? "ORANGE" : "PURPLE") << endl;
01681 bChange = true;
01682 }
01683 }
01684 }
01685
01686 if( bChange )
01687 {
01688 if( tempFrontierArc.size() > 0 )
01689 {
01690 if( tempFrontierArc.size() >= gMinMergeArcSize )
01691 {
01692
01693 if( !(bOrange) )
01694 {
01695 if( gDebug > 8 ) cout<< "Pushing temp arc with " << tempFrontierArc.size() << " cells to orange (color)" << endl;
01696 orangeFrontier.push_back(tempFrontierArc);
01697 }
01698 else
01699 {
01700 if( gDebug > 8 ) cout<< "Pushing temp arc with " << tempFrontierArc.size() << " cells to purple (color)" << endl;
01701 purpleFrontier.push_back(tempFrontierArc);
01702 }
01703 }
01704
01705 if( gDebug > 8 ) cout<< "Clearing temp arc (color)" << endl;
01706 tempFrontierArc = FrontierArc();
01707
01708 if( bFrontierCell )
01709 {
01710 tempFrontierArc.push_back(iBoundCell);
01711 }
01712 }
01713 }
01714 }
01715 }
01716 }
01717 }
01718
01719
01720
01721
01722
01723
01724
01725 }
01726
01727 if( tempFreeArc.size() > 0 )
01728 {
01729 if( m_freeArcs.size() > 0 && m_freeArcs[0][0] == lsrBound[iOffset] )
01730 {
01731 m_freeArcs[0].insert( m_freeArcs[0].begin(), tempFreeArc.begin(), tempFreeArc.end() );
01732 }
01733 else
01734 {
01735 m_freeArcs.push_back(tempFreeArc);
01736 }
01737 }
01738
01739 if( tempFrontierArc.size() >= gMinMergeArcSize )
01740 {
01741 if( bOrange )
01742 {
01743 if( orangeFrontier.size() > 0 && orangeFrontier[0][0] == lsrBound[iOffset] )
01744 {
01745 if( gDebug > 8 ) cout<< " Merging temp arc with " << tempFrontierArc.size() << " cells to orange" << endl;
01746 orangeFrontier[0].insert( orangeFrontier[0].begin(), tempFrontierArc.begin(), tempFrontierArc.end() );
01747 }
01748 else
01749 {
01750 if( gDebug > 8 ) cout<< " Pushing temp arc with " << tempFrontierArc.size() << " cells to orange" << endl;
01751 orangeFrontier.push_back(tempFrontierArc);
01752 }
01753 }
01754 else
01755 {
01756 if( purpleFrontier.size() > 0 && purpleFrontier[0][0] == lsrBound[iOffset] )
01757 {
01758 if( gDebug > 8 ) cout<< " Merging temp arc with " << tempFrontierArc.size() << " cells to purple" << endl;
01759 purpleFrontier[0].insert( purpleFrontier[0].begin(), tempFrontierArc.begin(), tempFrontierArc.end() );
01760 }
01761 else
01762 {
01763 if( gDebug > 8 ) cout<< " Pushing temp arc with " << tempFrontierArc.size() << " cells to purple" << endl;
01764 purpleFrontier.push_back(tempFrontierArc);
01765 }
01766 }
01767 }
01768
01769
01770 if( keepColor == KEEP_ORANGE || keepColor == KEEP_UNKNOWN )
01771 {
01772 if( gDebug > 1 ) cout<< "Keeping orange frontier, with " << orangeFrontier.size() << " arcs"<< endl;
01773 m_frontier = orangeFrontier;
01774 }
01775 else
01776 {
01777 if( gDebug > 1 ) cout<< "Keeping purple frontier, with " << purpleFrontier.size() << " arcs"<< endl;
01778 m_frontier = purpleFrontier;
01779 }
01780
01781 if( gDebug > 8 )
01782 {
01783 cout<< " Updated frontier size:" << endl;
01784 cout<< " " << m_frontier.size() << " frontier arcs" << endl;
01785 for( int i = 0; i < m_frontier.size(); i++ )
01786 {
01787 cout<< " Arc " << i << " has " << m_frontier[i].size() << " cells" << endl;
01788 }
01789 }
01790 }
01791
01792
01793 void PursuitAgent::updateNeighborFrontiers( AgentVector neighbors, Pose &curPose, vector<Frontier > &updatedNeighborFrontiers )
01794 {
01795 player_color_t color;
01796
01798
01800 for( int i = 0; i < neighbors.size(); i++ )
01801 {
01802 if( neighbors[i]->isLeader() && (neighbors[i]->getID() != getID()) )
01803 {
01804 Position neighborPos = neighbors[i]->getLSRPose().pos();
01805
01806 if( neighborPos.dist(curPose.pos()) > gOverlapFactor*(getSensorRange() + neighbors[i]->getSensorRange()) )
01807 {
01808 if( gDebug > 7 ) cout<< " " << getID() << " ignoring distant agent " << neighbors[i]->getID() << endl;
01809 continue;
01810 }
01811
01812 if( gDebug > 7 ) cout<< " " << getID() << " setting agent " << neighbors[i]->getID() << " frontiers" << endl;
01813
01814
01815 Frontier newFrontier;
01816 for( int j = 0; j < updatedNeighborFrontiers[i].size(); j++ )
01817 {
01818
01819 bool bErase = false;
01820 FrontierArc updatedNeighborArc = updatedNeighborFrontiers[i][j];
01821
01822 if( updatedNeighborArc.size() <= 3 )
01823 {
01824 if( neighbors[i]->getCell(updatedNeighborArc[0])->isLabelA() )
01825 {
01826 if( neighbors[i]->getCell(updatedNeighborArc[updatedNeighborArc.size()-1])->isLabelB() )
01827 {
01828 bErase = true;
01829 }
01830 }
01831 }
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897 Pose neighborPose = neighbors[i]->getLSRPose();
01898 Cell* pCell1 = neighbors[i]->getCell(updatedNeighborArc[0]);
01899 Cell* pCell2 = neighbors[i]->getCell(updatedNeighborArc[updatedNeighborArc.size()-1]);
01900
01901 if( !pCell1->isLabelA() && pCell1->isFrontier() )
01902 {
01903
01904
01905 bool bSet = false;
01906 Position translatedPos = neighborPose.pos() - curPose.pos() + pCell1->point();
01907 Cell* pTranslatedCell = m_LSR.getCell( translatedPos );
01908
01909 if( pTranslatedCell != NULL )
01910 {
01911 for( int x = -1; x <= 1; x++ )
01912 {
01913 for( int y = -1; y <= 1; y++ )
01914 {
01915 if( x != 0 || y != 0 )
01916 {
01917 DubInt iTheirs = pCell1->indexes() + DubInt(x,y);
01918 Cell* pTheirCell = neighbors[i]->getCell( iTheirs );
01919 DubInt iOurs = pTranslatedCell->indexes() + DubInt(x,y);
01920 Cell* pOurCell = m_LSR.getCell( iOurs );
01921
01922 if( pTheirCell != NULL && pOurCell != NULL )
01923 {
01924 if( pTheirCell->isFrontier() && pOurCell->isObstacle() )
01925 {
01926 bSet = true;
01927 }
01928 }
01929 }
01930 }
01931 }
01932
01933 vector<Cell* > nCells = pTranslatedCell->neighbours();
01934
01935 for( int l = 0; l < nCells.size(); l++ )
01936 {
01937 if( (m_LSR.getCell(nCells[l]->indexes())->isLabelA()) )
01938 {
01939 bSet = false;
01940 }
01941
01942 for( int a = 0; a < m_frontier.size(); a++ )
01943 {
01944 FrontierArc ourArc = m_frontier[a];
01945
01946 if( ourArc[0] == nCells[l]->indexes() )
01947 {
01948 bSet = false;
01949 }
01950
01951 if( ourArc[ourArc.size()-1] == nCells[l]->indexes() )
01952 {
01953 bSet = false;
01954 }
01955 }
01956 }
01957
01958 if( bSet )
01959 {
01960 if( gDebug > 7 ) cout<< getID() << " setting error correction neighbor obstacle begin point for neighbor's frontier" << endl;
01961 pCell1->setIsLabelA();
01962 if( gDebug >= 9 ) drawSquare( gColorGreen, neighborPose.pos() + pCell1->point(), 0.05, false );
01963 }
01964 }
01965 }
01966
01967 if( !pCell2->isLabelB() && pCell2->isFrontier() )
01968 {
01969
01970
01971 bool bSet = false;
01972 Position translatedPos = neighborPose.pos() - curPose.pos() + pCell2->point();
01973 Cell* pTranslatedCell = m_LSR.getCell( translatedPos );
01974
01975 if( pTranslatedCell != NULL )
01976 {
01977 for( int x = -1; x <= 1; x++ )
01978 {
01979 for( int y = -1; y <= 1; y++ )
01980 {
01981 if( x != 0 || y != 0 )
01982 {
01983 Cell* pTheirCell = neighbors[i]->getCell( pCell2->indexes() + DubInt(x,y) );
01984 Cell* pOurCell = m_LSR.getCell( pTranslatedCell->indexes() + DubInt(x,y) );
01985
01986 if( pTheirCell != NULL && pOurCell != NULL )
01987 {
01988 if( pTheirCell->isFrontier() && pOurCell->isObstacle() )
01989 {
01990 bSet = true;
01991 }
01992 }
01993 }
01994 }
01995 }
01996
01997 vector<Cell* > nCells = pTranslatedCell->neighbours();
01998
01999 for( int l = 0; l < nCells.size(); l++ )
02000 {
02001 if( (m_LSR.getCell(nCells[l]->indexes())->isLabelB()) )
02002 {
02003 bSet = false;
02004 }
02005
02006 for( int a = 0; a < m_frontier.size(); a++ )
02007 {
02008 FrontierArc ourArc = m_frontier[a];
02009
02010 if( ourArc[0] == nCells[l]->indexes() )
02011 {
02012 bSet = false;
02013 }
02014
02015 if( ourArc[ourArc.size()-1] == nCells[l]->indexes() )
02016 {
02017 bSet = false;
02018 }
02019 }
02020 }
02021
02022 if( bSet )
02023 {
02024 if( gDebug > 7 ) cout<< getID() << " setting error correction neighbor obstacle end point for neighbor's frontier" << endl;
02025 pCell2->setIsLabelB();
02026 if( gDebug >= 9 ) drawSquare( gColorRed, neighborPose.pos() + pCell2->point(), 0.05, false );
02027 }
02028 }
02029 }
02030
02031 if( !bErase )
02032 {
02033 newFrontier.push_back(updatedNeighborArc);
02034 }
02035 }
02036
02037
02038 if( neighbors[i]->isWaitingForAgent(getID()) )
02039 {
02040 neighbors[i]->clearWaitingForAgent();
02041 }
02042
02043
02044 neighbors[i]->setFrontier( newFrontier );
02045 }
02046 }
02047 }
02048
02049
02050 void PursuitAgent::postProcessOurFrontier( vector<Frontier > &ourNeighborFrontiers, Pose &curPose, bool bDebugDisplay )
02051 {
02053
02055 LSRBound lsrBound = m_LSR.lsrBound();
02056 for( int i = 0; i < m_freeArcs.size(); i++ )
02057 {
02058 if( m_freeArcs[i].size() < lsrBound.size() )
02059 {
02060 m_LSR.getCell(m_freeArcs[i][0])->setIsLabelA();
02061 m_LSR.getCell(m_freeArcs[i][m_freeArcs[i].size()-1])->setIsLabelB();
02062
02063 if( bDebugDisplay ) drawX( gColorGray, m_LSR.getCell(m_freeArcs[i][0])->point() + curPose.pos(), 0.05 );
02064 if( bDebugDisplay ) drawX( gColorBlue, m_LSR.getCell(m_freeArcs[i][m_freeArcs[i].size()-1])->point() + curPose.pos(), 0.05 );
02065 }
02066 }
02067
02068
02069
02070 for( int i = 0; i < m_frontier.size(); i++ )
02071 {
02072 if( m_frontier[i].size() < lsrBound.size() )
02073 {
02074 Cell* pCell1 = m_LSR.getCell(m_frontier[i][0]);
02075 Cell* pCell2 = m_LSR.getCell(m_frontier[i][m_frontier[i].size()-1]);
02076
02077 if( gDebug >= 9 )
02078 {
02079 drawSquare( gColorBlue, m_LSR.center().pos() + pCell1->point(), 0.02, false );
02080 drawSquare( gColorGray, m_LSR.center().pos() + pCell2->point(), 0.02, false );
02081 }
02082
02083 if( !pCell1->isLabelA() )
02084 {
02085 bool bSet = true;
02086
02087 vector<Cell* > nCells = pCell1->neighbours();
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097 for( int m = 0; (bSet && m < ourNeighborFrontiers.size()); m++ )
02098 {
02099 for( int j = 0; (bSet && j < ourNeighborFrontiers[m].size()); j++ )
02100 {
02101 FrontierArc ourNeighborArc = ourNeighborFrontiers[m][j];
02102
02103 for( int k = 0; (bSet && k < ourNeighborArc.size()); k++ )
02104 {
02105 for( int l = 0; l < nCells.size(); l++ )
02106 {
02107 if( ourNeighborArc[k] == nCells[l]->indexes() )
02108 {
02109
02110 if( !(m_LSR.getCell(nCells[l]->indexes())->isLSR()) && !(m_LSR.getCell(nCells[l]->indexes())->isObstacle()) )
02111 {
02112 if( gDebug >= 9 ) drawX( gColorGray, m_LSR.center().pos() + m_LSR.getCell(nCells[l]->indexes())->point(), 0.03 );
02113 bSet = false;
02114 break;
02115 }
02116 }
02117 }
02118 }
02119 }
02120 }
02121
02122 if( bSet )
02123 {
02124 if( gDebug > 7 ) cout<< getID() << " setting error correction obstacle begin point for frontier " << i << " of size " << m_frontier[i].size() << endl;
02125 pCell1->setIsLabelA();
02126 if( gDebug >= 9 ) drawX( gColorGreen, m_LSR.center().pos() + pCell1->point(), 0.05 );
02127 }
02128 }
02129
02130 if( !pCell2->isLabelB() )
02131 {
02132 bool bSet = true;
02133
02134 vector<Cell* > nCells = pCell2->neighbours();
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144 for( int m = 0; (bSet && m < ourNeighborFrontiers.size()); m++ )
02145 {
02146 for( int j = 0; (bSet && j < ourNeighborFrontiers[m].size()); j++ )
02147 {
02148 FrontierArc ourNeighborArc = ourNeighborFrontiers[m][j];
02149
02150 for( int k = 0; (bSet && k < ourNeighborArc.size()); k++ )
02151 {
02152 for( int l = 0; l < nCells.size(); l++ )
02153 {
02154 if( ourNeighborArc[k] == nCells[l]->indexes() )
02155 {
02156
02157 if( !(m_LSR.getCell(nCells[l]->indexes())->isLSR()) && !(m_LSR.getCell(nCells[l]->indexes())->isObstacle()) )
02158 {
02159 if( gDebug >= 9 ) drawX( gColorGray, m_LSR.center().pos() + m_LSR.getCell(nCells[l]->indexes())->point(), 0.03 );
02160 bSet = false;
02161 break;
02162 }
02163 }
02164 }
02165 }
02166 }
02167 }
02168
02169 if( bSet )
02170 {
02171 if( gDebug > 7 ) cout<< getID() << " setting error correction obstacle begin point for frontier " << i << " of size " << m_frontier[i].size() << endl;
02172 pCell2->setIsLabelB();
02173 if( gDebug >= 9 ) drawX( gColorRed, m_LSR.center().pos() + pCell2->point(), 0.05 );
02174 }
02175 }
02176 }
02177 }
02178
02180
02182 Frontier newFrontier;
02183 for( int i = 0; i < m_frontier.size(); i++ )
02184 {
02185 bool bKill = false;
02186 int iLSRCount = 0;
02187 FrontierArc arc = m_frontier[i];
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246 if( arc.size() <= 3 )
02247 {
02248 if( m_LSR.getCell(arc[0])->isLabelA() && m_LSR.getCell(arc[arc.size()-1])->isLabelB() )
02249 {
02250 bKill = true;
02251 }
02252 }
02253
02254 if( !bKill )
02255 {
02256 for( int j = 0; j < arc.size(); j++ )
02257 {
02258 if( !(m_LSR.getCell(arc[j])->isObstacle()) )
02259 {
02260 vector<Cell* > nCells = m_LSR.getCell(arc[j])->neighbours();
02261
02262
02263 for( int k = 0; k < nCells.size(); k++ )
02264 {
02265 if( nCells[k]->isLSR() && !(nCells[k]->isBoundary()) )
02266 {
02267 iLSRCount++;
02268 break;
02269 }
02270 }
02271 }
02272 }
02273
02274 bKill = (iLSRCount <= std::max(0, (arc.size()-2)/2));
02275 }
02276
02277 if( !bKill )
02278 {
02279 newFrontier.push_back(arc);
02280 }
02281 else
02282 {
02283 if( gDebug > 0 ) cout<< getID() << " erasing erroneous frontier" << endl;
02284 }
02285 }
02286 m_frontier = newFrontier;
02287 }
02288
02289
02290 void PursuitAgent::updateFrontier( AgentVector neighbors, bool bDebugDisplay )
02291 {
02292 if( isTraveling() )
02293 {
02294 return;
02295 }
02296
02297 if( m_bFrontierInitialized )
02298 {
02299
02300 return;
02301 }
02302
02303 if( gDebug > 7 ) cout<< " " << getID() << " updating frontier" << endl;
02304
02305 int bWaitForKeyboard = (gDebug > 9);
02306
02307 player_color_t color;
02308
02309
02310 setFrontier( m_LSR.frontier(), true );
02311 m_bFrontierInitialized = true;
02312 m_freeArcs.clear();
02313 Pose curPose = getLSRPose();
02314
02315
02316 vector<Frontier > ourNeighborFrontiers;
02317
02318 vector<Frontier > updatedNeighborFrontiers;
02319
02320
02321
02322 vector<DubInt > neighborObstacleEndpoints;
02323
02324 vector<DubInt > neighborObstacleBeginpoints;
02325
02326
02327 getNeighborFrontiers( neighbors, curPose, ourNeighborFrontiers, updatedNeighborFrontiers, neighborObstacleEndpoints, neighborObstacleBeginpoints );
02328
02329 m_prevFrontier.clear();
02330 m_prevLSR = Grid();
02331
02332
02333
02334
02335
02336
02337 if( bDebugDisplay )
02338 {
02339 if( gDebug > 5 ) cout<< " " << m_frontier.size() << " our frontier arcs" << endl;
02340 if( gDebug > 5 ) cout<< " " << ourNeighborFrontiers.size() << " neighbor frontiers" << endl;
02341 for( int i = 0; i < ourNeighborFrontiers.size(); i++ )
02342 {
02343 if( gDebug > 5 ) cout<< " " << ourNeighborFrontiers[i].size() << " neighbor frontier arcs" << endl;
02344 for( int j = 0; j < ourNeighborFrontiers[i].size(); j++ )
02345 {
02346 FrontierArc ourNeighborArc = ourNeighborFrontiers[i][j];
02347 if( gDebug > 5 )
02348 {
02349 cout<< " " << ourNeighborArc.size() << " neighbor frontier arc cells, from " ;
02350 cout<< ourNeighborArc[0].print() << " to " << ourNeighborArc[ourNeighborArc.size()-1].print() << endl;
02351 }
02352
02353 for( int k = 0; k < ourNeighborArc.size(); k++ )
02354 {
02355 Position arcCellPos = getCellPosition(ourNeighborArc[k]);
02356 Position globalPos = curPose.pos() + arcCellPos;
02357
02358 color.alpha = 0;
02359 color.red = 175;
02360 color.green = 175;
02361 color.blue = 175;
02362
02363 drawSquare( color, globalPos, 0.01, true );
02364 }
02365
02366 drawRedX( curPose.pos() + getCellPosition(ourNeighborArc[ourNeighborArc.size()-1]), 0.015 );
02367 }
02368 }
02369
02370 for( int i = 0; i < neighborObstacleBeginpoints.size(); i++ )
02371 {
02372 drawX( gColorGreen, curPose.pos() + getCellPosition(neighborObstacleBeginpoints[i]), 0.05 );
02373 }
02374
02375 for( int i = 0; i < neighborObstacleEndpoints.size(); i++ )
02376 {
02377 drawRedX( curPose.pos() + getCellPosition(neighborObstacleEndpoints[i]), 0.05 );
02378 }
02379
02380 for( int i = 0; (i < m_frontier.size()); i++ )
02381 {
02382 FrontierArc arc = m_frontier[i];
02383 for( int j = 0; (j < arc.size()); j++ )
02384 {
02385 Position arcCellPos = getCellPosition(arc[j]);
02386 Position globalPos = curPose.pos() + arcCellPos;
02387
02388 color.alpha = 0;
02389 color.red = 255;
02390 color.green = 175;
02391 color.blue = 255;
02392
02393 drawSquare( color, globalPos, 0.01, true );
02394
02395 if( j == 0 )
02396 {
02397 drawX( gColorGreen, curPose.pos() + getCellPosition(arc[j]), 0.05 );
02398 }
02399 else if( j == arc.size() - 1 )
02400 {
02401 drawRedX( curPose.pos() + getCellPosition(arc[j]), 0.05 );
02402 }
02403 }
02404 }
02405 }
02406
02407 if( bDebugDisplay )
02408 {
02409 if( bWaitForKeyboard )
02410 {
02411 cout<< "Waiting for go ahead..." << endl;
02412 char input[10];
02413 cin>> input;
02414 }
02415 else
02416 {
02417 TimeUtilities::sleep( Time(1,500000) );
02418 }
02419
02420
02421 }
02422
02423
02424 classifyOurFrontier( neighbors, curPose, ourNeighborFrontiers, neighborObstacleEndpoints, neighborObstacleBeginpoints, bDebugDisplay );
02425
02426
02427 updateNeighborFrontiers( neighbors, curPose, updatedNeighborFrontiers );
02428
02429
02430 postProcessOurFrontier( ourNeighborFrontiers, curPose, bDebugDisplay );
02431
02432 gIterCount++;
02433
02434
02435 if( gLogFile.is_open() )
02436 {
02437 if( gGlobalGrid != NULL )
02438 {
02439 Position lsrPos = getLSRPose().pos();
02440 for( int i = 0; i < getLSRSize(); i++ )
02441 {
02442 if( getCell(i)->isLSR() )
02443 {
02444 Position LSRpoint = lsrPos + getCell(i)->point();
02445
02446 Cell* pCell = gGlobalGrid->getCell( LSRpoint );
02447
02448 if( !pCell->isLSR() )
02449 {
02450 pCell->setIsLSR();
02451 gGlobalGrid->_lsr.push_back(pCell->indexes());
02452 }
02453 }
02454 }
02455 }
02456
02457 logData();
02458 }
02459
02460 if( bDebugDisplay )
02461 {
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483 if( bWaitForKeyboard )
02484 {
02485 cout<< "Waiting for go ahead..." << endl;
02486 char input[10];
02487 cin>> input;
02488 }
02489 else
02490 {
02491 TimeUtilities::sleep( Time(2,500000) );
02492 }
02493
02494 gGP->Clear();
02495 }
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529 }
02530
02531 ExplorationParams PursuitAgent::getExplParams( )
02532 {
02533 double maxRange = getSensorRange();
02534 return ExplorationParams( maxRange, (m_pLaserProxy->GetMaxAngle() - m_pLaserProxy->GetMinAngle()), m_pLaserProxy->GetCount(), m_pLaserProxy->GetScanRes());
02535 }
02536
02537 void PursuitAgent::recordLSR()
02538 {
02539
02540
02541 m_LSR = Grid( getExplParams(), getScan(), getPose(), 2*getSensorRange(), 2*getSensorRange(), 2*getWidth() );
02542
02543 m_LSR.defineBoard( gMinArcSize, gMinRadialArcSize, true );
02544
02545 cout<< " Cover field of view " << getCoverFieldOfView() << endl;
02546 }
02547
02548 double PursuitAgent::getCoverRange()
02549 {
02550 return (gCoverDistScalar * (getSensorRange() - getLSRResolution()));
02551 }
02552
02553 double PursuitAgent::getCoverFieldOfView()
02554 {
02555 return gSafeAngleFrac*(m_pLaserProxy->GetMaxAngle() - m_pLaserProxy->GetMinAngle());
02556 }
02557
02558 bool PursuitAgent::isCellCovered( Pose viewPoint, DubInt iCell, bool bSilent )
02559 {
02560 Position relPos = getCellPosition(iCell) - viewPoint.pos();
02561 if(!bSilent) cout<< " relPos : " << relPos.print() << " bearing " << relPos.bearing().print() << endl;
02562 if( relPos.norm() > (getCoverRange() + 0.01) )
02563 {
02564 if(!bSilent) cout<< " Distance fail" << endl;
02565 return false;
02566 }
02567
02568 if( fabs(viewPoint.ori().alDiff(relPos.bearing())) > (getCoverFieldOfView()/2.0 + 0.01) )
02569 {
02570 if(!bSilent)
02571 {
02572 cout<< " Angle fail, " << viewPoint.ori().print() << " vs " << relPos.bearing().print() << endl;
02573 cout<< " " << fabs(viewPoint.ori().alDiff(relPos.bearing())) << " " << getCoverFieldOfView()/2.0 << endl;
02574 }
02575
02576 return false;
02577 }
02578
02579 vector<Cell* > rasterLine = getRaster( getCell(viewPoint.pos())->indexes(), iCell );
02580
02581
02582 int iObstacleCount = 0;
02583 for( int i = 0; i < rasterLine.size() - 2; i++ )
02584 {
02585 if( !(rasterLine[i]->isLSR()) )
02586 {
02587 return false;
02588 }
02589
02590 if( rasterLine[i]->isObstacle() )
02591 {
02592 iObstacleCount++;
02593 }
02594 }
02595
02596 if( iObstacleCount > 1 )
02597 {
02598 if(!bSilent) cout<< " Obstacle fail" << endl;
02599 return false;
02600 }
02601
02602 if(!bSilent) cout<< " covered" << endl;
02603 return true;
02604 }
02605
02606 Pose PursuitAgent::pickBestViewPoint( int *iNumViewPoints, bool bDebugDisplay )
02607 {
02608 Frontier frontier = getFrontier();
02609 assert( frontier.size() > 0 );
02610 assert( m_freeArcs.size() > 0 );
02611
02612 if( gDebug > 2 ) cout<< "Picking best view point" << endl;
02613
02614 (*iNumViewPoints) = 1;
02615
02616 Pose viewPoint( 0.0, 0.0, 0.0 );
02617
02618 int iRelevantFreeArcs = 0;
02619 FrontierArc mostRelevantFreeArc;
02620 int iMaxRelevancy = 0;
02621 vector<DubInt > frontierCellsOnMRFA;
02622
02623
02624
02625
02626 for( int i = 0; i < m_freeArcs.size(); i++ )
02627 {
02628 FrontierArc freeArc = m_freeArcs[i];
02629 int iRelevancy = 0;
02630 vector<DubInt > frontierCellsOnFreeArc;
02631
02632 for( int k = 0; k < frontier.size(); k++ )
02633 {
02634 for( int l = 0; l < frontier[k].size(); l++ )
02635 {
02636 for( int j = 0; j < freeArc.size(); j++ )
02637 {
02638
02639 if( freeArc[j] == frontier[k][l] )
02640 {
02641 iRelevancy++;
02642 frontierCellsOnFreeArc.push_back( freeArc[j] );
02643 }
02644 }
02645 }
02646 }
02647
02648 if( gDebug > 5 ) cout << " Free arc " << i << " has " << frontierCellsOnFreeArc.size() << " frontier cells out of " << freeArc.size() << endl;
02649
02650 if( iRelevancy > 0 )
02651 {
02652 iRelevantFreeArcs++;
02653
02654 if( iRelevancy > iMaxRelevancy )
02655 {
02656 mostRelevantFreeArc = m_freeArcs[i];
02657 frontierCellsOnMRFA = frontierCellsOnFreeArc;
02658 iMaxRelevancy = iRelevancy;
02659 }
02660 }
02661 }
02662
02663 if( mostRelevantFreeArc.size() == 0 || frontierCellsOnMRFA.size() == 0 )
02664 {
02665 cerr<< "*** Error! *** Empty most relevant free arc, skipping agent " << getID() << endl;
02666 return getLSRPose();
02667 }
02668
02669 if( gDebug > 2 )
02670 {
02671 cout<< " Most relevant free arc: size " << mostRelevantFreeArc.size() << ", " << frontierCellsOnMRFA.size() << " frontier cells" << endl;
02672 }
02673
02674 Pose curPose = getLSRPose();
02675
02676 if( gDebug > 20 )
02677 {
02678 gGP->Clear();
02679
02680 for( int i = 0; i < frontierCellsOnMRFA.size(); i++ )
02681 {
02682 drawSquare( gColorFrontier, getCellPosition(frontierCellsOnMRFA[i]) + curPose.pos(), 0.01, true );
02683
02684 if( i%5 == 4 )
02685 {
02686 cout<< "Waiting for go ahead..." << endl;
02687 char input[10];
02688 cin>> input;
02689 }
02690 }
02691
02692 }
02693
02694
02695 int iMaxFrontierCoverage = 0;
02696 int iViewPoint = -1;
02697
02698
02699 double angWidthOfMRFA = 0.0;
02700
02701 Position frontierRight = getCellPosition(frontierCellsOnMRFA[0]);
02702 Angle rightAngle = atan2( frontierRight.y(), frontierRight.x() );
02703 Position frontierLeft = getCellPosition(frontierCellsOnMRFA.back());
02704 Angle leftAngle = atan2( frontierLeft.y(), frontierLeft.x() );
02705
02706 angWidthOfMRFA = angDistCCW( rightAngle.dCastPi(), leftAngle.dCastPi(), (frontierCellsOnMRFA.size() <= (int)(getSensorRange()/(getLSRResolution() + 0.01))) );
02707
02708 angWidthOfMRFA *= gOverlapFactor;
02709
02710
02711 double maxVPAngCoverage = 1.70 * acos( limit( gMinLength/(2*getCoverRange() - getWidth() - getLSRResolution()), 0.03, 0.49 ) );
02712
02713 (*iNumViewPoints) = 1;
02714
02715 for( int j = 0; j < frontierCellsOnMRFA.size(); j++ )
02716 {
02717 Position pos = getCellPosition(frontierCellsOnMRFA[j]);
02718 Angle angle = atan2( pos.y(), pos.x() );
02719
02720 if( angDistCCW( rightAngle.dCastPi(), angle.dCastPi(), true )*gOverlapFactor > maxVPAngCoverage )
02721 {
02722 (*iNumViewPoints)++;
02723 rightAngle = angle;
02724 }
02725 }
02726
02727 if( angWidthOfMRFA >= 2*M_PI - 0.01 )
02728 {
02729 (*iNumViewPoints) = 3;
02730 }
02731
02732 rightAngle = atan2( frontierRight.y(), frontierRight.x() );
02733
02734
02735
02736 if( gDebug > 2 ) cout << " VPs: " << (*iNumViewPoints) << " needed to cover MRFA with width " << angWidthOfMRFA << endl;
02737 if( gDebug > 5 ) cout << " " << rightAngle.dCastPi() << " right, " << leftAngle.dCastPi() << " left" << endl;
02738 if( gDebug > 5 ) cout << " (" << maxVPAngCoverage << " max coverage per VP)" << endl;
02739
02740
02741 LRR curLRR = getLSR()._lrr;
02742 double bestDistHeuristic = -1.0;
02743 double bestCoverage = 0.0;
02744 double minVPDist = std::min( std::max(gMinLength, 1.2*getWidth()), getSensorRange() - getWidth() - getLSRResolution());
02745 minVPDist = std::max( minVPDist, (double)2*getLSRResolution());
02746
02747 if( gDebug > 5 ) cout << " " << minVPDist << " minimum VP dist" << endl;
02748
02749 frontierRight = getCellPosition(frontierCellsOnMRFA[0]);
02750 frontierLeft = frontierRight;
02751
02752 if( gDebug > 10 ) cout<< " Must cover point " << getCellPosition(frontierCellsOnMRFA[0]).print() << endl;
02753
02754 for( int i = 0; i < curLRR.size(); i++ )
02755 {
02756 if( getCell(curLRR[i])->isBoundary() )
02757 {
02758 continue;
02759 }
02760
02761 int iFrontierCoverage = 0;
02762 double distHeuristic = 0.0;
02763 Angle rightAngleCovered = rightAngle;
02764 Angle leftAngleCovered = rightAngle;
02765 frontierLeft = frontierRight;
02766 double angCoverage = 0.0;
02767 Position baseVec = getCellPosition(frontierCellsOnMRFA[0]) - getCellPosition(curLRR[i]);
02768 Position rightVec = frontierRight - getCellPosition(curLRR[i]);
02769 Position leftVec = frontierLeft - getCellPosition(curLRR[i]);
02770 Pose tempViewPoint = Pose( getCellPosition(curLRR[i]), getCellPosition(curLRR[i]).bearing() );
02771
02772 if( gDebug > 19 )
02773 {
02774
02775
02776 }
02777
02778 if( !(isCellCovered( tempViewPoint, frontierCellsOnMRFA[0])) )
02779 {
02780
02781 continue;
02782 }
02783
02784
02785
02786
02787 if( getCell(curLRR[i])->distVP() < minVPDist )
02788 {
02789
02790 continue;
02791 }
02792
02793 if( (m_followers.size() > 0 || isWaitingForAnyAgent()) )
02794 {
02795
02796 bool bAllCovered = true;
02797 bool bAngCoverage = false;
02798
02799
02800 for( int j = 0; j < frontierCellsOnMRFA.size(); j++ )
02801 {
02802 if( isCellCovered(tempViewPoint, frontierCellsOnMRFA[j]) )
02803 {
02804 Position pos = getCellPosition(frontierCellsOnMRFA[j]);
02805 frontierLeft = pos;
02806 Angle angle = atan2( pos.y(), pos.x() );
02807 leftAngleCovered = angle;
02808
02809 iFrontierCoverage++;
02810 distHeuristic += getCellPosition(curLRR[i]).dist(pos);
02811
02812 angCoverage = angDistCCW( rightAngleCovered.dCastPi(), leftAngleCovered.dCastPi(), true );
02813
02814 if( (*iNumViewPoints) > 1 && (angCoverage) > (angWidthOfMRFA / (*iNumViewPoints)) )
02815 {
02816 break;
02817 }
02818 }
02819 else
02820 {
02821
02822 bAllCovered = false;
02823 break;
02824 }
02825 }
02826
02827 if( (*iNumViewPoints) == 1 )
02828 {
02829 if( iFrontierCoverage >= iMaxFrontierCoverage )
02830 {
02831 if( (iFrontierCoverage > iMaxFrontierCoverage) || (distHeuristic < bestDistHeuristic) || (bestDistHeuristic < 0.0) )
02832 {
02833 if( gDebug > 9 ) cout<< " New best VP at cell " << i << ", covers " << iFrontierCoverage << " with dist heur " << distHeuristic << endl;;
02834 iMaxFrontierCoverage = iFrontierCoverage;
02835 iViewPoint = i;
02836
02837 Position rightVec = frontierRight - getCellPosition(curLRR[i]);
02838 Position leftVec = frontierLeft - getCellPosition(curLRR[i]);
02839
02840 viewPoint = Pose( getCellPosition(curLRR[i]), rightVec.bearing() + std::min(getCoverFieldOfView()/2.0, (rightVec.bearing().ccwDiff(leftVec.bearing())/2.0)) );
02841 bestDistHeuristic = distHeuristic;
02842 }
02843 }
02844 }
02845 else
02846 {
02847 if( (iFrontierCoverage >= iMaxFrontierCoverage) )
02848 {
02849 if( (iFrontierCoverage > iMaxFrontierCoverage) || (distHeuristic < bestDistHeuristic) || (bestDistHeuristic < 0.0) )
02850 {
02851 if( gDebug > 9 ) cout<< " New best VP at cell " << i << ", covers " << iFrontierCoverage << " (" << angCoverage << ") with dist heur " << distHeuristic << endl;
02852 iMaxFrontierCoverage = iFrontierCoverage;
02853 bestCoverage = angCoverage;
02854 iViewPoint = i;
02855
02856 Position rightVec = frontierRight - getCellPosition(curLRR[i]);
02857 Position leftVec = frontierLeft - getCellPosition(curLRR[i]);
02858
02859 viewPoint = Pose( getCellPosition(curLRR[i]), rightVec.bearing() + std::min(getCoverFieldOfView()/2.0, (rightVec.bearing().ccwDiff(leftVec.bearing())/2.0)) );
02860 bestDistHeuristic = distHeuristic;
02861 }
02862 }
02863 }
02864 }
02865 else
02866 {
02867
02868
02869 for( int j = 0; j < frontier.size(); j++ )
02870 {
02871 for( int k = 0; k < frontier[j].size(); k++ )
02872 {
02873 if( isCellCovered( tempViewPoint, frontier[j][k] ) )
02874 {
02875 Position vec = getCellPosition(frontier[j][k]) - getCellPosition(curLRR[i]);
02876
02877
02878 iFrontierCoverage++;
02879 distHeuristic += vec.norm();
02880 }
02881 }
02882 }
02883
02884 if( (iFrontierCoverage > iMaxFrontierCoverage) ||
02885 ((iFrontierCoverage == iMaxFrontierCoverage) && (distHeuristic < bestDistHeuristic)) )
02886 {
02887 iMaxFrontierCoverage = iFrontierCoverage;
02888 iViewPoint = i;
02889
02890 viewPoint = tempViewPoint;
02891 bestDistHeuristic = distHeuristic;
02892
02893 if( gDebug > 15 ) cout<< " new best: " << viewPoint.print() << " covers " << iMaxFrontierCoverage << " with heuristic " << bestDistHeuristic << endl;
02894 }
02895 }
02896 }
02897
02898
02899 int iTotalFrontierCells = 0;
02900 for( int i = 0; i < frontier.size(); i++ )
02901 {
02902 iTotalFrontierCells += frontier[i].size();
02903 }
02904
02905 if( gDebug > 2 ) cout<< " View point " << viewPoint.print() << " covers " << iMaxFrontierCoverage << " out of " << iTotalFrontierCells << " frontier cells" << endl;
02906
02907 if( iMaxFrontierCoverage < iTotalFrontierCells )
02908 {
02909 (*iNumViewPoints) = std::max( (*iNumViewPoints), 2 );
02910 }
02911
02912 if( gDebug > 19 )
02913 {
02914 gGP->Clear();
02915
02916 for( int j = 0; j < frontier.size(); j++ )
02917 {
02918 for( int k = 0; k < frontier[j].size(); k++ )
02919 {
02920 if( isCellCovered( viewPoint, frontier[j][k] ) )
02921 {
02922 drawSquare( gColorFrontier, getCellPosition(frontier[j][k]) + curPose.pos(), 0.01, true );
02923 }
02924 else
02925 {
02926 drawSquare( gColorGray, getCellPosition(frontier[j][k]) + curPose.pos(), 0.01, true );
02927 }
02928 }
02929 }
02930
02931 cout<< "Waiting for continue ..." << endl;
02932 char input[10];
02933 cin>> input;
02934 }
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960 return viewPoint;
02961 }
02962
02963 void PursuitAgent::setFrontier(Frontier frontier, bool bForce )
02964 {
02965 if(bForce)
02966 {
02967 m_frontier = frontier;
02968 return;
02969 }
02970
02971 int iCells = 0;
02972 for( int i = 0; i < frontier.size(); i++ )
02973 {
02974 iCells += frontier[i].size();
02975 }
02976
02977 if( !m_bFrontierInitialized )
02978 {
02979 bool bDoUpdate = (iCells < getTotalFrontierCells());
02980
02981 m_prevFrontier = frontier;
02982
02983 if( bDoUpdate )
02984 {
02985 if( gDebug > 0 ) cout<< " " << getID() << " doing set prev frontier updated" << endl;
02986 processFrontier( AgentVector() );
02987 }
02988 }
02989 else
02990 {
02991 bool bDoUpdate = (iCells == 0 || iCells < getTotalFrontierCells());
02992
02993 m_frontier = frontier;
02994
02995 if( bDoUpdate && isWaitingForAnyAgent() )
02996 {
02997 processFrontier( AgentVector() );
02998 }
02999
03000 }
03001 }
03002
03003 int PursuitAgent::getTotalFrontierCells()
03004 {
03005 int iCells = 0;
03006 Frontier frontier = getFrontier();
03007 for( int i = 0; i < frontier.size(); i++ )
03008 {
03009 iCells += frontier[i].size();
03010 }
03011
03012 return iCells;
03013 }
03014
03015 Pose PursuitAgent::getViewpoint( )
03016 {
03017 if( m_path.size() > 0 )
03018 {
03019 return m_path.back();
03020 }
03021 else
03022 {
03023 return getPose();
03024 }
03025 }
03026
03027 Scan PursuitAgent::getScan( )
03028 {
03029 clientRead();
03030
03031 int iCount = m_pLaserProxy->GetCount();
03032
03033 vector<Ray> rays;
03034 vector<Ray> rays2;
03035
03036 for( int i = 0; i < iCount; i++ )
03037 {
03038
03039 rays.push_back( Ray( m_pLaserProxy->GetRange(i), m_pLaserProxy->GetBearing(i), true ) );
03040 }
03041
03042 return Scan( rays, Time() );
03043 }
03044
03045 vector<Cell* > PursuitAgent::getRaster( DubInt iCell1, DubInt iCell2 )
03046 {
03047 if( m_bFrontierInitialized )
03048 {
03049 return m_LSR.bresenham( getCell(iCell1), getCell(iCell2) );
03050 }
03051 else
03052 {
03053 return m_prevLSR.bresenham( getCell(iCell1), getCell(iCell2) );
03054 }
03055 }
03056
03057
03058 Pose PursuitAgent::getLSRPose()
03059 {
03060 if( m_bFrontierInitialized )
03061 {
03062 return m_LSR.center();
03063 }
03064 else
03065 {
03066 return m_prevLSR.center();
03067 }
03068 }
03069
03070 void PursuitAgent::setToExpand( Path path, bool bClearPrevFrontier, AgentVector neighbors, bool bDoExpand )
03071 {
03072 if( gDebug > 5 ) cout<< " " << getID() << ": set to EXPAND" << endl;
03073
03074 m_eBehavior = EXPAND;
03075
03076 m_LSR = Grid();
03077 m_frontier.clear();
03078 m_bFrontierInitialized = false;
03079 if( bClearPrevFrontier )
03080 {
03081 m_prevLSR = m_LSR;
03082 m_prevFrontier.clear();
03083 }
03084
03085 m_path = path;
03086
03087 if( getPosition().dist(path.back().pos()) > 0.01 || fabs(getPose().ori().alDiff(path.back().ori())) > (2*M_PI)/180)
03088 {
03089 goTo( path.back() );
03090 }
03091
03092 m_pWaitForAgent = NULL;
03093
03094 if( bDoExpand ) Expand( neighbors );
03095 }
03096
03097 void PursuitAgent::setToGuard( AgentVector neighbors )
03098 {
03099 if( gDebug > 5 ) cout<< " " << getID() << ": set to GUARD" << endl;
03100
03101 m_eBehavior = GUARD;
03102
03103 recordLSR();
03104
03105 m_frontier.clear();
03106 m_bFrontierInitialized = false;
03107
03108
03109
03110 m_pWaitForAgent = NULL;
03111
03112
03113
03114
03115
03116
03117 if( neighbors.size() > 0 )
03118 {
03119 Guard( neighbors );
03120 }
03121 }
03122
03123 void PursuitAgent::setToFollow( AgentVector neighbors )
03124 {
03125 if( gDebug > 5 ) cout<< " " << getID() << ": set to FOLLOW" << endl;
03126
03127 m_eBehavior = FOLLOW;
03128
03129 m_LSR = Grid();
03130 m_prevLSR = m_LSR;
03131 m_frontier.clear();
03132 m_prevFrontier.clear();
03133 m_bFrontierInitialized = false;
03134 m_freeArcs.clear();
03135 m_path.clear();
03136
03137 m_pWaitForAgent = NULL;
03138
03139
03140
03141
03142 while( !m_followers.empty() )
03143 {
03144
03145 m_followers.back()->setToWander(neighbors);
03146 m_followers.pop_back();
03147 }
03148 }
03149
03150 void PursuitAgent::setToWander( AgentVector neighbors )
03151 {
03152 if( gDebug > 5 ) cout<< " " << getID() << ": set to WANDER" << endl;
03153
03154 m_eBehavior = WANDER;
03155
03156 m_LSR = Grid();
03157 m_prevLSR = m_LSR;
03158 m_frontier.clear();
03159 m_prevFrontier.clear();
03160 m_bFrontierInitialized = false;
03161 m_freeArcs.clear();
03162 m_path.clear();
03163
03164 m_pWaitForAgent = NULL;
03165
03166 while( !m_followers.empty() )
03167 {
03168 m_followers.back()->setToWander( neighbors );
03169 m_followers.pop_back();
03170 }
03171
03172 for( uint i = 0; i < neighbors.size(); i++ )
03173 {
03174 if( neighbors[i]->getID() != getID() )
03175 {
03176 if( neighbors[i]->isWaitingForAgent(getID()) )
03177 {
03178 neighbors[i]->clearWaitingForAgent();
03179 }
03180 }
03181 }
03182
03183
03184
03185 }
03186
03187 void PursuitAgent::setToNoBehavior( )
03188 {
03189 if( gDebug > 5 ) cout<< " " << getID() << ": set to NO_BEHAVIOR" << endl;
03190
03191 m_eBehavior = NO_BEHAVIOR;
03192
03193 m_LSR = Grid();
03194 m_frontier.clear();
03195 m_freeArcs.clear();
03196 m_bFrontierInitialized = false;
03197 m_path.clear();
03198
03199 m_pWaitForAgent = NULL;
03200
03201 while( !m_followers.empty() )
03202 {
03203 m_followers.back()->setToNoBehavior();
03204 m_followers.pop_back();
03205 }
03206
03207
03208 goTo( getPose() );
03209 }
03210
03211 void PursuitAgent::goTo( Pose pose )
03212 {
03213 m_pPosProxy->GoTo((double)(pose.pos().x()),(double)(pose.pos().y()),(double)(pose.ori().dCast2Pi()));
03214
03215 for( int i = 0; i < m_followers.size(); i++ )
03216 {
03217 Position followerPos = getFollowerPosition();
03218 followerPos *= (i+1.0);
03219 m_followers[i]->goTo( Pose(pose.pos() - followerPos, pose.ori()) );
03220 }
03221 }
03222
03223 Position PursuitAgent::getFollowerPosition()
03224 {
03225 Position pos = Position( 0, 0 );
03226 if( m_path.size() > 1 )
03227 {
03228 pos = (m_path.back().pos() - m_path[m_path.size()-2].pos());
03229
03230
03231 double multiplier = (1.6*getWidth())/std::max(pos.norm(), 0.1);
03232
03233 pos *= multiplier;
03234 }
03235
03236 return pos;
03237 }
03238
03239 void PursuitAgent::addFollower( PursuitAgent* newFollower, bool bMove )
03240 {
03241 if( gDebug > 5 ) cout<< " " << getID() << " gained follower " << newFollower->getID() << endl;
03242
03243 if( newFollower->getID() == getID() )
03244 {
03245 assert(false);
03246 return;
03247 }
03248
03249 m_followers.push_back(newFollower);
03250
03251 if( bMove )
03252 {
03253 if( getPath().size() > 0 )
03254 {
03255 newFollower->goTo( Pose(getPath().back().pos() - getFollowerPosition()*m_followers.size(), getPath().back().ori()) );
03256 }
03257 else
03258 {
03259
03260 }
03261 }
03262 }
03263
03264 void PursuitAgent::doCurrentBehavior( AgentVector neighbors )
03265 {
03266
03267 AgentVector leaders;
03268
03269 clientRead();
03270
03271 switch (m_eBehavior) {
03272 case EXPAND:
03273 Expand( neighbors );
03274 break;
03275 case GUARD:
03276 Guard( neighbors );
03277 break;
03278 case FOLLOW:
03279 if( gDebug > 8 ) cout<< " " << getID() << ": following" << endl;
03280 break;
03281 case NO_BEHAVIOR:
03282 break;
03283 case WANDER:
03284 if( gDebug > 8 ) cout<< " " << getID() << ": wandering" << endl;
03285 Wander( neighbors );
03286 break;
03287 default:
03288 cerr<< "ERROR: No behavior category" << endl;
03289 assert(false);
03290 }
03291 }
03292
03293 bool PursuitAgent::isLeader()
03294 {
03295 return ((m_eBehavior == EXPAND) || (m_eBehavior == GUARD));
03296 }
03297
03298 bool PursuitAgent::isReady()
03299 {
03300 if( m_pPosProxy->GetSize().sw == 0 || m_pLaserProxy->GetCount() == 0 )
03301 {
03302 return false;
03303 }
03304
03305 if( isTraveling() )
03306 {
03307 return false;
03308 }
03309
03310 if( isWaitingForAnyAgent() )
03311 {
03312 return false;
03313 }
03314
03315 return true;
03316 }
03317
03318 bool PursuitAgent::isWaitingForAnyAgent()
03319 {
03320 if( m_pWaitForAgent != NULL )
03321 {
03322 return true;
03323 }
03324
03325 return false;
03326 }
03327
03328 bool PursuitAgent::isWaitingForAgent(int iID)
03329 {
03330 if( !isWaitingForAnyAgent() )
03331 {
03332 return false;
03333 }
03334
03335 if( m_pWaitForAgent->getID() == iID )
03336 {
03337 return true;
03338 }
03339
03340 return false;
03341 }
03342
03343 void PursuitAgent::clearWaitingForAgent()
03344 {
03345 m_pWaitForAgent = NULL;
03346 }
03347
03348 bool PursuitAgent::isTraveling()
03349 {
03350 if( m_path.empty() )
03351 {
03352 return false;
03353 }
03354
03355 clientRead();
03356
03357 Pose curPose = getPose();
03358 double dist = curPose.pos().dist(m_path.back().pos());
03359 double check = std::max(m_pPosProxy->GetSize().sw/4,m_pPosProxy->GetSize().sl/4);
03360
03361 check = std::max( check, 0.011 );
03362
03363 if( dist > check )
03364 {
03365
03366 {
03367 if( gDebug > 10 ) cout<< " " << getID() << " is travelling, at " << curPose.print() << " dist " << dist << " v. check " << check << endl;
03368 return true;
03369 }
03370 }
03371
03372 if( (m_pLaserProxy->GetMaxAngle() - m_pLaserProxy->GetMinAngle()) < 1.9*M_PI )
03373 {
03374 if( fabs(curPose.ori().alDiff( m_path.back().ori() )) > (2 * M_PI)/180 )
03375 {
03376 if( gDebug > 10 ) cout<< " " << getID() << " is turning to final pose, at " << curPose.print() << endl;
03377 return true;
03378 }
03379 }
03380
03381 return false;
03382 }
03383
03384 bool PursuitAgent::canDetectTargetPosition( Position targetPos )
03385 {
03386 Position curPos = getLSRPose().pos();
03387
03388 if( m_bFrontierInitialized || m_prevFrontier.size() > 0 )
03389 {
03390 Cell* targetCell = getCell( targetPos - curPos );
03391
03392 if( targetCell != NULL )
03393 {
03394 if( targetCell->isLSR() || targetCell->isObstacle() )
03395 {
03396 if( gDebug > 0 ) cout<< "Detection! Agent " << getID() << " at " << curPos.print() << " spots evader at " << targetPos.print() << endl;
03397 return true;
03398 }
03399 }
03400 }
03401
03402 return false;
03403 }
03404
03405 void PursuitAgent::drawBoundary( Graphics2dProxy &gp )
03406 {
03407 bool bDoAgentColors = (gDebug > 10);
03408 Position curPos = getLSRPose().pos();
03409
03410 LSRBound lsrBound = getLSR().lsrBound();
03411 Frontier frontier = getFrontier();
03412 int i, j, l;
03413 Cell* pBoundCell;
03414 bool bIsActualFrontier;
03415
03416 if( frontier.size() <= 0 )
03417 {
03418 return;
03419 }
03420
03421 for( l = 0; l < lsrBound.size(); l++ )
03422 {
03423 pBoundCell = getCell(lsrBound[l]);
03424
03425 bIsActualFrontier = false;
03426 for( i = 0; !bIsActualFrontier && i < frontier.size(); i++ )
03427 {
03428 for( j = 0; !bIsActualFrontier && j < frontier[i].size(); j++ )
03429 {
03430 bIsActualFrontier = (lsrBound[l] == frontier[i][j]);
03431 }
03432 }
03433
03434 if( bIsActualFrontier )
03435 {
03436 drawSquare( (bDoAgentColors ? gColorVec[getID()] : gColorFrontier), curPos + pBoundCell->point(), 0.013, true );
03437
03438 if( gDebug > 8 )
03439 {
03440 if( pBoundCell->isLabelA() )
03441 {
03442 drawX( gColorGreen, curPos + pBoundCell->point(), 0.02 );
03443 }
03444 else if( pBoundCell->isLabelB() )
03445 {
03446 drawX( gColorRed, curPos + pBoundCell->point(), 0.02 );
03447 }
03448 }
03449 }
03450 else if( pBoundCell->isFrontier() )
03451 {
03452 drawSquare( gColorFreeArc, curPos + pBoundCell->point(), 0.013, true );
03453 }
03454 else if( pBoundCell->isObstacle() )
03455 {
03456 drawSquare( gColorObstacle, curPos + pBoundCell->point(), 0.013, true );
03457 }
03458 }
03459
03460 if( m_path.size() > 0 )
03461 {
03462
03463 }
03464 }
03465
03466 void PursuitAgent::drawFrontier( Graphics2dProxy &gp )
03467 {
03468 bool bDoAgentColors = (gDebug > 8);
03469 Position curPos = getLSRPose().pos();
03470 player_point_2d_t point;
03471
03472 Frontier frontier = getFrontier();
03473
03474 for( int i = 0; i < frontier.size(); i++ )
03475 {
03476 player_point_2d_t frontierPts[frontier[i].size()];
03477 for( int j = 0; j < frontier[i].size(); j++ )
03478 {
03479 Cell* pCell = getCell(frontier[i][j]);
03480 if( pCell != NULL )
03481 {
03482 frontierPts[j].px = curPos.x() + pCell->point().x();
03483 frontierPts[j].py = curPos.y() + pCell->point().y();
03484
03485 drawSquare( gColorVec[getID()], curPos + pCell->point(), 0.01, true );
03486 }
03487 }
03488
03489 if( frontier[i].size() > 1 )
03490 {
03491 gp.Color( gColorVec[getID()] );
03492
03493 gp.DrawPolyline( frontierPts, frontier[i].size() );
03494 }
03495
03496 if( bDoAgentColors ) drawRedX( curPos + getCell(frontier[i][frontier[i].size()-1])->point(), .02 );
03497 }
03498
03499 if( m_path.size() > 0 )
03500 {
03501 if( bDoAgentColors ) drawX( gColorVec[getID()], m_path.back().pos(), 0.05 );
03502 }
03503 }
03504
03505 void PursuitAgent::drawLSR( Graphics2dProxy &gp, bool bOnlyLSR )
03506 {
03507 Position curPos = getLSRPose().pos();
03508 player_point_2d_t point;
03509
03510 int LSRsize = getLSRSize();
03511 player_color_t color;
03512
03513 for( int i = 0; i < LSRsize; i++ )
03514 {
03515 Position LSRpoint = getCell(i)->point();
03516
03517 if( !bOnlyLSR && getCell(i)->isFrontier() )
03518 {
03519 color.alpha = 0;
03520 color.red = 0;
03521 color.green = 0;
03522 color.blue = 255;
03523
03524 drawSquare( color, curPos + LSRpoint, 0.01, true );
03525 }
03526 else if( !bOnlyLSR && getCell(i)->isObstacle() )
03527 {
03528 color.alpha = 0;
03529 color.red = 255;
03530 color.green = 0;
03531 color.blue = 0;
03532
03533 drawSquare( color, curPos + LSRpoint, 0.01, true );
03534 }
03535 else if( !bOnlyLSR && getCell(i)->isLRR() )
03536 {
03537 color.alpha = 0;
03538 color.red = 0;
03539 color.green = 180;
03540 color.blue = 0;
03541
03542 drawSquare( color, curPos + LSRpoint, 0.01, true );
03543 }
03544 else if( getCell(i)->isLSR() )
03545 {
03546 color.alpha = 0;
03547 color.red = 0;
03548 color.green = 255;
03549 color.blue = 0;
03550
03551 drawSquare( color, curPos + LSRpoint, 0.01, true );
03552 }
03553 }
03554
03555 }
03556
03557 #endif