1 package cz.cuni.amis.pogamut.emohawk.agent.module.sensomotoric;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.logging.Level;
6
7 import SteeringProperties.ObstacleAvoidanceProperties;
8 import SteeringProperties.PathFollowingProperties;
9 import SteeringProperties.PeopleAvoidanceProperties;
10 import SteeringProperties.StickToPathProperties;
11 import SteeringProperties.SteeringProperties.BehaviorType;
12
13 import cz.cuni.amis.pogamut.base.agent.navigation.IPathExecutorState;
14 import cz.cuni.amis.pogamut.base.agent.navigation.IPathFuture;
15 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
16 import cz.cuni.amis.pogamut.base.utils.logging.LogCategory;
17 import cz.cuni.amis.pogamut.base.utils.math.DistanceUtils;
18 import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
19 import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
20 import cz.cuni.amis.pogamut.ut2004.agent.navigation.IUT2004GetBackToNavGraph;
21 import cz.cuni.amis.pogamut.ut2004.agent.navigation.IUT2004PathExecutor;
22 import cz.cuni.amis.pogamut.ut2004.agent.navigation.IUT2004RunStraight;
23 import cz.cuni.amis.pogamut.ut2004.agent.navigation.floydwarshall.FloydWarshallMap;
24 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
25 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Stop;
26 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage;
27 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Item;
28 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
29 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
30 import cz.cuni.amis.utils.flag.FlagListener;
31
32
33
34
35
36
37
38
39
40
41 public class EmohawkNavigation {
42
43
44 protected static final int NEW_PATH_DISTANCE_THRESHOLD = 40;
45
46 protected static final int ARRIVED_AT_LOCATION_XY_THRESHOLD = 50;
47
48 protected static final int ARRIVED_AT_LOCATION_Z_THRESHOLD = 100;
49
50 protected static final double PLAYER_DISTANCE_TRASHOLD = 600;
51
52 public static final double AT_PLAYER = 150;
53
54 public static final double AT_LOCATION = 150;
55
56
57 protected LogCategory log;
58
59 private Steering steering;
60
61 protected FloydWarshallMap fwMap;
62
63 protected UT2004Bot bot;
64
65 protected IWorldEventListener<EndMessage> endMessageListener = new IWorldEventListener<EndMessage>() {
66 @Override
67 public void notify(EndMessage event) {
68 navigate();
69 }
70 };
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 public EmohawkNavigation(UT2004Bot bot, Steering steering, FloydWarshallMap fwMap) {
86 this.log = bot.getLogger().getCategory(this.getClass().getSimpleName());
87 this.bot = bot;
88
89 this.steering = steering;
90 this.fwMap = fwMap;
91
92 initListeners();
93 }
94
95 private void initListeners() {
96 bot.getWorldView().addEventListener(EndMessage.class, endMessageListener);
97 }
98
99
100
101
102
103 public boolean isNavigating() {
104 return navigating;
105 }
106
107 public void setFocus(ILocated located) {
108 throw new UnsupportedOperationException("Not implemented yet.");
109 }
110
111 public void stopNavigation() {
112 reset(true);
113 bot.getAct().act(new Stop());
114 }
115
116 public void navigate(ILocated target) {
117 if (target == null) {
118 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Cannot navigate to NULL target!");
119 stopNavigation();
120 return;
121 }
122
123 if (target instanceof Player) {
124
125 navigate((Player)target);
126 return;
127 }
128
129 if (navigating) {
130 if (currentTarget == target || currentTarget.getLocation().equals(target.getLocation())) {
131
132 return;
133 }
134
135
136 reset(false);
137 }
138
139 if (log != null && log.isLoggable(Level.FINE)) log.fine("Start navigating to: " + target);
140
141 currentTarget = target;
142
143 startNavigate();
144 }
145
146 public void navigate(Player player) {
147 if (player == null) {
148 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Cannot navigate to NULL player!");
149 return;
150 }
151
152 if (navigating) {
153 if (currentTarget == player) {
154
155 return;
156 }
157
158
159 reset(false);
160 }
161
162 if (log != null && log.isLoggable(Level.FINE)) log.fine("Start pursuing: " + player);
163
164 currentTarget = player.getLocation();
165
166 currentTargetPlayer = player;
167
168 startNavigate();
169 }
170
171 public NavPoint getNearestNavPoint(ILocated location) {
172 if (location == null) return null;
173 if (location instanceof NavPoint) return (NavPoint)location;
174 if (location instanceof Item) {
175 if (((Item)location).getNavPoint() != null) return ((Item)location).getNavPoint();
176 }
177 return DistanceUtils.getNearest(bot.getWorldView().getAll(NavPoint.class).values(), location);
178 }
179
180 public List<ILocated> getCurrentPathCopy() {
181 List<ILocated> result = new ArrayList();
182 if (currentFuturePath != null) {
183 result.addAll(currentFuturePath.get());
184 }
185 return result;
186 }
187
188 public List<ILocated> getCurrentPathDirect() {
189 if (currentFuturePath != null) {
190 return currentFuturePath.get();
191 }
192 return null;
193 }
194
195 public ILocated getCurrentTarget() {
196 return currentTarget;
197 }
198
199 public Player getCurrentTargetPlayer() {
200 if (currentTarget instanceof Player) return (Player) currentTarget;
201 return null;
202 }
203
204 public NavPoint getCurrentTargetNavPoint() {
205 if (currentTarget instanceof NavPoint) return (NavPoint) currentTarget;
206 return null;
207 }
208
209
210 public ILocated getLastTarget() {
211 return lastTarget;
212 }
213
214 public NavPoint getLastTargetPlayer() {
215 if (lastTarget instanceof Player) return (NavPoint)lastTarget;
216 return null;
217 }
218
219 public NavPoint getLastTargetNavPoint() {
220 if (lastTarget instanceof NavPoint) return (NavPoint)lastTarget;
221 return null;
222 }
223
224
225
226
227
228
229 protected ILocated lastTarget = null;
230
231 protected Player lastTargetPlayer = null;
232
233 protected ILocated currentTarget = null;
234
235 protected Player currentTargetPlayer = null;
236
237 protected NavPoint fromNavPoint;
238
239 protected NavPoint toNavPoint;
240
241 protected IPathFuture currentFuturePath;
242
243 protected boolean navigating = false;
244
245 protected boolean runningStraightToPlayer = false;
246
247 protected Location runningStraightToPlayerFailedAt = null;
248
249
250
251
252
253 protected void startNavigate() {
254 if (!navigating) {
255 if (steering.isNavigating()) steering.stopNavigation();
256 steering.clearAllSteerings();
257 }
258 navigating = true;
259 navigate();
260 }
261
262 protected void navigate() {
263 if (!navigating) return;
264
265 if (log != null && log.isLoggable(Level.FINE)) {
266 log.fine("NAVIGATING");
267 }
268 if (currentTargetPlayer != null) {
269 if (log != null && log.isLoggable(Level.FINE)) log.fine("Pursuing " + currentTargetPlayer);
270 navigatePlayer();
271 } else {
272 if (log != null && log.isLoggable(Level.FINE)) log.fine("Navigating to " + currentTarget);
273 navigateLocation();
274 }
275 }
276
277 private void navigateLocation() {
278 if (steering.isNavigating()) {
279 if (log != null && log.isLoggable(Level.FINE)) log.fine("Steering running");
280
281 if (atLocation(currentTarget)) {
282 reset(true);
283 }
284
285 return;
286 }
287
288 fromNavPoint = getNearestNavPoint(bot.getLocation());
289 toNavPoint = getNearestNavPoint(currentTarget);
290
291 if (log != null && log.isLoggable(Level.FINE)) log.fine("Running from " + fromNavPoint.getId().getStringId() + " to " + toNavPoint.getId().getStringId());
292
293 currentFuturePath = fwMap.computePath(fromNavPoint, toNavPoint);
294
295 if (currentFuturePath == null || currentFuturePath.get() == null || currentFuturePath.get().size() == 0) {
296 log.warning("NON EXISTING PATH BETWEEN: " + fromNavPoint.getId().getStringId() + " -> " + toNavPoint.getId().getStringId());
297 }
298
299
300
301
302
303 processPathFuture(currentFuturePath);
304
305
306 PathFollowingProperties pathFollowingProperties = new PathFollowingProperties();
307 pathFollowingProperties.setBehaviorType(BehaviorType.ADVANCED);
308 pathFollowingProperties.setTargetLocation(currentTarget.getLocation());
309 pathFollowingProperties.setPath(currentFuturePath);
310 steering.addPathFollowingSteering(pathFollowingProperties);
311
312 PeopleAvoidanceProperties peopleAvoidanceProperties = new PeopleAvoidanceProperties();
313 peopleAvoidanceProperties.setBehaviorType(BehaviorType.ADVANCED);
314 peopleAvoidanceProperties.setAcceleration(true);
315 peopleAvoidanceProperties.setCircumvention(true);
316 peopleAvoidanceProperties.setDeceleration(true);
317 steering.addPeopleAvoidanceSteering(peopleAvoidanceProperties);
318
319 ObstacleAvoidanceProperties obstacleAvoidanceProperties = new ObstacleAvoidanceProperties();
320 obstacleAvoidanceProperties.setBehaviorType(BehaviorType.ADVANCED);
321 steering.addObstacleAvoidanceSteering(obstacleAvoidanceProperties);
322
323
324
325
326
327 steering.startNavigation();
328 }
329
330 private boolean atLocation(ILocated currentTarget) {
331 return bot.getLocation().getDistance(currentTarget.getLocation()) < AT_LOCATION;
332 }
333
334 private void navigatePlayer() {
335 throw new UnsupportedOperationException("Not implemented yet.");
336 }
337
338
339
340
341
342
343 protected void processPathFuture(IPathFuture futurePath) {
344 List<ILocated> pathList = futurePath.get();
345
346 if (pathList == null) {
347
348 return;
349 }
350
351 if (!pathList.isEmpty()) {
352 ILocated lastPathElement = pathList.get(pathList.size() - 1);
353 if (lastPathElement.getLocation().getDistance(currentTarget.getLocation()) > NEW_PATH_DISTANCE_THRESHOLD) {
354 currentFuturePath.get().add(currentTarget);
355 }
356 } else {
357 currentFuturePath.get().add(currentTarget);
358 }
359 }
360
361 protected void reset(boolean stopGetBackToNavGraph) {
362 if (currentTarget != null) {
363 lastTarget = currentTarget;
364 lastTargetPlayer = currentTargetPlayer;
365 }
366
367 navigating = false;
368
369 currentTarget = null;
370 currentTargetPlayer = null;
371
372 fromNavPoint = null;
373 toNavPoint = null;
374
375 currentFuturePath = null;
376
377 runningStraightToPlayer = false;
378 runningStraightToPlayerFailedAt = null;
379
380 steering.stopNavigation();
381 steering.clearAllSteerings();
382 }
383
384 }