00001
00002 #include "GT2005SelfLocator.h"
00003 #include "Tools/Math/Common.h"
00004
00005 #ifdef _WIN32
00006 #pragma warning(disable:4355) // VC++: "this" in initializer list is ok
00007 #endif
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 const double GT2005SelfLocator::QUASI_ZERO = 0.000001;
00043
00044
00045
00046
00047 GT2005SelfLocator::GT2005SelfLocator(const SelfLocatorInterfaces& interfaces)
00048 : SelfLocator(interfaces), sampleTemplateGenerator(parameters)
00049 {
00050 timeStamp = 0;
00051 testSample = 0;
00052 testSampleIndex = 0;
00053 speed = 0;
00054
00055 resetSamples();
00056
00057 timeStamp = 0;
00058
00059 calculateTrust();
00060
00061 OUTPUT(idText, text, "GT2005 SelfLocator initialized");
00062
00063 OUTPUT(idText,text,"line Z trust: " << linePointZAngleTrust);
00064 OUTPUT(idText,text,"line Y trust: " << linePointYAngleTrust);
00065 OUTPUT(idText,text,"crossings Z trust: " << crossingZAngleTrust);
00066 OUTPUT(idText,text,"crossings Y trust: " << crossingYAngleTrust);
00067
00068 OUTPUT(idText,text,"flags Y trust: " << flagYAngleTrust);
00069 OUTPUT(idText,text,"goal Z trust: " << goalZAngleTrust);
00070 OUTPUT(idText,text,"goal Y trust: " << goalYAngleTrust);
00071 }
00072
00073
00074 void GT2005SelfLocator::motionUpdate(const Pose2D& odometry, const Pose2D& camera, bool noise)
00075 {
00076 double transNoise = noise ? parameters.translationNoise : 0;
00077 double rotNoise = noise ? parameters.rotationNoise : 0;
00078 double transX = odometry.translation.x;
00079 double transY = odometry.translation.y;
00080 double dist = odometry.translation.abs();
00081 double angle = fabs(odometry.getAngle());
00082
00083
00084 double rotError = max(dist*parameters.movedDistWeight,
00085 angle*parameters.movedAngleWeight);
00086
00087
00088 double transXError = max( fabs(transX*parameters.majorDirTransWeight),
00089 fabs(transY*parameters.minorDirTransWeight));
00090 double transYError = max( fabs(transY*parameters.majorDirTransWeight),
00091 fabs(transX*parameters.minorDirTransWeight));
00092
00093 double improbability;
00094
00095
00096
00097
00098
00099
00100 int i;
00101 for (i = 0; i < SAMPLES_MAX; i++)
00102 {
00103 GT2005SelfLocatorSample& s = sampleSet[i];
00104
00105 if (s.isUsingOdometry)
00106 s += odometry;
00107
00108 if (s.probability>1) improbability = 0;
00109 else improbability = (1-s.probability)*(1-s.probability);
00110
00111
00112
00113 rotError = (random()*2-1) * max(rotError,rotNoise*improbability);
00114
00115
00116 double sampleTransXError = max(transXError,transNoise*improbability);
00117 double sampleTransYError = max(transYError,transNoise*improbability);
00118 Vector2<double> transErrorVec( (random()*2-1)*sampleTransXError,
00119 (random()*2-1)*sampleTransYError );
00120
00121
00122 s += Pose2D(rotError, transErrorVec);
00123 s.camera = s + camera;
00124 }
00125
00126 }
00127
00128
00129 void GT2005SelfLocator::updateByCenterCircle(const LinesPercept::CenterCircle& centerCircle)
00130 {
00131 Vector2<int> point = centerCircle.location;
00132 double pointDist = point.abs();
00133
00134
00135 double observedZAngle = atan2(parameters.headHeightEstimation,pointDist);
00136
00137 double observedYAngle = atan2((double)point.y,(double)point.x);
00138
00139
00140 lastSeenCenterCircle = Pose2D(centerCircle.orientation,(double)point.x,(double)point.y);
00141
00142
00143
00144
00145 for(int i = 0; i < SAMPLES_MAX; ++i)
00146 if (random() < parameters.updateProbCenterCircle)
00147 {
00148 GT2005SelfLocatorSample& s = sampleSet[i];
00149
00150 Pose2D pointFromSample = s + lastSeenCenterCircle;
00151 Vector2<double> vMin(0,0);
00152
00153 Vector2<double> v = (Pose2D(vMin) - s).translation;
00154
00155
00156 double zModel = atan2(parameters.headHeightEstimation,v.abs()),
00157 yModel = atan2(v.y,v.x);
00158
00159 double orientationDiff;
00160 if (centerCircle.orientationKnown)
00161 {
00162 double orientation = fabs(normalize(pointFromSample.rotation));
00163 orientationDiff = pi_2 - orientation;
00164 }
00165 else
00166 orientationDiff = 0;
00167
00168 double val = gaussian((zModel - observedZAngle) * centerCircleZAngleTrust) *
00169 gaussian((yModel - observedYAngle) * centerCircleYAngleTrust) *
00170 gaussian(orientationDiff * centerCircleOrientationAngleTrust);
00171
00172
00173 s.setPerceptProbability(GT2005SelfLocatorSample::lineCrossing, val, parameters);
00174 if (i==testSampleIndex)
00175 {
00176 Drawings::Color color = getSampleColor(val);
00177 NCIRCLE("gt05-sl:testSample", 0, 0, 40, 1, Drawings::ps_solid, color);
00178 NCIRCLE("gt05-sl:testSample", pointFromSample.translation.x, pointFromSample.translation.y, 40, 1, Drawings::ps_solid, color);
00179 NLINE("gt05-sl:testSample", 0, 0, pointFromSample.translation.x, pointFromSample.translation.y, 1, Drawings::ps_solid, color);
00180 }
00181 }
00182 }
00183
00184 void GT2005SelfLocator::updateByCrossing(const LinesPercept::LineCrossingPoint& crossingPoint)
00185 {
00186
00187 Vector2<int> point = crossingPoint.locationOnField;
00188
00189
00190 Pose2D point2(crossingPoint.angleOnField, (double)point.x, (double)point.y);
00191 Pose2D pointFromPose = robotPose + point2;
00192
00193
00194 Vector2<double> testCrossing = lineCrossingsTable.getClosestPoint(pointFromPose.translation, GT2005LineCrossingsTable::falseCrossing, 0);
00195 Vector2<double> testDiff = testCrossing - pointFromPose.translation;
00196 if (testDiff.abs()<300)
00197 {
00198 NCIRCLE("gt05-sl:lastCrossing",pointFromPose.translation.x,pointFromPose.translation.y,40,40,Drawings::ps_solid,Drawings::yellow);
00199 return;
00200 }
00201
00202
00203 Vector2<double> vMin;
00204 vMin = lineCrossingsTable.getClosestPoint(pointFromPose, crossingPoint, lastSeenCrossingClass);
00205 lastSeenCrossing = pointFromPose.translation;
00206 if(vMin.x != GT2005LineCrossingsTable::NO_POINT_DISTANCE)
00207 {
00208 lastModelCrossing = vMin;
00209 }
00210 else
00211 {
00212 lastModelCrossing = pointFromPose.translation;
00213
00214
00215 return;
00216 }
00217
00218 double pointDist = point.abs();
00219
00220 double observedZAngle = atan2(parameters.headHeightEstimation,pointDist),
00221
00222 observedYAngle = atan2((double)point.y,(double)point.x);
00223
00224
00225 for(int i = 0; i < SAMPLES_MAX; ++i)
00226 if (random() < parameters.updateProbCrossing)
00227 {
00228 GT2005SelfLocatorSample& s = sampleSet[i];
00229
00230 Pose2D pointFromSample = s + point2;
00231
00232 Vector2<double> vMin;
00233 GT2005LineCrossingsTable::CrossingClass crossingClass;
00234 vMin = lineCrossingsTable.getClosestPoint(pointFromSample, crossingPoint, crossingClass);
00235
00236 double val;
00237
00238 if(vMin.x != GT2005LineCrossingsTable::NO_POINT_DISTANCE)
00239 {
00240
00241 Vector2<double> v = (Pose2D(vMin) - s).translation;
00242
00243 double zModel = atan2(parameters.headHeightEstimation,v.abs()),
00244 yModel = atan2(v.y,v.x);
00245
00246
00247
00248
00249
00250
00251
00252
00253 val = gaussian((zModel - observedZAngle) * crossingZAngleTrust) *
00254 gaussian((yModel - observedYAngle) * crossingYAngleTrust);
00255
00256 s.setPerceptProbability(GT2005SelfLocatorSample::lineCrossing, val, parameters);
00257 if (i==testSampleIndex)
00258 {
00259 Drawings::Color color = getSampleColor(val);
00260 NCIRCLE("gt05-sl:testSample", vMin.x, vMin.y, 40, 1, Drawings::ps_solid, color);
00261 NCIRCLE("gt05-sl:testSample", pointFromSample.translation.x, pointFromSample.translation.y, 40, 1, Drawings::ps_solid, color);
00262 NLINE("gt05-sl:testSample", vMin.x, vMin.y, pointFromSample.translation.x, pointFromSample.translation.y, 1, Drawings::ps_solid, color);
00263 }
00264 }
00265 }
00266
00267 }
00268
00269
00270 void GT2005SelfLocator::updateByPoint(const LinesPercept::LinePoint& point,GT2005SelfLocatorSample::PerceptType type, LinesPercept::LineType observationTableIndex)
00271 {
00272
00273
00274 double pointDist = point.abs();
00275
00276
00277 double observedZAngle = atan2(parameters.headHeightEstimation,pointDist),
00278
00279 observedYAngle = atan2((double)point.y,(double)point.x);
00280
00281
00282
00283 Pose2D point2(point.angle, Vector2<double>(point.x, point.y));
00284
00285
00286 for(int i = 0; i < SAMPLES_MAX; ++i)
00287 {
00288 GT2005SelfLocatorSample& s = sampleSet[i];
00289
00290 Pose2D pointFromSample = s + point2;
00291
00292
00293
00294 Vector2<double> vMin;
00295
00296
00297 bool isY = (type == GT2005SelfLocatorSample::xFieldLine || type==GT2005SelfLocatorSample::yFieldLine) &&
00298 (fabs(pointFromSample.getAngle()) < pi / 4 ||
00299 fabs(pointFromSample.getAngle()) > 3 * pi / 4);
00300
00301 vMin = observationTable[observationTableIndex].getClosestPoint(pointFromSample);
00302
00303
00304 if(vMin.x != 1000000)
00305 {
00306
00307 Vector2<double> v = (Pose2D(vMin) - s).translation;
00308
00309 double zModel = atan2(parameters.headHeightEstimation,v.abs()),
00310 yModel = atan2(v.y,v.x);
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 double val = gaussian((zModel - observedZAngle) * linePointZAngleTrust) *
00321 gaussian((yModel - observedYAngle) * linePointYAngleTrust);
00322 s.setPerceptProbability(isY ? GT2005SelfLocatorSample::yFieldLine : type, val, parameters);
00323 if (i==testSampleIndex)
00324 {
00325 Drawings::Color color = getSampleColor(val);
00326 NCIRCLE("gt05-sl:testSample", vMin.x, vMin.y, 40, 1, Drawings::ps_solid, color);
00327 NCIRCLE("gt05-sl:testSample", pointFromSample.translation.x, pointFromSample.translation.y, 40, 1, Drawings::ps_solid, color);
00328 NLINE("gt05-sl:testSample", vMin.x, vMin.y, pointFromSample.translation.x, pointFromSample.translation.y, 1, Drawings::ps_solid, color);
00329 }
00330 }
00331 else
00332 {
00333 s.setPerceptProbability(isY ? GT2005SelfLocatorSample::yFieldLine : type, QUASI_ZERO, parameters);
00334 if (i==testSampleIndex)
00335 {
00336 Drawings::Color color = getSampleColor(0);
00337 NCIRCLE("gt05-sl:testSample", pointFromSample.translation.x, pointFromSample.translation.y, 40, 1, Drawings::ps_solid, color);
00338 }
00339 }
00340 }
00341 }
00342
00343
00344 void GT2005SelfLocator::lineObservationUpdate(const LinesPercept& linesPercept)
00345 {
00346 int i;
00347
00348
00349 if (linesPercept.centerCircleFound && parameters.centerCircleWeight > 0){
00350 updateByCenterCircle(linesPercept.centerCircle);
00351 }
00352
00353
00354
00355
00356 if (parameters.crossingWeight > 0)
00357 for(i=0;i<linesPercept.numberOfLineCrossings && i < parameters.maxCrossings;i++)
00358 {
00359 updateByCrossing(linesPercept.lineCrossings[i]);
00360 observationUpdateDone = true;
00361 }
00362
00363 for(int j = 0; j < linesPercept.points[LinesPercept::border].numberOfPoints && j < parameters.maxBorderpoints; ++j)
00364 {
00365 updateByPoint(linesPercept.points[LinesPercept::border].pointsOnField[rand() % linesPercept.points[LinesPercept::border].numberOfPoints],
00366 GT2005SelfLocatorSample::border,
00367 LinesPercept::border
00368 );
00369 observationUpdateDone = true;
00370 }
00371
00372 for(int j = 0; j < linesPercept.points[LinesPercept::field].numberOfPoints && j < parameters.maxLinepoints; ++j)
00373 {
00374 updateByPoint(linesPercept.points[LinesPercept::field].pointsOnField[rand() % linesPercept.points[LinesPercept::field].numberOfPoints],
00375 GT2005SelfLocatorSample::xFieldLine,
00376 LinesPercept::field
00377 );
00378 observationUpdateDone = true;
00379 }
00380
00381 if(linesPercept.points[LinesPercept::yellowGoal].numberOfPoints ||
00382 linesPercept.points[LinesPercept::skyblueGoal].numberOfPoints)
00383 for(int j = 0; j < linesPercept.points[LinesPercept::yellowGoal].numberOfPoints +
00384 linesPercept.points[LinesPercept::skyblueGoal].numberOfPoints && j < parameters.maxGoalpoints; ++j)
00385 {
00386 LinesPercept::LineType select = (random() + 1e-6) * linesPercept.points[LinesPercept::yellowGoal].numberOfPoints >
00387 linesPercept.points[LinesPercept::skyblueGoal].numberOfPoints
00388 ? LinesPercept::yellowGoal
00389 : LinesPercept::skyblueGoal;
00390 LinesPercept::LineType observationTableIndex;
00391 if(getPlayer().getTeamColor() == Player::blue)
00392
00393 observationTableIndex = (select == LinesPercept::yellowGoal) ? LinesPercept::skyblueGoal : LinesPercept::yellowGoal;
00394 else
00395 observationTableIndex = select;
00396 updateByPoint(linesPercept.points[select].pointsOnField[rand() % linesPercept.points[select].numberOfPoints],
00397 GT2005SelfLocatorSample::goal,
00398 observationTableIndex
00399 );
00400 observationUpdateDone = true;
00401 }
00402 }
00403
00404
00405
00406
00407 void GT2005SelfLocator::updateByFlag(const Vector2<double>& flagFieldPosition,
00408 FlagSides sideOfFlag,
00409 double measuredBearing)
00410 {
00411 observationUpdateDone = true;
00412 int i;
00413 for(i = 0; i < SAMPLES_MAX; ++i)
00414 if (random() < parameters.updateProbFlag)
00415 {
00416 GT2005SelfLocatorSample& s = sampleSet[i];
00417
00418
00419 Pose2D flagPos(flagFieldPosition.x,flagFieldPosition.y);
00420 flagPos -= s.camera;
00421
00422
00423 if (flagPos.translation.abs() > flagRadius)
00424 {
00425
00426 double assumedBearing = atan2(flagPos.translation.y,flagPos.translation.x) + sideOfFlag * asin(flagRadius / flagPos.translation.abs());
00427
00428
00429 double similarity = fabs((assumedBearing - measuredBearing)) / pi;
00430
00431
00432 if(similarity > 1)
00433 similarity = 2.0 - similarity;
00434
00435
00436
00437 double val = gaussian(similarity * flagYAngleTrust);
00438 s.setPerceptProbability(GT2005SelfLocatorSample::flag, val, parameters);
00439 if (i==testSampleIndex)
00440 {
00441 Drawings::Color color = getSampleColor(val);
00442 NCIRCLE("gt05-sl:testSample", flagFieldPosition.x, flagFieldPosition.y, 40, 1, Drawings::ps_solid, color);
00443 }
00444 }
00445 else
00446 {
00447 s.setPerceptProbability(GT2005SelfLocatorSample::flag, QUASI_ZERO, parameters);
00448 if (i==testSampleIndex)
00449 {
00450 Drawings::Color color = getSampleColor(0);
00451 NCIRCLE("gt05-sl:testSample", flagFieldPosition.x, flagFieldPosition.y, 40, 1, Drawings::ps_solid, color);
00452 }
00453 }
00454 }
00455 }
00456
00457
00458
00459
00460
00461 void GT2005SelfLocator::updateByGoalPost(const Vector2<double>& goalPost,
00462 double measuredBearing)
00463 {
00464 observationUpdateDone = true;
00465 int i;
00466 for(i = 0; i < SAMPLES_MAX; ++i)
00467 if (random() < parameters.updateProbGoalPost)
00468 {
00469 GT2005SelfLocatorSample& s = sampleSet[i];
00470 Pose2D p(goalPost.x,goalPost.y);
00471 p -= s.camera;
00472 double assumedBearing = atan2(p.translation.y,p.translation.x);
00473 double similarity = fabs((assumedBearing - measuredBearing)) / pi;
00474 if(similarity > 1)
00475 similarity = 2 - similarity;
00476
00477 double val = gaussian(similarity * goalYAngleTrust);
00478 s.setPerceptProbability(GT2005SelfLocatorSample::flag, val, parameters);
00479 if (i==testSampleIndex)
00480 {
00481 Drawings::Color color = getSampleColor(val);
00482 NCIRCLE("gt05-sl:testSample", goalPost.x, goalPost.y, 40, 1, Drawings::ps_solid, color);
00483 }
00484 }
00485 }
00486
00487
00488
00489
00490
00491
00492 void GT2005SelfLocator::landmarksObservationUpdate(const LandmarksPercept& landmarksPercept)
00493 {
00494 int i;
00495 for(i = 0; i < landmarksPercept.numberOfFlags; i++)
00496 {
00497
00498 const Flag& flag = landmarksPercept.flags[i];
00499
00500
00501 if(!flag.isOnBorder(flag.x.max))
00502 updateByFlag(flag.position,
00503 LEFT_SIDE_OF_FLAG,
00504 flag.x.max);
00505
00506 if(!flag.isOnBorder(flag.x.min))
00507 updateByFlag(flag.position,
00508 RIGHT_SIDE_OF_FLAG,
00509 flag.x.min);
00510
00511
00512 }
00513
00514
00515 bool skyblueGoalSeen = false;
00516 bool yellowGoalSeen = false;
00517 for (i = 0; i < landmarksPercept.numberOfGoals; i++)
00518 {
00519
00520 const Goal& goal = landmarksPercept.goals[i];
00521 if (goal.color == skyblue)
00522 skyblueGoalSeen = true;
00523 else if (goal.color == yellow)
00524 yellowGoalSeen = true;
00525
00526 if(!goal.isOnBorder(goal.x.max))
00527 updateByGoalPost(goal.leftPost,
00528 goal.x.max);
00529 if(!goal.isOnBorder(goal.x.min))
00530 updateByGoalPost(goal.rightPost,
00531 goal.x.min);
00532
00533
00534
00535
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 }
00547
00548
00549
00550 void GT2005SelfLocator::updateVariancesBySpeed(double speed)
00551 {
00552 linePointZAngleMotionDependentVariance = parameters.linePointZAngleVariance * (1 + speed * parameters.linePointZAngleMotionDependency);
00553 linePointZAngleTrust = parameters.linePointWeight / (linePointZAngleMotionDependentVariance + QUASI_ZERO );
00554
00555 }
00556
00557 void GT2005SelfLocator::calculateTrust()
00558 {
00559 linePointZAngleTrust =
00560 parameters.linePointWeight / ( parameters.linePointZAngleVariance + QUASI_ZERO ),
00561 linePointYAngleTrust =
00562 parameters.linePointWeight / ( parameters.linePointYAngleVariance + QUASI_ZERO ),
00563
00564 crossingZAngleTrust =
00565 parameters.crossingWeight / ( parameters.crossingZAngleVariance + QUASI_ZERO ),
00566 crossingYAngleTrust =
00567 parameters.crossingWeight / ( parameters.crossingYAngleVariance + QUASI_ZERO ),
00568
00569 centerCircleZAngleTrust =
00570 parameters.centerCircleWeight / ( parameters.centerCircleZAngleVariance + QUASI_ZERO ),
00571 centerCircleYAngleTrust =
00572 parameters.centerCircleWeight / ( parameters.centerCircleYAngleVariance + QUASI_ZERO ),
00573 centerCircleOrientationAngleTrust =
00574 parameters.centerCircleWeight / ( parameters.centerCircleOrientationAngleVariance + QUASI_ZERO ),
00575
00576
00577
00578
00579 flagYAngleTrust =
00580 parameters.flagWeight / ( parameters.flagYAngleVariance + QUASI_ZERO ),
00581
00582 goalZAngleTrust =
00583 parameters.goalWeight / ( parameters.goalZAngleVariance + QUASI_ZERO ),
00584 goalYAngleTrust =
00585 parameters.goalWeight / ( parameters.goalYAngleVariance + QUASI_ZERO );
00586 }
00587
00588 void GT2005SelfLocator::execute()
00589 {
00590 NDECLARE_DEBUGDRAWING( "gt05-sl:sampleSet" , "drawingOnField" , "shows the current sample set");
00591 NDECLARE_DEBUGDRAWING( "gt05-sl:templates" , "drawingOnField" , "shows the current template positions for new samples");
00592 NDECLARE_DEBUGDRAWING( "gt05-sl:flags" , "drawingOnField" , "shows the currently buffered flags for template calculation");
00593 NDECLARE_DEBUGDRAWING( "gt05-sl:testSample" , "drawingOnField" , "shows the currently selected test sample");
00594 NDECLARE_DEBUGDRAWING( "gt05-sl:lastSeenCenterCircle", "drawingOnField", "shows the last seen center circle");
00595 NDECLARE_DEBUGDRAWING( "gt05-sl:lastCrossing", "drawingOnField", "shows the last seen line crossing");
00596 NDECLARE_DEBUGDRAWING( "gt05-sl:covarianceEllipse", "drawingOnField", "shows the ellipse describing the sample distribution covariance matrix");
00597
00598 MODIFY( "gt05-sl:parameters", parameters );
00599
00600 DEBUG_RESPONSE( "gt05-sl:recalculate trust values",
00601 calculateTrust();
00602 );
00603
00604 DEBUG_RESPONSE( "gt05-sl:resetSamples",
00605 resetSamples();
00606 );
00607
00608 DEBUG_RESPONSE( "gt05-sl:resetSamplesWhenPenalized",
00609 resetSamplesWhenPenalized();
00610 );
00611
00612 DEBUG_RESPONSE( "gt05-sl:resetSamplesToZero",
00613 resetSamples(Pose2D(0, Vector2<double>(0,0)));
00614 );
00615
00616 DEBUG_RESPONSE( "gt05-sl:resetSamplesToCurrentRobotPose",
00617 resetSamples(robotPose);
00618 );
00619
00620 MODIFY( "gt05-sl:testSampleIndex", testSampleIndex);
00621
00622 testSample = &sampleSet[testSampleIndex];
00623
00624 MODIFY( "gt05-sl:testSample", *testSample);
00625
00626
00627 if (parameters.resetSamplesWhenPenalized && gameControlData.getRobot().penalty != GameControlData::notPenalized)
00628 {
00629
00630 resetSamplesWhenPenalized();
00631 return;
00632 }
00633
00634 teamColorBlue = (getPlayer().getTeamColor() == Player::blue);
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 robotPose.setFrameNumber(landmarksPercept.frameNumber);
00645 robotPose.setTimestamp(SystemCall::getCurrentSystemTime());
00646
00647
00648 Pose2D odometryDelta = odometryData - lastOdometry;
00649 lastOdometry = odometryData;
00650
00651
00652 if(SystemCall::getTimeSince(timeStamp) > 500)
00653 {
00654 speed = (odometryData - lastOdometry2).translation.abs() / SystemCall::getTimeSince(timeStamp) * 1000.0;
00655 lastOdometry2 = odometryData;
00656 timeStamp = SystemCall::getCurrentSystemTime();
00657 }
00658
00659
00660
00661
00662 motionUpdate(odometryDelta,Pose2D(landmarksPercept.cameraOffset.x,
00663 landmarksPercept.cameraOffset.y),
00664 observationUpdateDone || parameters.noiseWithoutObservationUpdate);
00665
00666
00667 for(int i = 0; i < SAMPLES_MAX; ++i)
00668 sampleSet[i].scaleProbabilities(parameters.agingFactor);
00669
00670 observationUpdateDone = false;
00671
00672
00673 if (cameraMatrix.isValid)
00674 {
00675 lineObservationUpdate(linesPercept);
00676 landmarksObservationUpdate(landmarksPercept);
00677
00678 if (observationUpdateDone)
00679 {
00680 sampleTemplateGenerator.generateTemplates(landmarksPercept,linesPercept,odometryDelta);
00681 resample();
00682 }
00683 }
00684
00685
00686 Pose2D pose;
00687 double validity;
00688 calcPose(pose,validity);
00689 robotPose.setPose(pose);
00690 robotPose.setValidity(validity);
00691
00692
00693
00694 draw();
00695
00696 sampleSet.link(selfLocatorSamples);
00697
00698 landmarksState.update(landmarksPercept);
00699 }
00700
00701
00702
00703
00704
00705
00706
00707 double GT2005SelfLocator::calcAveragePerceptTypeProbabilities()
00708 {
00709 int count[GT2005SelfLocatorSample::numberOfPerceptTypes];
00710 double probability = 1;
00711
00712
00713 for (int k=0; k<GT2005SelfLocatorSample::numberOfPerceptTypes; k++){
00714 count[k] = 0;
00715 averagePerceptTypeProb[k] = 0;
00716 }
00717
00718 int i;
00719 for (i=0;i<SAMPLES_MAX;i++)
00720 {
00721 GT2005SelfLocatorSample& sample = sampleSet[i];
00722 for (int k=0; k<GT2005SelfLocatorSample::numberOfPerceptTypes; k++){
00723 if(sample.perceptProbabilities[k]<=1)
00724 {
00725 count[k]++;
00726 averagePerceptTypeProb[k] += sample.perceptProbabilities[k];
00727 }
00728 }
00729 }
00730
00731 for (i=0;i<GT2005SelfLocatorSample::numberOfPerceptTypes;i++)
00732 {
00733 if (count[i]>0) averagePerceptTypeProb[i] /= count[i];
00734 else averagePerceptTypeProb[i] = 1.0;
00735
00736
00737 probability *= averagePerceptTypeProb[i];
00738 }
00739 return probability;
00740 }
00741
00742
00743
00744
00745
00746
00747
00748 void GT2005SelfLocator::resample()
00749 {
00750
00751 double averageProbability =
00752 calcAveragePerceptTypeProbabilities();
00753
00754
00755
00756
00757
00758 int i;
00759 for(i = 0; i < SAMPLES_MAX; ++i){
00760 sampleSet[i].updateProbability(averagePerceptTypeProb, parameters);
00761
00762 }
00763
00764
00765
00766 GT2005SelfLocatorSample* oldSet = sampleSet.swap();
00767
00768
00769
00770
00771
00772
00773 double probSum = 0;
00774 for(i = 0; i < SAMPLES_MAX; ++i)
00775 probSum += oldSet[i].getProbability();
00776
00777 double prob2Index;
00778 int resamplingSize;
00779 if (parameters.applyConstantResampling)
00780 {
00781 prob2Index = (double) SAMPLES_MAX * (1.0 - parameters.constantResamplingRate) / probSum;
00782 resamplingSize = (int)( (double)SAMPLES_MAX * (1.0 - parameters.constantResamplingRate) );
00783 }
00784 else
00785 {
00786 prob2Index = (double) SAMPLES_MAX / probSum;
00787 resamplingSize = SAMPLES_MAX;
00788 }
00789
00790 double indexSum = 0;
00791
00792 int j = 0;
00793
00794 testSampleIndex = -1;
00795
00796
00797
00798
00799 for(i = 0; i < SAMPLES_MAX; ++i)
00800 {
00801
00802 indexSum += oldSet[i].getProbability() * prob2Index;
00803 while(j < resamplingSize && j < indexSum - 0.5)
00804 {
00805 sampleSet[j++] = oldSet[i];
00806 if (testSampleIndex == -1 && testSample == &oldSet[i])
00807 {
00808 testSample = &sampleSet[j-1];
00809 testSampleIndex = j-1;
00810 }
00811
00812 oldSet[i].isUsingOdometry = (random() < (collisionPercept.getCollisionAggregate() ? parameters.odometryProbCollision : parameters.odometryProbNoCollision));
00813 }
00814 }
00815
00816 if (parameters.applyConstantResampling)
00817 {
00818
00819 for(; j < SAMPLES_MAX; ++j)
00820 {
00821 sampleSet[j] = sampleTemplateGenerator.getTemplate();
00822 sampleSet[j].isUsingOdometry = (random() < (collisionPercept.getCollisionAggregate() ? parameters.odometryProbCollision : parameters.odometryProbNoCollision));
00823 if (testSampleIndex == -1)
00824 {
00825 testSample = &sampleSet[j];
00826 testSampleIndex = j;
00827 }
00828 }
00829 }
00830 else
00831 {
00832
00833
00834 for(i = 0; i < SAMPLES_MAX; i++)
00835 {
00836 GT2005SelfLocatorSample& s = sampleSet[i];
00837
00838
00839
00840 if(s.getProbability()<=1 && sampleTemplateGenerator.getNumberOfTemplates() && random() * averageProbability > s.getProbability())
00841 {
00842 s = sampleTemplateGenerator.getTemplate();
00843 s.isUsingOdometry = (random() < (collisionPercept.getCollisionAggregate() ? parameters.odometryProbCollision : parameters.odometryProbNoCollision));
00844 if (testSampleIndex == -1)
00845 {
00846 testSample = &s;
00847 testSampleIndex = i;
00848 }
00849 }
00850 if(random() * averageProbability > s.getProbability())
00851 {
00852 s = GT2005SelfLocatorSample(field.randomPose());
00853 s.isUsingOdometry = (random() < (collisionPercept.getCollisionAggregate() ? parameters.odometryProbCollision : parameters.odometryProbNoCollision));
00854 if (testSampleIndex == -1)
00855 {
00856 testSample = &s;
00857 testSampleIndex = i;
00858 }
00859 }
00860 }
00861 if (testSampleIndex == -1)
00862 {
00863 testSample = &sampleSet[0];
00864 testSampleIndex = 0;
00865 }
00866 }
00867 }
00868
00869
00870
00871 double GT2005SelfLocator::calcDistributionValidityByStandardDeviation()
00872 {
00873 averageX = 0;
00874 averageY = 0;
00875 averageRot = 0;
00876 stdDevRot = 0;
00877
00878
00879 eigenVal0 = eigenVal1 = eigenSwap = 0;
00880 eigenVec0 = Vector2<double>(0,0);
00881 eigenVec1 = Vector2<double>(0,0);
00882
00883 varianceCovarianceMatrix[0][0] = varianceCovarianceMatrix[1][0]=
00884 varianceCovarianceMatrix[0][1] = varianceCovarianceMatrix[1][1] = 0;
00885
00886 int i = 0;
00887
00888 Vector2<double> angle(0,0);
00889 double pSum = 0;
00890
00891
00892 for (i=0;i<SAMPLES_MAX;i++)
00893 {
00894 if(sampleSet[i].isValid())
00895 {
00896 averageX += sampleSet[i].translation.x * sampleSet[i].getProbability();
00897 averageY += sampleSet[i].translation.y * sampleSet[i].getProbability();
00898 angle.x += cos(sampleSet[i].rotation) * sampleSet[i].getProbability();
00899 angle.y += sin(sampleSet[i].rotation) * sampleSet[i].getProbability();
00900 pSum += sampleSet[i].getProbability();
00901 }
00902 }
00903
00904
00905 averageX /= pSum;
00906 averageY /= pSum;
00907 averageRot = atan2(angle.y,angle.x);
00908
00909
00910
00911 for (i = 0; i < SAMPLES_MAX; i++)
00912 {
00913 if(sampleSet[i].isValid())
00914 {
00915 double xErr = (sampleSet[i].translation.x - averageX);
00916 double yErr = (sampleSet[i].translation.y - averageY);
00917 double rErr = normalize(sampleSet[i].rotation - averageRot);
00918 varianceCovarianceMatrix[0][0] += sampleSet[i].getProbability() * xErr * xErr;
00919 varianceCovarianceMatrix[0][1] += sampleSet[i].getProbability() * xErr * yErr;
00920 varianceCovarianceMatrix[1][1] += sampleSet[i].getProbability() * yErr * yErr;
00921 stdDevRot += sampleSet[i].getProbability() * rErr * rErr;
00922 }
00923 }
00924
00925 varianceCovarianceMatrix[0][0] /= pSum;
00926 varianceCovarianceMatrix[0][1] /= pSum;
00927 varianceCovarianceMatrix[1][1] /= pSum;
00928 stdDevRot /= pSum;
00929
00930 varianceCovarianceMatrix[1][0] = varianceCovarianceMatrix[0][1];
00931
00932
00933 double p_2,q;
00934 p_2 = (varianceCovarianceMatrix[0][0] + varianceCovarianceMatrix[1][1])/2;
00935 q = varianceCovarianceMatrix[0][0] * varianceCovarianceMatrix[1][1] -
00936 varianceCovarianceMatrix[0][1] * varianceCovarianceMatrix[0][1];
00937
00938 eigenVal0 = p_2 + sqrt(fabs(p_2*p_2 - q));
00939 eigenVal1 = p_2 - sqrt(fabs(p_2*p_2 - q));
00940
00941
00942 if (eigenVal1 > eigenVal0)
00943 {
00944 eigenSwap = eigenVal0;
00945 eigenVal0 = eigenVal1;
00946 eigenVal1 = eigenSwap;
00947 }
00948
00949
00950 double amount;
00951
00952 eigenVec0.y = ((varianceCovarianceMatrix[0][0] - eigenVal0) * varianceCovarianceMatrix[0][1]) /
00953 (-varianceCovarianceMatrix[1][1] + eigenVal0 + varianceCovarianceMatrix[0][1]*varianceCovarianceMatrix[0][1]);
00954 eigenVec0.x = (-varianceCovarianceMatrix[1][1] + eigenVal0) * eigenVec0.y / varianceCovarianceMatrix[0][1];
00955
00956 amount = sqrt(eigenVec0.x*eigenVec0.x + eigenVec0.y*eigenVec0.y);
00957
00958
00959 if (amount != 0)
00960 {
00961 eigenVec0.x /= amount;
00962 eigenVec0.y /= amount;
00963 }
00964
00965
00966 eigenVec1.y = ((varianceCovarianceMatrix[0][0] - eigenVal1) * varianceCovarianceMatrix[0][1]) /
00967 (-varianceCovarianceMatrix[1][1] + eigenVal1 + varianceCovarianceMatrix[0][1]*varianceCovarianceMatrix[0][1]);
00968 eigenVec1.x = (-varianceCovarianceMatrix[1][1] + eigenVal1) * eigenVec1.y / varianceCovarianceMatrix[0][1];
00969
00970 amount = sqrt(eigenVec1.x*eigenVec1.x + eigenVec1.y*eigenVec1.y);
00971
00972
00973 if (amount != 0)
00974 {
00975 eigenVec1.x /= amount;
00976 eigenVec1.y /= amount;
00977 }
00978
00979
00980 if (eigenVec0.x < 0)
00981 {
00982 eigenVec0 *= -1;
00983 }
00984
00985 if (eigenVec1.x < 0)
00986 {
00987 eigenVec1 *= -1;
00988 }
00989
00990 eigenVal0 = sqrt(eigenVal0);
00991 eigenVal1 = sqrt(eigenVal1);
00992 stdDevRot = sqrt(stdDevRot);
00993
00994 eigenVec0 *= eigenVal0;
00995 eigenVec1 *= eigenVal1;
00996 double validity = max(eigenVal0,eigenVal1);
00997 robotPose.setPositionVariance(validity*validity);
00998
00999 robotPose.directionOfGreatestUncertaintyExists = (eigenVal0 >= 1.7 * eigenVal1);
01000 robotPose.greatestUncertainty.translation.x = averageX;
01001 robotPose.greatestUncertainty.translation.y = averageY;
01002 robotPose.greatestUncertainty.rotation = atan2(eigenVec0.y, eigenVec0.x);
01003
01004 validity = gaussian(validity/500);
01005 validity = min(validity,gaussian(stdDevRot/0.5));
01006 DEBUG_RESPONSE("gt05-sl:display eigenvalues", OUTPUT(idText,text,"gt05-sl " << eigenVal0 << " " << eigenVal1 << " " << validity););
01007
01008 NCOMPLEX_DRAWING("gt05-sl:covarianceEllipse",
01009
01010 NLINE("gt05-sl:covarianceEllipse",averageX,averageY,averageX+300*cos(averageRot),averageY+300*sin(averageRot),10,Drawings::ps_solid,Drawings::black);
01011 NLINE("gt05-sl:covarianceEllipse",averageX,
01012 averageY,
01013 averageX+600*cos(averageRot+stdDevRot),
01014 averageY+600*sin(averageRot+stdDevRot),
01015 10,Drawings::ps_solid,Drawings::red);
01016 NLINE("gt05-sl:covarianceEllipse",averageX,
01017 averageY,
01018 averageX+600*cos(averageRot-stdDevRot),
01019 averageY+600*sin(averageRot-stdDevRot),
01020 10,Drawings::ps_solid,Drawings::red);
01021
01022 double alpha = atan2(eigenVec0.y,eigenVec0.x);
01023 double a = eigenVal0;
01024 double b = eigenVal1;
01025 double x1 = 0;
01026 double x2 = 0;
01027 double y1 = 0;
01028 double y2 = 0;
01029
01030 int step = (int)(a/10);
01031 if (!step)
01032 {
01033 step = 1;
01034 }
01035
01036 for (int xc = 0; (xc + step) < a; xc += step)
01037 {
01038 x1 = xc;
01039 y1 = (sqrt(1-sqr(x1/a))* b);
01040 x2 = xc + step;
01041 y2 = (sqrt(1-sqr(x2/a))* b);
01042
01043
01044 NLINE("gt05-sl:covarianceEllipse", cos(alpha)*(x1) + averageX - sin(alpha)*(y1),
01045 sin(alpha)*(x1) + cos(alpha)*(y1) + averageY,
01046 cos(alpha)*(x2) + averageX - sin(alpha)*(y2),
01047 sin(alpha)*(x2) + cos(alpha)*(y2) + averageY,
01048 4, Drawings::ps_solid,
01049 Drawings::red);
01050 NLINE("gt05-sl:covarianceEllipse", cos(alpha)*(x1) + averageX - sin(alpha)*(-y1),
01051 sin(alpha)*(x1) + cos(alpha)*(-y1) + averageY,
01052 cos(alpha)*(x2) + averageX - sin(alpha)*(-y2),
01053 sin(alpha)*(x2) + cos(alpha)*(-y2) + averageY,
01054 4, Drawings::ps_solid,
01055 Drawings::red);
01056 NLINE("gt05-sl:covarianceEllipse", cos(alpha)*(-x1) + averageX - sin(alpha)*(y1),
01057 sin(alpha)*(-x1) + cos(alpha)*(y1) + averageY,
01058 cos(alpha)*(-x2) + averageX - sin(alpha)*(y2),
01059 sin(alpha)*(-x2) + cos(alpha)*(y2) + averageY,
01060 4, Drawings::ps_solid,
01061 Drawings::red);
01062 NLINE("gt05-sl:covarianceEllipse", cos(alpha)*(-x1) + averageX - sin(alpha)*(-y1),
01063 sin(alpha)*(-x1) + cos(alpha)*(-y1) + averageY,
01064 cos(alpha)*(-x2) + averageX - sin(alpha)*(-y2),
01065 sin(alpha)*(-x2) + cos(alpha)*(-y2) + averageY,
01066 4, Drawings::ps_solid,
01067 Drawings::red);
01068 }
01069
01070 x1 = a;
01071 y1 = 0;
01072
01073 NLINE("gt05-sl:covarianceEllipse", cos(alpha)*(x1) + averageX - sin(alpha)*(y1),
01074 sin(alpha)*(x1) + cos(alpha)*(y1) + averageY,
01075 cos(alpha)*(x2) + averageX - sin(alpha)*(y2),
01076 sin(alpha)*(x2) + cos(alpha)*(y2) + averageY,
01077 4, Drawings::ps_solid,
01078 Drawings::red);
01079 NLINE("gt05-sl:covarianceEllipse", cos(alpha)*(x1) + averageX - sin(alpha)*(-y1),
01080 sin(alpha)*(x1) + cos(alpha)*(-y1) + averageY,
01081 cos(alpha)*(x2) + averageX - sin(alpha)*(-y2),
01082 sin(alpha)*(x2) + cos(alpha)*(-y2) + averageY,
01083 4, Drawings::ps_solid,
01084 Drawings::red);
01085 NLINE("gt05-sl:covarianceEllipse", cos(alpha)*(-x1) + averageX - sin(alpha)*(y1),
01086 sin(alpha)*(-x1) + cos(alpha)*(y1) + averageY,
01087 cos(alpha)*(-x2) + averageX - sin(alpha)*(y2),
01088 sin(alpha)*(-x2) + cos(alpha)*(y2) + averageY,
01089 4, Drawings::ps_solid,
01090 Drawings::red);
01091 NLINE("gt05-sl:covarianceEllipse", cos(alpha)*(-x1) + averageX - sin(alpha)*(-y1),
01092 sin(alpha)*(-x1) + cos(alpha)*(-y1) + averageY,
01093 cos(alpha)*(-x2) + averageX - sin(alpha)*(-y2),
01094 sin(alpha)*(-x2) + cos(alpha)*(-y2) + averageY,
01095 4, Drawings::ps_solid,
01096 Drawings::red);
01097 );
01098
01099
01100
01101 return validity;
01102
01103
01104
01105 }
01106
01107
01108 double GT2005SelfLocator::calcDistributionValidityByEntropy()
01109 {
01110 int gridX, gridY, gridR;
01111 gridX = 5;
01112 gridY = 5;
01113 gridR = 5;
01114
01115 int grid[15][15][15];
01116 double entropy = 0;
01117
01118 double x = 6000;
01119 double y = 3600;
01120 int transx = 0;
01121 int transy = 0;
01122 int rot = 0;
01123 int i;
01124
01125 for(i = 0; i < (gridX * 3); ++i)
01126 for(int j = 0; j < (gridY * 3); ++j)
01127 for(int k = 0; k < (gridR * 3); ++k)
01128 {
01129 grid[i][j][k] = 0;
01130 }
01131
01132
01133 for(i = 0; i < SAMPLES_MAX; ++i)
01134 {
01135 transx = (int)((sampleSet[i].translation.x + 1.5*x) / x / 3 * gridX);
01136 transy = (int)((sampleSet[i].translation.y + 1.5*y) / y / 3 * gridY);
01137 rot = (int)((sampleSet[i].rotation + pi) / (2*pi) * gridR);
01138
01139 if(transx < 0) {transx = 0;}
01140 if(transy < 0) {transy = 0;}
01141 while(rot < 0) {rot = rot + gridR;}
01142
01143 if(transx > gridX) {transx = (gridX-1);}
01144 if(transy > gridY) {transy = (gridY-1);}
01145 while(rot >= gridR) {rot = (rot - gridR);}
01146
01147 grid[transx][transy][rot]++;
01148 }
01149
01150 for(i = 0; i < gridX; ++i)
01151 for(int j = 0; j < gridY; ++j)
01152 for(int k = 0; k < gridR; ++k)
01153 {
01154 if (grid[i][j][k])
01155 {
01156 entropy -= ((double)grid[i][j][k]/SAMPLES_MAX)*log((double)grid[i][j][k]/SAMPLES_MAX);
01157 }
01158 }
01159 entropy /= log(2.0);
01160
01161 return gaussian(entropy);
01162 }
01163
01164 RobotPose GT2005SelfLocator::calcPoseFromSubCube(Cell poseSpace[POSE_SPACE_GRID][POSE_SPACE_GRID][POSE_SPACE_GRID],int xMax, int yMax, int rMax)
01165 {
01166
01167 double xSum = 0,
01168 ySum = 0,
01169 cosSum = 0,
01170 sinSum = 0,
01171 probabilitySum = 0;
01172
01173 RobotPose result;
01174
01175
01176 for(int r = 0; r < 2; r++)
01177 {
01178
01179 int rNext = (rMax + r) % POSE_SPACE_GRID;
01180
01181
01182 for(int y = 0; y < 2; y++)
01183 for(int x = 0; x < 2; x++)
01184 {
01185
01186
01187
01188 for(GT2005SelfLocatorSample* sample = poseSpace[rNext][yMax + y][xMax + x].first; sample; sample = sample->next)
01189 if(sample->isValid())
01190 {
01191
01192
01193
01194 xSum += sample->translation.x * sample->getProbability();
01195 ySum += sample->translation.y * sample->getProbability();
01196 cosSum += sample->getCos() * sample->getProbability();
01197 sinSum += sample->getSin() * sample->getProbability();
01198 probabilitySum += sample->getProbability();
01199 }
01200 }
01201 }
01202
01203
01204 if(probabilitySum>0)
01205 {
01206 double weightedX = xSum / probabilitySum;
01207 double weightedY = ySum / probabilitySum;
01208 double weightedRot = atan2(sinSum,cosSum);
01209 result.setPose(Pose2D(weightedRot,Vector2<double>(weightedX,weightedY)) );
01210 result.setValidity(probabilitySum / SAMPLES_MAX);
01211
01212 if (parameters.clipRobotPose)
01213 {
01214 double diff = field.clip(result.translation);
01215 if(diff > 1){
01216
01217 result.setValidity(result.getValidity() / sqrt(diff));
01218 }
01219 }
01220 }
01221
01222 return result;
01223 }
01224
01225
01226
01227
01228
01229
01230
01231 void GT2005SelfLocator::calcPose(Pose2D& pose,double& validity)
01232 {
01233
01234 Cell poseSpace[POSE_SPACE_GRID][POSE_SPACE_GRID][POSE_SPACE_GRID];
01235
01236 double width = field.x.getSize(),
01237 height = field.y.getSize();
01238
01239 int i;
01240
01241 for(i = 0; i < SAMPLES_MAX; i++)
01242 {
01243 GT2005SelfLocatorSample& sample = sampleSet[i];
01244
01245 if(sample.isValid())
01246 {
01247
01248
01249
01250 int r = static_cast<int>((sample.getAngle() / pi2 + 0.5) * POSE_SPACE_GRID);
01251
01252
01253 int y = static_cast<int>((sample.translation.y / height + 0.5) * POSE_SPACE_GRID);
01254 int x = static_cast<int>((sample.translation.x / width + 0.5) * POSE_SPACE_GRID);
01255
01256
01257
01258 if(x < 0)
01259 x = 0;
01260 else if(x >= POSE_SPACE_GRID)
01261 x = POSE_SPACE_GRID-1;
01262
01263 if(y < 0)
01264 y = 0;
01265 else if(y >= POSE_SPACE_GRID)
01266 y = POSE_SPACE_GRID-1;
01267
01268
01269
01270 if(r < 0)
01271 r = POSE_SPACE_GRID-1;
01272 else if(r >= POSE_SPACE_GRID)
01273 r = 0;
01274
01275
01276
01277 Cell& cell = poseSpace[r][y][x];
01278
01279
01280 sample.next = cell.first;
01281 cell.first = &sample;
01282 cell.count++;
01283 }
01284 }
01285
01286
01287
01288
01289 int rMax[NUM_OF_CALCULATED_POSES],
01290 yMax[NUM_OF_CALCULATED_POSES],
01291 xMax[NUM_OF_CALCULATED_POSES],
01292 countMax[NUM_OF_CALCULATED_POSES];
01293
01294 for (i=0;i<NUM_OF_CALCULATED_POSES;i++)
01295 {
01296 rMax[i] = 0;
01297 yMax[i] = 0;
01298 xMax[i] = 0;
01299 countMax[i] = 0;
01300 }
01301
01302
01303 for(int r = 0; r < POSE_SPACE_GRID; r++)
01304 {
01305
01306 int rNext = (r + 1) % POSE_SPACE_GRID;
01307
01308
01309 for(int y = 0; y < POSE_SPACE_GRID - 1; y++)
01310 for(int x = 0; x < POSE_SPACE_GRID - 1; x++)
01311 {
01312
01313
01314 int count = poseSpace[r][y][x].count +
01315 poseSpace[r][y][x+1].count +
01316 poseSpace[r][y+1][x].count +
01317 poseSpace[r][y+1][x+1].count +
01318 poseSpace[rNext][y][x].count +
01319 poseSpace[rNext][y][x+1].count +
01320 poseSpace[rNext][y+1][x].count +
01321 poseSpace[rNext][y+1][x+1].count;
01322
01323 if(count > countMax[0])
01324 {
01325
01326 if (NUM_OF_CALCULATED_POSES>1)
01327 {
01328 for (i=NUM_OF_CALCULATED_POSES-1;i>0;i--)
01329 {
01330 rMax[i] = rMax[i-1];
01331 xMax[i] = xMax[i-1];
01332 yMax[i] = yMax[i-1];
01333 countMax[i] = countMax[i-1];
01334 }
01335 }
01336 countMax[0] = count;
01337 rMax[0] = r;
01338 yMax[0] = y;
01339 xMax[0] = x;
01340 }
01341 }
01342 }
01343
01344 if(countMax[0] > 0)
01345 {
01346 for (i=0;i<NUM_OF_CALCULATED_POSES;i++)
01347 {
01348 if (countMax[i]>0)
01349 {
01350 robotPoseCollection.poses[i] = calcPoseFromSubCube(poseSpace, xMax[i],yMax[i],rMax[i]);
01351 CIRCLE(selfLocatorField,
01352 robotPoseCollection.poses[i].translation.x,
01353 robotPoseCollection.poses[i].translation.y,
01354 50,50,Drawings::ps_solid,Drawings::yellowOrange);
01355 } else
01356 {
01357 robotPoseCollection.poses[i].setValidity(-1);
01358 }
01359 }
01360 pose = robotPoseCollection.poses[0].getPose();
01361 validity = robotPoseCollection.poses[0].getValidity();
01362
01363
01364 DEBUG_RESPONSE("gt05-sl:validity by covariance",
01365 validity = calcDistributionValidityByStandardDeviation();
01366 );
01367
01368 DEBUG_RESPONSE("gt05-sl:validity by entropy",
01369 validity = calcDistributionValidityByEntropy();
01370 );
01371
01372
01373
01374 robotPoseCollection.numberOfPoses = NUM_OF_CALCULATED_POSES;
01375 } else {
01376 validity = 0;
01377 }
01378
01379
01380
01381 }
01382
01383 bool GT2005SelfLocator::handleMessage(InMessage& message)
01384 {
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400 return false;
01401 }
01402
01403 void GT2005SelfLocator::resetSamples()
01404 {
01405 for(int i = 0; i < SAMPLES_MAX; i++)
01406 {
01407 sampleSet[i].reset();
01408 (Pose2D&) sampleSet[i] = field.randomPose();
01409 }
01410 }
01411
01412 void GT2005SelfLocator::resetSamples(const Pose2D &pose)
01413 {
01414 for(int i = 0; i < SAMPLES_MAX; i++)
01415 {
01416 sampleSet[i].reset();
01417 (Pose2D&) sampleSet[i] = pose;
01418 }
01419 }
01420
01421 void GT2005SelfLocator::resetSamplesWhenPenalized()
01422 {
01423
01424 int i;
01425 Pose2D t;
01426 double randomFactor = 3;
01427
01428
01429 t.translation.x = 0;
01430 t.translation.y = yPosLeftSideline;
01431 t.rotation = -pi_2;
01432 for(i = 0; i < SAMPLES_MAX / 4; ++i)
01433 {
01434 sampleSet[i].reset();
01435 (Pose2D&) sampleSet[i] = Pose2D::random(Range<double>(t.translation.x - randomFactor * 50,
01436 t.translation.x + randomFactor * 50),
01437 Range<double>(t.translation.y - randomFactor * 50,
01438 t.translation.y + randomFactor * 50),
01439 Range<double>(t.getAngle() - randomFactor * 0.1,
01440 t.getAngle() + randomFactor * 0.1));
01441 }
01442
01443 t.translation.y = yPosRightSideline;
01444 t.rotation = pi_2;
01445 for(; i < SAMPLES_MAX / 2; ++i)
01446 {
01447 sampleSet[i].reset();
01448 (Pose2D&) sampleSet[i] = Pose2D::random(Range<double>(t.translation.x - randomFactor * 50,
01449 t.translation.x + randomFactor * 50),
01450 Range<double>(t.translation.y - randomFactor * 50,
01451 t.translation.y + randomFactor * 50),
01452 Range<double>(t.getAngle() - randomFactor * 0.1,
01453 t.getAngle() + randomFactor * 0.1));
01454 }
01455
01456 for(; i < SAMPLES_MAX; ++i)
01457 {
01458 sampleSet[i].reset();
01459 (Pose2D&) sampleSet[i] = field.randomPose();
01460 }
01461 }
01462
01463
01464
01465
01466
01467 void GT2005SelfLocator::draw() const
01468 {
01469 NCOMPLEX_DRAWING ( "gt05-sl:sampleSet",
01470
01471 for(int i = 0; i < SAMPLES_MAX; ++i)
01472 draw(sampleSet[i], getSampleColor(sampleSet[i].probability));
01473 );
01474
01475 NCOMPLEX_DRAWING( "gt05-sl:testSample",
01476 drawTestSample(*testSample, getSampleColor(testSample->probability));
01477 );
01478
01479 NCOMPLEX_DRAWING ( "gt05-sl:lastSeenCenterCircle",
01480 {
01481
01482 Pose2D pointFromPose = robotPose + lastSeenCenterCircle;
01483 NCIRCLE( "gt05-sl:lastSeenCenterCircle",
01484 pointFromPose.translation.x, pointFromPose.translation.y,
01485 60,30,Drawings::ps_solid,Drawings::white);
01486 Pose2D p1 = pointFromPose + Pose2D(0,60);
01487 Pose2D p2 = pointFromPose + Pose2D(0,-60);
01488 NLINE("gt05-sl:lastSeenCenterCircle",
01489 p1.translation.x,
01490 p1.translation.y,
01491 p2.translation.x,
01492 p2.translation.y,
01493 1,
01494 Drawings::ps_solid,
01495 Drawings::white);
01496 });
01497
01498 NCOMPLEX_DRAWING( "gt05-sl:lastCrossing",
01499 {
01500 int color = Drawings::black;
01501 switch(lastSeenCrossingClass)
01502 {
01503 case GT2005LineCrossingsTable::virtualCrossing:
01504 color = Drawings::blue;
01505 break;
01506 case GT2005LineCrossingsTable::lCrossing:
01507 color = Drawings::yellow;
01508 break;
01509 case GT2005LineCrossingsTable::tCrossing:
01510 color = Drawings::red;
01511 break;
01512 case GT2005LineCrossingsTable::xCrossing:
01513 color = Drawings::pink;
01514 break;
01515 }
01516 NCIRCLE("gt05-sl:lastCrossing",lastModelCrossing.x,lastModelCrossing.y,40,40,Drawings::ps_solid,color);
01517 NCIRCLE("gt05-sl:lastCrossing",lastSeenCrossing.x,lastSeenCrossing.y,30,30,Drawings::ps_solid,Drawings::red);
01518 NLINE("gt05-sl:lastCrossing",lastSeenCrossing.x,lastSeenCrossing.y,lastModelCrossing.x,lastModelCrossing.y,10,Drawings::ps_solid,Drawings::blue);
01519 });
01520
01521 DEBUG_RESPONSE("gt05-sl:display field tables",
01522 Field field;
01523 field.draw(Drawings::white, LinesPercept::field);
01524 field.draw(Drawings::red, LinesPercept::border);
01525 field.draw(Drawings::yellow, LinesPercept::yellowGoal);
01526 field.draw(Drawings::skyblue, LinesPercept::skyblueGoal);
01527 );
01528
01529 DEBUG_RESPONSE("gt05-sl:display field lines observation table, 0 deg",
01530 observationTable[LinesPercept::field].draw(0);
01531 );
01532 DEBUG_RESPONSE("gt05-sl:display field lines observation table, 90 deg",
01533 observationTable[LinesPercept::field].draw(pi_2);
01534 );
01535 DEBUG_RESPONSE("gt05-sl:display field lines observation table, 180 deg",
01536 observationTable[LinesPercept::field].draw(pi);
01537 );
01538 DEBUG_RESPONSE("gt05-sl:display field lines observation table, -90 deg",
01539 observationTable[LinesPercept::field].draw(-pi_2);
01540 );
01541
01542 DEBUG_RESPONSE("gt05-sl:display yellow goal lines observation table, 0 deg",
01543 observationTable[LinesPercept::yellowGoal].draw(0);
01544 );
01545 DEBUG_RESPONSE("gt05-sl:display yellow goal lines observation table, 90 deg",
01546 observationTable[LinesPercept::yellowGoal].draw(pi_2);
01547 );
01548 DEBUG_RESPONSE("gt05-sl:display yellow goal lines observation table, 180 deg",
01549 observationTable[LinesPercept::yellowGoal].draw(pi);
01550 );
01551 DEBUG_RESPONSE("gt05-sl:display yellow goal lines observation table, -90 deg",
01552 observationTable[LinesPercept::yellowGoal].draw(-pi_2);
01553 );
01554
01555 DEBUG_RESPONSE("gt05-sl:display carpet border observation table, 0 deg",
01556 observationTable[LinesPercept::border].draw(0);
01557 );
01558 DEBUG_RESPONSE("gt05-sl:display carpet border observation table, 90 deg",
01559 observationTable[LinesPercept::border].draw(pi_2);
01560 );
01561 DEBUG_RESPONSE("gt05-sl:display carpet border observation table, 180 deg",
01562 observationTable[LinesPercept::border].draw(pi);
01563 );
01564 DEBUG_RESPONSE("gt05-sl:display carpet border observation table, -90 deg",
01565 observationTable[LinesPercept::border].draw(-pi_2);
01566 );
01567
01568 }
01569
01570 Drawings::Color GT2005SelfLocator::getSampleColor(double probability) const
01571 {
01572 if (probability == 2 || probability <= QUASI_ZERO)
01573 return Drawings::black;
01574 else if (probability < 0.1)
01575 return Drawings::blue;
01576 else if (probability < 0.2)
01577 return Drawings::yellow;
01578 else if (probability < 0.5)
01579 return Drawings::orange;
01580 else if (probability < 0.8)
01581 return Drawings::red;
01582 else if (probability < 0.95)
01583 return Drawings::pink;
01584 else
01585 return Drawings::white;
01586 }
01587
01588 void GT2005SelfLocator::draw(const Pose2D& pose,Drawings::Color color) const
01589 {
01590 Pose2D p = pose + Pose2D(-100,0);
01591 NLINE("gt05-sl:sampleSet",
01592 pose.translation.x,
01593 pose.translation.y,
01594 p.translation.x,
01595 p.translation.y,
01596 1,
01597 Drawings::ps_solid,
01598 color);
01599 p = pose + Pose2D(-40,-40);
01600 NLINE("gt05-sl:sampleSet",
01601 pose.translation.x,
01602 pose.translation.y,
01603 p.translation.x,
01604 p.translation.y,
01605 1,
01606 Drawings::ps_solid,
01607 color);
01608 p = pose + Pose2D(-40,40);
01609 NLINE("gt05-sl:sampleSet",
01610 pose.translation.x,
01611 pose.translation.y,
01612 p.translation.x,
01613 p.translation.y,
01614 1,
01615 Drawings::ps_solid,
01616 color);
01617 }
01618
01619 void GT2005SelfLocator::drawTestSample(const Pose2D& pose,Drawings::Color color) const
01620 {
01621 Pose2D p = pose + Pose2D(-100,0);
01622 NLINE("gt05-sl:testSample",
01623 pose.translation.x,
01624 pose.translation.y,
01625 p.translation.x,
01626 p.translation.y,
01627 1,
01628 Drawings::ps_solid,
01629 color);
01630 p = pose + Pose2D(-40,-40);
01631 NLINE("gt05-sl:testSample",
01632 pose.translation.x,
01633 pose.translation.y,
01634 p.translation.x,
01635 p.translation.y,
01636 1,
01637 Drawings::ps_solid,
01638 color);
01639 p = pose + Pose2D(-40,40);
01640 NLINE("gt05-sl:testSample",
01641 pose.translation.x,
01642 pose.translation.y,
01643 p.translation.x,
01644 p.translation.y,
01645 1,
01646 Drawings::ps_solid,
01647 color);
01648 }