1 package cz.cuni.amis.pogamut.usar2004.samples;
2
3 import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
4 import cz.cuni.amis.pogamut.base3d.worldview.object.*;
5 import cz.cuni.amis.pogamut.usar2004.agent.*;
6 import cz.cuni.amis.pogamut.usar2004.agent.module.configuration.*;
7 import cz.cuni.amis.pogamut.usar2004.agent.module.datatypes.*;
8 import cz.cuni.amis.pogamut.usar2004.agent.module.geometry.GeoSensorEffecter;
9 import cz.cuni.amis.pogamut.usar2004.agent.module.logic.USAR2004BotLogicController;
10 import cz.cuni.amis.pogamut.usar2004.agent.module.master.*;
11 import cz.cuni.amis.pogamut.usar2004.agent.module.sensor.SensorLaser;
12 import cz.cuni.amis.pogamut.usar2004.agent.module.response.ResponseSensorEffecter;
13 import cz.cuni.amis.pogamut.usar2004.agent.module.sensor.*;
14 import cz.cuni.amis.pogamut.usar2004.communication.messages.datatypes.SensorMount;
15 import cz.cuni.amis.pogamut.usar2004.communication.messages.usarcommands.*;
16 import cz.cuni.amis.pogamut.usar2004.communication.messages.usarinfomessages.NfoMessage;
17 import cz.cuni.amis.pogamut.usar2004.samples.AirScanner.Record;
18 import cz.cuni.amis.pogamut.usar2004.samples.AirScanner.RiskLevel;
19 import cz.cuni.amis.pogamut.usar2004.samples.AirScanner.ScanPreview;
20 import cz.cuni.amis.pogamut.usar2004.samples.AirScanner.State;
21 import cz.cuni.amis.pogamut.usar2004.samples.AirScanner.ToolBox;
22 import cz.cuni.amis.pogamut.usar2004.utils.*;
23 import cz.cuni.amis.utils.exception.PogamutException;
24 import java.awt.geom.Point2D;
25 import java.util.HashMap;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.logging.Level;
30 import javax.swing.SwingUtilities;
31
32
33
34
35
36
37
38 @AgentScoped
39 public class AerialVehicle extends USAR2004BotLogicController<USAR2004Bot>
40 {
41
42
43
44
45
46
47 @Override
48 public void robotInitialized(NfoMessage nfom)
49 {
50 super.robotInitialized(nfom);
51
52
53 logicInitialize(logicModule);
54 getAct().act(new Initialize("USARBot.AirRobot", "AirRobot - aierial sample robot", nfom.getStartPoses().get(0).getName()));
55
56 System.out.println(logicModule.isRunning());
57 }
58
59 @Override
60 public void initializeController(USAR2004Bot bot)
61 {
62 super.initializeController(bot);
63
64
65 }
66
67
68
69
70
71
72
73
74 private final Location destCenter = new Location(-49,-225);
75 private final double destWidth = 774;
76 private final double destHeight = 774;
77 private final double seaLevel = 3;
78
79
80 private final Map<String, Point2D> highRiskAction = new HashMap<String, Point2D>()
81 {
82
83 {
84 put("L4", new math.geom2d.Point2D(-0.95, 0.31));
85 put("R4", new math.geom2d.Point2D(-0.95, -0.31));
86 put("L3", new math.geom2d.Point2D(-0.81, 0.59));
87 put("R3", new math.geom2d.Point2D(-0.81, -0.59));
88 put("L2", new math.geom2d.Point2D(-0.59, 0.81));
89 put("R2", new math.geom2d.Point2D(-0.59, -0.81));
90 put("L1", new math.geom2d.Point2D(-0.31, 0.95));
91 put("R1", new math.geom2d.Point2D(-0.31, -0.95));
92 put("M0", new math.geom2d.Point2D(-1, 0));
93 }
94 };
95 private final Map<String, Double> highRisk = new HashMap<String, Double>()
96 {
97
98 {
99 put("L4", 0.47d);
100 put("R4", 0.47d);
101 put("L3", 0.61d);
102 put("R3", 0.61d);
103 put("L2", 0.86d);
104 put("R2", 0.86d);
105 put("L1", 1.22d);
106 put("R1", 1.22d);
107 put("M0", 1.5d);
108 }
109 };
110 private final Map<String, Double> lowRisk = new HashMap<String, Double>()
111 {
112
113 {
114 put("L4", 1.57d);
115 put("R4", 1.57d);
116 put("L3", 1.91d);
117 put("R3", 1.91d);
118 put("L2", 2.72d);
119 put("R2", 2.72d);
120 put("L1", 3.5d);
121 put("R1", 3.5d);
122 put("M0", 4.2d);
123 }
124 };
125 private final String[] sonarOrder = new String[]
126 {
127 "L4", "L3", "L2", "L1", "M0", "R1", "R2", "R3", "R4"
128 };
129 private final Location zeroPoint = new Location(0, 0, 0);
130 private final int numOfRays = 10;
131 private final double minDensity = 15;
132 private final double scanAltitude = 6;
133 private final int dockWaitPenalty = 8;
134
135 private final double scanningSpeed = 0.2d;
136 private final double flyingSpeed = 0.35d;
137 private final int jammedLimit = 35;
138 private boolean singleFlight = true;
139 private Location destination = destCenter;
140 private double dWidth = destWidth;
141 private double dHeight = destHeight;
142 private Location longStep;
143 private Location shortStep;
144 private double altitude = scanAltitude;
145 private double actAlt = 0;
146 private Location actLoc;
147 private Rotation actRot;
148 private Location nextLoc;
149 private State state = State.DEFAULT;
150 private double speed = 0;
151 private double rotSpeed = 0;
152 private double minDev = 0.9d;
153
154
155
156 private boolean parametersObtained = false;
157 private boolean scanning = false;
158 private double maxLateralVelocity = 0;
159 private double maxLinearVelocity = 0;
160 private double maxRotationalVelocity = 0;
161 private double maxAltitudeVelocity = 0;
162 private boolean risen = false;
163 private int offset = 0;
164 private int cycle = 0;
165 private int cycleStop = 0;
166 private Location startLoc;
167 private String infoToShow = "";
168 private String infoToWrite = "";
169
170
171
172
173
174
175
176
177 @Override
178 public void logic() throws PogamutException
179 {
180 System.out.println("logika");
181 try
182 {
183 super.logic();
184 if(lf == null)
185 {
186 return;
187 }
188 time = staModule.getStatesByVehilceType(VehicleType.AERIAL_VEHICLE).getTime();
189 issueInfos();
190 while(resModule.size() > 0)
191 {
192 System.out.println(((ResponseSensorEffecter) resModule.pull()).getStatus());
193 }
194
195 if(!parametersObtained)
196 {
197 if(!acceptSensorMessage())
198 {
199 return;
200 }
201 getConfig();
202 return;
203 }
204 else
205 {
206 acceptSensorMessages();
207 checkBattery();
208 }
209 if(!risen)
210 {
211 rise();
212 }
213 else
214 {
215 move();
216
217 }
218 lf.setInfo(infoToShow);
219 lf.setPostInfo(infoToWrite);
220 }
221 catch(Exception e)
222 {
223 System.out.println("ERROR LOGIC. " + e.getMessage());
224 }
225
226 }
227
228
229
230
231
232 private void issueInfos()
233 {
234 infoToShow = "";
235 infoToShow += "\nRobot State: " + state.toString();
236 infoToShow += "\nTime Elapsed: " + ToolBox.getTime(System.currentTimeMillis() - startTime);
237 infoToShow += "\n\nnoRiskCount: " + noriskCount;
238 infoToShow += "\nriskCount: " + riskCount;
239 infoToWrite = "";
240 infoToWrite += "Elapsed: " + ToolBox.getTime(System.currentTimeMillis() - startTime);
241 infoToWrite += "\nBattery Cycles: " + battFills;
242 }
243
244
245
246
247
248
249
250
251 private boolean acceptSensorMessage()
252 {
253
254 if(!senModule.isSensorReady(SensorType.LASER_SENSOR)
255 || !senModule.isSensorReady(SensorType.INS_SENSOR)
256 || !senModule.isSensorReady(SensorType.GROUND_TRUTH)
257 || !senModule.isSensorReady(SensorType.RANGE_SENSOR))
258 {
259 return false;
260 }
261 laser = (SensorLaser) senModule.getSensorsBySensorType(SensorType.LASER_SENSOR).get(0);
262 ins = (SensorINS) senModule.getSensorsBySensorType(SensorType.INS_SENSOR).get(0);
263 sonar = (SensorRange) senModule.getSensorsBySensorType(SensorType.RANGE_SENSOR).get(0);
264 truth = (SensorGroundTruth) senModule.getSensorsBySensorType(SensorType.GROUND_TRUTH).get(0);
265 return true;
266 }
267
268
269
270
271 private void acceptSensorMessages()
272 {
273 List<SuperSensor> lasers = senModule.getSensorsBySensorType(SensorType.LASER_SENSOR);
274 List<SuperSensor> inses = senModule.getSensorsBySensorType(SensorType.INS_SENSOR);
275 List<SuperSensor> sonars = senModule.getSensorsBySensorType(SensorType.RANGE_SENSOR);
276 List<SuperSensor> truths = senModule.getSensorsBySensorType(SensorType.GROUND_TRUTH);
277
278 int minIndex = ToolBox.getMin(lasers.size(), inses.size(), sonars.size(), truths.size());
279
280 for(int i = 0; i < minIndex; i++)
281 {
282 laser = (SensorLaser) lasers.get(i);
283 truth = (SensorGroundTruth) truths.get(i);
284 ins = (SensorINS) inses.get(i);
285 sonar = (SensorRange) sonars.get(i);
286 refreshScanProcedure();
287 }
288 }
289
290
291
292
293
294 private void refreshScanProcedure()
295 {
296 actLoc = Location.sub(startLoc, truth.getLocation());
297 actRot = truth.getOrientation();
298
299 lf.setRecord(new Record(laser.getRanges(), null, laser.getFOV()));
300 lf.setLocation(actLoc);
301 lf.setOrientation(actRot);
302 lf.refreshGraphics();
303 }
304 private SensorLaser laser;
305 private SensorGroundTruth truth;
306 private SensorINS ins;
307 private SensorRange sonar;
308 private double timeStamp = -1;
309 private double time = 0;
310 private long startTime = 0;
311 private double trip = 0;
312 private Location prevLoc = null;
313 private int battFull = 0;
314 private final int battLife = 500;
315 private int battFills = 0;
316 private State stallState = State.DEFAULT;
317 private Location stallActLoc = null;
318 private Location stallNextLoc = null;
319
320
321
322
323
324
325 private void checkBattery()
326 {
327 trip += Location.getDistance2D(actLoc, prevLoc);
328 prevLoc = actLoc;
329 double battUsed = battFull - staModule.getStatesByVehilceType(VehicleType.AERIAL_VEHICLE).getBattery();
330 double range = (battLife - battUsed) * (trip / battUsed);
331 double distanceFromHome = Location.getDistance2D(actLoc, zeroPoint);
332 infoToShow += "\n\nBatteryLife: " + battLife;
333 infoToShow += "\nBatteryUsed: " + battUsed;
334 infoToShow += "\n\nDistance From Home: " + ToolBox.getTwoDecimalPlaces(distanceFromHome);
335 infoToShow += "\nDistance From Next: " + ToolBox.getTwoDecimalPlaces(Location.getDistance2D(actLoc, nextLoc));
336 infoToShow += "\nRange: " + ToolBox.getTwoDecimalPlaces(range);
337 if(state == State.CHARGE || state == State.CHARGING || state == State.TERMINATE || state == State.LAND || tempState == State.TERMINATE || tempState == State.CHARGE || trip < 5)
338 {
339 return;
340 }
341 if(distanceFromHome > range * 0.85)
342 {
343 if(state == State.CONTINUE)
344 {
345 finishGoalToStart();
346 return;
347 }
348 if(state == State.AVOIDING && tempState == State.CHARGE)
349 {
350 return;
351 }
352 if(state == State.AVOIDING)
353 {
354 stallState = tempState;
355 stallNextLoc = tempNextLoc;
356 tempNextLoc = null;
357 stallActLoc = (Location.getDistance2D(actLoc, stallNextLoc) < 15)?stallNextLoc:actLoc;
358 }
359 else
360 {
361 stallState = state;
362 stallNextLoc = nextLoc;
363
364 stallActLoc = (Location.getDistance2D(actLoc, nextLoc) < 15)?nextLoc:actLoc;
365 }
366 state = State.CHARGE;
367 nextLoc = zeroPoint;
368 minDev = 1.5d;
369 lf.setRechargeBreakPoint(actLoc);
370 }
371
372 }
373
374
375
376
377
378
379
380
381
382
383
384 private Location getClosestCorner(Location center, double width, double height, Location actual)
385 {
386 Location closest = new Location(center.x - width / 2, center.y + height / 2);
387 Location rt = new Location(center.x + width / 2, center.y + height / 2);
388 Location lb = new Location(center.x - width / 2, center.y - height / 2);
389 Location rb = new Location(center.x + width / 2, center.y - height / 2);
390
391 if(Location.getDistance2D(closest, actual) > Location.getDistance2D(rt, actual))
392 {
393 closest = rt;
394 }
395 if(Location.getDistance2D(closest, actual) > Location.getDistance2D(lb, actual))
396 {
397 closest = lb;
398 }
399 if(Location.getDistance2D(closest, actual) > Location.getDistance2D(rb, actual))
400 {
401 closest = rb;
402 }
403 return closest;
404 }
405
406
407
408
409
410
411
412 private void setupSteps(Location center, Location corner)
413 {
414
415
416
417
418 if(this.dHeight > this.dWidth)
419 {
420 double density = this.dWidth / Math.ceil(this.dWidth / this.minDensity);
421 this.longStep = new Location(0, this.dHeight * Math.signum(center.y - corner.y));
422 this.shortStep = new Location(density * Math.signum(center.x - corner.x), 0);
423 this.cycleStop = (int) (this.dWidth / density);
424 }
425 else
426 {
427 double density = this.dHeight / Math.ceil(this.dHeight / this.minDensity);
428 this.longStep = new Location(this.dWidth * Math.signum(center.x - corner.x), 0);
429 this.shortStep = new Location(0, density * Math.signum(center.y - corner.y));
430 this.cycleStop = (int) (this.dHeight / density);
431 }
432 }
433
434
435
436
437
438 private void checkAltitudeFromLaser()
439 {
440
441
442
443
444 offset = (int) ((actRot.roll >= Math.PI)?(360 - (actRot.roll * 180 / Math.PI)):(-actRot.roll * 180 / Math.PI));
445 actAlt = laser.getNMidAvg(numOfRays, offset);
446 lf.setOffset(offset);
447 }
448
449
450
451
452
453 private void rise()
454 {
455 if(altitude == 0)
456 {
457 return;
458 }
459
460 actAlt = laser.getNMidAvg(10);
461
462 bot.getAct().act(new DriveAerial(maxAltitudeVelocity / 4, 0, 0, 0, false));
463 if(altitude - actAlt < 0)
464 {
465 risen = true;
466 bot.getAct().act(new DriveAerial(0, 0, 0, 0, false));
467 }
468 }
469
470
471
472
473
474
475 private void move()
476 {
477 checkAltitudeFromLaser();
478 if(state != State.CHARGING && state != State.LAND)
479 {
480 if(checkSonars() == RiskLevel.HIGHRISK)
481 {
482 return;
483 }
484 }
485 approachNext();
486 scanning = (state == State.AVOIDING)?isScanning(tempState):isScanning(state);
487 if(state == State.CHARGING || state == State.LAND)
488 {
489 if(wait(dockWaitPenalty))
490 {
491 if(state == State.CHARGING)
492 {
493 setResumeState();
494 }
495 else if(!singleFlight && wait(dockWaitPenalty))
496 {
497 setupMultiple();
498 }
499 }
500 return;
501 }
502 if(hasReachedTarget(actLoc, nextLoc))
503 {
504 state = State.getNextState(state);
505 computeNext(state);
506 }
507 carryOnIfJammed();
508 }
509
510
511
512
513
514
515
516
517
518 private boolean isScanning(State state)
519 {
520 return (state == State.LONGFORTH || state == State.SHORTFORTH || state == State.LONGBACK || state == State.SHORTBACK);
521 }
522
523
524
525
526
527
528
529
530
531
532
533 private boolean hasReachedTarget(Location actual, Location target)
534 {
535 if(Location.getDistance2D(actual, target) > minDev)
536 {
537 return false;
538 }
539 return true;
540 }
541
542
543
544
545
546 private void finishGoalToStart()
547 {
548 this.state = State.TERMINATE;
549 nextLoc = new Location(0, 0, 0);
550 }
551
552
553
554
555
556
557
558 private void computeNext(State state)
559 {
560 switch(state)
561 {
562 case DEFAULT:
563 case LONGFORTH:
564 nextLoc = nextLoc.add(longStep);
565 break;
566 case SHORTFORTH:
567 case SHORTBACK:
568 nextLoc = nextLoc.add(shortStep);
569 if(cycle >= cycleStop)
570 {
571 finishGoalToStart();
572 }
573 cycle++;
574 break;
575 case LONGBACK:
576 nextLoc = nextLoc.sub(longStep);
577 break;
578 case TERMINATE:
579 break;
580 case LAND:
581 case CHARGING:
582 altitude = 0;
583 break;
584 case CONTINUED:
585 continueScanning();
586 break;
587 case AVOIDED:
588 tryReleaseDiversion();
589 break;
590 default:
591 System.out.println("Unexpected STATE");
592 }
593 }
594 private int multipleRunCount = 0;
595 private double multipleMargin = 10;
596
597
598
599
600
601
602
603 private void setupMultiple()
604 {
605 switch(multipleRunCount)
606 {
607 case 1:
608 destination = new Location(destCenter.x - dWidth / 2 - multipleMargin, destCenter.y + dHeight / 2 + multipleMargin);
609 break;
610 case 2:
611 destination = new Location(destCenter.x - dWidth / 2 - multipleMargin, destCenter.y - dHeight / 2 - multipleMargin);
612 break;
613 case 3:
614 destination = new Location(destCenter.x + dWidth / 2 + multipleMargin, destCenter.y - dHeight / 2 - multipleMargin);
615 break;
616 case 4:
617 altitude = 0;
618 break;
619 }
620 if(multipleRunCount < 4)
621 {
622 resetINS();
623 nextLoc = getClosestCorner(destination, dWidth, dHeight, new Location(0, 0, 0));
624 setupSteps(destination, nextLoc);
625 cycle = 0;
626 state = State.DEFAULT;
627 multipleRunCount++;
628 prepareForTakeof();
629 }
630 }
631
632
633
634
635
636 private void initMultipleRun()
637 {
638 this.dWidth = destWidth / 2 - multipleMargin;
639 this.dHeight = destHeight / 2 - multipleMargin;
640 this.destination = new Location(destCenter.x + dWidth / 2 + multipleMargin, destCenter.y + dHeight / 2 + multipleMargin);
641 }
642
643
644
645
646
647
648
649
650
651
652
653 private boolean wait(int timeSpan)
654 {
655 if(timeStamp == -1)
656 {
657 timeStamp = time;
658 }
659 else if(time - timeStamp > timeSpan)
660 {
661 return true;
662 }
663 return false;
664 }
665
666
667
668
669
670 private void tryReleaseDiversion()
671 {
672 if(state == State.AVOIDING || state == State.AVOIDED)
673 {
674 nextLoc = tempNextLoc;
675 tempNextLoc = null;
676 state = tempState;
677 }
678 }
679
680
681
682
683
684 private void continueScanning()
685 {
686 this.state = stallState;
687 nextLoc = stallNextLoc;
688 stallNextLoc = null;
689 minDev = 0.9d;
690 }
691
692
693
694
695
696
697
698 private void setResumeState()
699 {
700 resetINS();
701 state = State.CONTINUE;
702 nextLoc = stallActLoc;
703 stallActLoc = null;
704 prepareForTakeof();
705 }
706
707
708
709
710
711 private void prepareForTakeof()
712 {
713 risen = false;
714 battFills++;
715 double battUsed = battFull - staModule.getStatesByVehilceType(VehicleType.AERIAL_VEHICLE).getBattery();
716 double range = (battLife - battUsed) * (trip / battUsed);
717 System.out.println("range left: " + range + " trip odometer: " + trip + " battery used: " + battUsed);
718 battFull = staModule.getStatesByVehilceType(VehicleType.AERIAL_VEHICLE).getBattery();
719 trip = 0;
720 timeStamp = -1;
721 altitude = scanAltitude;
722 }
723
724
725
726
727
728 private void resetINS()
729 {
730 Location truthLoc = truth.getLocation();
731 Rotation truthRot = truth.getOrientation();
732 lf.setStartLocation(Location.sub(startLoc, truthLoc.getLocation()));
733 StringBuilder sb = new StringBuilder();
734 sb.append(truthLoc.x).append(',').append(truthLoc.y).append(',').append(truthLoc.z).append(',');
735 sb.append(truthRot.roll).append(',').append(truthRot.pitch).append(',').append(truthRot.yaw);
736 bot.getAct().act(new SetSensorEffecter("INS", "INS", "POSE", sb.toString()));
737 }
738
739
740
741
742
743
744
745
746 private double getAngle(double sx, double cx)
747 {
748 if(sx > 0 && cx > 0)
749 {
750 return Math.acos(Math.abs(cx)) * 180 / Math.PI;
751 }
752 else if(sx > 0 && cx <= 0)
753 {
754 return 180 - Math.acos(Math.abs(cx)) * 180 / Math.PI;
755 }
756 else if(sx <= 0 && cx <= 0)
757 {
758 return 180 + Math.acos(Math.abs(cx)) * 180 / Math.PI;
759 }
760 else
761 {
762 return 360 - Math.acos(Math.abs(cx)) * 180 / Math.PI;
763 }
764 }
765
766
767
768
769
770
771
772 private void approachNext()
773 {
774 speed = (scanning)?scanningSpeed:flyingSpeed;
775 rotSpeed = (scanning)?scanningSpeed:flyingSpeed * 2 / 3;
776
777 double rotVel;
778 double altVel;
779 double linVel = maxLinearVelocity * speed;
780
781 double diff = getTargetAngle(false);
782
783 rotVel = Math.signum(-diff) * Math.min(Math.abs((double) (maxRotationalVelocity * (-diff / 90))), rotSpeed);
784
785 if(actLoc.z < seaLevel + 1 && actAlt > scanAltitude && (state != State.LAND && state != State.CHARGING))
786 {
787 altVel = (double) (maxAltitudeVelocity * (seaLevel - actLoc.z) / 6);
788 }
789 else
790 {
791 altVel = (double) (maxAltitudeVelocity * (altitude - actAlt) / 5);
792 }
793
794
795 if(state == State.AVOIDING || Location.getDistance2D(actLoc, nextLoc) < 2.7)
796 {
797 linVel = (Math.abs(rotVel) >= rotSpeed)?0:linVel;
798 }
799 else
800 {
801 linVel = (Math.abs(rotVel) >= rotSpeed)?linVel * 3 / 5:linVel;
802 }
803 shouldGoWithIt = true;
804 if(Math.abs(rotVel) >= rotSpeed)
805 {
806 noriskCount = Math.max(0, noriskCount - 1);
807 if(state == State.AVOIDING)
808 {
809 shouldGoWithIt = false;
810 }
811 }
812
813 if(state == State.TERMINATE || state == State.CHARGE)
814 {
815 linVel *= Math.min((Location.getDistance2D(actLoc, nextLoc)) / 6, 1);
816 }
817
818 if(state == State.LAND || state == State.CHARGING)
819 {
820 bot.getAct().act(new DriveAerial(altVel, 0, 0, 0, false));
821 }
822 else
823 {
824 altVel = (Math.abs(rotVel) >= rotSpeed)?0:altVel;
825 bot.getAct().act(new DriveAerial(altVel, linVel, 0, rotVel, false));
826 }
827 }
828 Location tempNextLoc;
829 State tempState;
830 List<SensorMount> sonarGeo;
831 Map.Entry<String, Double> greatestRiskSonar;
832 private final double sonarThreashold = 4.91d;
833
834
835
836
837
838 private void computeDiversion(Map<String, Double> sonars)
839 {
840
841
842
843 boolean leftSide = true;
844 double leftWM = 0;
845 double rightWM = 0;
846 double leftFittest = 0;
847 double rightFittest = 0;
848 int leftFindex = 0;
849 int rightFindex = 0;
850
851
852
853
854 int greatestRiskIndex = -1;
855 for(int i = 0; i < sonars.size(); i++)
856 {
857 Double entry = sonars.get(sonarOrder[i]);
858 if(sonarOrder[i].equals(greatestRiskSonar.getKey()))
859 {
860 greatestRiskIndex = i;
861 leftSide = false;
862 continue;
863 }
864
865
866 if(leftSide)
867 {
868 leftWM += entry * entry;
869 if(leftFittest < entry || entry > sonarThreashold)
870 {
871 leftFittest = entry;
872 leftFindex = i;
873 }
874 }
875 else
876 {
877 rightWM += entry * entry;
878
879 if(rightFittest < entry && rightFittest < sonarThreashold)
880 {
881 rightFittest = entry;
882 rightFindex = i;
883 }
884 }
885 }
886 if(leftWM < rightWM)
887 {
888 if(rightFindex < 7 && sonars.get(sonarOrder[rightFindex - 1]) < 2.5d)
889 {
890 RiskLevel righterRisk = getRiskLevel(sonarOrder[rightFindex + 2], sonars.get(sonarOrder[rightFindex + 2]));
891 if(righterRisk == RiskLevel.NORISK)
892 {
893 rightFindex += 2;
894 }
895 }
896
897 else if(
898
899 rightFindex < 8)
900 {
901 RiskLevel righterRisk = getRiskLevel(sonarOrder[rightFindex + 1], sonars.get(sonarOrder[rightFindex + 1]));
902 if(righterRisk == RiskLevel.NORISK)
903 {
904 rightFindex++;
905 }
906 }
907 int targetIndex = getSonarTargetIndex();
908 if(targetIndex > rightFindex && targetIndex < 8)
909 {
910 RiskLevel targetRiskLevel = getRiskLevel(sonarOrder[targetIndex], sonars.get(sonarOrder[targetIndex]));
911 if(targetRiskLevel == RiskLevel.NORISK)
912 {
913
914 rightFindex = targetIndex;
915 tryReleaseDiversion();
916 return;
917 }
918 }
919 setDiversionPoint(rightFindex, rightFittest);
920 }
921 else
922 {
923 if(leftFindex > 1 && sonars.get(sonarOrder[leftFindex + 1]) < 1.5d)
924 {
925 RiskLevel lefterRisk = getRiskLevel(sonarOrder[leftFindex - 2], sonars.get(sonarOrder[leftFindex - 2]));
926 if(lefterRisk == RiskLevel.NORISK)
927 {
928 leftFindex -= 2;
929 }
930 }
931 else if(
932
933 leftFindex > 0)
934 {
935 RiskLevel lefterRisk = getRiskLevel(sonarOrder[leftFindex - 1], sonars.get(sonarOrder[leftFindex - 1]));
936 if(lefterRisk == RiskLevel.NORISK)
937 {
938 leftFindex--;
939 }
940 }
941 int targetIndex = getSonarTargetIndex();
942 if(targetIndex < leftFindex && targetIndex > 0)
943 {
944 RiskLevel targetRiskLevel = getRiskLevel(sonarOrder[targetIndex], sonars.get(sonarOrder[targetIndex]));
945 if(targetRiskLevel == RiskLevel.NORISK)
946 {
947 leftFindex = targetIndex;
948 tryReleaseDiversion();
949 return;
950 }
951 }
952 setDiversionPoint(leftFindex, leftFittest);
953 }
954 }
955 private boolean shouldGoWithIt = true;
956
957
958
959
960
961
962
963
964 private void setDiversionPoint(int index, double fittest)
965 {
966 Rotation sonarRot = sonarGeo.get(index).getOrientation();
967
968 double angle = Math.PI / 2 - (sonarRot.yaw + actRot.yaw) + ((greatestRiskSonar.getKey().charAt(0) == 'L')?-0.3:(greatestRiskSonar.getKey().charAt(0) == 'R')?0.3:0);
969 Location actDiv = new Location(-Math.sin(angle) * fittest, -Math.cos(angle) * fittest);
970 Location diversion = actLoc.add(actDiv);
971 lf.setDivPoint(diversion);
972 if(state != State.AVOIDING)
973 {
974 tempState = state;
975 tempNextLoc = nextLoc;
976 }
977
978 state = State.AVOIDING;
979 nextLoc = diversion;
980 }
981
982
983
984
985
986
987
988
989
990
991
992
993 private double getTargetAngle(boolean actual)
994 {
995
996 double v1x;
997 double v1y;
998 if(actual && state == State.AVOIDING && tempNextLoc != null)
999 {
1000 v1x = tempNextLoc.x - actLoc.x;
1001 v1y = tempNextLoc.y - actLoc.y;
1002 }
1003 else
1004 {
1005 v1x = nextLoc.x - actLoc.x;
1006 v1y = nextLoc.y - actLoc.y;
1007
1008 }
1009 double v1l = Math.sqrt(v1x * v1x + v1y * v1y);
1010
1011 double sinv1 = v1y / v1l;
1012 double cosv1 = v1x / v1l;
1013
1014 double v1Theta = (getAngle(sinv1, cosv1) + 180) % 360;
1015 double v2Theta = actRot.yaw * 180 / Math.PI;
1016 double diff = v2Theta - v1Theta;
1017 if(diff > 180)
1018 {
1019 diff = diff - 360;
1020 }
1021 else if(diff < -180)
1022 {
1023 diff = diff + 360;
1024 }
1025 return diff;
1026 }
1027
1028
1029
1030
1031
1032
1033
1034 private int getSonarTargetIndex()
1035 {
1036 int sonarIndex = -1;
1037 int count = 0;
1038 double v1Theta = getTargetAngle(true) / 180 * Math.PI;
1039 double minDiv = 7;
1040 for(SensorMount sensorMount : sonarGeo)
1041 {
1042 if(minDiv > Math.abs(v1Theta - sensorMount.getOrientation().yaw))
1043 {
1044 minDiv = Math.abs(v1Theta - sensorMount.getOrientation().yaw);
1045 sonarIndex = count;
1046 }
1047 count++;
1048 }
1049 return sonarIndex;
1050 }
1051
1052
1053
1054
1055
1056 private void abortAim()
1057 {
1058 String key = greatestRiskSonar.getKey();
1059 Point2D velocity = highRiskAction.get(key);
1060 getAct().act(new DriveAerial(0, velocity.getX() * 40, velocity.getY() * 40, 0, true));/
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073 private RiskLevel checkSonars()
1074 {
1075
1076 RiskLevel worstThread = getRiskLevel(sonar.getRanges());
1077
1078
1079 if(worstThread != RiskLevel.NORISK && greatestRiskSonar.getValue() > Location.getDistance2D(actLoc, nextLoc))
1080 {
1081 return RiskLevel.NORISK;
1082 }
1083
1084 switch(worstThread)
1085 {
1086 case NORISK:
1087 noriskCount++;
1088 if(noriskCount > 6)
1089 {
1090 tryReleaseDiversion();
1091 }
1092 if(noriskCount > 15)
1093 {
1094 riskCount = 0;
1095 }
1096 break;
1097 case LOWRISK:
1098
1099 if(shouldGoWithIt)
1100 {
1101 computeDiversion(sonar.getRanges());
1102 }
1103 noriskCount = 0;
1104 riskCount++;
1105 lf.setLowRiskPoint(actLoc);
1106 break;
1107 case HIGHRISK:
1108 abortAim();
1109 noriskCount = 0;
1110 lf.setHighRiskPoint(actLoc);
1111 riskCount++;
1112 break;
1113 }
1114 return worstThread;
1115 }
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125 private void carryOnIfJammed()
1126 {
1127 if(riskCount > jammedLimit * (flyingSpeed / speed))
1128 {
1129 if(state == State.CHARGE || tempState == State.CHARGE || tempState == State.TERMINATE || state == State.TERMINATE)
1130 {
1131 getAct().act(new DriveAerial(0, -maxLinearVelocity, 0, 0, false));
1132 riskCount = 0;
1133 return;
1134 }
1135 if(state == State.AVOIDING)
1136 {
1137 tryReleaseDiversion();
1138 }
1139 else if(state == State.CONTINUE)
1140 {
1141 continueScanning();
1142 }
1143 state = State.getNextState(state);
1144 computeNext(state);
1145 riskCount = 0;
1146 }
1147 }
1148
1149
1150
1151
1152
1153
1154
1155
1156 private RiskLevel getRiskLevel(Map<String, Double> sonars)
1157 {
1158 List<Double> sonarValues = new LinkedList<Double>();
1159 for(int i = 0; i < sonars.size(); i++)
1160 {
1161 sonarValues.add(sonars.get(sonarOrder[i]));
1162 }
1163 lf.setSonars(sonarValues);
1164 RiskLevel globalRisk = RiskLevel.NORISK;
1165 double riskValue = sonarThreashold;
1166
1167
1168 for(Map.Entry<String, Double> entry : sonars.entrySet())
1169 {
1170 RiskLevel risk = getRiskLevel(entry);
1171
1172
1173
1174 if(risk.isGreaterRisk(globalRisk))
1175 {
1176 globalRisk = risk;
1177 riskValue = entry.getValue();
1178 greatestRiskSonar = entry;
1179 }
1180 else if(risk == globalRisk)
1181 {
1182 if(entry.getValue() < riskValue)
1183 {
1184 riskValue = entry.getValue();
1185 greatestRiskSonar = entry;
1186 }
1187 }
1188 }
1189
1190 return globalRisk;
1191 }
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201 private RiskLevel getRiskLevel(Map.Entry<String, Double> sonar)
1202 {
1203 return (sonar.getValue() < lowRisk.get(sonar.getKey()))?(sonar.getValue() < highRisk.get(sonar.getKey()))?RiskLevel.HIGHRISK:RiskLevel.LOWRISK:RiskLevel.NORISK;
1204 }
1205
1206
1207
1208
1209
1210
1211
1212
1213 private RiskLevel getRiskLevel(String sonar, double value)
1214 {
1215 return (value < lowRisk.get(sonar))?(value < highRisk.get(sonar))?RiskLevel.HIGHRISK:RiskLevel.LOWRISK:RiskLevel.NORISK;
1216 }
1217
1218
1219
1220
1221
1222
1223
1224 private boolean isLargeSpace()
1225 {
1226 return ((destHeight > 150) || (destWidth > 150));
1227 }
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257 private void getConfig()
1258 {
1259 if(!confModule.isReady())
1260 {
1261 confModule.queryConfigurationByType("Robot");
1262 }
1263 else if(!geoModule.isReady())
1264 {
1265 geoModule.queryGeometryByType("Sonar");
1266 }
1267 else if(senModule.isReady())
1268 {
1269 ConfigAerial robotCfg = (ConfigAerial) confModule.getConfigurationsByConfigType(ConfigType.AERIAL_VEHICLE).get(0);
1270
1271 maxLateralVelocity = Double.parseDouble(robotCfg.getFeatureValueBy("MaxLateralVelocity"));
1272 maxLinearVelocity = Double.parseDouble(robotCfg.getFeatureValueBy("MaxLinearVelocity"));
1273 maxAltitudeVelocity = Double.parseDouble(robotCfg.getFeatureValueBy("MaxAltitudeVelocity"));
1274 maxRotationalVelocity = Double.parseDouble(robotCfg.getFeatureValueBy("MaxRotationalVelocity"));
1275
1276
1277 startLoc = ins.getLocation();
1278
1279 singleFlight = !isLargeSpace();
1280
1281 actLoc = zeroPoint;
1282 prevLoc = zeroPoint;
1283 lf.setStartLocation(zeroPoint);
1284 if(singleFlight)
1285 {
1286 nextLoc = getClosestCorner(destination, destWidth, destHeight, new Location(0, 0, 0));
1287 setupSteps(destination, nextLoc);
1288 }
1289 else
1290 {
1291 initMultipleRun();
1292 setupMultiple();
1293 }
1294 battFull = staModule.getStatesByVehilceType(VehicleType.AERIAL_VEHICLE).getBattery();
1295 startTime = System.currentTimeMillis();
1296
1297 sonarGeo = ((GeoSensorEffecter) geoModule.getGeometriesByGeometryType(GeometryType.SENSOR_EFFECTER).get(0)).getSensorMountCollection();
1298
1299 parametersObtained = true;
1300 }
1301 }
1302
1303
1304
1305
1306
1307
1308
1309 @Override
1310 public void prepareBot(USAR2004Bot bot)
1311 {
1312 super.prepareBot(bot);
1313
1314 senModule = SensorMasterModuleQueued.getModuleInstance(bot);
1315 geoModule = GeometryMasterModule.getModuleInstance(bot);
1316 confModule = ConfigMasterModule.getModuleInstance(bot);
1317 resModule = ResponseModule.getModuleInstance(bot);
1318 staModule = StateMasterModule.getModuleInstance(bot);
1319 }
1320 private SensorMasterModuleQueued senModule;
1321 private GeometryMasterModule geoModule;
1322 private ConfigMasterModule confModule;
1323 private ResponseModule resModule;
1324 private StateMasterModule staModule;
1325 static ScanPreview lf = null;
1326
1327 public static void main(String[] args)
1328 {
1329 SwingUtilities.invokeLater(new Runnable()
1330 {
1331 @Override
1332 public void run()
1333 {
1334 try
1335 {
1336 lf = new ScanPreview();
1337 lf.runScanPreview();
1338 lf.show();
1339
1340 }
1341 catch(Exception e)
1342 {
1343 System.out.println("error");
1344 }
1345 }
1346 });
1347
1348 try
1349 {
1350 new USAR2004BotRunner(AerialVehicle.class, "PogamutBotBot", "127.0.0.1", 3000).setMain(true).setLogLevel(Level.OFF).startAgent();
1351
1352 }
1353 catch(Exception e)
1354 {
1355 System.out.println(e.getCause());
1356 }
1357 }
1358 }