00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Platform/GTAssert.h"
00011 #include "GT2004SelfLocator.h"
00012 #include "Platform/SystemCall.h"
00013 #include "Tools/FieldDimensions.h"
00014 #include "Tools/Player.h"
00015 #include "Tools/Debugging/Debugging.h"
00016 #include "Tools/Math/Geometry.h"
00017 #include "Tools/Streams/InStreams.h"
00018 #include "Tools/Debugging/GenericDebugData.h"
00019
00020 double GT2004SelfLocator::paramUp = 0.01,
00021 GT2004SelfLocator::paramDown = 0.005,
00022 GT2004SelfLocator::paramDelay = 3,
00023 GT2004SelfLocator::paramHeight = 150,
00024 GT2004SelfLocator::paramZ = 10,
00025 GT2004SelfLocator::paramY = 2,
00026 GT2004SelfLocator::paramR = 2,
00027 GT2004SelfLocator::paramTrans = 100,
00028 GT2004SelfLocator::paramRot = 0.5;
00029
00030 GT2004SelfLocator::Sample::Sample()
00031 {
00032 for(int i = 0; i < numberOfQualities; ++i)
00033 quality[i] = 0.5;
00034 probability = 2;
00035 }
00036
00037 GT2004SelfLocator::Sample::Sample(const Pose2D& pose,const double* quality)
00038 : PoseSample(pose)
00039 {
00040 for(int i = 0; i < numberOfQualities; ++i)
00041 this->quality[i] = 2;
00042 probability = 2;
00043 }
00044
00045 void GT2004SelfLocator::Sample::updateQuality(const double* average)
00046 {
00047 probability = 1;
00048 for(int i = 0; i < numberOfQualities; ++i)
00049 probability *= quality[i] == 2 ? average[i] - paramDelay * paramUp : quality[i];
00050 }
00051
00052 void GT2004SelfLocator::Sample::setProbability(LinesPercept::LineType type,double value)
00053 {
00054 double& q = quality[type > LinesPercept::yellowGoal ? type - 1 : type];
00055 if(type > LinesPercept::yellowGoal)
00056 {
00057 if(q == 2)
00058 q = value;
00059 else if(value < q)
00060 if(value < q - 0.05)
00061 q -= 0.05;
00062 else
00063 q = value;
00064 else
00065 if(value > q + 0.1)
00066 q += 0.1;
00067 else
00068 q = value;
00069 }
00070 else
00071 {
00072 if(q == 2)
00073 q = value - paramDelay * paramUp;
00074 else if(value < q)
00075 if(value < q - paramDown)
00076 q -= paramDown;
00077 else
00078 q = value;
00079 else
00080 if(value > q + paramUp)
00081 q += paramUp;
00082 else
00083 q = value;
00084 }
00085 }
00086
00087 GT2004SelfLocator::GT2004SelfLocator(const SelfLocatorInterfaces& interfaces)
00088 : SelfLocator(interfaces),
00089 distanceToBorderEstimator(interfaces)
00090 {
00091 int i;
00092 for(i = 0; i < Sample::numberOfQualities; ++i)
00093 average[i] = 0.5;
00094 for(i = 0; i < SAMPLES_MAX; ++i)
00095 (Pose2D&) sampleSet[i] = field.randomPose();
00096 numberOfTypes = 0;
00097 numOfFlags = 0;
00098 sensorUpdated = false;
00099 timeStamp = 0;
00100 speed = 0;
00101 }
00102
00103 void GT2004SelfLocator::execute()
00104 {
00105 const int maxPercepts = 3;
00106
00107
00108
00109 robotPose.setFrameNumber(landmarksPercept.frameNumber);
00110
00111 distanceToBorderEstimator.execute();
00112
00113 Pose2D odometry = odometryData - lastOdometry;
00114 lastOdometry = odometryData;
00115 if(SystemCall::getTimeSince(timeStamp) > 500)
00116 {
00117 speed = (odometryData - lastOdometry2).translation.abs() / SystemCall::getTimeSince(timeStamp) * 1000.0;
00118 lastOdometry2 = odometryData;
00119 timeStamp = SystemCall::getCurrentSystemTime();
00120 }
00121 paramZ = 10 - 9 * speed / 400;
00122
00123
00124
00125 paramTrans = 50 - speed / 10;
00126
00127
00128 updateByOdometry(odometry,
00129 Pose2D(landmarksPercept.cameraOffset.x,
00130 landmarksPercept.cameraOffset.y),
00131 sensorUpdated);
00132
00133
00134 numberOfTypes = 0;
00135 sensorUpdated = false;
00136 if(cameraMatrix.isValid)
00137 {
00138 int i;
00139 for(i = 0; i < 2; ++i)
00140 for(int j = 0; j < linesPercept.numberOfPoints[i] && j < maxPercepts; ++j)
00141 {
00142 updateByPoint(linesPercept.points[i][rand() % linesPercept.numberOfPoints[i]],
00143 LinesPercept::LineType(i));
00144 sensorUpdated = true;
00145 }
00146
00147 if(linesPercept.numberOfPoints[LinesPercept::yellowGoal])
00148 types[numberOfTypes++] = LinesPercept::yellowGoal;
00149 if(linesPercept.numberOfPoints[LinesPercept::skyblueGoal])
00150 types[numberOfTypes++] = LinesPercept::skyblueGoal;
00151
00152 if(linesPercept.numberOfPoints[LinesPercept::yellowGoal] ||
00153 linesPercept.numberOfPoints[LinesPercept::skyblueGoal])
00154 for(int j = 0; j < linesPercept.numberOfPoints[LinesPercept::yellowGoal] +
00155 linesPercept.numberOfPoints[LinesPercept::skyblueGoal] && j < maxPercepts; ++j)
00156 {
00157 LinesPercept::LineType select = (random() + 1e-6) * linesPercept.numberOfPoints[LinesPercept::yellowGoal] >
00158 linesPercept.numberOfPoints[LinesPercept::skyblueGoal]
00159 ? LinesPercept::yellowGoal
00160 : LinesPercept::skyblueGoal;
00161 updateByPoint(linesPercept.points[select][rand() % linesPercept.numberOfPoints[select]],
00162 select);
00163 sensorUpdated = true;
00164 }
00165 for(i = 0; i < landmarksPercept.numberOfFlags; ++i)
00166 {
00167 const Flag& flag = landmarksPercept.flags[i];
00168 if(!flag.isOnBorder(flag.x.max))
00169 updateByFlag(flag.position,
00170 LEFT_SIDE_OF_FLAG,
00171 flag.x.max);
00172 if(!flag.isOnBorder(flag.x.min))
00173 updateByFlag(flag.position,
00174 RIGHT_SIDE_OF_FLAG,
00175 flag.x.min);
00176 }
00177 for(i = 0; i < landmarksPercept.numberOfGoals; ++i)
00178 {
00179 const Goal& goal = landmarksPercept.goals[i];
00180 if(!goal.isOnBorder(goal.x.max))
00181 updateByGoalPost(goal.leftPost,
00182 goal.x.max);
00183 if(!goal.isOnBorder(goal.x.min))
00184 updateByGoalPost(goal.rightPost,
00185 goal.x.min);
00186 }
00187
00188 if(sensorUpdated)
00189 {
00190
00191 generatePoseTemplates(landmarksPercept,odometry);
00192 resample();
00193 }
00194 }
00195
00196 Pose2D pose;
00197 double validity;
00198 calcPose(pose,validity);
00199 robotPose.setPose(pose);
00200 robotPose.setValidity(validity);
00201 sampleSet.link(selfLocatorSamples);
00202
00203 DEBUG_DRAWING_FINISHED(selfLocatorField);
00204 DEBUG_DRAWING_FINISHED(selfLocator);
00205
00206 landmarksState.update(landmarksPercept);
00207 }
00208
00209 static double fmax(double a,double b)
00210 {
00211 return a> b ? a : b;
00212 }
00213
00214 void GT2004SelfLocator::updateByOdometry(const Pose2D& odometry,
00215 const Pose2D& camera,
00216 bool noise)
00217 {
00218 double transNoise = noise ? 200 : 0,
00219 rotNoise = noise ? 0.5 : 0;
00220 double dist = odometry.translation.abs();
00221 double angle = fabs(odometry.getAngle());
00222 double f;
00223
00224 for(int i = 0; i < SAMPLES_MAX; ++i)
00225 {
00226 Sample& s = sampleSet[i];
00227 s += odometry;
00228 if(s.probability == 2)
00229 f = 0;
00230 else
00231 f = (1 - s.probability) * (1 - s.probability);
00232 double rotError = ((random() * 2 - 1) * fmax(fmax(dist * 0.002,angle * 0.2),rotNoise * f));
00233 Vector2<double> transError((random() * 2 - 1) * max(fmax(fabs(odometry.translation.x) * 0.1,
00234 fabs(odometry.translation.y) * 0.02),
00235 transNoise * f),
00236 (random() * 2 - 1) * max(fmax(fabs(odometry.translation.y) * 0.1,
00237 fabs(odometry.translation.x) * 0.02),
00238 transNoise * f));
00239 s += Pose2D(rotError,transError);
00240 s.camera = s + camera;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 }
00257
00258 void GT2004SelfLocator::updateByPoint(const LinesPercept::LinePoint& point,LinesPercept::LineType type)
00259 {
00260 COMPLEX_DRAWING(selfLocator,draw(point,type));
00261
00262 int index = type;
00263 if(getPlayer().getTeamColor() == Player::blue && type >= LinesPercept::yellowGoal)
00264 index = LinesPercept::yellowGoal + LinesPercept::skyblueGoal - type;
00265 double d = point.abs();
00266 double zObs = atan2(paramHeight ,d),
00267 yObs = atan2((double)point.y,(double)point.x);
00268 Pose2D point2(point.angle, Vector2<double>(point.x, point.y));
00269 for(int i = 0; i < SAMPLES_MAX; ++i)
00270 {
00271 Sample& s = sampleSet[i];
00272 Pose2D p = s + point2;
00273 Vector2<double> vMin;
00274 bool isY = index == LinesPercept::field && (fabs(p.getAngle()) < pi / 4 || fabs(p.getAngle()) > 3 * pi / 4);
00275 if(isY)
00276 vMin = observationTable[LinesPercept::numberOfLineTypes].getClosestPoint(p.translation);
00277 else
00278 vMin = observationTable[index].getClosestPoint(p.translation);
00279 if(vMin.x != 1000000)
00280 {
00281 Vector2<double> diff = vMin - p.translation;
00282 Vector2<double> v = (Pose2D(vMin) - s).translation;
00283 double zModel = atan2(paramHeight ,v.abs()),
00284 yModel = atan2(v.y,v.x);
00285 s.setProbability(isY ? LinesPercept::LineType(LinesPercept::numberOfLineTypes + 1) : type, sigmoid((zModel - zObs) * paramZ) * sigmoid((yModel - yObs) * paramY));
00286 }
00287 else
00288 s.setProbability(type,0.000001);
00289 }
00290 }
00291
00292 void GT2004SelfLocator::updateByFlag(const Vector2<double>& flag,
00293 FlagSides sideOfFlag,
00294 double measuredBearing)
00295 {
00296 sensorUpdated = true;
00297 for(int i = 0; i < SAMPLES_MAX; ++i)
00298 {
00299 Sample& s = sampleSet[i];
00300 Pose2D p(flag.x,flag.y);
00301 p -= s.camera;
00302 double assumedBearing = atan2(p.translation.y,p.translation.x) + sideOfFlag * asin(flagRadius / p.translation.abs());
00303 double similarity = fabs((assumedBearing - measuredBearing)) / pi;
00304 if(similarity > 1)
00305 similarity = 2.0 - similarity;
00306 s.setProbability(LinesPercept::numberOfLineTypes,sigmoid(similarity * 7));
00307 }
00308 }
00309
00310 void GT2004SelfLocator::updateByGoalPost(const Vector2<double>& goalPost,
00311 double measuredBearing)
00312 {
00313 sensorUpdated = true;
00314 for(int i = 0; i < SAMPLES_MAX; ++i)
00315 {
00316 Sample& s = sampleSet[i];
00317 Pose2D p(goalPost.x,goalPost.y);
00318 p -= s.camera;
00319 double assumedBearing = atan2(p.translation.y,p.translation.x);
00320 double similarity = fabs((assumedBearing - measuredBearing)) / pi;
00321 if(similarity > 1)
00322 similarity = 2 - similarity;
00323 s.setProbability(LinesPercept::numberOfLineTypes,sigmoid(similarity * 7));
00324 }
00325 }
00326
00327 void GT2004SelfLocator::resample()
00328 {
00329 int i,j,
00330 count[Sample::numberOfQualities];
00331
00332 for(i = 0; i < Sample::numberOfQualities; ++i)
00333 {
00334 average[i] = 0;
00335 count[i] = 0;
00336 }
00337
00338 for(i = 0; i < SAMPLES_MAX; ++i)
00339 {
00340 Sample& s = sampleSet[i];
00341 for(j = 0; j < Sample::numberOfQualities; ++j)
00342 if(s.quality[j] != 2)
00343 {
00344 average[j] += s.quality[j];
00345 ++count[j];
00346 }
00347 }
00348
00349 double average2 = 1;
00350 for(i = 0; i < Sample::numberOfQualities; ++i)
00351 {
00352 if(count[i])
00353 average[i] /= count[i];
00354 else
00355 average[i] = 0.5;
00356 average2 *= average[i];
00357 }
00358
00359
00360 for(i = 0; i < SAMPLES_MAX; ++i)
00361 sampleSet[i].updateQuality(average);
00362
00363
00364 Sample* oldSet = sampleSet.swap();
00365
00366 double probSum = 0;
00367 for(i = 0; i < SAMPLES_MAX; ++i)
00368 probSum += oldSet[i].getQuality();
00369 double prob2Index = (double) SAMPLES_MAX / probSum;
00370
00371 double indexSum = 0;
00372 j = 0;
00373 for(i = 0; i < SAMPLES_MAX; ++i)
00374 {
00375 indexSum += oldSet[i].getQuality() * prob2Index;
00376 while(j < SAMPLES_MAX && j < indexSum - 0.5)
00377 sampleSet[j++] = oldSet[i];
00378 }
00379
00380 for(i = 0; i < SAMPLES_MAX; ++i)
00381 {
00382 Sample& s = sampleSet[i];
00383
00384 if(numOfTemplates && random() * average2 > s.getQuality())
00385 s = getTemplate();
00386 else
00387 {
00388 COMPLEX_DRAWING(selfLocatorField,draw(s,Drawings::black));
00389 }
00390 }
00391 }
00392
00393 void GT2004SelfLocator::calcPose(Pose2D& pose,double& validity)
00394 {
00395 Cell cells[GRID_MAX][GRID_MAX][GRID_MAX];
00396 double width = field.x.getSize(),
00397 height = field.y.getSize();
00398
00399
00400 for(int i = 0; i < SAMPLES_MAX; ++i)
00401 {
00402 Sample& p = sampleSet[i];
00403 if(p.isValid())
00404 {
00405 int r = static_cast<int>((p.getAngle() / pi2 + 0.5) * GRID_MAX),
00406 y = static_cast<int>((p.translation.y / height + 0.5) * GRID_MAX),
00407 x = static_cast<int>((p.translation.x / width + 0.5) * GRID_MAX);
00408 if(x < 0)
00409 x = 0;
00410 else if(x >= GRID_MAX)
00411 x = GRID_MAX-1;
00412 if(y < 0)
00413 y = 0;
00414 else if(y >= GRID_MAX)
00415 y = GRID_MAX-1;
00416 if(r < 0)
00417 r = GRID_MAX-1;
00418 else if(r >= GRID_MAX)
00419 r = 0;
00420 Cell& c = cells[r][y][x];
00421 p.next = c.first;
00422 c.first = &p;
00423 ++c.count;
00424 }
00425 }
00426
00427
00428 int rMax = 0,
00429 yMax = 0,
00430 xMax = 0,
00431 countMax = 0,
00432 r;
00433 for(r = 0; r < GRID_MAX; ++r)
00434 {
00435 int rNext = (r + 1) % GRID_MAX;
00436 for(int y = 0; y < GRID_MAX - 1; ++y)
00437 for(int x = 0; x < GRID_MAX - 1; ++x)
00438 {
00439 int count = cells[r][y][x].count +
00440 cells[r][y][x+1].count +
00441 cells[r][y+1][x].count +
00442 cells[r][y+1][x+1].count +
00443 cells[rNext][y][x].count +
00444 cells[rNext][y][x+1].count +
00445 cells[rNext][y+1][x].count +
00446 cells[rNext][y+1][x+1].count;
00447 if(count > countMax)
00448 {
00449 countMax = count;
00450 rMax = r;
00451 yMax = y;
00452 xMax = x;
00453 }
00454 }
00455 }
00456
00457 if(countMax > 0)
00458 {
00459
00460 double xSum = 0,
00461 ySum = 0,
00462 cosSum = 0,
00463 sinSum = 0,
00464 qualitySum = 0;
00465 for(r = 0; r < 2; ++r)
00466 {
00467 int r2 = (rMax + r) % GRID_MAX;
00468 for(int y = 0; y < 2; ++y)
00469 for(int x = 0; x < 2; ++x)
00470 {
00471 for(Sample* p = cells[r2][yMax + y][xMax + x].first; p; p = p->next)
00472 {
00473 xSum += p->translation.x * p->getQuality();
00474 ySum += p->translation.y * p->getQuality();
00475 cosSum += p->getCos() * p->getQuality();
00476 sinSum += p->getSin() * p->getQuality();
00477 qualitySum += p->getQuality();
00478 }
00479 }
00480 }
00481 if(qualitySum)
00482 {
00483 pose = Pose2D(atan2(sinSum,cosSum),
00484 Vector2<double>(xSum / qualitySum,ySum / qualitySum));
00485 validity = qualitySum / SAMPLES_MAX;
00486 double diff = field.clip(pose.translation);
00487 if(diff > 1)
00488 validity /= sqrt(diff);
00489 return;
00490 }
00491 }
00492 validity = 0;
00493 }
00494
00495
00496
00497
00498 bool GT2004SelfLocator::poseFromBearings(double dir0,double dir1,double dir2,
00499 const Vector2<double>& mark0,
00500 const Vector2<double>& mark1,
00501 const Vector2<double>& mark2,
00502 const Vector2<double>& cameraOffset,
00503 Pose2D& resultingPose) const
00504 {
00505 double w1 = dir1 - dir0,
00506 w2 = dir2 - dir1;
00507 if(sin(w1) != 0 && sin(w2) != 0)
00508 {
00509 Vector2<double> p = mark2 - mark1;
00510 double a2 = p.abs();
00511 p = (Pose2D(mark0) - Pose2D(atan2(p.y,p.x),mark1)).translation;
00512 double a1 = p.abs();
00513 if(a1 > 0 && a2 > 0)
00514 {
00515 double w3 = pi2 - w1 - w2 - atan2(p.y,p.x);
00516 double t = a1 * sin(w2) / (a2 * sin(w1)) + cos(w3);
00517 if(t != 0)
00518 {
00519 double w = atan(sin(w3) / t);
00520 double b = a1 * sin(w) / sin(w1);
00521 w = pi - w1 - w;
00522 p = mark0 - mark1;
00523 resultingPose = Pose2D(atan2(p.y,p.x) - w,mark1)
00524 + Pose2D(Vector2<double>(b,0));
00525 p = (Pose2D(mark1) - resultingPose).translation;
00526 resultingPose += Pose2D(atan2(p.y,p.x) - dir1);
00527 resultingPose += Pose2D(Vector2<double>(-cameraOffset.x,
00528 -cameraOffset.y));
00529 return true;
00530 }
00531 }
00532 }
00533 return false;
00534 }
00535
00536 int GT2004SelfLocator::poseFromBearingsAndDistance(
00537 double dir0,double dir1,double dist,
00538 const Vector2<double>& mark0,
00539 const Vector2<double>& mark1,
00540 const Vector2<double>& cameraOffset,
00541 Pose2D& resultingPose1,
00542 Pose2D& resultingPose2) const
00543 {
00544 double alpha = dir0 - dir1;
00545 Vector2<double> diff = mark0 - mark1;
00546 double dir10 = atan2(diff.y,diff.x);
00547 double f = dist * sin(alpha) / diff.abs();
00548 if(fabs(f) <= 1)
00549 {
00550 double gamma = asin(f),
00551 beta = pi - alpha - gamma;
00552 resultingPose1 = Pose2D(dir10 + beta,mark1) +
00553 Pose2D(pi - dir1,Vector2<double>(dist,0)) +
00554 Pose2D(Vector2<double>(-cameraOffset.x,
00555 -cameraOffset.y));
00556 if(fabs(alpha) < pi_2 || fabs(alpha) > 3 * pi_2)
00557 {
00558 if(gamma > 0)
00559 gamma = pi - gamma;
00560 else
00561 gamma = -pi - gamma;
00562 beta = pi - alpha - gamma;
00563 resultingPose2 = Pose2D(dir10 + beta,mark1) +
00564 Pose2D(pi - dir1,Vector2<double>(dist,0)) +
00565 Pose2D(Vector2<double>(-cameraOffset.x,
00566 -cameraOffset.y));
00567 return 2;
00568 }
00569 else
00570 return 1;
00571 }
00572 else
00573 return 0;
00574 }
00575
00576 bool GT2004SelfLocator::getBearing(const LandmarksPercept& landmarksPercept,int i,
00577 Vector2<double>& mark,
00578 double& dir,double& dist) const
00579 {
00580 if(i < numOfFlags)
00581 {
00582 const Flag& flag = flags[i];
00583 mark = flag.position;
00584 dir = flag.angle;
00585 dist = flag.distance;
00586 return true;
00587 }
00588 else
00589 {
00590 i -= numOfFlags;
00591 const Goal& goal = landmarksPercept.goals[i >> 1];
00592 if((i & 1) == 0 && !goal.isOnBorder(goal.x.min))
00593 {
00594 mark = goal.rightPost;
00595 dir = goal.x.min;
00596 dist = goal.distance;
00597 return true;
00598 }
00599 else if((i & 1) == 1 && !goal.isOnBorder(goal.x.max))
00600 {
00601 mark = goal.leftPost;
00602 dir = goal.x.max;
00603 dist = goal.distance;
00604 return true;
00605 }
00606 else
00607 return false;
00608 }
00609 }
00610
00611 void GT2004SelfLocator::addFlag(const Flag& flag)
00612 {
00613 if(!flag.isOnBorder(flag.x.min) && !flag.isOnBorder(flag.x.max))
00614 {
00615 int i;
00616 for(i = 0; i < numOfFlags && flags[i].type != flag.type; ++i)
00617 ;
00618 if(i < numOfFlags)
00619 --numOfFlags;
00620 if(i < FLAGS_MAX)
00621 ++i;
00622 while(--i > 0)
00623 flags[i] = flags[i - 1];
00624 flags[0] = flag;
00625 if(numOfFlags < FLAGS_MAX)
00626 ++numOfFlags;
00627 }
00628 }
00629
00630 void GT2004SelfLocator::generatePoseTemplates(const LandmarksPercept& landmarksPercept,
00631 const Pose2D& odometry)
00632 {
00633 randomFactor = 0;
00634 int i;
00635 for(i = 0; i < numOfFlags; ++i)
00636 {
00637 Flag& flag = flags[i];
00638 Vector2<double> p = (Pose2D(flag.angle)
00639 + Pose2D(Vector2<double>(flag.distance,0)) - odometry).translation;
00640 flag.angle = atan2(p.y,p.x);
00641 flag.distance = p.abs();
00642 }
00643 for(i = 0; i < landmarksPercept.numberOfFlags; ++i)
00644 addFlag(landmarksPercept.flags[i]);
00645
00646 numOfTemplates = 0;
00647 nextTemplate = 0;
00648 double dir0,
00649 dir1,
00650 dir2;
00651 double dist0,
00652 dist1;
00653 Vector2<double> mark0,
00654 mark1,
00655 mark2,
00656 cameraOffset(landmarksPercept.cameraOffset.x,
00657 landmarksPercept.cameraOffset.y);
00658 int n = numOfFlags + 2 * landmarksPercept.numberOfGoals;
00659 for(i = 0; i < n - 2; ++i)
00660 if(getBearing(landmarksPercept,i,mark0,dir0,dist0))
00661 for(int j = i + 1; j < n - 1; ++j)
00662 if(getBearing(landmarksPercept,j,mark1,dir1,dist1))
00663 {
00664 if(numOfTemplates >= SAMPLES_MAX - 4)
00665 return;
00666 numOfTemplates += poseFromBearingsAndDistance(dir0,dir1,dist1,mark0,mark1,cameraOffset,
00667 templates[numOfTemplates],templates[numOfTemplates + 1]);
00668 numOfTemplates += poseFromBearingsAndDistance(dir1,dir0,dist0,mark1,mark0,cameraOffset,
00669 templates[numOfTemplates],templates[numOfTemplates + 1]);
00670 for(int k = j + 1; k < n; ++k)
00671 if(getBearing(landmarksPercept,k,mark2,dir2,dist0))
00672 if(poseFromBearings(dir0,dir1,dir2,mark0,mark1,mark2,cameraOffset,
00673 templates[numOfTemplates]))
00674 if(++numOfTemplates == SAMPLES_MAX)
00675 return;
00676 }
00677 for(i = 0; i < numberOfTypes; ++i)
00678 {
00679 LinesPercept::LineType type = types[i];
00680 for(int j = 0; j < linesPercept.numberOfPoints[type]; ++j)
00681 {
00682 const Vector2<int>& point = linesPercept.points[type][j];
00683 int index = type;
00684 if(getPlayer().getTeamColor() == Player::blue && type >= LinesPercept::yellowGoal)
00685 index = LinesPercept::yellowGoal + LinesPercept::skyblueGoal - type;
00686 templates[numOfTemplates++] = templateTable[index - LinesPercept::yellowGoal].sample(point.abs()) + Pose2D(-atan2((double)point.y,(double)point.x));
00687 if(numOfTemplates == SAMPLES_MAX)
00688 return;
00689 }
00690 }
00691 }
00692
00693 GT2004SelfLocator::Sample GT2004SelfLocator::getTemplate()
00694 {
00695 if(nextTemplate >= numOfTemplates)
00696 {
00697 nextTemplate = 0;
00698 ++randomFactor;
00699 }
00700 while(nextTemplate < numOfTemplates)
00701 {
00702 const Pose2D& t = templates[nextTemplate++];
00703 if(field.isInside(t.translation))
00704 {
00705 COMPLEX_DRAWING(selfLocatorField,draw(t,Drawings::red));
00706 return Sample(Pose2D::random(Range<double>(t.translation.x - randomFactor * 50,
00707 t.translation.x + randomFactor * 50),
00708 Range<double>(t.translation.y - randomFactor * 50,
00709 t.translation.y + randomFactor * 50),
00710 Range<double>(t.getAngle() - randomFactor * 0.1,
00711 t.getAngle() + randomFactor * 0.1)),
00712 average);
00713 }
00714 }
00715 return Sample(field.randomPose(),average);
00716 }
00717
00718
00719
00720
00721 void GT2004SelfLocator::draw(const Pose2D& pose,Drawings::Color color) const
00722 {
00723 Pose2D p = pose + Pose2D(-100,0);
00724 LINE(selfLocatorField,
00725 pose.translation.x,
00726 pose.translation.y,
00727 p.translation.x,
00728 p.translation.y,
00729 1,
00730 Drawings::ps_solid,
00731 color);
00732 p = pose + Pose2D(-40,-40);
00733 LINE(selfLocatorField,
00734 pose.translation.x,
00735 pose.translation.y,
00736 p.translation.x,
00737 p.translation.y,
00738 1,
00739 Drawings::ps_solid,
00740 color);
00741 p = pose + Pose2D(-40,40);
00742 LINE(selfLocatorField,
00743 pose.translation.x,
00744 pose.translation.y,
00745 p.translation.x,
00746 p.translation.y,
00747 1,
00748 Drawings::ps_solid,
00749 color);
00750 }
00751
00752 void GT2004SelfLocator::draw(const Vector2<int>& point,LinesPercept::LineType type) const
00753 {
00754 static const Drawings::Color colors[] =
00755 {
00756 Drawings::red,
00757 Drawings::green,
00758 Drawings::yellow,
00759 Drawings::skyblue
00760 };
00761
00762 CameraInfo cameraInfo(getRobotConfiguration().getRobotDesign());
00763
00764 Vector2<int> p;
00765 Geometry::calculatePointInImage(
00766 point,
00767 cameraMatrix, cameraInfo,
00768 p);
00769 CIRCLE(selfLocator,p.x,p.y,3,1,Drawings::ps_solid,colors[type]);
00770 }
00771
00772 bool GT2004SelfLocator::handleMessage(InMessage& message)
00773 {
00774 switch(message.getMessageID())
00775 {
00776 case idLinesSelfLocatorParameters:
00777 GenericDebugData d;
00778 message.bin >> d;
00779 paramUp = d.data[0];
00780 paramDown = d.data[1];
00781 paramDelay = d.data[2];
00782 paramHeight = d.data[3];
00783 paramZ = d.data[4];
00784 paramY = d.data[5];
00785 paramTrans = d.data[6];
00786 paramRot = d.data[7];
00787 return true;
00788 }
00789 return false;
00790 }
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863