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