00001
00002
00003
00004
00005
00006
00007
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 #include "Component/ModelManager.H"
00040 #include "Media/FrameSeries.H"
00041 #include "Transport/FrameInfo.H"
00042 #include "Raster/GenericFrame.H"
00043 #include "Image/Image.H"
00044 #include "Image/DrawOps.H"
00045 #include "Image/lapack.H"
00046 #include "Image/MatrixOps.H"
00047 #include "Image/MathOps.H"
00048 #include "GUI/ImageDisplayStream.H"
00049 #include "GUI/DebugWin.H"
00050 #include "Robots/RobotBrain/HippocampusI.H"
00051 #include <math.h>
00052
00053
00054
00055 HippocampusI::HippocampusI(OptionManager& mgr,
00056 const std::string& descrName, const std::string& tagName) :
00057 ModelComponent(mgr, descrName, tagName),
00058 itsCurrentState(new RobotSimEvents::StateMessage),
00059 itsCurrentGPSPos(new RobotSimEvents::GPSMessage),
00060 itsCurrentMotion(new RobotSimEvents::MotionMessage),
00061 itsCurrentLandmarks(new RobotSimEvents::LandmarksMessage),
00062 itsLastLandmarkState(new RobotSimEvents::StateMessage),
00063 itsLmDistanceMax(0),
00064 itsNumParticles(300),
00065 itsRangeVariance(50),
00066 itsBearingVariance(.5),
00067 itsFrame(0)
00068 {
00069
00070 itsOfs = nub::ref<OutputFrameSeries>(new OutputFrameSeries(mgr));
00071 addSubComponent(itsOfs);
00072
00073
00074 itsCurrentState->xPos = 0;
00075 itsCurrentState->yPos = 0;
00076 itsCurrentState->orientation = 0;
00077
00078 itsLastLandmarkState->xPos = itsCurrentState->xPos;
00079 itsLastLandmarkState->yPos = itsCurrentState->yPos;
00080 itsLastLandmarkState->orientation = itsCurrentState->orientation;
00081
00082
00083 itsCurrentGPSPos->xPos = 0;
00084 itsCurrentGPSPos->yPos = 0;
00085 itsCurrentGPSPos->orientation = 0;
00086
00087 itsCurrentMotion->distance = 0;
00088 itsCurrentMotion->angle = 0;
00089
00090 itsMap = Image<PixRGB<byte> > (800, 800, ZEROS);
00091
00092
00093 itsParticles.resize(itsNumParticles);
00094 for(int i=0; i<itsNumParticles; i++)
00095 {
00096 itsParticles.at(i).x = itsCurrentState->xPos;
00097 itsParticles.at(i).y = itsCurrentState->yPos;
00098 itsParticles.at(i).theta = itsCurrentState->orientation;
00099 itsParticles.at(i).w = 1/itsNumParticles;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 Image<double> cov(2,2,ZEROS);
00141 addLandmark(Landmark(string("L1"), 609.6*3, 609.6*-1, cov));
00142 addLandmark(Landmark(string("L2"), 609.6*-1, 609.6*4, cov));
00143 addLandmark(Landmark(string("L3"), 609.6*4, 609.6*0, cov));
00144 addLandmark(Landmark(string("L4"), 609.6*-1.5, 609.6*2, cov));
00145 addLandmark(Landmark(string("L5"), 609.6*3.5, 609.6*3, cov));
00146 addLandmark(Landmark(string("L6"), 609.6*1, 609.6*4, cov));
00147 addLandmark(Landmark(string("L7"), 609.6*3.5, 609.6*1, cov));
00148 addLandmark(Landmark(string("L8"), 609.6*1, 609.6*5.5, cov));
00149 addLandmark(Landmark(string("L9"), 609.6*-1.5, 609.6*3, cov));
00150 addLandmark(Landmark(string("L10"), 609.6*2, 609.6*3, cov));
00151 addLandmark(Landmark(string("L11"), 609.6*-0.8, 609.6*5, cov));
00152 addLandmark(Landmark(string("L12"), 609.6*-0.5, 609.6*-1, cov));
00153 addLandmark(Landmark(string("L13"), 609.6*1, 609.6*-1, cov));
00154 addLandmark(Landmark(string("L14"), 609.6*2.5, 609.6*6, cov));
00155
00156
00157 }
00158
00159
00160 HippocampusI::~HippocampusI()
00161 {
00162 SimEventsUtils::unsubscribeSimEvents(itsTopicsSubscriptions, itsObjectPrx);
00163 }
00164
00165
00166
00167 void HippocampusI::init(Ice::CommunicatorPtr ic, Ice::ObjectAdapterPtr adapter)
00168 {
00169
00170 Ice::ObjectPtr hippPtr = this;
00171 itsObjectPrx = adapter->add(hippPtr,
00172 ic->stringToIdentity("Hippocampus"));
00173
00174
00175 IceStorm::TopicPrx topicPrx;
00176
00177 itsTopicsSubscriptions.push_back(SimEventsUtils::TopicInfo("GPSMessageTopic", topicPrx));
00178 itsTopicsSubscriptions.push_back(SimEventsUtils::TopicInfo("MotionMessageTopic", topicPrx));
00179 itsTopicsSubscriptions.push_back(SimEventsUtils::TopicInfo("LandmarksMessageTopic", topicPrx));
00180
00181 SimEventsUtils::initSimEvents(ic, itsObjectPrx, itsTopicsSubscriptions);
00182
00183 itsEventsPub = RobotSimEvents::EventsPrx::uncheckedCast(
00184 SimEventsUtils::getPublisher(ic, "StateMessageTopic")
00185 );
00186
00187 IceUtil::ThreadPtr hippThread = this;
00188 hippThread->start();
00189
00190 usleep(10000);
00191 }
00192
00193
00194
00195 void HippocampusI::run()
00196 {
00197 sleep(1);
00198
00199 while(1)
00200 {
00201 evolve();
00202 usleep(100000);
00203 }
00204 }
00205
00206
00207 void HippocampusI::evolve()
00208 {
00209
00210 float xPos = 0, yPos = 0, orientation = 0;
00211 for(int i=0; i<itsNumParticles; i++)
00212 {
00213 xPos += itsParticles.at(i).x;
00214 yPos += itsParticles.at(i).y;
00215 orientation += itsParticles.at(i).theta;
00216 }
00217 xPos /= itsParticles.size();
00218 yPos /= itsParticles.size();
00219 orientation /= itsParticles.size();
00220
00221 itsCurrentState->xPos = xPos;
00222 itsCurrentState->yPos = yPos;
00223 itsCurrentState->orientation = orientation;
00224
00225 LDEBUG("%f %f %f\n",
00226 itsCurrentState->xPos,
00227 itsCurrentState->yPos,
00228 itsCurrentState->orientation);
00229
00230 itsEventsPub->updateMessage(itsCurrentState);
00231 }
00232
00233
00234 void HippocampusI::updateMessage(const RobotSimEvents::EventMessagePtr& eMsg, const Ice::Current&)
00235 {
00236
00237 if(eMsg->ice_isA("::RobotSimEvents::GPSMessage"))
00238 {
00239 RobotSimEvents::GPSMessagePtr gpsMsg = RobotSimEvents::GPSMessagePtr::dynamicCast(eMsg);
00240 itsCurrentGPSPos->xPos = gpsMsg->xPos;
00241 itsCurrentGPSPos->yPos = gpsMsg->yPos;
00242 itsCurrentGPSPos->orientation = gpsMsg->orientation;
00243 }
00244
00245 if(eMsg->ice_isA("::RobotSimEvents::MotionMessage"))
00246 {
00247 RobotSimEvents::MotionMessagePtr motionMsg = RobotSimEvents::MotionMessagePtr::dynamicCast(eMsg);
00248 itsCurrentMotion->distance = motionMsg->distance;
00249 itsCurrentMotion->angle = motionMsg->angle;
00250
00251 updateParticleMotion(itsCurrentMotion);
00252 itsFrame++;
00253
00254
00255
00256
00257
00258 }
00259
00260 if(eMsg->ice_isA("::RobotSimEvents::LandmarksMessage"))
00261 {
00262
00263 RobotSimEvents::LandmarksMessagePtr landmarksMsg = RobotSimEvents::LandmarksMessagePtr::dynamicCast(eMsg);
00264
00265 updateParticleSlamObservation(landmarksMsg);
00266
00267 itsFrame++;
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 itsCurrentLandmarks->landmarks = landmarksMsg->landmarks;
00284
00285
00286 int maxP = 0; float maxVal=itsParticles[0].w;
00287 for(uint i=1; i<itsParticles.size(); i++)
00288 {
00289 if (itsParticles[i].w > maxVal)
00290 {
00291 maxVal = itsParticles[i].w;
00292 maxP = i;
00293 }
00294 }
00295
00296 itsLandmarkDB = itsParticles[maxP].landmarksDB;
00297
00298
00299 displayMap();
00300 resampleParticles();
00301
00302 }
00303 fflush(stdout);
00304 }
00305
00306
00307 void HippocampusI::updateParticleMotion(RobotSimEvents::MotionMessagePtr newMotion)
00308 {
00309
00310
00311
00312
00313
00314 double alpha[4] = {0.002, 0, 0.2, 0};
00315
00316
00317
00318
00319
00320
00321 if(abs(newMotion->angle)<10 && abs(newMotion->distance)<25) {
00322 itsParticlesMutex.lock();
00323
00324 for(int i=0; i<itsNumParticles; i++)
00325 {
00326
00327 float theta = itsParticles.at(i).theta;
00328 float dx = newMotion->distance*cos(theta);
00329 float dy = newMotion->distance*sin(theta);
00330
00331
00332
00333
00334
00335 float rot1 = atan2(dy, dx) - theta;
00336 float trans = sqrt(pow(dx,2)+pow(dy,2));
00337 float rot2 = (theta+newMotion->angle*M_PI/180) - theta - rot1;
00338
00339
00340 float nr1 = rot1 - randomDoubleFromNormal(alpha[0]*abs(rot1)+alpha[1]*abs(trans));
00341 float ntr = trans - randomDoubleFromNormal(alpha[2]*abs(trans)+alpha[3]*abs(rot1+rot2));
00342 float nr2 = rot2 - randomDoubleFromNormal(alpha[0]*abs(rot2)+alpha[1]*abs(trans));
00343
00344
00345 itsParticles.at(i).x += ntr*cos(theta+nr1);
00346 itsParticles.at(i).y += ntr*sin(theta+nr1);
00347 itsParticles.at(i).theta += nr1 + nr2;
00348
00349
00350 if(itsParticles.at(i).theta > M_PI)
00351 {
00352 itsParticles.at(i).theta -= 2*M_PI;
00353
00354 }
00355 if(itsParticles.at(i).theta < M_PI)
00356 {
00357 itsParticles.at(i).theta += 2*M_PI;
00358 }
00359 }
00360 itsParticlesMutex.unlock();
00361 }
00362
00363 }
00364
00365
00366 void HippocampusI::updateParticleSlamObservation(RobotSimEvents::LandmarksMessagePtr landmarksMsg)
00367 {
00368 itsParticlesMutex.lock();
00369 float sum = 0;
00370 std::vector<Particle>::iterator particleIt =
00371 itsParticles.begin();
00372
00373 for(; particleIt != itsParticles.end(); particleIt++)
00374 {
00375 for(uint li=0; li<landmarksMsg->landmarks.size(); li++)
00376 {
00377
00378 std::string landmarkName = landmarksMsg->landmarks[li].name;
00379 float range = landmarksMsg->landmarks[li].range*1000;
00380 float bearing = landmarksMsg->landmarks[li].bearing;
00381
00382
00383 std::map<std::string, Landmark>::iterator landIt =
00384 particleIt->landmarksDB.find(landmarkName);
00385
00386
00387
00388 Image<double> sensorNoise(2,2, ZEROS);
00389 sensorNoise.setVal(0,0, squareOf(500));
00390 sensorNoise.setVal(1,1, squareOf(5*M_PI/180));
00391
00392
00393
00394 if(landIt == particleIt->landmarksDB.end())
00395 {
00396
00397
00398 double landmarkXPos = particleIt->x + range*cos(bearing + particleIt->theta);
00399 double landmarkYPos = particleIt->y + range*sin(bearing + particleIt->theta);
00400
00401
00402 double dx = landmarkXPos - particleIt->x;
00403 double dy = landmarkYPos - particleIt->y;
00404 double d2 = squareOf(dx) + squareOf(dy);
00405 double d = sqrt(d2);
00406
00407
00408 Image<double> G(2,2, NO_INIT);
00409 G.setVal(0,0, dx/d); G.setVal(1,0, dy/d);
00410 G.setVal(0,1, -dy/d2); G.setVal(1,1, dx/d2);
00411
00412 Image<double> Ginv = matrixInv(G);
00413
00414
00415 Image<double> cov = matrixMult(matrixMult(Ginv,sensorNoise),transpose(Ginv));
00416
00417
00418 Landmark lm(landmarkName, landmarkXPos, landmarkYPos, cov);
00419 particleIt->landmarksDB[landmarkName] = lm;
00420 particleIt->w *= 0.00001;
00421 }
00422 else {
00423
00424
00425
00426
00427
00428 double landmarkXPos = landIt->second.posX;
00429 double landmarkYPos = landIt->second.posY;
00430
00431 double dx = landmarkXPos - particleIt->x;
00432 double dy = landmarkYPos - particleIt->y;
00433 double d2 = squareOf(dx) + squareOf(dy);
00434 double d = sqrt(d2);
00435
00436 double beliefRange = d;
00437 double beliefBearing = atan2(dy, dx) - particleIt->theta;
00438
00439
00440 if (beliefBearing < M_PI)
00441 {
00442 beliefBearing += 2*M_PI;
00443 }
00444 if (beliefBearing > M_PI)
00445 {
00446 beliefBearing -= 2*M_PI;
00447 }
00448
00449
00450 Image<double> G(2,2, NO_INIT);
00451 G.setVal(0,0, dx/d); G.setVal(1,0, dy/d);
00452 G.setVal(0,1, -dy/d2); G.setVal(1,1, dx/d2);
00453
00454 Image<double> innov(1,2,NO_INIT);
00455 innov.setVal(0,0, range - beliefRange);
00456 innov.setVal(0,1, bearing - beliefBearing);
00457
00458
00459 Image<double> PHt = matrixMult(landIt->second.cov,transpose(G));
00460 Image<double> S = matrixMult(G, PHt) + sensorNoise;
00461
00462
00463 S = S+transpose(S);
00464 S = S *0.5;
00465
00466 Image<double> SChol = lapack::dpotrf(&S);
00467 SChol.setVal(0,1,0);
00468
00469 Image<double> SCholInv = matrixInv(SChol);
00470
00471
00472 Image<double> W1 = matrixMult(PHt, SCholInv);
00473 Image<double> K = matrixMult(W1, transpose(SCholInv));
00474
00475
00476 Image<double> dLandmarkPos = matrixMult(K,innov);
00477 landIt->second.posX += dLandmarkPos.getVal(0,0);
00478 landIt->second.posY += dLandmarkPos.getVal(0,1);
00479
00480 landIt->second.cov -= matrixMult(W1, transpose(W1));
00481
00482
00483 Image<double> Q = matrixMult(matrixMult(G, landIt->second.cov),transpose(G)) + sensorNoise;
00484
00485 Image<double> diffSq = matrixMult(matrixMult(transpose(innov), matrixInv(Q)), innov);
00486
00487 particleIt->w *= exp(-0.5*diffSq.getVal(0,0)) + 0.001;
00488
00489 }
00490 }
00491
00492 sum += particleIt->w;
00493
00494 }
00495
00496
00497 for(uint i=0; i<itsParticles.size(); i++)
00498 itsParticles.at(i).w /= sum;
00499
00500 itsParticlesMutex.unlock();
00501 }
00502
00503
00504 void HippocampusI::updateParticleObservation(RobotSimEvents::LandmarksMessagePtr landmarksMsg)
00505 {
00506 itsParticlesMutex.lock();
00507 float sum = 0;
00508 for(int particle=0; particle<itsNumParticles; particle++)
00509 {
00510 for(uint li=0; li<landmarksMsg->landmarks.size(); li++)
00511 {
00512
00513 std::map<std::string, Landmark>::iterator landIt = itsLandmarkDB.find(landmarksMsg->landmarks.at(li).name);
00514
00515
00516 if(landIt == itsLandmarkDB.end())
00517 {
00518
00519 continue;
00520 }
00521
00522 Landmark currLand = landIt->second;
00523
00524 float bearing = landmarksMsg->landmarks[li].bearing;
00525 float range = landmarksMsg->landmarks[li].range*1000;
00526
00527 float beliefRange = sqrt(pow(currLand.posY - itsParticles.at(particle).y, 2) +
00528 pow(currLand.posX - itsParticles.at(particle).x, 2));
00529 float beliefBearing = atan2(currLand.posY - itsParticles.at(particle).y,
00530 currLand.posX - itsParticles.at(particle).x)
00531 - itsParticles.at(particle).theta;
00532
00533 if (beliefBearing < M_PI)
00534 beliefBearing += 2*M_PI;
00535 if (beliefBearing > M_PI)
00536 beliefBearing -= 2*M_PI;
00537
00538 float innovRange = range - beliefRange;
00539 float innovBearing = bearing - beliefBearing;
00540
00541
00542
00543 float prob = exp(-0.5*pow(innovRange, 2) / itsRangeVariance ) + .0001;
00544 prob = exp(-0.5*pow(innovBearing, 2) / itsBearingVariance) + .0001;
00545
00546 itsParticles.at(particle).w = prob;
00547
00548 }
00549 sum += itsParticles.at(particle).w;
00550 }
00551
00552
00553 for(uint i=0; i<itsParticles.size(); i++)
00554 itsParticles.at(i).w /= sum;
00555
00556 itsParticlesMutex.unlock();
00557 }
00558
00559
00560 void HippocampusI::addLandmark(Landmark lm)
00561 {
00562
00563 LINFO("Adding Landmark %s pos", lm.name.c_str());
00564 itsGTLandmarkDB[lm.name] = lm;
00565 }
00566
00567
00568
00569
00570 void HippocampusI::resampleParticles()
00571 {
00572
00573
00574 itsParticlesMutex.lock();
00575
00576 std::vector<Particle> newParticles;
00577
00578
00579 std::vector<float> CDF;
00580 CDF.resize(itsParticles.size());
00581
00582 CDF.at(0) = itsParticles.at(0).w;
00583 for(uint i=1; i<CDF.size(); i++)
00584 CDF.at(i) = CDF.at(i-1) + itsParticles.at(i).w;
00585
00586 uint i = 0;
00587 float u = randomDouble()* 1.0/float(itsParticles.size());
00588
00589 for(uint j=0; j < itsParticles.size(); j++)
00590 {
00591 while(u > CDF.at(i))
00592 i++;
00593
00594 Particle p = itsParticles.at(i);
00595 p.w = 1.0/float(itsParticles.size());
00596
00597 newParticles.push_back(p);
00598
00599 u += 1.0/float(itsParticles.size());
00600 }
00601
00602 itsParticles = newParticles;
00603
00604 itsParticlesMutex.unlock();
00605 }
00606
00607
00608 void HippocampusI::displayMap()
00609 {
00610 int circRadius = 10;
00611 Image<PixRGB<byte> > tmpMap = itsMap;
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 Image<float> probMap(itsMap.getDims(), ZEROS);
00640
00641
00642 float scale = 1.0/7.0;
00643 Point2D<int> offset((int)(609.6*3.0*scale), (int)(609.6*2.0*scale));
00644
00645 Point2D<int> p1 = Point2D<int>(scale*609.6*0 , scale*609.6*0) + offset;
00646 Point2D<int> p2 = Point2D<int>(scale*609.6*3 , scale*609.6*0) + offset;
00647 Point2D<int> p3 = Point2D<int>(scale*609.6*3 , scale*609.6*5) + offset;
00648 Point2D<int> p4 = Point2D<int>(scale*609.6*-0.5, scale*609.6*5) + offset;
00649 Point2D<int> p5 = Point2D<int>(scale*609.6*-0.5, scale*609.6*0) + offset;
00650
00651 drawLine(tmpMap, p1, p2, PixRGB<byte>(50,50,50));
00652 drawLine(tmpMap, p2, p3, PixRGB<byte>(50,50,50));
00653 drawLine(tmpMap, p3, p4, PixRGB<byte>(50,50,50));
00654 drawLine(tmpMap, p4, p5, PixRGB<byte>(50,50,50));
00655 drawLine(tmpMap, p5, p1, PixRGB<byte>(50,50,50));
00656
00657
00658 for(uint particle=0; particle<itsParticles.size(); particle++) {
00659 Point2D<int> particlePos( itsParticles.at(particle).x*scale,
00660 itsParticles.at(particle).y*scale);
00661 float prob = itsParticles.at(particle).w;
00662 if (probMap.coordsOk(offset + particlePos))
00663 probMap.setVal(offset + particlePos, prob);
00664 }
00665
00666
00667 std::map<std::string, Landmark>::iterator landIt = itsGTLandmarkDB.begin();
00668 for(;landIt != itsGTLandmarkDB.end(); ++landIt)
00669 {
00670 Point2D<int> lmPos(
00671 (*landIt).second.posX * scale,
00672 (*landIt).second.posY * scale
00673 );
00674 drawCross(tmpMap, lmPos + offset, PixRGB<byte>(0,100, 0));
00675
00676 }
00677
00678
00679
00680 landIt = itsLandmarkDB.begin();
00681 for(;landIt != itsLandmarkDB.end(); ++landIt)
00682 {
00683 Point2D<int> lmPos(
00684 (*landIt).second.posX * scale,
00685 (*landIt).second.posY * scale
00686 );
00687
00688 if(tmpMap.coordsOk(offset+lmPos) &&
00689 tmpMap.coordsOk(offset+lmPos+Point2D<int>(landIt->second.name.size()*10, circRadius*2.5)))
00690 {
00691 Image<PixRGB<byte> > labelImage(landIt->second.name.size()*10, circRadius*2.5, ZEROS);
00692
00693 drawCircle(labelImage, Point2D<int>(circRadius,circRadius), circRadius, PixRGB<byte>(0,0,150),0);
00694
00695 writeText(
00696 labelImage,
00697 Point2D<int>(circRadius/2,circRadius/2),
00698 landIt->second.name.c_str(),
00699 PixRGB<byte>(75,75,255),
00700 PixRGB<byte>(0,0,0),
00701 SimpleFont::FIXED(6),
00702 true
00703 );
00704
00705 labelImage = flipVertic(labelImage);
00706 inplacePaste(tmpMap, labelImage, offset+lmPos-Point2D<int>(circRadius, circRadius));
00707 }
00708 }
00709
00710
00711 for(uint li=0; li<itsCurrentLandmarks->landmarks.size(); li++)
00712 {
00713 float bearing = itsCurrentLandmarks->landmarks[li].bearing;
00714 float range = (itsCurrentLandmarks->landmarks[li].range*1000);
00715
00716 float posX = itsCurrentState->xPos + (range*cos(itsCurrentState->orientation + bearing));
00717 float posY = itsCurrentState->yPos + (range*sin(itsCurrentState->orientation + bearing));
00718
00719 drawLine(tmpMap,
00720 offset + Point2D<int>((int)(itsCurrentState->xPos*scale),
00721 ((int)(itsCurrentState->yPos*scale))),
00722 offset + Point2D<int>((int)(posX*scale), ((int)(posY*scale))),
00723 PixRGB<byte>(0,0,255));
00724 }
00725
00726 Point2D<int> posOnMap((int)(itsCurrentState->xPos*scale),
00727 (int)( itsCurrentState->yPos*scale));
00728
00729
00730 if (itsMap.coordsOk(offset + posOnMap))
00731 {
00732 itsMap.setVal(offset + posOnMap, PixRGB<byte>(255,0,0));
00733 drawDisk(tmpMap, offset + posOnMap, 10, PixRGB<byte>(100,200,100));
00734
00735 Point2D<int> robotAng(int(cos(itsCurrentState->orientation)*9),
00736 int(sin(itsCurrentState->orientation)*9));
00737
00738 drawLine(tmpMap, offset + posOnMap, offset + posOnMap + robotAng, PixRGB<byte>(0,0,0), 2);
00739 }
00740
00741 inplaceNormalize(probMap, 0.0F, 255.0F);
00742
00743
00744 printf("%d %d %d ", itsFrame, posOnMap.i, posOnMap.j);
00745 std::map<std::string, Landmark>::iterator gtIt = itsGTLandmarkDB.begin();
00746 for(;gtIt != itsGTLandmarkDB.end(); gtIt++) {
00747
00748 printf("%s ", gtIt->second.name.c_str());
00749
00750
00751 std::map<std::string, Landmark>::iterator lIt = itsLandmarkDB.find(gtIt->second.name);
00752
00753 if(lIt == itsLandmarkDB.end())
00754 {
00755
00756 printf("0 0 ");
00757 }
00758 else
00759 {
00760
00761 printf("%f %f ", lIt->second.posX, lIt->second.posY);
00762 }
00763 }
00764 printf("\n");
00765
00766
00767 itsOfs->writeRGB(flipVertic(tmpMap), "Map", FrameInfo("Map", SRC_POS));
00768 itsOfs->writeRGB(flipVertic(toRGB(probMap)), "ProbMap", FrameInfo("Map", SRC_POS));
00769 }
00770