1 package SteeringStuff;
2
3 import SocialSteeringsBeta.TriangleSteer;
4 import java.util.HashMap;
5 import java.util.Random;
6
7 import javax.vecmath.Vector3d;
8
9 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
10 import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
11 import cz.cuni.amis.pogamut.base3d.worldview.object.Rotation;
12 import cz.cuni.amis.pogamut.ut2004.agent.module.sensomotoric.Raycasting;
13 import cz.cuni.amis.pogamut.ut2004.bot.command.AdvancedLocomotion;
14 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
15 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Configuration;
16 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.PlayAnimation;
17 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage;
18 import javax.vecmath.Tuple3d;
19
20 import SteeringProperties.*;
21 import Steerings.*;
22
23
24
25
26 public class SteeringManager {
27
28
29 public static final boolean DEBUG = false;
30
31
32 protected UT2004Bot botself;
33
34 protected AdvancedLocomotion locomotion;
35 protected RaycastingManager rayManager;
36 private HashMap<SteeringType,ISteering> mySteerings;
37 public HashMap<SteeringType,Double> steeringWeights;
38 private HashMap<SteeringType,Vector3d> steeringForces;
39 private Vector3d myActualVelocity;
40 protected Vector3d myNextVelocity;
41 protected double multiplier;
42 private double lastVeloWeight = 2;
43 private boolean useLastVeloWeight = false;
44
45 public static final double MAX_FORCE = 2000;
46
47 protected static final double WALK_VELOCITY_LENGTH=220;
48
49
50 private static final double MIN_VALUE_TO_SUM = 0.3*WALK_VELOCITY_LENGTH;
51 public static final Location BASIC_LOCATION=new Location(800,-1500,-3446.65);
52
53
54
55
56
57
58 protected boolean drawRaycasting;
59
60
61 private boolean canEnlargeVelocity;
62
63 private boolean WAPath = true;
64 public static boolean Thomas = false;
65 private boolean turning = true;
66 private boolean WA_debugg = true;
67
68
69
70
71
72 private IWorldEventListener<EndMessage> endMessageListener = new IWorldEventListener<EndMessage>() {
73 @Override
74 public void notify(EndMessage event) {
75
76 run();
77 }
78 };
79
80
81
82
83
84
85
86
87 public SteeringManager(UT2004Bot bot, Raycasting raycasting, AdvancedLocomotion locomotion) {
88 this.botself = bot;
89
90 this.locomotion = locomotion;
91 this.multiplier = 1;
92 rayManager = new RaycastingManager(botself, raycasting);
93 mySteerings = new HashMap<SteeringType,ISteering>();
94 steeringWeights = new HashMap<SteeringType, Double>();
95 steeringForces = new HashMap<SteeringType, Vector3d>();
96 steeringManagerInitialized();
97 myActualVelocity = new Vector3d();
98 myNextVelocity = new Vector3d();
99 drawRaycasting = false;
100 canEnlargeVelocity = true;
101 }
102
103
104
105
106
107
108
109
110 public SteeringManager(UT2004Bot bot, Raycasting raycasting, AdvancedLocomotion locomotion, double multiplier) {
111 this.botself = bot;
112
113 this.locomotion = locomotion;
114 this.multiplier = multiplier;
115 rayManager = new RaycastingManager(botself, raycasting);
116 mySteerings = new HashMap<SteeringType,ISteering>();
117 steeringWeights = new HashMap<SteeringType, Double>();
118 steeringForces = new HashMap<SteeringType, Vector3d>();
119 steeringManagerInitialized();
120 myActualVelocity = new Vector3d();
121 myNextVelocity = new Vector3d();
122 drawRaycasting = false;
123 canEnlargeVelocity = true;
124 }
125
126 private void steeringManagerInitialized() {
127 locomotion.setWalk();
128 if (Thomas) {
129 botself.getAct().act(new PlayAnimation().setName("walk_loop").setLoop(true));
130 }
131 botself.getAct().act(new Configuration().setDrawTraceLines(drawRaycasting).setAutoTrace(true).setSpeedMultiplier((double)1));
132 }
133
134
135 public void addSteering(SteeringType type) {
136 addSteering(type, 1);
137 }
138
139
140 public void addSteering(SteeringType type, double weight) {
141 switch (type) {
142 case OBSTACLE_AVOIDANCE:
143 mySteerings.put(type, new ObstacleAvoidanceSteer(botself, rayManager));
144 break;
145 case TARGET_APPROACHING:
146 mySteerings.put(type, new TargetApproachingSteer(botself));
147 break;
148 case LEADER_FOLLOWING:
149 mySteerings.put(type, new LeaderFollowingSteer(botself));
150 break;
151 case PATH_FOLLOWING:
152 if (WAPath && mySteerings.containsKey(SteeringType.WALK_ALONG)) {
153
154 } else {
155 mySteerings.put(type, new PathFollowingSteer(botself));
156 }
157 break;
158 case PEOPLE_AVOIDANCE:
159 mySteerings.put(type, new PeopleAvoidanceSteer(botself));
160 break;
161 case WALK_ALONG:
162 mySteerings.put(type, new WalkAlongSteer(botself));
163 break;
164 case WALL_FOLLOWING:
165 mySteerings.put(type, new WallFollowingSteer(botself, rayManager));
166 break;
167 case TRIANGLE:
168 mySteerings.put(type, new TriangleSteer(botself));
169 break;
170 }
171 steeringWeights.put(type, new Double(weight));
172 }
173
174
175 public boolean hasSteering(SteeringType type) {
176 return mySteerings.containsKey(type);
177 }
178
179
180 public void removeSteering(SteeringType type) {
181 if ((type == SteeringType.OBSTACLE_AVOIDANCE) || (type == SteeringType.WALL_FOLLOWING)) {
182 rayManager.removeRays(type);
183 }
184 mySteerings.remove(type);
185 steeringWeights.remove(type);
186 }
187
188
189 public void setSteeringProperties(SteeringType type, SteeringProperties newProperties) {
190 ISteering steer = mySteerings.get(type);
191 if (steer!=null) steer.setProperties(newProperties);
192 }
193
194
195
196
197
198 public void run() {
199 steeringForces.clear();
200
201 Vector3d velocity = botself.getVelocity().getVector3d();
202
203 if (SteeringManager.DEBUG) System.out.println("Velocity "+velocity+" length "+velocity.length());
204
205
206 Vector3d nextVelocity = new Vector3d(velocity.x, velocity.y, velocity.z);
207
208 double actualWeight;
209
210 if (useLastVeloWeight) {
211 actualWeight = lastVeloWeight;
212 } else {
213 actualWeight = 3 - velocity.length()/WALK_VELOCITY_LENGTH;
214 if (actualWeight <1)
215 actualWeight = 1;
216 else if (actualWeight > 2)
217 actualWeight = 2;
218 if (velocity.length() == 0)
219 actualWeight = 0;
220 }
221
222
223 nextVelocity.scale(actualWeight);
224
225 myActualVelocity = new Vector3d(nextVelocity.x, nextVelocity.y, nextVelocity.z);
226 Vector3d myStopVelocity = new Vector3d(nextVelocity.x, nextVelocity.y, nextVelocity.z);
227
228 double totalWeight = actualWeight;
229
230 boolean everyoneWantsToGoFaster = canEnlargeVelocity;
231 RefBoolean wantsToGoFaster = new RefBoolean(false);
232 RefBoolean wantsToStop = new RefBoolean(false);
233 Location focusLoc = new Location(0,0,0);
234
235 for(SteeringType stType : mySteerings.keySet()) {
236 ISteering steering = mySteerings.get(stType);
237 Location newFocus = new Location(0, 0, 0);
238 Vector3d newVelocity = setVelocitySpecific(steering, wantsToGoFaster, wantsToStop, newFocus);
239 focusLoc = setFocusSpecific(stType,wantsToStop.getValue(),newFocus,focusLoc);
240 if (wantsToStop.getValue()) {
241 newVelocity.x = -myStopVelocity.x;
242 newVelocity.y = -myStopVelocity.y;
243 newVelocity.z = -myStopVelocity.z;
244 myStopVelocity.sub(newVelocity);
245 everyoneWantsToGoFaster = false;
246 if (SteeringManager.DEBUG) System.out.println("We stop.");
247 wantsToStop.setValue(false);
248 } else {
249 if (newVelocity.length() > MAX_FORCE) newVelocity.scale(MAX_FORCE/newVelocity.length());
250 newVelocity.scale(steeringWeights.get(stType));
251 everyoneWantsToGoFaster = everyoneWantsToGoFaster && wantsToGoFaster.getValue();
252 }
253 if (newVelocity.length()>0) {
254
255
256 newVelocity.add((Tuple3d)nextVelocity);
257 nextVelocity = newVelocity;
258 if (newVelocity.length() > MIN_VALUE_TO_SUM)
259 totalWeight += steeringWeights.get(stType);
260 }
261 if (SteeringManager.DEBUG) System.out.println(steering.toString()+"| length "+newVelocity.length()+" | weight: "+steeringWeights.get(stType));
262 steeringForces.put(stType, newVelocity);
263 }
264 if (SteeringManager.DEBUG) System.out.print("Sum "+nextVelocity.length()+" TotalWeight: "+totalWeight);
265 if (totalWeight > 0) {
266 nextVelocity.scale(1/totalWeight);
267 }
268 if (SteeringManager.DEBUG) System.out.println(" Result "+nextVelocity.length());
269
270 moveTheBot(nextVelocity, everyoneWantsToGoFaster, focusLoc);
271 }
272
273
274
275
276 public void moveTheBot(Vector3d nextVelocity, boolean everyoneWantsToGoFaster, Location focusLocation) {
277
278 double nextVelocityLength = nextVelocity.length() * multiplier;
279
280 if (SteeringManager.DEBUG) System.out.println("next velocity before scaling "+nextVelocityLength+" : "+(nextVelocityLength/WALK_VELOCITY_LENGTH));
281
282 if (nextVelocityLength == 0) {
283 if (!focusLocation.equals(new Location(0,0,0))) {
284 if (turning) {
285 locomotion.turnTo(focusLocation);
286 if (SteeringManager.DEBUG) System.out.println("We stop and turn to the location "+focusLocation);
287 }
288 } else {
289 if (SteeringManager.DEBUG) System.out.println("We stop but don't turn to the location "+focusLocation);
290 }
291 locomotion.stopMovement();
292 if (Thomas) botself.getAct().act(new PlayAnimation().setName("idleanim").setLoop(true));
293
294 myNextVelocity = new Vector3d(0,0,0);
295 return;
296 }
297
298 if (nextVelocityLength < 0.8*WALK_VELOCITY_LENGTH && everyoneWantsToGoFaster) {
299 if (SteeringManager.DEBUG) System.out.println("we enlarge the velocity");
300 nextVelocityLength = 0.8 * WALK_VELOCITY_LENGTH;
301 }
302
303 double nextVelMult = nextVelocityLength / WALK_VELOCITY_LENGTH;
304
305
306
307
308 if (nextVelMult > 2.5) {
309 locomotion.setRun();
310 if (Thomas) botself.getAct().act(new PlayAnimation().setName("run_normal01").setLoop(true));
311 if (SteeringManager.DEBUG) System.out.println("run");
312 if (nextVelMult > 20.5) {
313 nextVelMult = 20.5;
314 }
315 nextVelMult -= 2.5;
316 nextVelMult = nextVelMult/18;
317 nextVelMult = (0.8+nextVelMult);
318 } else {
319 locomotion.setWalk();
320 if (Thomas) botself.getAct().act(new PlayAnimation().setName("walk_loop").setLoop(true));
321 if (SteeringManager.DEBUG) System.out.println("walk");
322 if (nextVelMult > 0.8) {
323 nextVelMult = 0.85 + 0.1*Math.sqrt(10*(nextVelMult - 0.8));
324 } else {
325 nextVelMult = nextVelMult*0.75 + 0.25;
326 }
327 }
328 nextVelocityLength = nextVelMult * WALK_VELOCITY_LENGTH;
329 nextVelocity.normalize();
330 nextVelocity.scale(nextVelocityLength);
331
332 myNextVelocity = new Vector3d(nextVelocity.x, nextVelocity.y, nextVelocity.z);
333
334 if (SteeringManager.DEBUG) System.out.println("next velocity "+nextVelocity.length()+" : "+(nextVelocity.length()/WALK_VELOCITY_LENGTH));
335
336
337 botself.getAct().act(new Configuration().setSpeedMultiplier(nextVelocityLength / WALK_VELOCITY_LENGTH).setAutoTrace(true).setDrawTraceLines(drawRaycasting));
338
339 locomotion.moveTo(new Location(botself.getLocation().x + nextVelocity.x, botself.getLocation().y + nextVelocity.y, botself.getLocation().z));
340
341 if (WA_debugg && mySteerings.containsKey(SteeringType.WALK_ALONG)) {
342 WalkAlongSteer WAsteering = (WalkAlongSteer)mySteerings.get(SteeringType.WALK_ALONG);
343 myActualVelocity = WAsteering.getForceToPartner();
344 if (myActualVelocity == null) {
345 myActualVelocity = new Vector3d(0,0,0);
346 }
347 myNextVelocity = WAsteering.getForceToTarget();
348 if (myNextVelocity == null) {
349 myNextVelocity = new Vector3d(0,0,0);
350 }
351 }
352 }
353
354
355 private Location addLocations(Location focusLoc, Location newFocus) {
356 if (focusLoc.equals(new Location(0,0,0))) return newFocus;
357 if (newFocus.equals(new Location(0,0,0))) return focusLoc;
358 Location result = new Location((focusLoc.x + newFocus.x) / 2, (focusLoc.y + newFocus.y) / 2, (focusLoc.z + newFocus.z) / 2);
359 return result;
360 }
361
362
363 public static Location getRandomStartLocation() {
364 Random random = new Random();
365 int znam = 1;
366 if (random.nextBoolean()) znam = -1;
367 return new Location(BASIC_LOCATION.x - random.nextInt(500)*znam, BASIC_LOCATION.y - random.nextInt(500)*znam, BASIC_LOCATION.z);
368 }
369
370
371 public static Rotation getRandomStartRotation() {
372 Random random = new Random();
373 return new Rotation(0,angleToUTUnits(random.nextInt(360)-180),0);
374 }
375
376
377
378
379
380
381 private static int angleToUTUnits(double angle){
382 return (int) Math.round((angle*65535)/360);
383 }
384
385
386 public HashMap<SteeringType, Vector3d> getSteeringForces() {
387 return steeringForces;
388 }
389
390
391 public Vector3d getMyActualVelocity() {
392 return myActualVelocity;
393 }
394
395
396 public Vector3d getMyNextVelocity() {
397 return myNextVelocity;
398 }
399
400
401 public boolean isDrawRaycasting() {
402 return drawRaycasting;
403 }
404
405
406 public void setDrawRaycasting(boolean drawRaycasting) {
407 this.drawRaycasting = drawRaycasting;
408 }
409
410
411 public void setCanEnlargeVelocity(boolean canEnlargeVelocity) {
412 this.canEnlargeVelocity = canEnlargeVelocity;
413 }
414
415
416 public boolean isCanEnlargeVelocity() {
417 return canEnlargeVelocity;
418 }
419
420
421
422
423 public void setMultiplier(double multiplier) {
424 this.multiplier = multiplier;
425 }
426
427 public void setLastVeloWeight(double lastVeloWeight) {
428 this.lastVeloWeight = lastVeloWeight;
429 }
430
431 public void setUseLastVeloWeight(boolean useLastVeloWeight) {
432 this.useLastVeloWeight = useLastVeloWeight;
433 }
434
435
436
437
438
439 public void start() {
440 if (!botself.getWorldView().isListening(EndMessage.class, endMessageListener))
441 botself.getWorldView().addEventListener(EndMessage.class, endMessageListener);
442 }
443
444
445
446
447
448
449 public void stop() {
450 if (botself.getWorldView().isListening(EndMessage.class, endMessageListener))
451 botself.getWorldView().removeEventListener(EndMessage.class, endMessageListener);
452 }
453
454
455
456
457
458
459 public boolean isNavigating() {
460 return botself.getWorldView().isListening(EndMessage.class, endMessageListener);
461 }
462
463
464
465
466 public void clearSteerings() {
467 for (SteeringType type : mySteerings.keySet()) {
468 removeSteering(type);
469 }
470 }
471
472
473
474
475
476 public LeaderFollowingProperties getLeaderFollowingProperties() {
477 ISteering steering = mySteerings.get(SteeringType.LEADER_FOLLOWING);
478 if (steering != null)
479 return ((LeaderFollowingSteer) steering).getProperties();
480
481 return null;
482 }
483
484
485
486
487
488 public ObstacleAvoidanceProperties getObstacleAvoidanceProperties() {
489 ISteering steering = mySteerings.get(SteeringType.OBSTACLE_AVOIDANCE);
490 if (steering != null)
491 return ((ObstacleAvoidanceSteer) steering).getProperties();
492
493 return null;
494 }
495
496
497
498
499
500 public PathFollowingProperties getPathFollowingProperties() {
501 ISteering steering = mySteerings.get(SteeringType.PATH_FOLLOWING);
502 if (steering != null)
503 return ((PathFollowingSteer) steering).getProperties();
504
505 return null;
506 }
507
508
509
510
511
512 public PeopleAvoidanceProperties getPeopleAvoidanceProperties() {
513 ISteering steering = mySteerings.get(SteeringType.PEOPLE_AVOIDANCE);
514 if (steering != null)
515 return ((PeopleAvoidanceSteer) steering).getProperties();
516
517 return null;
518 }
519
520
521
522
523
524 public TargetApproachingProperties getTargetApproachingProperties() {
525 ISteering steering = mySteerings.get(SteeringType.TARGET_APPROACHING);
526 if (steering != null)
527 return ((TargetApproachingSteer) steering).getProperties();
528
529 return null;
530 }
531
532
533
534
535
536 public WalkAlongProperties getWalkAlongProperties() {
537 ISteering steering = mySteerings.get(SteeringType.WALK_ALONG);
538 if (steering != null)
539 return ((WalkAlongSteer) steering).getProperties();
540
541 return null;
542 }
543
544
545
546
547
548 public WallFollowingProperties getWallFollowingProperties() {
549 ISteering steering = mySteerings.get(SteeringType.WALL_FOLLOWING);
550 if (steering != null)
551 return ((WallFollowingSteer) steering).getProperties();
552
553 return null;
554 }
555
556 public void addLeaderFollowingSteering(LeaderFollowingProperties properties) {
557 addSteering(SteeringType.LEADER_FOLLOWING);
558 setSteeringProperties(SteeringType.LEADER_FOLLOWING, properties);
559 }
560
561 public void removeLeaderFollowingSteering() {
562 removeSteering(SteeringType.LEADER_FOLLOWING);
563 }
564
565 public void setLeaderFollowingSteering(LeaderFollowingProperties properties) {
566 setSteeringProperties(SteeringType.LEADER_FOLLOWING, properties);
567 }
568
569 public boolean isLeaderFollowingActive() {
570 return hasSteering(SteeringType.LEADER_FOLLOWING);
571 }
572
573 public void addObstacleAvoidanceSteering(ObstacleAvoidanceProperties properties) {
574 addSteering(SteeringType.OBSTACLE_AVOIDANCE);
575 setSteeringProperties(SteeringType.OBSTACLE_AVOIDANCE, properties);
576 }
577
578 public void removeObstacleAvoidanceSteering() {
579 removeSteering(SteeringType.OBSTACLE_AVOIDANCE);
580 }
581
582 public void setObstacleAvoidanceSteering(ObstacleAvoidanceProperties properties) {
583 setSteeringProperties(SteeringType.OBSTACLE_AVOIDANCE, properties);
584 }
585
586 public boolean isObstacleAvoidanceActive() {
587 return hasSteering(SteeringType.OBSTACLE_AVOIDANCE);
588 }
589
590 public void addPathFollowingSteering(PathFollowingProperties properties) {
591 addSteering(SteeringType.PATH_FOLLOWING);
592 setSteeringProperties(SteeringType.PATH_FOLLOWING, properties);
593 }
594
595 public void removePathFollowingSteering() {
596 removeSteering(SteeringType.PATH_FOLLOWING);
597 }
598
599 public void setPathFollowingSteering(PathFollowingProperties properties) {
600 setSteeringProperties(SteeringType.PATH_FOLLOWING, properties);
601 }
602
603 public boolean isPathFollowingActive() {
604 return hasSteering(SteeringType.PATH_FOLLOWING);
605 }
606
607 public void addPeopleAvoidanceSteering(PeopleAvoidanceProperties properties) {
608 addSteering(SteeringType.PEOPLE_AVOIDANCE);
609 setSteeringProperties(SteeringType.OBSTACLE_AVOIDANCE, properties);
610 }
611
612 public void removePeopleAvoidanceSteering() {
613 removeSteering(SteeringType.PEOPLE_AVOIDANCE);
614 }
615
616 public void setPeopleAvoidanceSteering(PeopleAvoidanceProperties properties) {
617 setSteeringProperties(SteeringType.PEOPLE_AVOIDANCE, properties);
618 }
619
620 public boolean isPeopleAvoidanceActive() {
621 return hasSteering(SteeringType.PEOPLE_AVOIDANCE);
622 }
623
624 public void addTargetApproachingSteering(TargetApproachingProperties properties) {
625 addSteering(SteeringType.TARGET_APPROACHING);
626 setSteeringProperties(SteeringType.TARGET_APPROACHING, properties);
627 }
628
629 public void removeTargetApproachingSteering() {
630 removeSteering(SteeringType.TARGET_APPROACHING);
631 }
632
633 public void setTargetApproachingSteering(TargetApproachingProperties properties) {
634 setSteeringProperties(SteeringType.TARGET_APPROACHING, properties);
635 }
636
637 public boolean isTargetApproachingActive() {
638 return hasSteering(SteeringType.TARGET_APPROACHING);
639 }
640
641 public void addWalkAlongSteering(WalkAlongProperties properties) {
642 addSteering(SteeringType.WALK_ALONG);
643 setSteeringProperties(SteeringType.WALK_ALONG, properties);
644 }
645
646 public void removeWalkAlongSteering() {
647 removeSteering(SteeringType.WALK_ALONG);
648 }
649
650 public void setWalkAlongSteering(WalkAlongProperties properties) {
651 setSteeringProperties(SteeringType.WALK_ALONG, properties);
652 }
653
654 public boolean isWalkAlongActive() {
655 return hasSteering(SteeringType.WALK_ALONG);
656 }
657
658 public void addWallFollowingSteering(WallFollowingProperties properties) {
659 addSteering(SteeringType.WALL_FOLLOWING);
660 setSteeringProperties(SteeringType.WALL_FOLLOWING, properties);
661 }
662
663 public void removeWallFollowingSteering() {
664 removeSteering(SteeringType.WALL_FOLLOWING);
665 }
666
667 public void setWallFollowingSteering(WallFollowingProperties properties) {
668 setSteeringProperties(SteeringType.WALL_FOLLOWING, properties);
669 }
670
671 public boolean isWallFollowingActive() {
672 return hasSteering(SteeringType.WALL_FOLLOWING);
673 }
674
675
676 protected Location setFocusSpecific(SteeringType steeringType, boolean wantsToStop, Location newFocus, Location focusLoc) {
677 if(wantsToStop)
678 {
679 return addLocations(focusLoc, newFocus);
680 }
681 else
682 {
683 return focusLoc;
684 }
685
686 }
687
688
689
690
691
692
693 protected Vector3d setVelocitySpecific(ISteering steering, RefBoolean wantsToGoFaster, RefBoolean wantsToStop, Location newFocus) {
694 Vector3d newVelocity = steering.run(myActualVelocity, wantsToGoFaster, wantsToStop, newFocus);
695 return newVelocity;
696 }
697
698
699
700 }