MRXT: The Multi-Robot eXploration Tool
Multi-Robot autonomous exploration and mapping simulator.
src/architecture/slam/mapbuilders/EKFilter.cpp
00001 #include "EKFilter.h"
00002 #include <opencv2/opencv.hpp>
00003 #include <list>
00004 
00005 #ifndef WIN32
00006 #include "sys/time.h"
00007 #endif
00008 
00009 using namespace std;
00010 
00011 // Para registrar la clase en la factoria
00012 namespace{
00013         slamInterface* CreateEKFilter(int bots, ConfigFile& file){
00014                 return new EKFilter(bots, file);
00015         }
00016         const int EKF = 1;
00017         const bool registered = slamFactory::Instance().Register(EKF, slamCreator(CreateEKFilter));
00018 }
00019 
00020 /// Constructor
00021 EKFilter::EKFilter():
00022         vslamFilter(),
00023         robotcells(0),
00024         dispRobot(0),
00025         odoData(0),
00026         lastOdoData(0),
00027         rsData(0),
00028         lmData(0),
00029         endSlam(false),
00030         omap(0),
00031         ppmap(0),
00032         ipmap(0),
00033         vmap(0),
00034         Identity3(matrix::identity(3)),
00035         maxCorrect(0.0f),
00036         minIncorrect(999999999.9f)
00037 {
00038         //printf("[EKF] EKF default constructor\n");
00039 }
00040 
00041 /// Constructor
00042 EKFilter::EKFilter(int nrobots, ConfigFile& configFile):
00043         vslamFilter             (nrobots,configFile),
00044         state                   (3*nrobots,1,3*(nrobots+nmarks),1),
00045         covariance              (3*nrobots,3*nrobots,3*(nrobots+nmarks),3*(nrobots+nmarks)),
00046         robotcells              (new point[nBots]),
00047         dispRobot               (new float[nBots]),
00048         odoData                 (new pose*[nBots]),
00049         lastOdoData             (new pose*[nBots]),
00050         rsData                  (new rangeSensorData*[nBots]),
00051         lmData                  (new landmarksData*[nBots]),
00052         endSlam                 (false),
00053         omap                    (gridMapFactory::Instance().CreateObject(gmtype,width, height, resolution, xorigin, yorigin)),
00054         ppmap                   (new binMap(gmwidth, gmheight, resolution, xorigin, yorigin)),
00055         ipmap                   (new binMap(gmwidth, gmheight, resolution, xorigin, yorigin)),
00056         vmap                    (visualMapFactory::Instance().CreateObject(vmtype,nmarks,configFile)),
00057         Identity3               (matrix::identity(3)),
00058 //      range                   (configFile.read<float>("SEARCHRANGE")),
00059         mahTh                   (configFile.read<float>("MAHALANOBISTH")),
00060         descTh                  (configFile.read<float>("DESCRIPTORTH")),
00061         nearestNeighbourOrderBy (configFile.read<int>("NEARESTNEIGHBOURBY")),
00062         maxCorrect              (0.0f),
00063         minIncorrect            (999999999.9f)
00064 {
00065         for (int r = 0; r< nBots; r++){
00066                 dispRobot[r] = 0.0f;
00067                 rbase[r] = 0;
00068                 odoData[r] = 0;
00069                 lastOdoData[r] = 0;
00070                 rsData[r] = 0;
00071                 lmData[r] = 0;
00072                 robotsEnabled[r]=true;
00073         }
00074         printf("[EKF] EKF created\n");
00075 }
00076 
00077 /// Destructor
00078 EKFilter::~EKFilter(){
00079         //printf("[EKF] EKF destroyer...");
00080         stop();
00081         if (logstr){
00082                 char myfilestr[100];
00083                 sprintf(myfilestr,"%somap.jpg",logstr);
00084                 omap->saveMapAsImage(myfilestr);
00085                 sprintf(myfilestr,"%sppmap.jpg",logstr);
00086                 ppmap->saveMapAsImage(myfilestr);
00087                 sprintf(myfilestr,"%svmap",logstr);
00088                 vmap->saveMap(myfilestr);
00089         }
00090         if (robotcells)                 delete[] robotcells;
00091         if (dispRobot)                  delete[] dispRobot;
00092         if (odoData){                   for (int i=0; i< nBots; i++) if (odoData[i]) delete odoData[i];
00093                                         delete[] odoData;
00094         }
00095         if (lastOdoData){               for (int i=0; i< nBots; i++) if (lastOdoData[i]) delete lastOdoData[i];
00096                                         delete[] lastOdoData;
00097         }
00098         if (rsData){                    for (int i=0; i< nBots; i++) if (rsData[i]) delete rsData[i];
00099                                         delete[] rsData;}
00100         if (lmData){                    for (int i=0; i< nBots; i++) if (lmData[i]) delete lmData[i];
00101                                         delete[] lmData;}
00102         if (omap)                       delete omap;
00103         if (ppmap)                      delete ppmap;
00104         if (ipmap)                      delete ipmap;
00105         if (vmap)                       delete vmap;
00106         //printf("EKF destroyed\n");
00107 }
00108 
00109 ///initializer  
00110 void EKFilter::initialize(int nrobots, ConfigFile& configfile){
00111         vslamFilter::initialize(nrobots, configfile);
00112         
00113         state.initialize(3*nrobots,1,3*(nrobots+nmarks),1);
00114         covariance.initialize(3*nrobots,3*nrobots,3*(nrobots+nmarks),3*(nrobots+nmarks));
00115         
00116         if (robotcells)         delete[] robotcells;
00117         robotcells              = new point[nBots];
00118         if (dispRobot)          delete[] dispRobot;
00119         dispRobot               = new float[nBots];
00120         if (odoData)            delete[] odoData;
00121         odoData                 = new pose*[nBots];
00122         if (lastOdoData)        delete[] lastOdoData;
00123         lastOdoData             = new pose*[nBots];
00124         if (rsData)             delete[] rsData;
00125         rsData                  = new rangeSensorData*[nBots];
00126         if (lmData)             delete[] lmData;
00127         lmData                  = new landmarksData*[nBots];
00128         endSlam                 = false;
00129         if (omap)               delete omap;
00130         omap                    = gridMapFactory::Instance().CreateObject(gmtype, width, height, resolution, xorigin, yorigin);
00131         if (ppmap)              delete ppmap;
00132         ppmap                   = new binMap(gmwidth, gmheight, resolution, xorigin, yorigin);
00133         if (ipmap)              delete ipmap;
00134         ipmap                   = new binMap(gmwidth, gmheight, resolution, xorigin, yorigin);
00135         if (vmap)               delete vmap;
00136         vmap                    = visualMapFactory::Instance().CreateObject(vmtype,nmarks,configfile);
00137         
00138         for (int r = 0; r< nBots; r++){
00139                 dispRobot[r] = 0.0f;
00140                 rbase[r] = 0;
00141                 odoData[r] = 0;
00142                 lastOdoData[r] = 0;
00143                 rsData[r] = 0;
00144                 lmData[r] = 0;
00145                 robotsEnabled[r]=true;
00146         }
00147 }
00148 
00149 /// set up for the execution thread
00150 int EKFilter::setup(){
00151         prio = 50;
00152         return 0;
00153 }
00154 
00155 /// called before stopping
00156 void EKFilter::onStop(){
00157         if (!endSlam){          
00158                 endSlam = true;
00159                 //scene->beginProduction();
00160                 //scene->endProduction();
00161                 closing.lock();
00162                 closing.unlock();
00163         }
00164         printf("[EKF] SLAM stopped\n");
00165 }
00166 
00167 /// primary execution loop
00168 void EKFilter::execute(){
00169         closing.lock();
00170         printf("[EKF] \t\t\t\t\t\t\t Running SLAM\n");
00171         endSlam=false;
00172         int r;
00173 
00174         // open the log file
00175         FILE* slamlog=0;
00176         CvVideoWriter* avifile=0;
00177 
00178         if (logstr){
00179                 char myfilestr[100];
00180                 sprintf(myfilestr,"%sslam.m",logstr);   
00181                 slamlog = fopen(myfilestr,"w");
00182                 fprintf(slamlog,"poses_est=[");
00183 
00184 //              if (saveAviFile){
00185 //                      sprintf(myfilestr,"outfiles/%svideo.avi",logstr);       
00186 //                      avifile =  cvCreateVideoWriter( myfilestr, -1, 25, cvSize(gmwidth,gmheight),1);
00187 //                      //printf("[EKF] avifile created\n");
00188 //              }
00189         }
00190 
00191 //      if (displayomap){
00192 //              if (windowName) cvNamedWindow(windowName,0);
00193 //              else cvNamedWindow("OMAP",0);
00194 //      }
00195 //      if (displayppmap) cvNamedWindow("PPMAP", 0);
00196 //      if (displayipmap) cvNamedWindow("IPMAP", 0);
00197 
00198         // inicializamos SLAM
00199         for (r=0; r<nBots; r++){
00200                 if (rbase[r]) rbase[r]->beginConsumition();
00201                 odoData[r] = rbase[r]->getOdometry();
00202                 state.set(r*3,0,odoData[r]->x);
00203                 state.set(r*3+1,0,odoData[r]->y);
00204                 state.set(r*3+2,0,odoData[r]->th);
00205                 pose pos = getPos(r);
00206                 robotcells[r].x = (int) floor((pos.x - xorigin)/resolution);
00207                 robotcells[r].y = (int) floor((pos.y - yorigin)/resolution);
00208                 if (rbase[r]) rbase[r]->endConsumition();
00209         }
00210         //state.print("initial state");
00211         covariance.clear();
00212 //      #ifndef WIN32
00213 //      struct timeval tv1, tv2;
00214 //      double initime, curtime, time1, time2, time3;
00215 //      #endif
00216 //      
00217         int paso = 0;
00218         int nBotsx3 = 3*nBots;
00219         matrix Ft = matrix::identity(nBotsx3);  
00220         Ematrix Qt(nBotsx3,nBotsx3);
00221 
00222 
00223         errorcount = 0;
00224         while (!endSlam){
00225                 //printID("SLAM EKF");
00226                 paso++;
00227                 // Leemos sensores
00228                 //printf("[EKF] \t\t\tslam step\n");
00229                 for (r=0; r<nBots; r++){
00230                         if (robotsEnabled[r]){
00231                                 //printf("[EKF][robot %d] waiting to consume data...\n", r);
00232                                 rbase[r]->beginConsumition();
00233                                 if (robotsEnabled[r]){
00234                                         if (lastOdoData[r]) delete lastOdoData[r];
00235                                         lastOdoData[r] = odoData[r];
00236                                         odoData[r] = rbase[r]->getOdometry();
00237                                         if (rsData[r]) delete rsData[r];
00238                                         rsData[r]  = rbase[r]->getRangeSensorData();
00239                                         if (lmData[r]) delete lmData[r];
00240                                         lmData[r]  = rbase[r]->getLandmarksData();
00241                                 }
00242                                 //printf("[EKF][robot %d] data consumed\n", r);
00243                                 rbase[r]->endConsumition();
00244                         }
00245                 }
00246                 //printf("[EKF] \t\t\tconsumed\n");
00247                 
00248 //              #ifndef WIN32
00249 //              gettimeofday(&tv1, NULL);
00250 //              initime = tv1.tv_sec*1000.0 + tv1.tv_usec/1000.0;
00251 //              //printf("init time = %f\n",initime);
00252 //              #endif
00253                 
00254                 //sleepms(2000);
00255                 
00256                 int nmarksprev = vmap->getNLandmarks();
00257                 int nmarksprev3 = 3*nmarksprev;
00258                 
00259                 Ematrix G(nBotsx3+nmarksprev3,2);
00260                 Ematrix& xpkmas1 = state;               
00261                 
00262 //              #ifndef WIN32
00263 //              gettimeofday(&tv2, NULL);
00264 //              time1 = tv2.tv_sec*1000.0 + tv2.tv_usec/1000.0;
00265 //              printf("Prediction Time: %f \n", time1-initime);
00266 //              #endif
00267                 
00268                 int nummarks=0;
00269                 for (r=0; r<nBots; r++){
00270                         if (robotsEnabled[r]){
00271                                 int r3 = 3*r;
00272                                 // pose
00273                                 pose xrk = getPos(r);   // cogemos la pose del estado           
00274                                 // odo inc
00275                                 pose deltaOdo = *(odoData[r]) - *(lastOdoData[r]);              // incremento de odo
00276                                 if (deltaOdo.th>PI)             deltaOdo.th -= PIx2;
00277                                 else if (deltaOdo.th <= -PI)    deltaOdo.th += PIx2;
00278 
00279         //              #ifndef WIN32
00280         //              gettimeofday(&tv2, NULL);
00281         //              time1 = tv2.tv_sec*1000.0 + tv2.tv_usec/1000.0;
00282         //              printf("Prediction Time: %f \n", time1-initime);
00283 
00284 
00285         //              #endif
00286 
00287                                 //deltaOdo.print("\t\t\t\t\t\t\t\t\tdeltaOdo=");
00288                                 // prediction
00289                                 Ft.set(r3,r3,jacobianF(xrk, deltaOdo,lastOdoData[r]->th));                              // ampliamos el jacobiano F                                             
00290                                 Ematrix G = jacobianG(xrk, deltaOdo,lastOdoData[r]->th);                                // jacobiano G
00291                                 Qt.set(r3,r3,G*(noiseQ(xrk,deltaOdo,lastOdoData[r]->th)*G.transpose()));
00292                                 
00293                                 xpkmas1.set(r3, 0, motionModel (xrk, deltaOdo, lastOdoData[r]->th));                    // modelo de movimiento
00294                                 nummarks += lmData[r]->getNLandmarks();
00295                                 //if (lmData[r]->getNLandmarks() < 3) printf("[EKF] [robot %d] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OJO MARCAS MENOR QUE 3!!!!!! solo %d\n", r, lmData[r]->getNLandmarks());
00296                         }
00297                 }
00298 //              #ifndef WIN32
00299 //              gettimeofday(&tv2, NULL);
00300 //              time1 = tv2.tv_sec*1000.0 + tv2.tv_usec/1000.0;
00301                 //printf("Prediction Time: %f \n", time1-initime);
00302 //              #endif
00303 
00304 //              covariance.print("P=");
00305 
00306 //              F.print("F=");
00307 //              Ft.print("Ft=");
00308 
00309 //              Q.print("Q=");
00310 //              Qt.print("Qt=");
00311 
00312 //              Ematrix Ppkmas1 = F * (covariance * F.transpose()) +Q;                  // matriz de covarianza
00313 //              Ppkmas1.print("completa\n");
00314                 
00315                 Ematrix& Ppkmas1 = covariance;
00316                 matrix Fttrans = Ft.transpose();
00317                 matrix Pvv = Ppkmas1.subMat(0,nBotsx3-1,0,nBotsx3-1);
00318 //              Pvv.print("Pvv=");
00319                 Ppkmas1.set(0,0,Qt + ( Ft* (Pvv*Fttrans) ));
00320                 matrix Pvl = Ppkmas1.subMat(0,nBotsx3-1,nBotsx3,nBotsx3+nmarksprev3-1);
00321 //              Pvl.print("Pvl=");
00322                 Ppkmas1.set(0,nBotsx3,Ft*Pvl);
00323                 Ppkmas1.set(nBotsx3,0,(Ppkmas1.subMat(0,nBotsx3-1,nBotsx3,nBotsx3+nmarksprev3-1)).transpose());
00324                 
00325                 //Ppkmas1.print("Predicted P\n");
00326                 
00327                 //Ppkmas1 = Ppkmas1t;
00328                 
00329 //              #ifndef WIN32
00330 //              gettimeofday(&tv2, NULL);
00331 //              time1 = tv2.tv_sec*1000.0 + tv2.tv_usec/1000.0;
00332 //              //printf("[EKF] Prediction Time: %f \n", time1-initime);
00333 //              #endif
00334                 
00335                 // update               
00336                 
00337                 int nummarks3 = 3*nummarks;
00338                 
00339                 Ematrix H(0,nBotsx3+nmarksprev3,3*nummarks,nBotsx3+nmarksprev3+nummarks3);
00340                 Ematrix ZT(0,1,nummarks3,1);
00341                 Ematrix zgorro(0,1,nummarks3,1);
00342                 Ematrix Rt(0,0,nummarks3,nummarks3);
00343                 
00344                 int markid=0;
00345 
00346                 for (r=0; r<nBots; r++){
00347                         if (robotsEnabled[r]){
00348                                 int r3 = 3*r;
00349                                 int r3mas2 = r3+2; 
00350                                 pose xrpkmas1   = xpkmas1.subMat(r3,r3mas2,0,0).toPose();               
00351                                 matrix H2       = jacobianH2(xrpkmas1);                                                                         // jacobiano H
00352                                 matrix H2trans  = H2.transpose();
00353                                 //xrpkmas1.print("Xk|k-1 = ");
00354                                 //printf("numero de observaciones= %d\n",lmData[r]->getNLandmarks());
00355                                 //if (lmData[r]->getNLandmarks()>2){
00356                                         for (int j = 0; j < lmData[r]->getNLandmarks(); j++){                                                   // for each detected mark
00357                                                 //printf("Marca vista con descriptor: %f\n", lmData[r]->getLandmark(j).descriptor[0]);
00358                                                 pos3d lpos  = base2global(vmap->cam2base(lmData[r]->getLandmark(j).pos), xrpkmas1);             // medida en coordenadas globales       
00359                                                 matrix ZTi      = lmData[r]->getLandmark(j).pos;                                                // Medida (coordenadas de camara)
00360                                                 matrix Rti      = lmData[r]->getLandmark(j).covariance;                                         // covarianza de la medida
00361                                                 //ZTi.print("Observacion = ");
00362                                                 //Rti.print("RTi=");
00363                                                 // data association 
00364                                                 
00365                                                 landmark* mark = (perfectMatching)?
00366                                                         vmap->getLandmarkByDesc(lmData[r]->getLandmark(j).descriptor) :
00367                 //                                      vmap->dataAssociation(ZTi, Rti, lpos,  xrpkmas1, H2, H2trans, lmData[r]->getLandmark(j).descriptor) ;
00368                                                         dataAssociation(ZTi, Rti, lpos,  xrpkmas1, H2, H2trans, lmData[r]->getLandmark(j).descriptor,Ppkmas1,r) ;
00369                                                 
00370                                                 if (mark){      // si hay matching
00371                                                         
00372                                                         //printf("matching con la marca %f\n",mark->descriptor[0]);
00373                                                         
00374                                                         int markid3 = 3*markid;
00375                                                         ZT.extend(3,0);
00376                                                         ZT.set(markid3,0,ZTi);
00377                                                         Rt.extend(3,3);
00378                                                         Rt.set(markid3,markid3,Rti);
00379                                                         matrix zgorroi  = vmap->base2cam(global2base(mark->pos, xrpkmas1));     // medida estimada
00380                                                         zgorro.extend(3,0);
00381                                                         zgorro.set(markid3,0,zgorroi);
00382                                                         
00383                                                         matrix H1= jacobianH1(xrpkmas1,mark->pos);
00384                                                         int lid = vmap->returnLastReturnedId();
00385                                                         H.extend(3,0);
00386                                                         H.set(markid3,nBotsx3+3*lid,H2);
00387                                                         H.set(markid3,r3,H1);
00388                                                         
00389                                                         markid++;
00390                                                         
00391                                                         for (int k=0; k< mark->desclength; k++)
00392                                                                 mark->descriptor[k] = (mark->descriptor[k] + lmData[r]->getLandmark(j).descriptor[k])/2;
00393                                                         vmap->changeLastReturnedLandmark(*mark);
00394                                                 }
00395                                                 else{ // new mark
00396                                                         //printf("marca nueva\n");
00397                                                         matrix Pl2 = H2trans*(Rti*(H2));
00398                                                         //Rti.print("RTi=");
00399                                                         mark = new landmark(lpos,                                                               // global pos
00400                                                                                                 Pl2,                                            // covariance
00401                                                                                                 lmData[r]->getLandmark(j).descriptor,           // descriptor
00402                                                                                                 lmData[r]->getLandmark(j).desclength,           // descriptor length
00403                                                                                                 0);                                             // repeated
00404                                                         vmap->addLandmark(*mark);
00405                                                         
00406                                                         int numm = 3*(vmap->getNLandmarks()-1);
00407                                                         
00408                                                         // add the mark to the state map
00409                                                         xpkmas1.extend(3,0);
00410                                                         xpkmas1.set(nBotsx3+numm,0,matrix(lpos));
00411                                                         
00412                                                         Ematrix J1 = jacobianJ1(xrpkmas1,lpos);
00413                                                         
00414                                                         Ematrix R = J1*Ppkmas1.subMat(r3,r3mas2, 0, nBotsx3+numm-1);
00415                                                         Ematrix Pr = Ppkmas1.subMat(r3,r3mas2,r3,r3mas2);
00416                                                         Ematrix Pl = J1*Pr*J1.transpose() + Pl2;
00417                                                         
00418                                                         Ppkmas1.extend(3,3);
00419                                                         Ppkmas1.set(0,nBotsx3+numm,R.transpose());
00420                                                         Ppkmas1.set(nBotsx3+numm,0,R);
00421                                                         Ppkmas1.set(nBotsx3+numm,nBotsx3+numm,Pl);
00422                                                         
00423                                                         H.extend(0,3);
00424                                                 }
00425                                                 if (mark) {delete mark; mark=0;}
00426                                         } // for each mark
00427                                 //}
00428                         }
00429                 }// for each robot
00430 
00431 //              #ifndef WIN32
00432 //              gettimeofday(&tv2, NULL);
00433 //              time2 = tv2.tv_sec*1000.0 + tv2.tv_usec/1000.0;
00434 //              //printf("[EKF] Data Association Time: %f \n", time2-time1);
00435 //              #endif
00436 
00437 
00438                 //Ppkmas1.print("Ppkmas1");
00439 
00440 //              if(markid>2){
00441                 if(markid){
00442                         Ematrix Htrans          = H.transpose();
00443                         Ematrix In              = (ZT - zgorro);                        // innovacion
00444                         Ematrix S               = ((H*(Ppkmas1.mul2(Htrans))) + Rt);    // covarianza de la innovacion
00445                         Ematrix K               = (Ppkmas1.mul2((Htrans)*(S.inverse())));       // ganancia
00446                         xpkmas1                 = (K*In)+xpkmas1;                       // actualizamos el estado
00447                         Ppkmas1                 = Ppkmas1-K.mul2(H*Ppkmas1);            // actualizamos covarianza
00448                         //K.print("K=");
00449                         //H.print("H=");
00450                         //Rt.print("Rt=");
00451                         //In.print("IN=");
00452                         //ZT.print("ZT=");
00453                         //zgorro.print("zgorro=");
00454                         //float totalin =  3.0f*In.totalsum()/In.getNumRows();
00455                         //printf("totalin = %f\n", totalin);
00456                         //if (totalin > 2 ) errorcount++; 
00457                         //else errorcount = 0;
00458                         //if (errorcount >= 3 ) exit(-1);
00459                 }
00460                 //xpkmas1.subMat(0,2,0,0).toPose().print("Xk|k = ");
00461                 
00462 //              #ifndef WIN32
00463 //              gettimeofday(&tv2, NULL);
00464 //              time3 = tv2.tv_sec*1000.0 + tv2.tv_usec/1000.0;
00465 //              //printf("[EKF] Update Time: %f \n", time3-time2);
00466 //              #endif
00467                         
00468                 //state = xpkmas1;
00469                 //covariance = Ppkmas1;
00470         
00471                 //xpkmas1.print("X=");
00472                 //Ppkmas1.print("Cov=");
00473 
00474                 float uncertainty = evalUncertainty();
00475                 //printf("[EKF] uncertainty = %f\n",uncertainty);
00476 
00477                 // pasar los valores de las matrices al mapa
00478                 for (int l = 0; l < vmap->getNLandmarks(); l++){
00479                         landmark* mark          = vmap->getLandmarkById(l);
00480                         if (mark){
00481                                 mark->pos               = state.subMat(nBotsx3+l*3,nBotsx3+l*3+2,0,0).toPos3d();
00482                                 mark->covariance        = covariance.subMat(nBotsx3+l*3,nBotsx3+l*3+2,nBotsx3+l*3,nBotsx3+l*3+2);                                       
00483                                 vmap->changeLastReturnedLandmark(*mark);
00484                                 delete mark;
00485                                 mark = 0;
00486                         }
00487                 }
00488 
00489                 //printf("[EKF] marcas en el mapa= %d\n",vmap->getNLandmarks());
00490                 
00491                 //printf("\t\t\tupdate\n");
00492                 for (r=0; r<nBots; r++){
00493                         if (robotsEnabled[r]){
00494                                 if (xpkmas1.get(3*r+2,3*r+2)>PI)                        xpkmas1.set(3*r+2,3*r+2,xpkmas1.get(3*r+2,3*r+2)- PIx2);
00495                                 else if (xpkmas1.get(3*r+2,3*r+2) <= -PI)               xpkmas1.set(3*r+2,3*r+2,xpkmas1.get(3*r+2,3*r+2)+ PIx2);
00496                                 evalDisp(r);
00497                                 pose pos = getPos(r);
00498                                 robotcells[r].x = (int) floor((pos.x - xorigin)/resolution);
00499                                 robotcells[r].y = (int) floor((pos.y - yorigin)/resolution);
00500                         
00501                                 omap->update(*(rsData[r]), pos, getDisp(r));                                    // updating occupation map
00502                                 updatePPMap(robotcells[r], *ppmap, getDisp(r), badlocalized[r]);
00503                                 updateIPMap(robotcells[r], *ipmap, getDisp(r), badlocalized[r]);
00504                         }
00505                 }
00506                 step();
00507 
00508 
00509                 emit slamUpdated();
00510 
00511                 //if (paso%10==0){
00512                 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  show maps  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00513 //              IplImage* im, *im2, *im3;
00514 //              if (displayomap){
00515 //                      //printf("[EKF] displaying maps...\n");
00516 //                      im = omap->getMapAsImage();
00517 //                      CvScalar redcolor = CV_RGB(255,0,0);
00518 //                      //int hinv = gmheight-1;
00519 //                      //binMap front;
00520 //                      //omap->frontiers(front);
00521 //                      //front.showMap("frontiers");
00522 //                      if (displayposes)                                               // display all particles
00523 //                              for (r=0; r<nBots; r++)
00524 //                                      drawPose (*im, getPos(r), getCovariance(r),  xorigin,  yorigin,  resolution);
00525 //                      if (displayfeatures) vmap->drawMarks(*im,xorigin,yorigin,resolution);
00526 //                      if (windowName) cvShowImage(windowName,im);
00527 //                      else cvShowImage("OMAP",im);
00528 
00529 //                      //printf("voy a hacer el frame grabe %d, %d\n",saveAviFile,avifile);
00530 //                      if(saveAviFile && avifile){
00531 //                              int res = cvWriteFrame(avifile, im);
00532 //                              //printf("[EKF] frame grabber, result %d\n",res); 
00533 //                      }
00534 //                      //printf("[EKF] acabo\n");
00535 //              }
00536 //              if (displayppmap){
00537 //                      im2 = ppmap->getMapAsImage();
00538 //                      cvShowImage("PPMAP",im2);
00539 //              }
00540 //              if (displayipmap){
00541 //                      im3 = ipmap->getMapAsImage();
00542 //                      cvShowImage("IPMAP",im3);
00543 //              }
00544 //              //printf("[EKF] aqui\n");
00545 //              //if (displayomap || displayppmap || displayipmap) cvWaitKey(2);
00546 //              //printf("[EKF] aqui 2\n");
00547 //              if (displayomap)  cvReleaseImage(&im);
00548 //              if (displayppmap) cvReleaseImage(&im2);
00549 //              if (displayipmap) cvReleaseImage(&im3);
00550                 //}
00551                 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  end show maps  
00552                 
00553                 //printf("[EKF] logging...\n");
00554 
00555                 // write logs
00556                 if (logstr){
00557                         fprintf(slamlog,"%d",getStep());
00558                         for (r=0; r<nBots;r++){
00559                                 pose p = state.subMat(r*3,r*3+2,0,0).toPose();
00560                                 //fprintf(slamlog,", %f, %f, %f, %f, %f, %f, %f", p.x, p.y, p.th, getDisp(r),uncertainty,mediana,determinante);
00561                                 fprintf(slamlog,", %f, %f, %f, %f", p.x, p.y, p.th, getDisp(r));
00562                         }
00563                         fprintf(slamlog,"\n");
00564                 }
00565                 
00566 //              #ifndef WIN32
00567 //              gettimeofday(&tv2, NULL);
00568 //              curtime = tv2.tv_sec*1000.0 + tv2.tv_usec/1000.0;
00569 //              //printf("[EKF] Save and show Time: %f \n", curtime-time3);
00570 //              //printf("[EKF] Total Time: %f \n", curtime-initime);
00571 //              #endif
00572                 
00573         }// while (!endSlam)
00574         
00575         if (logstr){
00576                 fprintf(slamlog,"];");  
00577                 fclose(slamlog);
00578         }
00579         
00580         //if (saveAviFile && avifile) cvReleaseVideoWriter( &avifile );
00581         
00582 //      if (displayomap){
00583 //              if (windowName) cvDestroyWindow(windowName);
00584 //              else cvDestroyWindow("OMAP");
00585 //      }
00586 //      if (displayppmap) cvDestroyWindow("PPMAP");
00587 //      if (displayipmap) cvDestroyWindow("IPMAP");
00588         
00589         //printf("[EKF] Stopping SLAM\n");
00590         closing.unlock();
00591 }
00592 
00593 QImage* EKFilter::getQImage(){
00594 //      IplImage* img = omap->getMapAsImage();
00595 //      QImage* qim = new QImage((const uchar *)img->imageData, img->width, img->height, img->widthStep, QImage::Format_RGB888);
00596 //      QImage* qim = slam->getQImage();
00597 //      QPixmap mapfig = QPixmap::fromImage(*qim);
00598 //      cvReleaseImage(&img);
00599 //      return qim;
00600         return 0;
00601 }
00602 
00603 
00604 QPixmap* EKFilter::getPixmap(){
00605 //      IplImage* img = omap->getMapAsImage();
00606 //      cvSaveImage("imgoctmp.jpg",img);
00607 //      cvReleaseImage(&img);
00608 //      QPixmap* pix = new QPixmap("imgoctmp.jpg");
00609 //      return pix; 
00610 
00611         IplImage* img = omap->getMapAsImage();
00612         for (int r=0; r<nBots; r++)
00613                 drawPose (*img, getPos(r), getCovariance(r),  xorigin,  yorigin,  resolution);
00614         vmap->drawMarks(*img,xorigin,yorigin,resolution);
00615         
00616         QImage* qim = new QImage((const uchar *)img->imageData, img->width, img->height, img->widthStep, QImage::Format_RGB888);
00617         QPixmap* mapfig = new QPixmap(QPixmap::fromImage(*qim));
00618         cvReleaseImage(&img);
00619         delete qim;
00620         return mapfig;
00621 
00622 }
00623 
00624 
00625 // odometry noise matrix Q
00626 Ematrix EKFilter::noiseQ(const pose& pos, const pose& deltaOdo, float thetaodo){
00627 //      float deltatrans2 = ((deltaOdo.x*deltaOdo.x+deltaOdo.y*deltaOdo.y));
00628 //      float dtheta = fabs(deltaOdo.th);
00629 //      Ematrix Q(3,3);
00630 //      Q.set(0,0, pow(alfa3*deltatrans+alfa4*dtheta,2));
00631 //      Q.set(1,1, pow(alfa2*deltatrans+alfa1*dtheta,2));
00632 //      Q.set(2,2, pow(alfa2*deltatrans+alfa1*dtheta,2));
00633 //      Ematrix Q(2,2);
00634 //      Q.set(0,0, alfa3*alfa3*deltatrans2);
00635 //      Q.set(0,1, alfa4*alfa4*deltaOdo.th*deltaOdo.th);
00636 //      Q.set(1,0, alfa2*alfa2*deltatrans2);
00637 //      Q.set(1,1, alfa1*alfa1*deltaOdo.th*deltaOdo.th);
00638 //      Q.set(0,0, alfa3*alfa3*deltatrans2+alfa4*alfa4*deltaOdo.th*deltaOdo.th);
00639 //      Q.set(1,1, alfa2*alfa2*deltatrans2+alfa1*alfa1*deltaOdo.th*deltaOdo.th);
00640         float deltat  = sqrt((deltaOdo.x*deltaOdo.x+deltaOdo.y*deltaOdo.y));
00641         float deltar1;
00642         if (!(fabs(deltaOdo.x) < 0.000001 && fabs(deltaOdo.y) < 0.000001))
00643                 deltar1 = atan2(deltaOdo.y,deltaOdo.x)-thetaodo;
00644         else
00645                 deltar1 = 0;
00646         float deltar2 = deltaOdo.th - deltar1;
00647         if      (deltar1>PI)            deltar1-= PIx2;
00648         else if (deltar1 <= -PI)        deltar1+= PIx2;
00649         if      (deltar2>PI)            deltar2-= PIx2;
00650         else if (deltar2 <= -PI)        deltar2+= PIx2;
00651         Ematrix Q(3,3);
00652         Q.set(0,0, pow(alfa1*fabs(deltar1) + alfa2*deltat                   ,2));
00653         Q.set(1,1, pow(alfa3*deltat        + alfa4*(fabs(deltar1+deltar2))  ,2));
00654         Q.set(2,2, pow(alfa1*fabs(deltar2) + alfa2*deltat                   ,2));
00655         return Q;
00656 }
00657 
00658 // Motion model
00659 matrix EKFilter::motionModel (const pose& pos, const pose& deltaOdo, float thetaodo){
00660         float deltatrans = sqrt((deltaOdo.x*deltaOdo.x+deltaOdo.y*deltaOdo.y));
00661         float aux = atan2(deltaOdo.y,deltaOdo.x) - thetaodo + pos.th;
00662         if      (aux>PI)                aux-= PIx2;
00663         else if (aux <= -PI)            aux+= PIx2;
00664 //      float aux = deltaOdo.th/2+pos.th; /// OJO ESTO PODRIA ESTAR MAL!!!! pag 134 prob robotics eqs 2 3 4
00665 //      printf("aux1 = %15.15f, aux2 = %15.15f ", aux, aux2);
00666 //      if (fabs(aux - aux2) > 0.000000001) printf(" >>>>>>>>>>> SON DISTINTOS!!!!!!\n");
00667 //      else printf("ok\n");
00668         matrix X(3,1);
00669         X.set(0,0,deltatrans*cos(aux)+pos.x);
00670         X.set(1,0,deltatrans*sin(aux)+pos.y);
00671         X.set(2,0,pos.th+deltaOdo.th);
00672         if (X.get(2,0)>PI)                      X.set(2,0,X.get(2,0)- PIx2);
00673         else if (X.get(2,0) <= -PI)             X.set(2,0,X.get(2,0)+ PIx2);
00674         return X;
00675 }
00676 
00677 // jacobian F
00678 matrix EKFilter::jacobianF(const pose& pos, const pose& deltaOdo, float thetaodo){
00679         float deltatrans = sqrt((deltaOdo.x*deltaOdo.x+deltaOdo.y*deltaOdo.y));
00680         float aux = atan2(deltaOdo.y,deltaOdo.x) - thetaodo + pos.th;
00681         if      (aux>PI)                aux-= PIx2;
00682         else if (aux <= -PI)            aux+= PIx2;
00683 //      float aux = deltaOdo.th/2+pos.th; /// OJO ESTO PODRIA ESTAR MAL!!!! pag 134 prob robotics eqs 2 3 4
00684         matrix F(3,3);
00685         F.set(0,0,1);
00686         F.set(0,2,-deltatrans*sin(aux));
00687         F.set(1,1,1);
00688         F.set(1,2, deltatrans*cos(aux));
00689         F.set(2,2,1);
00690         return F;
00691 }
00692 
00693 // jacobian G
00694 Ematrix EKFilter::jacobianG(const pose& pos, const pose& deltaOdo, float thetaodo){
00695         float deltatransm = sqrt((deltaOdo.x*deltaOdo.x+deltaOdo.y*deltaOdo.y));
00696         float aux = atan2(deltaOdo.y,deltaOdo.x) - thetaodo + pos.th;
00697         if      (aux>PI)                aux-= PIx2;
00698         else if (aux <= -PI)            aux+= PIx2;
00699 //      float aux = deltaOdo.th/2+pos.th; /// OJO ESTO PODRIA ESTAR MAL!!!! pag 134 prob robotics eqs 2 3 4
00700         Ematrix G(3,3,3+3*nmarks,3);
00701 //      Ematrix G(3,2,3+3*nmarks,2);
00702         G.set(0,0,-deltatransm*sin(aux));
00703         G.set(0,1, cos(aux));
00704         G.set(1,0, deltatransm*cos(aux));
00705         G.set(1,1, sin(aux));
00706         G.set(2,0,1);
00707         G.set(2,2,1);
00708         return G;
00709 }
00710 
00711 // jacobian H
00712 matrix EKFilter::jacobianH1(const pose& pos, const pos3d& mark){
00713         matrix H(3,3);
00714         float costh = (float)cos(pos.th);
00715         float sinth = (float)sin(pos.th);
00716         float auxx = mark.getX() - pos.x;
00717         float auxy = mark.getY() - pos.y;
00718         H.set(0,0,-costh);
00719         H.set(0,1,-sinth);
00720         H.set(0,2,-(auxx)*sinth + (auxy)*costh );
00721         H.set(1,0, sinth);
00722         H.set(1,1,-costh);
00723         H.set(1,2,-(auxx)*costh - (auxy)*sinth );
00724         return H;
00725 }
00726 
00727 matrix EKFilter::jacobianH2(const pose& pos){
00728         matrix H(3,3);
00729         float costh = (float)cos(pos.th);
00730         float sinth = (float)sin(pos.th);
00731         H.set(0,0,costh);
00732         H.set(0,1,sinth);
00733         H.set(1,0,-sinth);
00734         H.set(1,1,costh);
00735         H.set(2,2,1.0f);
00736         return H;
00737 }
00738 
00739 // jacobian J1
00740 matrix EKFilter::jacobianJ1(const pose& pos, const pos3d& mark){
00741         matrix J1(3,3);
00742         float costh = (float)cos(pos.th);
00743         float sinth = (float)sin(pos.th);
00744         pos3d p = vmap->cam2base(mark);
00745         J1.set(0,0,1);
00746         J1.set(0,2,-p.getX()*sinth - p.getY()*costh);
00747         J1.set(1,1,1);
00748         J1.set(1,2, p.getX()*costh - p.getY()*sinth);
00749         J1.set(2,2,1);
00750         return J1;
00751 }
00752 
00753 // asociacion de datos
00754 landmark* EKFilter::dataAssociation(const matrix& ZT, const matrix& Rt, const pos3d& globalpos, const pose& robotPos, const matrix& H2, const matrix& H2trans, const float* desc, const Ematrix& Pcomp, int r) {
00755         float minDist=descTh, dist;
00756         float maxDist=mahTh;
00757         //landmark* res = 0;
00758         landmark* tmpmark = 0;
00759         int markid=-1;
00760 //      printf("Comienzo asociacion de datos>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
00761         for (int i = 0; i< vmap->getNLandmarks(); i++){
00762                 tmpmark = vmap->getLandmarkById(i);
00763         //      if (sqrt( pow(tmpmark->pos.getX()-globalpos.getX(),2)+ pow(tmpmark->pos.getY()-globalpos.getY(),2))<range){ 
00764                         
00765                         matrix H(3,6);
00766                         H.set(0,0,jacobianH1(robotPos,tmpmark->pos));
00767                         H.set(0,3,H2);
00768                         matrix Htrans = H.transpose();
00769                         matrix P(6,6);
00770                         
00771                         P.set(0,0,Pcomp.subMat(r*3,r*3+3,r*3,r*3+3));
00772                         P.set(0,3,Pcomp.subMat(r*3,r*3+3,3*nBots+i*3,3*nBots+i*3+3));
00773                         P.set(3,0,Pcomp.subMat(3*nBots+i*3,3*nBots+i*3+3,r*3,r*3+3));
00774                         P.set(3,3,Pcomp.subMat(3*nBots+i*3,3*nBots+i*3+3,3*nBots+i*3,3*nBots+i*3+3));
00775 
00776                         matrix zgorro   = vmap->base2cam(global2base(tmpmark->pos, robotPos));
00777                         matrix In               = ZT - zgorro;
00778                         matrix Z                = (H*(P*(Htrans))) + Rt; /////////////////////////////////////////////////////////////
00779 
00780                         //float pmatch =  exp(-0.5*vmap->mahalanobis(In.toPos3d(), Z)) /(sqrt((Z*PIx2).det()));                 
00781                         float pmatch =  vmap->mahalanobis(In.toPos3d(), Z);                     
00782                         if (tmpmark->descriptor[0]==desc[0]){
00783                                 if (pmatch > maxCorrect){
00784                                         maxCorrect = pmatch;
00785 /*                                      printf("Desc %f\n",desc[0]);
00786                                         printf("match = %f\n",pmatch);
00787                                         globalpos.print("new estimated pos=");
00788                                         tmpmark->pos.print("map position=");
00789                                         robotPos.print("robot pose=");
00790                                         ZT.print("ZT=");
00791                                         zgorro.print("zgorro=");
00792                                         P.print("P=");
00793                                         Rt.print("Rt=");
00794                                         H.print("H=");
00795                                         In.print("IN=");
00796                                         Z.print("Z=");
00797 */                              }
00798                         }
00799                         else{
00800                                 if (pmatch < minIncorrect){
00801                                         minIncorrect = pmatch;
00802 /*                                      printf("Desc %f\n",desc[0]);
00803                                         globalpos.print("new estimated pos=");
00804                                         tmpmark->pos.print("map position=");
00805                                         robotPos.print("robot pose=");
00806                                         ZT.print("ZT=");
00807                                         zgorro.print("zgorro=");
00808                                         P.print("P=");
00809                                         Rt.print("Rt=");
00810                                         H.print("H=");
00811                                         In.print("IN=");
00812                                         Z.print("Z=");
00813 */                              }
00814                         }
00815                         //printf("maxCorrect=%f, minIncorrect = %f\n",maxCorrect,minIncorrect);
00816                         if ( pmatch < mahTh){                                                   // check mahalanobis
00817                                 dist = visualMap::descDist(tmpmark->descriptor, desc, tmpmark->desclength);
00818                                 if (dist < descTh){             // get the minor descriptor distance but bigger than descTh
00819                                         if (nearestNeighbourOrderBy == 0){ // nearest desc
00820                                                 if(dist < minDist){ 
00821                                                         markid = i;
00822                                                         minDist = dist;
00823                                                 }       
00824                                         }
00825                                         else{                                                           // nearest mahalanobis
00826                                                 if(pmatch < maxDist){ 
00827                                                         markid = i;
00828                                                         maxDist = pmatch;
00829                                                 }
00830                                         }
00831                                 }
00832                         }
00833                 //}
00834                 delete tmpmark; tmpmark=0;
00835         }
00836         //printf("fin de la asociacion de datos\n");
00837         landmark* match = 0;
00838         if (markid>=0){
00839                 match = vmap->getLandmarkById(markid);
00840                 //if (desc[0]!= match->descriptor[0]) printf("DATA ASSOCIATION ERRORRR!!!!!!!!!!!\n");
00841         }
00842         //printf("Fin asociacion de datos>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
00843 
00844         return (markid>=0)? match:0;
00845 }
00846 
00847 
00848 // evaluates the uncertainty on the position of each robot
00849 void EKFilter::evalDisp(int r){
00850         matrix covariance = getCovariance(r);
00851 
00852         CvMat* cov = cvCreateMat(2,2,CV_32FC1);
00853         CvMat* evects = cvCreateMat(2,2,CV_32FC1);
00854         CvMat* evals = cvCreateMat(2,1,CV_32FC1);
00855         cvmSet(cov,0,0, covariance(0,0));
00856         cvmSet(cov,0,1, covariance(0,1));
00857         cvmSet(cov,1,0, covariance(1,0));
00858         cvmSet(cov,1,1, covariance(1,1));
00859 
00860         cvEigenVV( cov, evects, evals, DBL_EPSILON);
00861 
00862         float a = 3*sqrt(cvmGet(evals,0,0));
00863         float b = 3*sqrt(cvmGet(evals,1,0));
00864         if (a != a) a = 0.0f;
00865         if (b != b) b = 0.0f;
00866 
00867         cvReleaseMat(&cov);
00868         cvReleaseMat(&evects);
00869         cvReleaseMat(&evals);
00870 
00871         dispRobot[r] = PI*a*b;
00872 
00873         if (badlocalized[r] == false && dispRobot[r]>th_high)   badlocalized[r] = true;
00874         if (badlocalized[r] == true && dispRobot[r]<th_low)     badlocalized[r] = false;
00875 }
00876 
00877 float EKFilter::evalUncertainty(){
00878 /*
00879         CvMat* cov = cvCreateMat(covariance.getNumRows(),covariance.getNumCols(),CV_32FC1);
00880         CvMat* evects = cvCreateMat(covariance.getNumRows(),covariance.getNumCols(),CV_32FC1);
00881         CvMat* evals = cvCreateMat(1,covariance.getNumCols(),CV_32FC1);
00882         for (int i = 0 ; i < covariance.getNumRows(); i++)
00883                 for (int j = 0 ; j < covariance.getNumCols(); j++)
00884                         cvmSet(cov,i,j, covariance(i,j));
00885 
00886         cvEigenVV( cov, evects, evals, DBL_EPSILON);
00887 */
00888         float trace = 0;
00889         //list<float> eigenvalues;
00890         //determinante = 0.0;
00891         for (int i = 0; i < covariance.getNumRows(); i++){
00892                 trace += covariance(i,i);
00893                 //determinante += log(cvmGet(evals,0,i));
00894                 //eigenvalues.push_back(cvmGet(evals,0,i));
00895         }
00896         trace /= covariance.getNumRows();
00897         //determinante -= log((float)covariance.getNumRows());
00898 
00899         //eigenvalues.sort();
00900         //mediana = 0.0f;
00901         //for (unsigned int v = 0; v < eigenvalues.size()/2; v++) eigenvalues.pop_back();
00902         //mediana = eigenvalues.back();
00903 
00904         //cvReleaseMat(&cov);
00905         //cvReleaseMat(&evects);
00906         //cvReleaseMat(&evals);
00907 
00908         return trace;
00909 }
00910 
00911 
00912 
00913 // maps
00914 gridMapInterface* EKFilter::getOMap() {
00915         return omap->clone();
00916 }
00917 
00918 visualMap* EKFilter::getVMap() {
00919         return vmap->clone();
00920 }
00921 
00922 binMap* EKFilter::getPreMap() {
00923         return new binMap(*ppmap);      
00924 }
00925 
00926 binMap* EKFilter::getImpMap() {
00927         return new binMap(*ipmap);
00928 }
00929 
00930 /// returns the matrix that represents the covariance of robots and marks
00931 Ematrix EKFilter::getGlobalCovariance() const{
00932         return(covariance);
00933 };
00934 
00935 /// returns the current pose of the robot
00936 pose EKFilter::getPos(int r){
00937         return state.subMat(r*3,r*3+2,0,0).toPose();
00938 }
00939 
00940 /// returns the current cell of the robot
00941 point EKFilter::getCell(int robot){
00942         return robotcells[robot];
00943 }
00944 
00945 /// returns the matrix that represents the covariance of the position of the robot
00946 matrix EKFilter::getCovariance(int r) const{
00947         return covariance.subMat(r*3,r*3+2,r*3,r*3+2);
00948 }
00949 
00950 /// returns a measure of the dispersion of the robot
00951 float EKFilter::getDisp(int r) const{
00952         return dispRobot[r];
00953 }
00954 
00955 void EKFilter::drawPose (IplImage& im, const pose& pos, const matrix& covariance, float xorigin, float yorigin, float resolution) {
00956         
00957         //pos.print("pos=");
00958         //covariance.print("Cov=");
00959         //printf("%e %e %e\n",covariance.get(0,0),covariance.get(1,1),covariance.get(2,2));     
00960         
00961         CvScalar redcolor = CV_RGB(255,0,0);
00962         CvPoint p = cvPoint (   (int) floor ( (pos.x - xorigin)/resolution),                            // posicion
00963                                 (int) (im.height-1-floor((pos.y - yorigin)/resolution)));
00964         CvPoint p2 = cvPoint (  (int) floor ( (pos.x+0.5*cos(pos.th) - xorigin)/resolution),                            // posicion
00965                                 (int) (im.height-1-floor((pos.y+0.5*sin(pos.th) - yorigin)/resolution)));
00966 
00967         CvMat* cov = cvCreateMat(2,2,CV_32FC1);
00968         CvMat* evects = cvCreateMat(2,2,CV_32FC1);
00969         CvMat* evals = cvCreateMat(2,1,CV_32FC1);
00970         cvmSet(cov,0,0, covariance(0,0));
00971         cvmSet(cov,0,1, covariance(0,1));
00972         cvmSet(cov,1,0, covariance(1,0));
00973         cvmSet(cov,1,1, covariance(1,1));
00974 
00975         cvEigenVV( cov, evects, evals, DBL_EPSILON);
00976 
00977         float a = 3*sqrt(cvmGet(evals,0,0));
00978         float b = 3*sqrt(cvmGet(evals,1,0));
00979         float alfa;
00980 
00981         if (a != a) a = 0.0f;
00982         if (b != b) b = 0.0f;
00983         if (a<b){
00984                 float tmp = a;
00985                 a = b;
00986                 b = tmp;
00987                 alfa = 180.0f/PI*atan2(cvmGet(evects,0,0),cvmGet(evects,0,1));
00988         }
00989         else    alfa = 180.0f/PI*atan2(cvmGet(evects,0,1),cvmGet(evects,0,0));
00990 
00991         //printf("a= %f, b=%f\n",a,b);
00992 
00993         int ia = (int)floor(a/resolution+0.5);
00994         int ib = (int)floor(b/resolution+0.5);
00995         
00996         if (ia >= 0 && ia < im.width && ib >= 0 && ib < im.width){
00997                 cvEllipse(&im, p, cvSize(ia,ib), alfa, 0, 360, redcolor, CV_FILLED );
00998         }
00999 
01000 //      cvLine(&im, p, p2,  cvScalar(255,0,0), 1);
01001 
01002 
01003         cvReleaseMat(&cov);
01004         cvReleaseMat(&evects);
01005         cvReleaseMat(&evals);
01006 
01007 }
 All Classes Functions Variables Typedefs