View Javadoc

1   package cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   import java.util.logging.Level;
6   import java.util.logging.Logger;
7   
8   import cz.cuni.amis.pogamut.base.agent.navigation.IStuckDetector;
9   import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
10  import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
11  import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
12  import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectListener;
13  import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
14  import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
15  import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
16  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage;
17  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
18  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Self;
19  
20  public class UT2004DistanceStuckDetector implements IStuckDetector {
21  
22  	private UT2004Bot bot;
23  	
24  	private Location botTarget;
25  	
26  	private boolean botWaiting = false;
27  	
28  	private int historyLength;
29  	
30  	private List<Location> positionHistory;
31  	
32  	private List<Double> distanceHistory;
33  	
34  	private Boolean closing;
35  	
36  	private Boolean distancing;
37  	
38  	private int closingCount = 0;
39  	
40  	private int distancingCount = 0;
41  	
42  	private boolean stuck = false;
43  	
44  	private boolean enabled = false;
45  	
46  	private int totalClosingCountMoreThanOne = 0;
47  	private int totalDistancingCountMoreThanOne = 0;
48  
49  	
50  	private class SelfListener implements IWorldObjectListener<Self> {
51  
52  		public SelfListener(IWorldView worldView) {
53  			worldView.addObjectListener(Self.class, this);
54  		}
55  		
56  		@Override
57  		public void notify(IWorldObjectEvent<Self> event) {
58  			eventSelf(event);
59  		}
60  		
61  	};
62  	
63  	private SelfListener selfListener;
64  	
65  	private Logger log;
66  
67  	private double minMovementZ;
68  
69  	public UT2004DistanceStuckDetector(UT2004Bot bot) {
70  		if (this.log == null) {
71  			this.log = bot.getLogger().getCategory(this.getClass().getSimpleName());
72  		}
73  		this.bot = bot;		
74  		selfListener = new SelfListener(bot.getWorldView());
75  		
76  		this.historyLength = 2;
77  		
78  		if (this.historyLength < 0) throw new IllegalArgumentException("historyLength can't be < 0");
79  		
80  		this.distanceHistory = new ArrayList<Double>(this.historyLength);
81  		this.positionHistory = new ArrayList<Location>(this.historyLength);
82  	}
83  	
84  	@Override
85  	public void setEnabled(boolean state) {
86  		if (this.enabled == state) return;
87  		this.enabled = state;		
88  	}
89  		
90  	@Override
91  	public void setBotWaiting(boolean state) {
92  		this.botWaiting = state;
93  		if (this.botWaiting) {
94  			Location botTarget = this.botTarget;
95  			reset();
96  			this.botTarget = botTarget;
97  		}
98  	}
99  	
100 	@Override
101 	public void setBotTarget(ILocated target) {
102 		if (this.botTarget != null) {
103 			if (log != null && log.isLoggable(Level.FINER)) log.finer("TARGET APPROACHING STUCK DETECTOR - previous stats:");
104 			if (log != null && log.isLoggable(Level.FINER)) log.finer("  Closing count:              " + closingCount);
105 			if (log != null && log.isLoggable(Level.FINER)) log.finer("  Distancing count:           " + distancingCount);
106 			
107 			if (closingCount > 1) ++totalClosingCountMoreThanOne;
108 			if (distancingCount > 1) ++totalDistancingCountMoreThanOne;
109 			
110 			if (log != null && log.isLoggable(Level.FINER)) log.finer("  Total closing count > 1:    " + totalClosingCountMoreThanOne);
111 			if (log != null && log.isLoggable(Level.FINER)) log.finer("  Total distancing count > 1: " + totalDistancingCountMoreThanOne);
112 		}
113 		
114 		boolean botWaiting = this.botWaiting;
115 		reset();
116 		this.botWaiting = botWaiting;
117 		
118 		if (target == null || target instanceof Player) {
119 			this.botTarget = null;
120 		} else {
121 			this.botTarget = target.getLocation();
122 		}
123 		if (this.botTarget == null) {
124 			stuck = false;
125 		}
126 	}
127 	
128 	public void eventSelf(IWorldObjectEvent<Self> event) {
129 		if (!enabled) return;   // not enabled
130 		if (botWaiting) return; // we're just waiting...
131 		
132 		if (botTarget == null) return; // nothing to watch over
133 		
134 		Location currentLocation = event.getObject().getLocation();
135 		double currentDistance = currentLocation.getDistance(botTarget);
136 		
137 		positionHistory.add(currentLocation);
138 		distanceHistory.add(currentDistance);
139 		
140 		if (positionHistory.size() == 1) return; // not enought info yet
141 		
142 		Location previousLocation = positionHistory.get(positionHistory.size()-2);
143 		double previousDistance = distanceHistory.get(distanceHistory.size()-2);
144 		
145 		boolean currentClosing = currentDistance < previousDistance;
146 		boolean currentDistancing = !currentClosing;
147 		
148 		if (closing == null) {
149 			// positionHistory.size() == 2
150 			closing = currentClosing;
151 			distancing = currentDistancing;
152 			closingCount = closing ? 1 : 0;
153 			distancingCount = distancing ? 1 : 0;
154 			return;
155 		}
156 		
157 		// WE HAVE ALL SET UP TO CHECK TARGET-APPROACHING-STUCK
158 		
159 		boolean previousClosing = closing;
160 		boolean previousDistancing = distancing;
161 		
162 		this.closing = currentClosing;
163 		this.distancing = currentDistancing;
164 		
165 		if (currentClosing) {
166 			// WE'RE CURRENTLY CLOSING TO TARGET
167 			if (previousClosing) {
168 				// AND WE'VE BEEN CLOSING PREVIOUSLY AS WELL
169 				// => all proceeds ok so far...				
170 			} else {
171 				++closingCount;
172 			}			
173 		} else {
174 			// WE'RE DISTANCING
175 			if (previousDistancing) {
176 				// AND WE'VE BEEN DISTANCING PREVIOUSLY AS WELL
177 				// ... hmmmmm
178 			} else {
179 				++distancingCount;
180 				if (distancingCount > 1) {
181 					if (log != null && log.isLoggable(Level.WARNING)) log.warning("Bot stuck detected, #closing " + closingCount + ", #distancing " + distancingCount); 
182 					stuck = true;
183 				}
184 			}
185 		}
186 		
187 		if (log != null && log.isLoggable(Level.FINER)) log.finer("TARGET APPROACHING STUCK DETECTOR");
188 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Current distance:    " + currentDistance);
189 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Current closing:     " + currentClosing);
190 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Current distancing:  " + currentDistancing);
191 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Previous closing:    " + previousClosing);
192 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Previous distancing: " + previousDistancing);
193 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Closing count:       " + closingCount);
194 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Distancing count:    " + distancingCount);
195 	}
196 	
197 	@Override
198 	public boolean isStuck() {
199 		return stuck;
200 	}
201 
202 	@Override
203 	public void reset() {
204 		if (log != null && log.isLoggable(Level.FINER)) log.finer("Reset.");
205 		this.distanceHistory.clear();
206 		this.positionHistory.clear();
207 		closing = null;
208 		distancing = null;
209 		closingCount = 0;
210 		distancingCount = 0;
211 		stuck = false;
212 		botTarget = null;
213 		botWaiting = false;
214 	}
215 
216 	
217 
218 }