00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "GT2004ObstaclesLocator.h"
00010 #include "Tools/Debugging/DebugDrawings.h"
00011 #include "Tools/Math/Geometry.h"
00012 #include "Tools/FieldDimensions.h"
00013 #include "Tools/Math/Matrix2x2.h"
00014 #include "Tools/Debugging/GenericDebugData.h"
00015 #include "Platform/SystemCall.h"
00016
00017 GT2004ObstaclesLocator::GT2004ObstaclesLocator(const ObstaclesLocatorInterfaces& interfaces)
00018 : ObstaclesLocator(interfaces), headTiltClipPSD(-.3)
00019 {
00020 usePSD = true;
00021 useLinesPercept = false;
00022 useObstaclesPercept = true;
00023 useAging = true;
00024
00025 sectorWidth = pi2/(double)ObstaclesModel::numOfSectors;
00026
00027 for(int i = 0; i < ObstaclesModel::numOfSectors; i++)
00028 {
00029 obstacles[i].x = 0;
00030 obstacles[i].y = 0;
00031 obstacleTypes[i] = ObstaclesPercept::unknown;
00032 }
00033 }
00034
00035
00036 void GT2004ObstaclesLocator::execute()
00037 {
00038 odometry = odometryData - lastOdometry;
00039 lastOdometry = odometryData;
00040
00041 moveObstaclesByOdometry();
00042
00043
00044 if(useObstaclesPercept) addObstaclesPercept();
00045 if(useLinesPercept) addLinesPercept();
00046
00047 setObstaclesModel(true);
00048 obstaclesModel.setFrameNumber(obstaclesPercept.frameNumber);
00049
00050
00051 determineFreePartsOfGoals();
00052 determineNextFreeTeammate();
00053 DEBUG_DRAWING_FINISHED(sketch);
00054 }
00055
00056 void GT2004ObstaclesLocator::moveObstaclesByOdometry()
00057 {
00058
00059
00060
00061
00062
00063
00064 Vector2<double> c1(cos(odometry.rotation),-sin(odometry.rotation));
00065 Vector2<double> c2(sin(odometry.rotation),cos(odometry.rotation));
00066 Matrix2x2<double> R(c1, c2);
00067
00068 Vector2<double> movedObstacles[ObstaclesModel::numOfSectors];
00069 unsigned long movedTimestamps[ObstaclesModel::numOfSectors];
00070 ObstaclesPercept::ObstacleType movedObstacleTypes[ObstaclesModel::numOfSectors];
00071 int numOfObstacles = 0;
00072
00073 int i;
00074
00075 for(i = 0; i < ObstaclesModel::numOfSectors; i++)
00076 {
00077 if (
00078 (obstacles[i].x != 0 || obstacles[i].y != 0) &&
00079 (!useAging ||
00080 SystemCall::getTimeSince(timestamps[i]) < timeAfterWhichObstacleIsForgotten)
00081 )
00082 {
00083 movedObstacles[numOfObstacles] = R*obstacles[i];
00084 movedObstacles[numOfObstacles] -= odometry.translation;
00085 movedObstacleTypes[numOfObstacles] = obstacleTypes[i];
00086 movedTimestamps[numOfObstacles] = timestamps[i];
00087 numOfObstacles++;
00088 }
00089 obstacles[i].x = obstacles[i].y = 0;
00090 obstacleTypes[i] = ObstaclesPercept::unknown;
00091 }
00092
00093 for(i = 0; i < numOfObstacles; i++)
00094 {
00095 int targetSector = ObstaclesModel::getSectorFromAngle(movedObstacles[i].angle());
00096 double sqrDistance = movedObstacles[i]*movedObstacles[i];
00097
00098 if
00099 (
00100 sqrDistance >= 10.0 &&
00101
00102 (
00103 (obstacles[targetSector].x == 0 && obstacles[targetSector].y == 0) ||
00104 sqrDistance <= obstacles[targetSector]*obstacles[targetSector]
00105 )
00106 )
00107 {
00108 obstacles[targetSector] = movedObstacles[i];
00109 obstacleTypes[targetSector] = movedObstacleTypes[i];
00110 timestamps[targetSector] = movedTimestamps[i];
00111 }
00112 }
00113 }
00114
00115 void GT2004ObstaclesLocator::setObstaclesModel(bool addWorldModel)
00116 {
00117 int i;
00118 double distance;
00119
00120 ObstaclesModel buffer;
00121
00122
00123 for(i = 0; i < ObstaclesModel::numOfSectors; i++)
00124 {
00125 distance = obstacles[i].abs();
00126
00127
00128 if (getPlayer().getPlayerNumber() != Player::one)
00129
00130 {
00131 if (FieldDimensions::distanceToOwnPenaltyArea(robotPose) > 0)
00132 {
00133 double distToPenaltyArea = field.getDistanceToOwnPenaltyArea(robotPose + Pose2D(ObstaclesModel::getAngleOfSector(i)));
00134 if (distToPenaltyArea > 50 && distToPenaltyArea < ObstaclesModel::maxDistance)
00135 if ((distToPenaltyArea < distance) || (distance == 0))
00136 distance = distToPenaltyArea;
00137 }
00138 }
00139
00140 if(distance > 0)
00141 {
00142 buffer.distance[i] = (int)distance;
00143 buffer.obstacleType[i] = obstacleTypes[i];
00144 }
00145 else
00146 {
00147 buffer.distance[i] = ObstaclesModel::maxDistance;
00148 buffer.obstacleType[i] = ObstaclesPercept::unknown;
00149 }
00150 }
00151
00152
00153
00154
00155
00156 for(i = 0; i < ObstaclesModel::numOfSectors; i++)
00157 {
00158
00159
00160
00161 if ((buffer.distance[i] - buffer.distance[(i+1)%ObstaclesModel::numOfSectors] < -200) &&
00162 (buffer.distance[i] - buffer.distance[(i+ObstaclesModel::numOfSectors-1)%ObstaclesModel::numOfSectors]) < -200)
00163 {
00164 obstaclesModel.distance[i] = (buffer.distance[(i+1)%ObstaclesModel::numOfSectors] +
00165 buffer.distance[(i-1)%ObstaclesModel::numOfSectors])/2;
00166 }
00167 else
00168 {
00169 obstaclesModel.distance[i] = buffer.distance[i];
00170 }
00171
00172 obstaclesModel.obstacleType[i] = buffer.obstacleType[i];
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182 double closest = ObstaclesModel::maxDistance;
00183 for(i = ObstaclesModel::getSectorFromAngle(-pi_2); i < ObstaclesModel::getSectorFromAngle(pi_2); i++)
00184 {
00185 if ((obstacles[i].x < closest) && (obstacles[i].x > 10)
00186 && (obstacles[i].y < 90) && (obstacles[i].y > -90))
00187 closest = obstacles[i].x;
00188 }
00189 obstaclesModel.corridorInFront = (int )closest;
00190
00191 obstaclesModel.bodyPSD = psdPercept[psdPercept.numOfPercepts - 1].body;
00192 }
00193
00194 void GT2004ObstaclesLocator::addPSDPercept()
00195 {
00196 for (int i = 0; i < psdPercept.numOfPercepts; i++)
00197 {
00198 if (psdPercept[i].neckTilt > headTiltClipPSD && psdPercept[i].isValid)
00199 {
00200
00201 Vector2<double> psdPoint(psdPercept[i].x, psdPercept[i].y);
00202 int sector = ObstaclesModel::getSectorFromAngle(psdPoint.angle());
00203
00204
00205 if(psdPercept[i].z < 90)
00206 {
00207 double sqrDistance = obstacles[sector] * obstacles[sector];
00208
00209 if (sqrDistance > 0 &&
00210 sqrDistance < psdPoint * psdPoint)
00211 {
00212 obstacles[sector].x = psdPoint.x;
00213 obstacles[sector].y = psdPoint.y;
00214 timestamps[sector] = SystemCall::getCurrentSystemTime();
00215 }
00216 }
00217
00218 else if (!psdPercept[i].tooFarAway)
00219 {
00220 double angleToPoint = normalize(psdPoint.angle());
00221 double angleToBall = Geometry::angleTo(robotPose.getPose(), ballModel.seen);
00222
00223 if(toDegrees(normalize(angleToPoint - angleToBall)) < 10 &&
00224 toDegrees(normalize(angleToPoint - angleToBall)) > -10 &&
00225 SystemCall::getTimeSince(ballModel.seen.timeWhenLastSeen) < 1000)
00226 {
00227 DOT(sketch, 20, 10, Drawings::green, Drawings::green);
00228 }
00229 else
00230 {
00231 obstacles[sector].x = psdPoint.x;
00232 obstacles[sector].y = psdPoint.y;
00233 timestamps[sector] = SystemCall::getCurrentSystemTime();
00234 }
00235 }
00236
00237 else
00238 {
00239 obstacles[sector].x = 0;
00240 obstacles[sector].y = 0;
00241 }
00242 }
00243 }
00244 }
00245
00246 void GT2004ObstaclesLocator::addLinesPercept()
00247 {
00248 int i;
00249 for(i = 0; i < linesPercept.numberOfPoints[LinesPercept::redRobot]; i++)
00250 {
00251 Vector2<double> obstaclePoint(linesPercept.points[LinesPercept::redRobot][i].x, linesPercept.points[LinesPercept::redRobot][i].y);
00252 addObstaclePoint(obstaclePoint, limit);
00253 }
00254 for(i = 0; i < linesPercept.numberOfPoints[LinesPercept::blueRobot]; i++)
00255 {
00256 Vector2<double> obstaclePoint(linesPercept.points[LinesPercept::blueRobot][i].x, linesPercept.points[LinesPercept::blueRobot][i].y);
00257 addObstaclePoint(obstaclePoint, limit);
00258 }
00259 for(i = 0; i < linesPercept.numberOfPoints[LinesPercept::border]; i++)
00260 {
00261 Vector2<double> obstaclePoint(linesPercept.points[LinesPercept::border][i].x, linesPercept.points[LinesPercept::border][i].y);
00262 addObstaclePoint(obstaclePoint, extend);
00263 }
00264 }
00265
00266 void GT2004ObstaclesLocator::addObstaclesPercept()
00267 {
00268 int i;
00269
00270 for(i = 0; i < obstaclesPercept.numberOfPoints ; i++)
00271 {
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 addObstaclePoints(
00285 obstaclesPercept.nearPoints[i],
00286 obstaclesPercept.farPoints[i],
00287 obstaclesPercept.farPointIsOnImageBorder[i],
00288 obstaclesPercept.obstacleType[i]);
00289 }
00290 }
00291
00292 void GT2004ObstaclesLocator::addObstaclePoint
00293 (
00294 const Vector2<double>& obstaclePoint,
00295 UpdateMode mode
00296 )
00297 {
00298 double angleToPoint = normalize(obstaclePoint.angle());
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 int sector = ObstaclesModel::getSectorFromAngle(angleToPoint);
00313
00314 if ( sector >= ObstaclesModel::numOfSectors || ObstaclesModel::numOfSectors < 0 )
00315 {
00316 sector = 0;
00317 return;
00318
00319 OUTPUT ( idText, text, "sector >= ObstaclesModel::numOfSectors" );
00320 }
00321 double sqrDistanceInModel = obstacles[sector] * obstacles[sector];
00322 double sqrDistanceToPoint = obstaclePoint * obstaclePoint;
00323
00324 if(sqrt(sqrDistanceToPoint) < 150)
00325 {
00326 DOT(sketch, 30, 10, Drawings::blue, Drawings::blue);
00327 return;
00328 }
00329
00330 switch(mode)
00331 {
00332 case overwrite:
00333 obstacles[sector].x = obstaclePoint.x;
00334 obstacles[sector].y = obstaclePoint.y;
00335 timestamps[sector] = SystemCall::getCurrentSystemTime();
00336 break;
00337 case extend:
00338
00339 if(sqrDistanceInModel < sqrDistanceToPoint)
00340 {
00341 obstacles[sector].x = obstaclePoint.x;
00342 obstacles[sector].y = obstaclePoint.y;
00343 timestamps[sector] = SystemCall::getCurrentSystemTime();
00344 }
00345 break;
00346 case limit:
00347
00348 if(
00349 (obstacles[sector].x == 0 && obstacles[sector].y == 0) ||
00350 sqrDistanceToPoint < sqrDistanceInModel)
00351 {
00352 obstacles[sector].x = obstaclePoint.x;
00353 obstacles[sector].y = obstaclePoint.y;
00354 timestamps[sector] = SystemCall::getCurrentSystemTime();
00355 }
00356 break;
00357 }
00358 }
00359
00360 void GT2004ObstaclesLocator::addObstaclePoints
00361 (
00362 const Vector2<int>& nearPoint,
00363 const Vector2<int>& farPoint,
00364 bool farPointIsOnImageBorder,
00365 ObstaclesPercept::ObstacleType obstacleType
00366 )
00367 {
00368 double angleToPoints = normalize(farPoint.angle());
00369 int sector = ObstaclesModel::getSectorFromAngle(angleToPoints);
00370
00371 if ( sector >= ObstaclesModel::numOfSectors || ObstaclesModel::numOfSectors < 0 )
00372 {
00373 sector = 0;
00374 return;
00375 OUTPUT ( idText, text, "sector >= ObstaclesModel::numOfSectors" );
00376 }
00377 double sqrDistanceInModel = obstacles[sector] * obstacles[sector];
00378 double sqrDistanceToNearPoint = nearPoint * nearPoint;
00379 double sqrDistanceToFarPoint = farPoint * farPoint;
00380
00381 if(sqrDistanceToNearPoint > sqrDistanceInModel && sqrDistanceInModel != 0) return;
00382 else if(!farPointIsOnImageBorder)
00383 {
00384 obstacles[sector].x = farPoint.x;
00385 obstacles[sector].y = farPoint.y;
00386 if(obstacleType != ObstaclesPercept::unknown || (fabs(sqrDistanceToFarPoint - sqrDistanceInModel) > 500))
00387 obstacleTypes[sector] = obstacleType;
00388 timestamps[sector] = SystemCall::getCurrentSystemTime();
00389 }
00390 else if(sqrDistanceInModel < sqrDistanceToFarPoint && sqrDistanceInModel != 0)
00391 {
00392 obstacles[sector].x = farPoint.x;
00393 obstacles[sector].y = farPoint.y;
00394 timestamps[sector] = SystemCall::getCurrentSystemTime();
00395 }
00396 }
00397
00398
00399 void GT2004ObstaclesLocator::determineFreePartsOfGoals()
00400 {
00401 for(int i = 0; i < 2; i++)
00402 {
00403 if (obstaclesPercept.angleToFreePartOfGoalWasDetermined[i])
00404 {
00405 lastTimeFreePartOfGoalWasDetermined[i] = SystemCall::getCurrentSystemTime();
00406 if(
00407 obstaclesPercept.widthOfFreePartOfGoal[i] > widthOfFreePartOfGoal[i]
00408 ||
00409 (
00410 angleToFreePartOfGoal[i] - widthOfFreePartOfGoal[i] / 2.0 <
00411 obstaclesPercept.angleToFreePartOfGoal[i]
00412 &&
00413 obstaclesPercept.angleToFreePartOfGoal[i] <
00414 angleToFreePartOfGoal[i] + widthOfFreePartOfGoal[i] / 2.0
00415 )
00416 )
00417 {
00418 angleToFreePartOfGoal[i] = obstaclesPercept.angleToFreePartOfGoal[i];
00419 widthOfFreePartOfGoal[i] = obstaclesPercept.widthOfFreePartOfGoal[i];
00420 distanceToFreePartOfGoal[i] = obstaclesPercept.distanceToFreePartOfGoal[i];
00421
00422 obstaclesModel.angleToFreePartOfGoalWasDetermined[i] = true;
00423 }
00424 }
00425 else if(SystemCall::getTimeSince(lastTimeFreePartOfGoalWasDetermined[i]) < 2000)
00426 {
00427 angleToFreePartOfGoal[i] -= odometry.getAngle();
00428 obstaclesModel.angleToFreePartOfGoalWasDetermined[i] = true;
00429 }
00430 else
00431 {
00432 angleToFreePartOfGoal[i] = 0.0;
00433 widthOfFreePartOfGoal[i] = 0.0;
00434 distanceToFreePartOfGoal[i] = 1000.0;
00435
00436 obstaclesModel.angleToFreePartOfGoalWasDetermined[i] = false;
00437 }
00438 obstaclesModel.angleToFreePartOfGoal[i] = angleToFreePartOfGoal[i];
00439 obstaclesModel.widthOfFreePartOfGoal[i] = widthOfFreePartOfGoal[i];
00440 obstaclesModel.distanceToFreePartOfGoal[i] = distanceToFreePartOfGoal[i];
00441 }
00442 }
00443
00444 void GT2004ObstaclesLocator::determineNextFreeTeammate()
00445 {
00446 int distanceToNextTeammate = 10000;
00447 double angleToNextTeammate = 0;
00448
00449 bool foundTeammate = false;
00450
00451 for(int i = 0; i < playerPoseCollection.numberOfOwnPlayers; i++)
00452 {
00453 PlayerPose currentPose = playerPoseCollection.getOwnPlayerPose(i);
00454 int currentDistance = (int)((currentPose.getPose().translation - robotPose.translation).abs());
00455 double currentAngle = normalize(Geometry::angleTo(robotPose, currentPose.getPose().translation));
00456
00457 int targetSector = ObstaclesModel::getSectorFromAngle(currentAngle);
00458 int distanceOfTargetSector = (int)obstacles[targetSector].abs();
00459
00460 if(currentDistance < distanceToNextTeammate &&
00461 (
00462 distanceOfTargetSector == 0 ||
00463 distanceOfTargetSector + 200 > distanceToNextTeammate
00464 )
00465 )
00466 {
00467 foundTeammate = true;
00468 angleToNextTeammate = currentAngle;
00469 distanceToNextTeammate = currentDistance;
00470 }
00471 }
00472 if(foundTeammate)
00473 {
00474 obstaclesModel.angleToNextFreeTeammateWasDetermined = true;
00475 obstaclesModel.angleToNextFreeTeammate = angleToNextTeammate;
00476 obstaclesModel.distanceToNextFreeTeammate = distanceToNextTeammate;
00477 }
00478 else
00479 {
00480 obstaclesModel.angleToNextFreeTeammateWasDetermined = false;
00481 }
00482 }
00483
00484
00485 bool GT2004ObstaclesLocator::handleMessage(InMessage& message)
00486 {
00487 bool handled = false;
00488
00489 switch(message.getMessageID())
00490 {
00491 case idGenericDebugData:
00492 GenericDebugData d;
00493 message.bin >> d;
00494 if(d.id == GenericDebugData::defaultObstaclesLocator)
00495 {
00496 OUTPUT(idText,text,"generic debug message handled by module DefaultObstaclesLocator");
00497
00498 headTiltClipPSD = d.data[0];
00499 switch((int)d.data[1])
00500 {
00501 case 0: usePSD = true; useLinesPercept = false; useAging = false;
00502 break;
00503 case 1: usePSD = false; useLinesPercept = true; useAging = false;
00504 break;
00505 case 2: usePSD = false; useLinesPercept = true; useAging = true;
00506 break;
00507 case 3: usePSD = true; useLinesPercept = true; useAging = false;
00508 break;
00509 case 4: usePSD = true; useLinesPercept = true; useAging = true;
00510 break;
00511 };
00512 }
00513 handled = true;
00514 break;
00515
00516 }
00517 return handled;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730