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
70
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;
134 if (botWaiting) return;
135
136 if (botTarget == null) return;
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;
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
154 closing = currentClosing;
155 distancing = currentDistancing;
156 closingCount = closing ? 1 : 0;
157 distancingCount = distancing ? 1 : 0;
158 return;
159 }
160
161
162
163 boolean previousClosing = closing;
164 boolean previousDistancing = distancing;
165
166 this.closing = currentClosing;
167 this.distancing = currentDistancing;
168
169 if (currentClosing) {
170
171 if (previousClosing) {
172
173
174 } else {
175 ++closingCount;
176 }
177 } else {
178
179 if (previousDistancing) {
180
181
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 }