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