Coverage Report - cz.cuni.amis.pogamut.ut2004.agent.navigation.UT2004GetBackToNavGraph
 
Classes in this File Line Coverage Branch Coverage Complexity
UT2004GetBackToNavGraph
0%
0/95
0%
0/68
3.625
UT2004GetBackToNavGraph$1
0%
0/3
N/A
3.625
 
 1  
 package cz.cuni.amis.pogamut.ut2004.agent.navigation;
 2  
 
 3  
 import java.util.ArrayList;
 4  
 import java.util.List;
 5  
 import java.util.logging.Level;
 6  
 
 7  
 import cz.cuni.amis.pogamut.base.agent.navigation.IStuckDetector;
 8  
 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
 9  
 import cz.cuni.amis.pogamut.base.utils.logging.LogCategory;
 10  
 import cz.cuni.amis.pogamut.base.utils.math.DistanceUtils;
 11  
 import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
 12  
 import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
 13  
 import cz.cuni.amis.pogamut.base3d.worldview.object.Rotation;
 14  
 import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.AgentInfo;
 15  
 import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.Senses;
 16  
 import cz.cuni.amis.pogamut.ut2004.agent.module.utils.TabooSet;
 17  
 import cz.cuni.amis.pogamut.ut2004.agent.navigation.IUT2004GetBackToNavGraph;
 18  
 import cz.cuni.amis.pogamut.ut2004.agent.navigation.IUT2004PathRunner;
 19  
 import cz.cuni.amis.pogamut.ut2004.agent.navigation.UT2004RunStraight;
 20  
 import cz.cuni.amis.pogamut.ut2004.agent.navigation.loquenavigator.KefikRunner;
 21  
 import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004DistanceStuckDetector;
 22  
 import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004PositionStuckDetector;
 23  
 import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004TimeStuckDetector;
 24  
 import cz.cuni.amis.pogamut.ut2004.bot.command.AdvancedLocomotion;
 25  
 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
 26  
 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Move;
 27  
 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage;
 28  
 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
 29  
 
 30  
 /**
 31  
  * This class is meant to provide easy "get-back-to-navigation-graph-in-order-I-can-safely-navigate-through-map"
 32  
  * implementation. 
 33  
  * 
 34  
  * Automatically uses {@link UT2004TimeStuckDetector}, {@link UT2004PositionStuckDetector} and {@link UT2004DistanceStuckDetector}.
 35  
  * 
 36  
  * @author Jimmy
 37  
  */
 38  
 public class UT2004GetBackToNavGraph implements IUT2004GetBackToNavGraph {
 39  
 
 40  
         public static final int CLOSE_ENOUGH = 50;
 41  
 
 42  
         public static final double MAX_ANGLE = UT2004RunStraight.MAX_ANGLE;
 43  
         
 44  
         protected UT2004Bot bot;
 45  
         
 46  
         protected AgentInfo info;
 47  
         
 48  
         protected IUT2004PathRunner runner;
 49  
         
 50  
         protected boolean executing;
 51  
         
 52  
         protected LogCategory log;
 53  
         
 54  
         protected int randomMoveDirection;
 55  
 
 56  0
         protected IWorldEventListener<EndMessage> endListener = new IWorldEventListener<EndMessage>() {
 57  
                 
 58  
                 @Override
 59  
                 public void notify(EndMessage event) {
 60  0
                         getBackOnNavGraph();
 61  0
                 }
 62  
                 
 63  
         };
 64  
         
 65  0
         protected List<IStuckDetector> stuckDetectors = new ArrayList<IStuckDetector>();
 66  
 
 67  
         protected ILocated focus;
 68  
         
 69  0
         public UT2004GetBackToNavGraph(UT2004Bot bot, AgentInfo info, AdvancedLocomotion move) {
 70  0
                 this.log = bot.getLogger().getCategory(this.getClass().getSimpleName());
 71  0
                 this.bot = bot;
 72  0
                 this.info = info;                
 73  0
                 this.runner = new KefikRunner(bot, info, move, log);
 74  
                 
 75  0
                 stuckDetectors.add(new UT2004TimeStuckDetector(bot, 3000, 5000));
 76  0
                 stuckDetectors.add(new UT2004PositionStuckDetector(bot));
 77  0
                 stuckDetectors.add(new UT2004DistanceStuckDetector(bot));
 78  
                 
 79  0
                 bot.getWorldView().addEventListener(EndMessage.class, endListener);
 80  0
         }
 81  
         
 82  
         @Override
 83  
         public void addStuckDetector(IStuckDetector stuckDetector) {
 84  0
                 stuckDetectors.add(stuckDetector);
 85  0
         }
 86  
         
 87  
         @Override
 88  
         public void removeStuckDetector(IStuckDetector stuckDetector) {
 89  0
                 stuckDetectors.remove(stuckDetector);
 90  0
         }
 91  
         
 92  
         @Override
 93  
         public void clearStuckDetectors() {
 94  0
                 stuckDetectors.clear();
 95  0
         }
 96  
                 
 97  
         @Override
 98  
         public NavPoint getNearestNavPoint() {
 99  0
                 return info.getNearestNavPoint();
 100  
         }
 101  
         
 102  
         @Override
 103  
         public boolean isOnNavGraph() {
 104  0
                 return info.isOnNavGraph();
 105  
         }
 106  
         
 107  
         @Override
 108  
         public boolean isExecuting() {
 109  0
                 return executing;
 110  
         }
 111  
         
 112  
         @Override
 113  
         public void setFocus(ILocated located) {
 114  0
                 this.focus = located;
 115  0
         }
 116  
         
 117  
         @Override
 118  
         public void backToNavGraph() {
 119  0
                 if (executing) return;
 120  
                 
 121  0
                 if (log != null && log.isLoggable(Level.INFO)) log.info("STARTED");
 122  
                 
 123  0
                 reset();
 124  
                 
 125  0
                 initialLocation = info.getLocation();
 126  
                 
 127  0
                 for (IStuckDetector stuckDetector : stuckDetectors) {                        
 128  0
                         stuckDetector.reset();
 129  0
                         stuckDetector.setEnabled(true);
 130  
                 }
 131  
                         
 132  0
                 executing = true;
 133  0
         }
 134  
         
 135  
         @Override
 136  
         public void stop() {
 137  0
                 if (!executing) return;
 138  0
                 if (log != null && log.isLoggable(Level.INFO)) log.info("STOPPED");
 139  
                                 
 140  0
                 executing = false;
 141  0
                 reset();
 142  
                 
 143  0
                 for (IStuckDetector stuckDetector : stuckDetectors) {
 144  0
                         stuckDetector.setEnabled(false);
 145  
                 }
 146  0
         }
 147  
         
 148  
         //
 149  
         // VARIABLES
 150  
         //
 151  
         
 152  
         protected TabooSet<NavPoint> tried;
 153  
 
 154  
         protected NavPoint tryingNav;
 155  
         
 156  
         protected Location initialLocation;
 157  
         
 158  
         //
 159  
         // RESET
 160  
         // 
 161  
         
 162  
         protected void reset() {
 163  0
                 if (log != null && log.isLoggable(Level.FINER)) log.finer("Reset");
 164  
                 
 165  0
                 if (tried == null) {
 166  0
                         tried = new TabooSet<NavPoint>(bot);
 167  
                 } else {
 168  0
                         tried.clear();
 169  
                 }
 170  
                 
 171  0
                 tryingNav = null;                
 172  0
         }
 173  
         
 174  
         //
 175  
         // EXECUTION
 176  
         //
 177  
 
 178  
         protected void getBackOnNavGraph() {
 179  0
                 if (!executing) return;
 180  
         
 181  0
                 if (isOnNavGraph()) {
 182  
                         // WE'VE MANAGED TO GET BACK ON NAVIGATION GRAPH
 183  0
                         if (log != null && log.isLoggable(Level.INFO)) log.info("Got back to Navigation Graph.");
 184  0
                         stop();
 185  0
                         return;
 186  
                 }
 187  
                 
 188  
                 while (true) {
 189  0
                         if (runToNavPoint()) {
 190  
                                 // WE'RE ON THE WAY...
 191  0
                                 return;
 192  
                         }
 193  
                         // RUNNING FAILED
 194  
                         // => select new navpoint
 195  0
                         while (tryingNav == null) {
 196  0
                                 tryingNav = DistanceUtils.getNearest(tried.filter(bot.getWorldView().getAll(NavPoint.class).values()), info.getLocation());
 197  
                         
 198  
                                 // CHECK SUITABILITY
 199  0
                                 if (tryingNav == null || info.getLocation().getDistance(tryingNav.getLocation()) > 2000) {
 200  
                                         // FAILURE, NO MORE SUITABLE NAV POINTS TO TRY
 201  
                                         // => clear taboo set and start retrying...
 202  0
                                         if (tried.size() == 0) {
 203  
                                                 // TOTAL FAILURE!!! No suitable navpoints :-( lest try to move the bot a bit.
 204  0
                                                 runSomewhere();
 205  
                                                 //stop();
 206  0
                                                 return;
 207  
                                         }
 208  
                                         
 209  0
                                         tried.clear();
 210  0
                                         tryingNav = null;        
 211  
                                         
 212  0
                                         continue;
 213  
                                 }
 214  
                         }
 215  
                         
 216  0
                         if (log != null && log.isLoggable(Level.FINE)) log.fine("Trying to get to: " + tryingNav);
 217  
                         
 218  
                         // NAV POINT CHOSEN
 219  0
                         initialLocation = info.getLocation();
 220  0
                         for (IStuckDetector stuckDetector : stuckDetectors) {
 221  0
                                 stuckDetector.reset();
 222  0
                                 stuckDetector.setBotTarget(tryingNav);
 223  
                         }
 224  0
                         runner.reset();
 225  
                         
 226  
                         // CONTINUE WITH NEXT CYCLE THAT WILL TRY TO RUN TO tryingNav
 227  
                 }
 228  
         }
 229  
         
 230  
         /**
 231  
          * Last resort - keep trying random points 200 UT units from bot location - 90 degrees left, right and backwards. :-)
 232  
          */
 233  
         protected void runSomewhere() {
 234  0
                 randomMoveDirection++;
 235  0
                 if (randomMoveDirection >= 2)
 236  0
                         randomMoveDirection = -1;
 237  
                                         
 238  0
                 Location backwardsLoc = bot.getLocation();
 239  
                 
 240  0
                 Rotation rot = bot.getRotation();
 241  0
                 rot.setYaw(rot.getYaw() + randomMoveDirection * 16000);
 242  0
                 backwardsLoc = backwardsLoc.sub(rot.toLocation().getNormalized().scale(200));                                        
 243  
                 
 244  0
                 double hDistance = bot.getLocation().getDistance2D(backwardsLoc);
 245  0
                 double vDistance = bot.getLocation().getDistanceZ(backwardsLoc);
 246  
                 
 247  0
                 double angle = Math.atan(Math.abs(vDistance) / hDistance);                
 248  0
                 runner.runToLocation(initialLocation, backwardsLoc, null, focus == null ? backwardsLoc : focus, null, angle < MAX_ANGLE);                                
 249  0
         }
 250  
 
 251  
         protected boolean runToNavPoint() {
 252  0
                 if (tryingNav == null) return false;
 253  
                 // WE'RE TRYING TO RUN TO SOME NAVPOINT
 254  
                 
 255  0
                 if (log != null && log.isLoggable(Level.FINE)) log.fine("Running to: " + tryingNav);
 256  
                 
 257  0
                 double hDistance = bot.getLocation().getDistance2D(tryingNav.getLocation());
 258  0
                 double vDistance = bot.getLocation().getDistanceZ(tryingNav.getLocation());
 259  
                 
 260  0
                 double angle = Math.atan(Math.abs(vDistance) / hDistance);
 261  
                 
 262  0
                 if (runner.runToLocation(initialLocation, tryingNav.getLocation(), null, focus == null ? tryingNav.getLocation() : focus, null, angle < MAX_ANGLE)) {
 263  
                         // RUNNING SEEMS OK
 264  
                         // => check stuck detectors
 265  0
                         for (IStuckDetector stuckDetector : stuckDetectors) {
 266  0
                                 if (stuckDetector.isStuck()) {
 267  
                                         // WE'RE STUCK!
 268  0
                                         runFailed();
 269  0
                                         return false;
 270  
                                 }
 271  
                         }
 272  
                         
 273  0
                         return true;
 274  
                 } else {
 275  
                         // RUNNER FAILED...
 276  0
                         runFailed();                        
 277  0
                         return false;
 278  
                 }
 279  
         }
 280  
 
 281  
         protected void runFailed() {
 282  
                 // RUNNING FAILED 
 283  
                 // => ban nav point
 284  0
                 tried.add(tryingNav);
 285  0
                 tryingNav = null;
 286  0
         }
 287  
 
 288  
 }