MRXT: The Multi-Robot eXploration Tool
Multi-Robot autonomous exploration and mapping simulator.
src/architecture/slam/mapbuilders/RBPFilter.cpp
00001 /*
00002 *
00003 * Author: Miguel Julia <mjulia@umh.es> 
00004 * 
00005 * Date:   2008
00006 * 
00007 * Class RBPFilter
00008 *
00009 * Implements an slam algorithm consisting on a rao-blackwellized particle filter
00010 *
00011 */
00012 
00013 #include "RBPFilter.h"
00014 #include "gridMapInterface.h"
00015 #include <math.h>
00016 #include <iostream>
00017 #include <stdlib.h>
00018 #include <opencv2/opencv.hpp>
00019 
00020 #ifndef WIN32 
00021 #include <sys/time.h>
00022 #else
00023 #include <process.h>
00024 #endif
00025 
00026 using namespace std;
00027 
00028 // Para registrar la clase en la factoria
00029 namespace{
00030         slamInterface* CreateRBPFilter(int bots, ConfigFile& file){
00031                 return new RBPFilter(bots, file);
00032         }
00033         const int RBPF = 0;
00034         const bool registered = slamFactory::Instance().Register(RBPF, slamCreator(CreateRBPFilter));
00035 }
00036 
00037 // Constructor
00038 RBPFilter::RBPFilter():
00039         vslamFilter(),
00040         M(0),
00041         p(0),
00042         newp(0),
00043         index(0),
00044         dispRobot(0),
00045         odoData(0),
00046         lastOdoData(0),
00047         rsData(0),
00048         lmData(0),
00049         endSlam(false),
00050         onlyonegridmap(true),
00051         omap(0),
00052         ppmap(0),
00053         ipmap(0),
00054         Identity3(matrix::identity(3)),
00055         mahTh(0.0f)
00056 {
00057 //      printf("RBPF default constructor\n");
00058 }
00059 
00060 RBPFilter::RBPFilter(int nrobots, ConfigFile& configFile):
00061         vslamFilter             (nrobots,configFile),
00062         M                       (nrobots*configFile.read<int>("PARTICLESPERROBOT")),
00063         p                       (new particle[M]()),
00064         newp                    (new particle[M]()),
00065         index                   (0),
00066         dispRobot               (new float[nBots]),
00067         odoData                 (new pose*[nBots]),
00068         lastOdoData             (new pose*[nBots]),
00069         rsData                  (new rangeSensorData*[nBots]),
00070         lmData                  (new landmarksData*[nBots]),
00071         endSlam                 (true),
00072         onlyonegridmap          (configFile.keyExists("ONLYONEGRIDMAP")? configFile.read<bool>("ONLYONEGRIDMAP") : true ),
00073         omap                    (0),
00074         ppmap                   (0),
00075         ipmap                   (0),
00076         Identity3               (matrix::identity(3)),
00077         mahTh                   (configFile.read<float>("MAHALANOBISTH"))
00078 {
00079         if (onlyonegridmap){
00080                 omap = gridMapFactory::Instance().CreateObject(gmtype,width, height, resolution, xorigin, yorigin);
00081                 ppmap = new binMap(gmwidth, gmheight, resolution, xorigin, yorigin);
00082                 ipmap = new binMap(gmwidth, gmheight, resolution, xorigin, yorigin);
00083         }
00084         int gt = (onlyonegridmap)? -1: gmtype;
00085         for (int m = 0; m< M; m++)
00086                 p[m].initialize(nrobots, width, height, resolution, xorigin, yorigin, gt, vmtype, nmarks, configFile);
00087         for (int r = 0; r< nBots; r++){
00088                 dispRobot[r] = 0.0f;
00089         }
00090 //      printf("RBPF created\n");
00091 }
00092 
00093 RBPFilter::~RBPFilter(){
00094 //      printf("RBPF destroyer...");
00095         stop();
00096         if (logstr){
00097                 char myfilestr[100];
00098                 if (onlyonegridmap){
00099                         sprintf(myfilestr,"%somap.jpg",logstr);
00100                         omap->saveMapAsImage(myfilestr);
00101                         sprintf(myfilestr,"%sppmap.jpg",logstr);
00102                         ppmap->saveMapAsImage(myfilestr);
00103                 }
00104                 else{
00105                         sprintf(myfilestr,"%somap.jpg",logstr);
00106                         p[index].getOMap().saveMapAsImage(myfilestr);
00107                         sprintf(myfilestr,"%sppmap.jpg",logstr);
00108                         p[index].getPrecisePoseMap().saveMapAsImage(myfilestr);
00109                 }
00110                 sprintf(myfilestr,"%svmap",logstr);
00111                 p[index].getVMap().saveMap(myfilestr);
00112         }
00113         if (p)                          delete[] p;
00114         if (newp)                       delete[] newp;
00115         if (dispRobot)          delete[] dispRobot;
00116         if (odoData)            delete[] odoData;
00117         if (lastOdoData)        delete[] lastOdoData;
00118         if (rsData)                     delete[] rsData;
00119         if (lmData)                     delete[] lmData;
00120         if (omap)                       delete omap;
00121         if (ppmap)                      delete ppmap;
00122         if (ipmap)                      delete ipmap;
00123 
00124 //      printf("RBPF destroyed\n");
00125 }
00126 
00127 // Initializer
00128 void RBPFilter::initialize(int nrobots, ConfigFile& configFile){
00129         vslamFilter::initialize(nrobots, configFile);
00130         
00131         M                       = configFile.read<int>("PARTICLESPERROBOT")*nBots;
00132         if (p)                  delete[] p;
00133         p                       = new particle[M]();
00134         if (newp)               delete[] newp;
00135         newp                    = new particle[M]();
00136         index                   = 0;
00137         if (dispRobot)  delete[] dispRobot;
00138         dispRobot               = new float[nBots];
00139         if (odoData)    delete[] odoData;
00140         odoData                 = new pose*[nBots];
00141         if (lastOdoData) delete[] lastOdoData;
00142         lastOdoData             = new pose*[nBots];
00143         if (rsData)             delete[] rsData;
00144         rsData                  = new rangeSensorData*[nBots];
00145         if (lmData)             delete[] lmData;
00146         lmData                  = new landmarksData*[nBots];
00147         endSlam                 = false;
00148         onlyonegridmap          = configFile.keyExists("ONLYONEGRIDMAP")? configFile.read<bool>("ONLYONEGRIDMAP") : true ;
00149         mahTh                   = configFile.read<float>("MAHALANOBISTH");
00150 
00151         if (onlyonegridmap){
00152                 if (omap)  delete omap;
00153                 if (ppmap) delete ppmap;
00154                 if (ipmap) delete ipmap;
00155                 omap = gridMapFactory::Instance().CreateObject(gmtype, width, height, resolution, xorigin, yorigin);
00156                 ppmap = new binMap(gmwidth, gmheight, resolution, xorigin, yorigin);
00157                 ipmap = new binMap(gmwidth, gmheight, resolution, xorigin, yorigin);
00158         }
00159         
00160         int gt = (onlyonegridmap)? -1: gmtype;
00161         for (int m = 0; m< M; m++)
00162                 p[m].initialize(nrobots, width, height, resolution, xorigin, yorigin, gt, vmtype, nmarks, configFile);
00163         for (int r = 0; r< nBots; r++){
00164                 dispRobot[r] = 0.0f;
00165         }
00166 }
00167 
00168 int RBPFilter::setup(){
00169         prio = 50;
00170         return 0;
00171 }
00172 
00173 void RBPFilter::onStop(){
00174         if (!endSlam){
00175                 endSlam = true;
00176                 closing.lock();
00177                 closing.unlock();
00178         }
00179         printf("[FastSLAM] SLAM stopped\n");
00180 }
00181 
00182 void RBPFilter::execute(){
00183         printf("[FastSLAM] \t\t\t\t\t\t Running SLAM\n");
00184         closing.lock();
00185         int r;
00186 
00187         // open the log file
00188         FILE* slamlog=0;
00189         if (logstr){
00190                 char myfilestr[100];
00191                 sprintf(myfilestr,"%sslam.m",logstr);   
00192                 slamlog = fopen(myfilestr,"w");
00193                 fprintf(slamlog,"poses_est=[");
00194         }
00195 
00196         if (displayomap)  cvNamedWindow("OMAP",  CV_WINDOW_AUTOSIZE);
00197         if (displayppmap) cvNamedWindow("PPMAP", CV_WINDOW_AUTOSIZE);
00198         if (displayipmap) cvNamedWindow("IPMAP", CV_WINDOW_AUTOSIZE);
00199         
00200         // inicializamos SLAM
00201         
00202 //      printf("[FastSLAM 1] initializing slam...\n");
00203         for (r=0; r<nBots; r++){
00204                 if (rbase[r]) rbase[r]->beginConsumition();     
00205                 lastOdoData[r] = rbase[r]->getOdometry();
00206                 //printf("initial pose r%d: x:%f, y%f, th=%f\n",r,lastOdoData[r]->x,lastOdoData[r]->y,lastOdoData[r]->th);
00207                 for (int i = 0; i < M; i++){
00208                         p[i].setPos(*(lastOdoData[r]),r);
00209                 }
00210                 if (rbase[r]) rbase[r]->endConsumition();
00211         }
00212 //      printf("[FastSLAM 1] slam initialized\n");
00213         
00214         float cw = 1.0f/M;
00215         for (int i = 0; i < M; i++){
00216                 p[i].setWeight(cw);     // Resetamos el peso de las particulas
00217         }
00218 
00219         endSlam=false;
00220         while (!endSlam){
00221                 //printID("SLAM RBPF");
00222                 //Sleep(10);
00223                 // Leemos sensores
00224                 
00225 //              printf("[FastSLAM 1] slam step\n");
00226                 for (r=0; r<nBots; r++){
00227                         if (robotsEnabled[r]){
00228                                 rbase[r]->beginConsumition();
00229                                 if (robotsEnabled[r]){
00230                                         odoData[r] = rbase[r]->getOdometry();
00231                                         rsData[r]  = rbase[r]->getRangeSensorData();
00232                                         lmData[r]  = rbase[r]->getLandmarksData();
00233                                 }
00234                                 rbase[r]->endConsumition();
00235                         }
00236                 }
00237 //              printf("[FastSLAM 1] consumed\n");
00238                 
00239 //              printf("[FastSLAM 1] fastslam found: %d, in the map: %d\n",lmData[0]->getNLandmarks(), p[index].getVMap().getNLandmarks());
00240 
00241                 // Fastslam
00242                 for (r=0; r<nBots; r++){
00243                         if (robotsEnabled[r]){
00244                                 pose deltaOdo = *(odoData[r]) - *(lastOdoData[r]);
00245                                 fastSlam(r, *(lmData[r]), *(lastOdoData[r]), deltaOdo);
00246                         }
00247                 }
00248 //              printf("[FastSLAM 1] resample\n");
00249                 double neff = resample();                                                               //      resampling
00250 //              printf("[FastSLAM 1] neff=%f\n",neff);
00251                 //printf("estimated pose x: %f, y: %f, th: %f\n",p[index].getPos(0).x,p[index].getPos(0).y,p[index].getPos(0).th);
00252 
00253 //              printf("[FastSLAM 1] update\n");
00254                 for (r=0; r<nBots; r++) updateAll(*(rsData[r]),r);              // updating occupation map
00255                 step();
00256 //              printf("[FastSLAM 1] clean data\n");
00257                 // delete sensor data
00258                 for (r=0; r<nBots; r++){
00259                         if (robotsEnabled[r]){
00260                                 if (lastOdoData[r]) delete lastOdoData[r];
00261                                 lastOdoData[r] = odoData[r];
00262                                 if (rsData[r]) delete rsData[r];
00263                                 if (lmData[r]) delete lmData[r];
00264                         }
00265                 }
00266 
00267                 emit slamUpdated();
00268 
00269 /*              // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  show maps  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00270                 printf("\t\t\tshow\n");
00271                 IplImage* im, *im2, *im3;
00272                 if (displayomap){
00273                         im = (onlyonegridmap)? omap->getMapAsImage(): p[index].getOMap().getMapAsImage();
00274                         CvScalar redcolor = CV_RGB(255,0,0);
00275                         int hinv = gmheight-1;
00276                         if (displayposes)                                               // display all particles
00277                                 for(int m=0; m<M; m++)
00278                                         for (r=0; r<nBots; r++)
00279                                                 cvCircle( im, cvPoint(p[m].getCell(r).x, hinv - p[m].getCell(r).y), 0, redcolor, 1 );
00280                         if (displayfeatures) p[index].getVMap().drawMarks(*im,xorigin,yorigin,resolution);
00281                         if (windowName) cvShowImage(windowName,im);
00282                         else cvShowImage("OMAP",im);            }
00283                 if (displayppmap){
00284                         im2 = (onlyonegridmap)? ppmap->getMapAsImage(): p[index].getPrecisePoseMap().getMapAsImage();
00285                         cvShowImage("PPMAP",im2);
00286                 }
00287                 if (displayipmap){
00288                         im3 = (onlyonegridmap)? ipmap->getMapAsImage(): p[index].getImprecisePoseMap().getMapAsImage();
00289                         cvShowImage("IPMAP",im3);
00290                 }
00291                 
00292                 if (displayomap || displayppmap || displayipmap) cvWaitKey(10);
00293                 if (displayomap)  cvReleaseImage(&im);
00294                 if (displayppmap) cvReleaseImage(&im2);
00295                 if (displayipmap) cvReleaseImage(&im3);
00296                 
00297                 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  end show maps  
00298 */              
00299                 // write logs
00300                 if (logstr){
00301                         fprintf(slamlog,"%d",getStep());
00302                         for (r=0; r<nBots;r++){
00303                                 fprintf(slamlog,", %f, %f, %f, %f",p[index].getPos(r).x, p[index].getPos(r).y, p[index].getPos(r).th, getDisp(r));
00304                         }
00305                         fprintf(slamlog,", %f\n", neff);
00306                 }
00307                 
00308 //              printf("[FastSLAM 1] end loop\n");
00309         }// while (!endSlam)
00310         
00311         if (logstr){
00312                 fprintf(slamlog,"];");  
00313                 fclose(slamlog);
00314         }
00315         
00316         if (displayomap)  cvDestroyWindow("OMAP");
00317         if (displayppmap) cvDestroyWindow("PPMAP");
00318         if (displayipmap) cvDestroyWindow("IPMAP");
00319         
00320 //      printf("[FastSLAM 1] Stopping SLAM\n");
00321         closing.unlock();
00322 }
00323 
00324 
00325 void RBPFilter::updateParticle(int robot, const landmarksData& lmData, const pose& lastOdo, const pose& deltaOdo, int i){
00326         
00327         // Hacemos avanzar la pose del robot en la particula segun la odometria y el ruido
00328         p[i].setPos(odometryModel(lastOdo, deltaOdo, p[i].getPos(robot) ),robot);
00329         
00330         matrix G = jacobian(p[i].getPos(robot));                                                        // jacobiano
00331         matrix Ginv = G.inverse();
00332         matrix Gtrans = G.transpose();
00333         matrix Ginvtrans = Ginv.transpose();
00334         
00335         //printf("marcas %d\n",lmData.getNLandmarks());
00336         for (int j = 0; j < lmData.getNLandmarks(); j++){ // Se aplica de manera repetida para todas las medidas realizadas. Se multiplican los pesos
00337                 
00338                 pos3d lpos  = base2global(p[i].getVMap().cam2base(lmData.getLandmark(j).pos), p[i].getPos(robot));      // medida en coordenadas globales       
00339                 matrix ZT       = lmData.getLandmark(j).pos;                                                                                    // Medida (coordenadas de camara)
00340                 matrix Rt       = lmData.getLandmark(j).covariance;                                                                             // covarianza de la medida
00341                 
00342                 //printf("mark medi %d, (x: %f, y: %f, z: %f)\n", j, lmData.getLandmark(j).pos.getX(), lmData.getLandmark(j).pos.getY(), lmData.getLandmark(j).pos.getZ());
00343                 //printf("mark real %d, (x: %f, y: %f, z: %f)\n", j, lpos.getX(), lpos.getY(), lpos.getZ());
00344                 
00345                 // associacion de datos
00346                 landmark* mark = (perfectMatching)?
00347                         p[i].getVMap().getLandmarkByDesc(lmData.getLandmark(j).descriptor) :
00348                         p[i].getVMap().dataAssociation(ZT, Rt, lpos, p[i].getPos(robot), G, Gtrans, lmData.getLandmark(j).descriptor) ;
00349                         
00350                 
00351         // Si es una nueva landmark, la inicializamos
00352                 if(!mark) {
00353                         mark = new landmark(lpos,                                                                                                       // global pos
00354                                                                 Ginv*(Rt*(Ginvtrans)),                                                                  // covariance
00355                                                                 lmData.getLandmark(j).descriptor,                                               // descriptor
00356                                                                 lmData.getLandmark(j).desclength,                                               // descriptor length
00357                                                                 0);                                                                                                             // repeated
00358                         p[i].getVMap().addLandmark(*mark);                                                                                      // la insertamos en el mapa de la particula
00359                         p[i].setWeight(p[i].getWeight()*mahTh);                                                                         // Dividimos el peso de la particula
00360                 }
00361                 // Si es una landmark anterior, le calculamos su EKF
00362         else {
00363                         matrix zgorro   = p[i].getVMap().base2cam(global2base(mark->pos, p[i].getPos(robot)));          // medida estimada
00364             matrix In           = (ZT - zgorro);                                                                                        // innovacion
00365             matrix Z            = ((G*(mark->covariance*(Gtrans))) + Rt);                                       // covarianza de la innovacion
00366             matrix Zinv         = Z.inverse();
00367                         matrix K                = (mark->covariance*((Gtrans)*(Zinv)));                                         // ganancia
00368             mark->pos           = ((K*In)+mark->pos).toPos3d();                                                         // actualizamos pose
00369             mark->covariance= (Identity3-K*G)*mark->covariance;                                                 // actualizamos covarianza
00370                         
00371                         for (int k=0; k< mark->desclength; k++)
00372                                 mark->descriptor[k] = (mark->descriptor[k] + lmData.getLandmark(j).descriptor[k])/2;
00373 
00374             p[i].getVMap().changeLastReturnedLandmark(*mark);
00375                         
00376                         // Calculamos el nuevo peso
00377             p[i].setWeight(p[i].getWeight()*exp(-0.5*visualMap::mahalanobis(In.toPos3d(), Z)) /(sqrt((Z*PIx2).det())));
00378                 }
00379                 delete mark;
00380         }
00381 }
00382 
00383 // fastslam algorithm
00384 void RBPFilter::fastSlam(int robot, const landmarksData& lmData, const pose& lastOdo, const pose& deltaOdo){
00385         int i;
00386 
00387         //printf("\t\t\tfastslam...\n");
00388         // update particles
00389         for (i = 0; i < M; i++){                
00390                 updateParticle(robot,lmData,lastOdo,deltaOdo,i);
00391         }
00392         //printf("\t\t\tok\n");
00393         
00394         // Normalize weight
00395         double suma = 0;
00396         //double sumalog = 0;
00397         for (i = 0; i < M; i++) suma += p[i].getWeight();
00398         if (suma > 0){
00399                 for (i = 0; i < M; i++){
00400                         p[i].setWeight(p[i].getWeight()/suma);
00401                         p[i].setSumLogWeight(p[i].getSumLogWeight() + log(p[i].getWeight()));
00402                 }
00403         }
00404         else{
00405 //              printf("[FastSLAM 1] Null sum of weigths!!!! - Resetting to ones\n");
00406                 double invM = 1.0f/M;
00407                 for (int i = 0; i < M; i++){
00408                         p[i].setWeight(invM);
00409                         p[i].setSumLogWeight(0.0);
00410                 }
00411         }
00412 }
00413 
00414 // update occupancy, precise poses and imprecise poses maps
00415 void RBPFilter::updateAll(const rangeSensorData& rsData, int r ){
00416         evalDisp(r);
00417         if (onlyonegridmap){
00418                 omap->update(rsData, p[index].getPos(r), getDisp(r));
00419                 updatePPMap(p[index].getCell(r), *ppmap, getDisp(r), badlocalized[r]);
00420                 updateIPMap(p[index].getCell(r), *ipmap, getDisp(r), badlocalized[r]);
00421         }
00422         else{
00423                 for (int m = 0; m < M ; m++){
00424                         p[m].getOMap().update(rsData, p[m].getPos(r), getDisp(r));
00425                         updatePPMap(p[m].getCell(r), p[m].getPrecisePoseMap(), getDisp(r), badlocalized[r]);
00426                         updateIPMap(p[m].getCell(r), p[m].getImprecisePoseMap(), getDisp(r), badlocalized[r]);
00427                 }
00428         }
00429 }
00430 
00431 
00432 // importance resampling
00433 double RBPFilter::resample(){
00434 
00435         int i,m;
00436         double suma = 0;
00437         int newindex = 0;
00438         double maxweight = p[0].getWeight();
00439 
00440         for (i = 0; i < M; i++){
00441                 suma += p[i].getWeight()*p[i].getWeight();
00442                 if(p[i].getSumLogWeight() > maxweight){
00443                         newindex = i;
00444                         maxweight = p[i].getSumLogWeight();
00445                 }
00446         }
00447         double Neff = 1/suma;
00448 
00449         if (Neff > M + 1 || Neff < 1){ 
00450 //              printf("[FastSLAM] error\n");
00451                 exit(0);
00452         }
00453 
00454         if (Neff < M){
00455                 
00456                 // muestreo con resposicion de M muestras equiespaciadas aleatorio
00457                 int* resamp = new int[M];
00458                 
00459                 double r = ((double(rand())+1)/(double(RAND_MAX)+2))/M;                 // me ha fallado alguna vez
00460                 //double r = 0.5/M;                                                                                             // tambien se puede poner fijo a la mitad
00461                 double u = r;
00462                 int j = 0;
00463                 double c = p[0].getWeight();
00464                 
00465                 double inc = 1.0/M;
00466                 for (m = 0; m < M; m++){
00467                         while(u > c){
00468                                 j++;
00469                                 if (j>=M) {
00470 //                                      printf("[FastSLAM] ERROR!!!\n"); //Sleep(100000);
00471                                 }
00472                                 c += p[j].getWeight();
00473                         }
00474                         resamp[m]=j;
00475                         u += inc;
00476                 }
00477 
00478                 double w0 = 1.0/M;
00479                 for (i = 0; i < M; i++){
00480                         p[i].setWeight(w0);
00481                 }
00482 
00483                 // RESAMPLING
00484                 sampling.lock();
00485                 for (m = 0; m < M; m++){
00486                         newp[m] = p[resamp[m]];
00487                 }
00488                 index = resamp[newindex];
00489                 particle* aux = p;
00490                 p = newp;
00491                 newp = aux;
00492                 sampling.unlock();
00493 
00494                 for (m = 0; m < M; m++) newp[m].releaseVMap();
00495                 
00496                 delete[] resamp;
00497         }
00498         return Neff;
00499 }
00500 
00501 // Evaluates th uncertainty in the position for each robot
00502 void RBPFilter::evalDisp(int r){
00503         int j;
00504         float sigma;
00505         float meanx, meany, meanth;
00506         double sum=M;
00507 
00508         meanx=0; meany=0; meanth=0;
00509         for (j =0; j < M ; j++){
00510                 meanx  += p[j].getPos(r).x ;
00511                 meany  += p[j].getPos(r).y ;
00512                 meanth += p[j].getPos(r).th;
00513                 //sum += p[j].getSumLogWeight();
00514         }
00515 
00516         meanx/= sum; meany/= sum; meanth/= sum;
00517         sigma = 0;
00518         for (j =0; j < M ; j++){
00519                 sigma += (pow(p[j].getPos(r).x  - meanx,2) + pow(p[j].getPos(r).y  - meany,2));
00520         }       
00521         sigma = sqrt(sigma/sum);
00522 
00523         dispRobot[r] = sigma;
00524 
00525         //printf("[FastSLAM 1] sigma = %f\n",sigma);
00526         // LOCALIZATION HYSTERESIS LOOP 
00527         if (badlocalized[r] == false && sigma>th_high)  badlocalized[r] = true;
00528         if (badlocalized[r] == true && sigma<th_low)    badlocalized[r] = false;
00529 }
00530 
00531 matrix RBPFilter::jacobian(const pose& pos){
00532 
00533         matrix res(3,3);
00534 
00535         float costh = (float)cos(pos.th);
00536         float sinth = (float)sin(pos.th);
00537 
00538         res.set(0,0,costh);
00539         res.set(0,1,sinth);
00540         res.set(1,0,-sinth);
00541         res.set(1,1,costh);
00542         res.set(2,2,1.0f);
00543 
00544         return res;
00545 }
00546 
00547 //TODO eval a covariance from the particles
00548 matrix RBPFilter::getCovariance(int robot) const{
00549         matrix mat(3,3);
00550         return mat;
00551 };
00552 
00553 
00554 
00555 gridMapInterface* RBPFilter::getOMap() {
00556         sampling.lock();
00557         gridMapInterface* map = (onlyonegridmap)? omap->clone() : p[index].getOMap().clone();
00558         sampling.unlock();
00559         return map;
00560 }
00561 
00562 visualMap* RBPFilter::getVMap() {
00563         sampling.lock();
00564         visualMap* map = p[index].getVMap().clone();
00565         sampling.unlock();
00566         return map;
00567 }
00568 
00569 binMap* RBPFilter::getPreMap() {
00570         sampling.lock();
00571         binMap* map = new binMap( (onlyonegridmap)? *ppmap : p[index].getPrecisePoseMap() );    
00572         sampling.unlock();
00573         return map;
00574 }
00575 
00576 binMap* RBPFilter::getImpMap() {
00577         sampling.lock();
00578         binMap* map = new binMap( (onlyonegridmap)? *ipmap : p[index].getImprecisePoseMap() );
00579         sampling.unlock();
00580         return map;
00581 }
00582 
00583 pose RBPFilter::getPos(int robot) {
00584         sampling.lock();
00585         pose pos =  p[index].getPos(robot);
00586         sampling.unlock();
00587         return pos;
00588 }
00589 
00590 point RBPFilter::getCell(int robot) {
00591         sampling.lock();
00592         point c = p[index].getCell(robot);
00593         sampling.unlock();
00594         return c;
00595 }
00596 
00597 Ematrix RBPFilter::getGlobalCovariance() const{
00598 
00599         return Ematrix();
00600 
00601 }
00602 
00603 QPixmap* RBPFilter::getPixmap(){
00604 //      IplImage* img = omap->getMapAsImage();
00605 //      cvSaveImage("imgoctmp.jpg",img);
00606 //      cvReleaseImage(&img);
00607 //      QPixmap* pix = new QPixmap("imgoctmp.jpg");
00608 //      return pix; 
00609 
00610         gridMapInterface* map = getOMap();
00611         visualMap* vismap = getVMap();
00612 
00613         IplImage* img = map->getMapAsImage();
00614         for (int r=0; r<nBots; r++)
00615                 drawPoses (*img, xorigin,  yorigin,  resolution);
00616         vismap->drawMarks(*img,xorigin,yorigin,resolution);
00617         
00618         delete map;
00619         delete vismap; 
00620 
00621         QImage* qim = new QImage((const uchar *)img->imageData, img->width, img->height, img->widthStep, QImage::Format_RGB888);
00622         QPixmap* mapfig = new QPixmap(QPixmap::fromImage(*qim));
00623         cvReleaseImage(&img);
00624         delete qim;
00625 
00626         return mapfig;
00627 
00628 }
00629 
00630 
00631 void RBPFilter::drawPoses (IplImage& im, float xorigin, float yorigin, float resolution) {
00632 
00633         CvScalar redcolor = CV_RGB(255,0,0);
00634         sampling.lock();
00635         for (int r=0; r<nBots; r++){
00636                 for (int m = 0; m < M ; m++){
00637                         point cell = p[m].getCell(r);
00638                         cvEllipse(&im, cvPoint(cell.x,im.height-cell.y), cvSize(0,0), 0, 0, 360, redcolor, CV_FILLED );
00639                 }
00640         }
00641         sampling.unlock();
00642 }
00643 
 All Classes Functions Variables Typedefs