MRXT: The Multi-Robot eXploration Tool
Multi-Robot autonomous exploration and mapping simulator.
|
00001 /* 00002 * 00003 * Author: Miguel Julia <mjulia@umh.es> 00004 * 00005 * Date: 2008 00006 * 00007 * Class visualMap 00008 * 00009 * Implements a visual landmark 3d map 00010 * 00011 */ 00012 00013 #include "vMapArray.h" 00014 #include <stdlib.h> 00015 #include <stdio.h> 00016 #include <assert.h> 00017 #include "matFuns.h" 00018 00019 namespace{ 00020 visualMap* CreateVMapArray(int n, const ConfigFile& configFile){ 00021 return new vMapArray(n,configFile); 00022 }; 00023 const int VMAPARRAY = 0; 00024 const bool registered = visualMapFactory::Instance().Register(VMAPARRAY, visualMapCreator(CreateVMapArray)); 00025 } 00026 00027 // Constructor 00028 vMapArray::vMapArray(): 00029 visualMap(), 00030 nMarksReserved(0), 00031 lastRetId(-1), 00032 landmarks(0) 00033 { 00034 00035 } 00036 00037 // Constructor 00038 vMapArray::vMapArray(int n, const ConfigFile& configFile): 00039 visualMap(n,configFile), 00040 nMarksReserved(n), 00041 lastRetId(-1), 00042 landmarks(new landmark[n]()) 00043 { 00044 00045 } 00046 00047 // copy constructor 00048 vMapArray::vMapArray(const vMapArray &map): 00049 visualMap(map), 00050 nMarksReserved(map.nMarksReserved), 00051 lastRetId(map.lastRetId), 00052 landmarks(new landmark[map.nMarksReserved]()) 00053 { 00054 for (int i = 0; i < nlandmarks; i++) 00055 landmarks[i] = map.landmarks[i]; 00056 } 00057 00058 // destructor 00059 vMapArray::~vMapArray(){ 00060 if (landmarks) delete[] landmarks; 00061 } 00062 00063 // initializer 00064 void vMapArray::initialize(int n, const ConfigFile& configFile){ 00065 visualMap::initialize(n,configFile); 00066 if (landmarks) delete[] landmarks; 00067 landmarks = new landmark[n](); 00068 nMarksReserved = n; 00069 lastRetId = -1; 00070 } 00071 00072 // assignment operator 00073 vMapArray& vMapArray::operator=(const visualMap& vmap){ 00074 assert(typeid(vmap) == typeid(*this)); 00075 const vMapArray& map = dynamic_cast<const vMapArray&>(vmap); 00076 visualMap::operator=(vmap); 00077 00078 if (nMarksReserved != map.nMarksReserved){ 00079 nMarksReserved = map.nMarksReserved; 00080 if (landmarks) delete[] landmarks; 00081 landmarks = new landmark[nMarksReserved](); 00082 } 00083 for (int i = 0; i < nlandmarks; i++) 00084 landmarks[i] = map.landmarks[i]; 00085 00086 return *this; 00087 } 00088 00089 // Data functions 00090 void vMapArray::addLandmark(const landmark& mark){ 00091 if (nlandmarks < nMarksReserved){ 00092 landmarks[nlandmarks] = mark; 00093 nlandmarks++; 00094 } 00095 } 00096 00097 void vMapArray::changeLastReturnedLandmark(const landmark& mark){ 00098 if (lastRetId>=0) landmarks[lastRetId] = mark; 00099 00100 } 00101 00102 void vMapArray::changeLandmark(int id, const landmark& mark){ 00103 if (id>=0) landmarks[id] = mark; 00104 } 00105 00106 // get landmark by index 00107 landmark* vMapArray::getLandmarkById(int n) { 00108 if (n<nlandmarks){ 00109 lastRetId = n; 00110 return new landmark (landmarks[n]); 00111 } 00112 else{ 00113 lastRetId = -1; 00114 return 0; 00115 } 00116 } 00117 00118 // get landmark by descriptor 00119 landmark* vMapArray::getLandmarkByDesc(const float* desc) { 00120 const landmark* landres=0; 00121 lastRetId = -1; 00122 for (int i = 0; i< nlandmarks; i++){ 00123 if (descDist(landmarks[i].descriptor,desc,landmarks[i].desclength)<descTh){ 00124 landres = &landmarks[i]; 00125 lastRetId = i; 00126 } 00127 } 00128 return (landres)? new landmark(*landres) : 0; 00129 } 00130 00131 // asociacion de datos 00132 landmark* vMapArray::dataAssociation(const matrix& ZT, const matrix& Rt, const pos3d& globalpos, const pose& robotPos, const matrix& H, const matrix& Htrans, const float* desc) { 00133 float minDist=1000.0f, dist; 00134 lastRetId = -1; 00135 landmark* res = 0; 00136 for (int i = 0; i< nlandmarks; i++){ 00137 // if (sqrt( pow(landmarks[i].pos.getX()-globalpos.getX(),2)+ pow(landmarks[i].pos.getY()-globalpos.getY(),2))<range){ 00138 00139 matrix zgorro = base2cam(global2base(landmarks[i].pos, robotPos)); 00140 matrix In = ZT - zgorro; 00141 matrix Z = (H*(landmarks[i].covariance*(Htrans))) + Rt; 00142 00143 float pmatch = exp(-0.5*mahalanobis(In.toPos3d(), Z));// /(sqrt((Z*PIx2).det())); 00144 00145 if ( pmatch > mahTh){ // check mahalanobis 00146 dist = visualMap::descDist(landmarks[i].descriptor, desc, landmarks[i].desclength); 00147 if (dist < minDist && dist < descTh){ // get the minor descriptor distance but bigger than descTh 00148 lastRetId = i; 00149 res = &landmarks[i]; 00150 minDist = dist; 00151 } 00152 } 00153 // } 00154 } 00155 return (res)? new landmark(*res):0; 00156 } 00157 00158 void vMapArray::clear(){ 00159 nlandmarks=0; 00160 } 00161 00162 void vMapArray::saveMap(const char* str) { 00163 char mystr[50]; 00164 sprintf(mystr,"%s.m",str); 00165 FILE * outfile = fopen( mystr, "w" ); 00166 fprintf(outfile,"landmarks_map=[",str); 00167 for(int i = 0; i < nlandmarks; i++) 00168 fprintf(outfile, "%e,%e,%e,%e,%e,%e,%e,%e,%e,%e,%e,%e,%f\n",landmarks[i].pos.getX(), landmarks[i].pos.getY(), landmarks[i].pos.getZ(), 00169 landmarks[i].covariance(0,0), landmarks[i].covariance(0,1), landmarks[i].covariance(0,2), 00170 landmarks[i].covariance(1,0), landmarks[i].covariance(1,1), landmarks[i].covariance(1,2), 00171 landmarks[i].covariance(2,0), landmarks[i].covariance(2,1), landmarks[i].covariance(2,2), 00172 landmarks[i].descriptor[0]); 00173 fprintf(outfile,"];"); 00174 fclose(outfile); 00175 } 00176 00177 void vMapArray::drawMarks (IplImage& im, float xorigin, float yorigin, float resolution) { 00178 00179 //printf("nland: %d\n",getNLandmarks()); 00180 CvScalar greencolor = CV_RGB(0,255,0); 00181 for (int l=0; l<nlandmarks; l++){ 00182 CvPoint p = cvPoint ((int) floor ( (landmarks[l].pos.getX() - xorigin)/resolution), // posicion 00183 (int) (im.height-1-floor((landmarks[l].pos.getY() - yorigin)/resolution))); 00184 /* 00185 CvMat* cov = cvCreateMat(3,3,CV_32FC1); 00186 CvMat* evects = cvCreateMat(3,3,CV_32FC1); 00187 CvMat* evals = cvCreateMat(1,3,CV_32FC1); 00188 cvmSet(cov,0,0, landmarks[l].covariance(0,0)); 00189 cvmSet(cov,0,1, landmarks[l].covariance(0,1)); 00190 cvmSet(cov,0,2, landmarks[l].covariance(0,2)); 00191 cvmSet(cov,1,0, landmarks[l].covariance(1,0)); 00192 cvmSet(cov,1,1, landmarks[l].covariance(1,1)); 00193 cvmSet(cov,1,2, landmarks[l].covariance(1,2)); 00194 cvmSet(cov,2,0, landmarks[l].covariance(2,0)); 00195 cvmSet(cov,2,1, landmarks[l].covariance(2,1)); 00196 cvmSet(cov,2,2, landmarks[l].covariance(2,2)); 00197 cvEigenVV( cov, evects, evals, DBL_EPSILON); 00198 */ 00199 CvMat* cov = cvCreateMat(2,2,CV_32FC1); 00200 CvMat* evects = cvCreateMat(2,2,CV_32FC1); 00201 CvMat* evals = cvCreateMat(2,1,CV_32FC1); 00202 cvmSet(cov,0,0, landmarks[l].covariance(0,0)); 00203 cvmSet(cov,0,1, landmarks[l].covariance(0,1)); 00204 cvmSet(cov,1,0, landmarks[l].covariance(1,0)); 00205 cvmSet(cov,1,1, landmarks[l].covariance(1,1)); 00206 cvEigenVV( cov, evects, evals, DBL_EPSILON); 00207 00208 float a = 3*sqrt(cvmGet(evals,0,0)); 00209 float b = 3*sqrt(cvmGet(evals,1,0)); 00210 float alfa; 00211 if (a != a) a = 0.0f; 00212 if (b != b) b = 0.0f; 00213 00214 if (a>b){ 00215 float tmp = a; 00216 a = b; 00217 b = tmp; 00218 alfa = 180.0f/PI*atan2(cvmGet(evects,0,0),cvmGet(evects,0,1)); 00219 } 00220 else 00221 alfa = 180.0f/PI*atan2(cvmGet(evects,0,1),cvmGet(evects,0,0)); 00222 00223 cvReleaseMat(&cov); 00224 cvReleaseMat(&evects); 00225 cvReleaseMat(&evals); 00226 00227 int ia = (int)(a/resolution); 00228 int ib = (int)(b/resolution); 00229 00230 if (ia >= 0 && ia < im.width && ib >= 0 && ib < im.width){ 00231 cvEllipse(&im, p, cvSize(ia,ib), alfa, 0, 360, greencolor, CV_FILLED ); 00232 } 00233 } 00234 }