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