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  	public UT2004DistanceStuckDetector(UT2004Bot bot) {
68  		if (this.log == null) {
69  			this.log = bot.getLogger().getCategory(this.getClass().getSimpleName());
70  		}
71  		this.bot = bot;		
72  		selfListener = new SelfListener(bot.getWorldView());
73  		
74  		this.historyLength = 2;
75  		
76  		if (this.historyLength < 0) throw new IllegalArgumentException("historyLength can't be < 0");
77  		
78  		this.distanceHistory = new ArrayList<Double>(this.historyLength);
79  		this.positionHistory = new ArrayList<Location>(this.historyLength);
80  	}
81  	
82  	@Override
83  	public void setEnabled(boolean state) {
84  		if (this.enabled == state) return;
85  		this.enabled = state;		
86  	}
87  		
88  	@Override
89  	public void setBotWaiting(boolean state) {
90  		this.botWaiting = state;
91  		if (this.botWaiting) {
92  			Location botTarget = this.botTarget;
93  			reset();
94  			this.botTarget = botTarget;
95  		}
96  	}
97  	
98  	@Override
99  	public void setBotTarget(ILocated target) {
100 		if (this.botTarget != null) {
101 			if (log != null && log.isLoggable(Level.FINER)) log.finer("TARGET APPROACHING STUCK DETECTOR - previous stats:");
102 			if (log != null && log.isLoggable(Level.FINER)) log.finer("  Closing count:              " + closingCount);
103 			if (log != null && log.isLoggable(Level.FINER)) log.finer("  Distancing count:           " + distancingCount);
104 			
105 			if (closingCount > 1) ++totalClosingCountMoreThanOne;
106 			if (distancingCount > 1) ++totalDistancingCountMoreThanOne;
107 			
108 			if (log != null && log.isLoggable(Level.FINER)) log.finer("  Total closing count > 1:    " + totalClosingCountMoreThanOne);
109 			if (log != null && log.isLoggable(Level.FINER)) log.finer("  Total distancing count > 1: " + totalDistancingCountMoreThanOne);
110 		}
111 		
112 		boolean botWaiting = this.botWaiting;
113 		reset();
114 		this.botWaiting = botWaiting;
115 		
116 		if (target == null || target instanceof Player) {
117 			this.botTarget = null;
118 		} else {
119 			this.botTarget = target.getLocation();
120 		}
121 		if (this.botTarget == null) {
122 			stuck = false;
123 		}
124 	}
125 	
126 	public void eventSelf(IWorldObjectEvent<Self> event) {
127 		if (!enabled) return;   // not enabled
128 		if (botWaiting) return; // we're just waiting...
129 		
130 		if (botTarget == null) return; // nothing to watch over
131 		
132 		Location currentLocation = event.getObject().getLocation();
133 		double currentDistance = currentLocation.getDistance(botTarget);
134 		
135 		positionHistory.add(currentLocation);
136 		distanceHistory.add(currentDistance);
137 		
138 		if (positionHistory.size() == 1) return; // not enought info yet
139 		
140 		Location previousLocation = positionHistory.get(positionHistory.size()-2);
141 		double previousDistance = distanceHistory.get(distanceHistory.size()-2);
142 		
143 		boolean currentClosing = currentDistance < previousDistance;
144 		boolean currentDistancing = !currentClosing;
145 		
146 		if (closing == null) {
147 			// positionHistory.size() == 2
148 			closing = currentClosing;
149 			distancing = currentDistancing;
150 			closingCount = closing ? 1 : 0;
151 			distancingCount = distancing ? 1 : 0;
152 			return;
153 		}
154 		
155 		// WE HAVE ALL SET UP TO CHECK TARGET-APPROACHING-STUCK
156 		
157 		boolean previousClosing = closing;
158 		boolean previousDistancing = distancing;
159 		
160 		this.closing = currentClosing;
161 		this.distancing = currentDistancing;
162 		
163 		if (currentClosing) {
164 			// WE'RE CURRENTLY CLOSING TO TARGET
165 			if (previousClosing) {
166 				// AND WE'VE BEEN CLOSING PREVIOUSLY AS WELL
167 				// => all proceeds ok so far...				
168 			} else {
169 				++closingCount;
170 			}			
171 		} else {
172 			// WE'RE DISTANCING
173 			if (previousDistancing) {
174 				// AND WE'VE BEEN DISTANCING PREVIOUSLY AS WELL
175 				// ... hmmmmm
176 			} else {
177 				++distancingCount;
178 				if (distancingCount > 1) {
179 					if (log != null && log.isLoggable(Level.WARNING)) log.warning("Bot stuck detected, #closing " + closingCount + ", #distancing " + distancingCount); 
180 					stuck = true;
181 				}
182 			}
183 		}
184 		
185 		if (log != null && log.isLoggable(Level.FINER)) log.finer("TARGET APPROACHING STUCK DETECTOR");
186 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Current distance:    " + currentDistance);
187 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Current closing:     " + currentClosing);
188 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Current distancing:  " + currentDistancing);
189 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Previous closing:    " + previousClosing);
190 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Previous distancing: " + previousDistancing);
191 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Closing count:       " + closingCount);
192 		if (log != null && log.isLoggable(Level.FINER)) log.finer("  Distancing count:    " + distancingCount);
193 	}
194 
195 	
196 	@Override
197 	public boolean isStuck() {
198 		return stuck;
199 	}
200 
201 	@Override
202 	public void reset() {
203 		if (log != null && log.isLoggable(Level.FINER)) log.finer("Reset.");
204 		this.distanceHistory.clear();
205 		this.positionHistory.clear();
206 		closing = null;
207 		distancing = null;
208 		closingCount = 0;
209 		distancingCount = 0;
210 		stuck = false;
211 		botTarget = null;
212 		botWaiting = false;
213 	}
214 
215 	
216 
217 }