MRXT: The Multi-Robot eXploration Tool
Multi-Robot autonomous exploration and mapping simulator.
|
00001 #include "simulatedModel.h" 00002 #include "ConfigFile.h" 00003 #include "StringTokenizer.h" 00004 #include <iostream> 00005 #include "matFuns.h" 00006 #ifndef WIN32 00007 #include <sys/time.h> 00008 #include <pthread.h> 00009 #endif 00010 #include <QDir> 00011 00012 #ifdef WIN32 00013 #include <direct.h> // getcwd() gets current working dir 00014 #endif 00015 00016 #define MAXACQUIREDLANDMARKS 60 00017 00018 //TODO: Hacer el numero de robots dinámico a medida que llegan getids() 00019 00020 simulatedModel::simulatedModel(): 00021 nBots(0), 00022 maxNumRobots(0), 00023 step(0), 00024 rsData(0), 00025 lmData(0), 00026 odo(0), 00027 gt(0), 00028 lastodo(0), 00029 lastgt(0), 00030 rbase(0), 00031 robotsEnabled(0), 00032 velo(0), 00033 logstr(0), 00034 alfa1(0.0f), 00035 alfa2(0.0f), 00036 alfa3(0.0f), 00037 alfa4(0.0f), 00038 drifttrans(1.0f), 00039 imgwidth(0), 00040 imgheight(0), 00041 f(0.0f), 00042 I(0.0f), 00043 sigma2r(0.0f), 00044 sigma2c(0.0f), 00045 sigma2cp(0.0f), 00046 sigmar(0.0f), 00047 sigmac(0.0f), 00048 sigmacp(0.0f), 00049 betaMAX(0.0f), 00050 gammaMAX(0.0f), 00051 distMAX(0.0f), 00052 distMIN(0.0f), 00053 camx(0.0), 00054 camy(0.0), 00055 camz(0.0), 00056 rx(0.0), 00057 ry(0.0), 00058 rz(0.0), 00059 sample_time(0.0f), 00060 numSensors(0), 00061 devError(0.0f), 00062 realError(0.0f), 00063 gammamax(0.0f), 00064 aperture(0.0f), 00065 maxDist(0.0f), 00066 minDist(0.0f), 00067 //robots_lines(0), 00068 endth(true), 00069 idCounter(0), 00070 Scam(9,9), 00071 width(0), 00072 height(0), 00073 showsimulation(false), 00074 // groupInitialPoses (false), 00075 // maxInitialPoseDist (0), 00076 numfeat (0), 00077 mapLoaded(false), 00078 omap(0), 00079 omapfilename(new char[50]) 00080 { 00081 printf("[SIM] Default simulated model created\n"); 00082 } 00083 00084 simulatedModel::simulatedModel(int b, ConfigFile& config, float sampletime): 00085 nBots (b), 00086 maxNumRobots (config.read<int>("MAXNUMROBOTS")), 00087 step (0), 00088 rsData (new rangeSensorData[maxNumRobots]), 00089 lmData (new landmarksData[maxNumRobots]), 00090 odo (new pose[maxNumRobots]), 00091 gt (new pose[maxNumRobots]), 00092 lastodo (new pose[maxNumRobots]), 00093 lastgt (new pose[maxNumRobots]), 00094 rbase (new robotBase*[maxNumRobots]), 00095 robotsEnabled (new bool[maxNumRobots]), 00096 velo (new speed[maxNumRobots]), 00097 logstr (0), 00098 alfa1 (config.read<float>("alfa1")), 00099 alfa2 (config.read<float>("alfa2")), 00100 alfa3 (config.read<float>("alfa3")), 00101 alfa4 (config.read<float>("alfa4")), 00102 drifttrans (1.0), 00103 00104 imgwidth (config.read<int>("WIDTH")), 00105 imgheight (config.read<int>("HEIGHT")), 00106 00107 sigma2f (0.0), 00108 sigmaf (0.0), 00109 f (config.read<float>("f")), 00110 Realf (normrnd(f,sigmaf)), 00111 00112 sigma2I (0.0), 00113 sigmaI (0.0), 00114 I (config.read<float>("I")), 00115 RealI (normrnd(I,sigmaI)), 00116 00117 sigma2Cx (0.0), 00118 sigmaCx (0.0), 00119 Cx (imgwidth/2.0), 00120 RealCx (normrnd(Cx,sigmaCx)), 00121 00122 sigma2Cy (0.0), 00123 sigmaCy (0.0), 00124 Cy (imgheight/2.0), 00125 RealCy (normrnd(Cy,sigmaCy)), 00126 00127 sigma2Cxp (0.0), 00128 sigmaCxp (0.0), 00129 Cxp (imgwidth/2.0), 00130 RealCxp (normrnd(Cxp,sigmaCxp)), 00131 00132 sigmar (config.read<float>("sigmar")), 00133 sigmac (config.read<float>("sigmac")), 00134 sigmacp (0.0), 00135 sigmad (config.read<float>("sigmad")), 00136 sigma2r (pow(sigmar,2)), 00137 sigma2c (pow(sigmac,2)), 00138 sigma2cp (0.0), 00139 sigma2d (pow(sigmad,2)), 00140 00141 betaMAX (atan2(Cy,f)), 00142 gammaMAX (atan2(Cx,f)), 00143 00144 distMAX (config.read<float>("distMAX")), 00145 distMIN (config.read<float>("distMIN")), 00146 camx (config.read<float>("camx")), 00147 camy (config.read<float>("camy")), 00148 camz (config.read<float>("camz")), 00149 rx (0.0), 00150 ry (0.0), 00151 rz (0.0), 00152 00153 numSensors (config.read<int>("NUMPOINTS")), 00154 devError (config.read<float>("LASERSIGMA")), 00155 realError (devError), 00156 gammamax (config.read<float>("LASERMAXANGLE")*PI/180.0), 00157 aperture (0.0), 00158 maxDist (config.read<float>("LASERMAXDIST")), 00159 minDist (config.read<float>("LASERMINDIST")), 00160 sample_time (sampletime), 00161 //robots_lines (new std::vector<line>[nBots]), 00162 endth (true), 00163 idCounter (0), 00164 Scam (9,9), 00165 // width (config.read<int>("SIMULATORWIDTH")), 00166 // height (config.read<int>("SIMULATORHEIGHT")), 00167 width (800), 00168 height (600), 00169 // showsimulation (config.read<bool>("SHOWSIMULATION")), 00170 showsimulation (false), 00171 //groupInitialPoses (false), 00172 //maxInitialPoseDist (0), 00173 numfeat (0), 00174 mapLoaded (false), 00175 omap (0), 00176 omapfilename (new char[50]) 00177 { 00178 robots_lines.reserve(maxNumRobots); 00179 00180 string robotpos = config.read<string>("FOOTPRINT"); 00181 StringTokenizer st(&robotpos[0]); 00182 robot_footprint.clear(); 00183 for (int t = 0; t < st.countTokens(); t++){ 00184 float pt = atof(st.nextToken()); 00185 robot_footprint.push_back(pt); 00186 } 00187 00188 // Matriz de covarianza del sensor 00189 Scam.set(0,0,sigma2c); // S = [sigma2c 0 0 0 0 0 0 0 ] 00190 Scam.set(1,1,sigma2r); // [ 0 sigma2r 0 0 0 0 0 0 ] 00191 Scam.set(2,2,sigma2cp); // [ 0 0 sigma2cp 0 0 0 0 0 ] 00192 Scam.set(3,3,sigma2Cx); // [ 0 0 0 sigma2Cx 0 0 0 0 ] 00193 Scam.set(4,4,sigma2Cy); // [ 0 0 0 0 sigma2Cy 0 0 0 ] 00194 Scam.set(5,5,sigma2Cxp);// [ 0 0 0 0 0 sigma2Cxp 0 0 ] 00195 Scam.set(6,6,sigma2f); // [ 0 0 0 0 0 0 sigma2f 0 ] 00196 Scam.set(7,7,sigma2I); // [ 0 0 0 0 0 0 0 sigma2I ] 00197 Scam.set(8,8,sigma2d); 00198 00199 robots_lines.clear(); 00200 00201 for (int r=0; r<maxNumRobots; r++){ 00202 std::vector<line> v(robot_footprint.size()); 00203 robots_lines.push_back(v); 00204 } 00205 00206 reset(); 00207 00208 loadMapFile(config); 00209 00210 printf("[SIM] simulation model created\n"); 00211 } 00212 00213 void simulatedModel::reset(){ 00214 00215 idCounter=0; 00216 00217 for (int r=0; r<maxNumRobots; r++){ 00218 rsData[r].initialize(numSensors, devError, gammamax, aperture, maxDist, minDist); 00219 rbase[r] = 0; 00220 lmData[r].reserve(MAXACQUIREDLANDMARKS); 00221 robotsEnabled[r]=true; 00222 } 00223 } 00224 00225 void simulatedModel::setNumRobots(int n){ 00226 nBots = n; 00227 reset(); 00228 } 00229 00230 simulatedModel::~simulatedModel(){ 00231 stop(); 00232 if (rsData) delete[] rsData; 00233 if (lmData) delete[] lmData; 00234 if (odo) delete[] odo; 00235 if (gt) delete[] gt; 00236 if (lastodo) delete[] lastodo; 00237 if (lastgt) delete[] lastgt; 00238 if (velo) delete[] velo; 00239 if (logstr) delete[] logstr; 00240 if (rbase) delete[] rbase; 00241 if (robotsEnabled) delete[] robotsEnabled; 00242 if (omap) delete omap; 00243 if (omapfilename) delete[] omapfilename; 00244 00245 printf("[SIM] Simulation ended\n"); 00246 } 00247 00248 // initializer 00249 void simulatedModel::initialize(int b, ConfigFile& config, float sampletime){ 00250 00251 printf("initializing simulation model...\n"); 00252 nBots = b; 00253 maxNumRobots = config.read<int>("MAXNUMROBOTS"); 00254 step = 0; 00255 if (rsData) delete[] rsData; 00256 rsData = new rangeSensorData[maxNumRobots]; 00257 if (lmData) delete[] lmData; 00258 lmData = new landmarksData[maxNumRobots]; 00259 if (odo) delete[] odo; 00260 odo = new pose[maxNumRobots]; 00261 if (gt) delete[] gt; 00262 gt = new pose[maxNumRobots]; 00263 if (lastodo) delete[] lastodo; 00264 lastodo = new pose[maxNumRobots]; 00265 if (lastgt) delete[] lastgt; 00266 lastgt = new pose[maxNumRobots]; 00267 if (velo) delete[] velo; 00268 velo = new speed[maxNumRobots]; 00269 if (logstr) delete[] logstr; 00270 logstr = 0; 00271 if (rbase) delete[] rbase; 00272 rbase = new robotBase*[maxNumRobots]; 00273 if (robotsEnabled) delete[] robotsEnabled; 00274 robotsEnabled = new bool[maxNumRobots]; 00275 if (omap) delete omap; 00276 omap = 0; 00277 if (omapfilename) delete[] omapfilename; 00278 omapfilename = new char[50]; 00279 00280 alfa1 = config.read<float>( "alfa1" ); 00281 alfa2 = config.read<float>( "alfa2" ); 00282 alfa3 = config.read<float>( "alfa3" ); 00283 alfa4 = config.read<float>( "alfa4" ); 00284 drifttrans = 1.0; 00285 00286 imgwidth = config.read<int>("WIDTH"); 00287 imgheight = config.read<int>("HEIGHT"); 00288 00289 sigma2f = 0.0; 00290 sigmaf = 0.0; 00291 f = config.read<float>("f"); 00292 Realf = normrnd(f,sigmaf); 00293 00294 sigma2I = 0.0; 00295 sigmaI = 0.0; 00296 I = config.read<float>("I"); 00297 RealI = normrnd(I,sigmaI); 00298 00299 sigma2Cx = 0.0; 00300 sigmaCx = 0.0; 00301 Cx = imgwidth/2.0; 00302 RealCx = normrnd(Cx,sigmaCx); 00303 00304 sigma2Cy = 0.0; 00305 sigmaCy = 0.0; 00306 Cy = imgheight/2.0; 00307 RealCy = normrnd(Cy,sigmaCy); 00308 00309 sigma2Cxp = 0.0; 00310 sigmaCxp = 0.0; 00311 Cxp = imgwidth/2.0; 00312 RealCxp = normrnd(Cxp,sigmaCxp); 00313 00314 sigmar = config.read<float>("sigmar"); 00315 sigmac = config.read<float>("sigmac"); 00316 sigmacp = 0.0; 00317 sigmad = config.read<float>("sigmad"); 00318 sigma2r = pow(sigma2r,2); 00319 sigma2c = pow(sigma2c,2); 00320 sigma2cp = pow(sigma2cp,2); 00321 sigma2d = pow(sigma2d,2); 00322 00323 betaMAX = atan2(Cy,f); 00324 gammaMAX = atan2(Cx,f); 00325 distMAX = config.read<float>( "distMAX" ); 00326 distMIN = config.read<float>( "distMIN" ); 00327 00328 camx = config.read<float>( "camx" ); 00329 camy = config.read<float>( "camy" ); 00330 camz = config.read<float>( "camz" ); 00331 rx = 0.0; 00332 ry = 0.0; 00333 rz = 0.0; 00334 00335 // sonar 00336 numSensors = config.read<int>("NUMPOINTS"); 00337 devError = config.read<float>("LASERSIGMA"); 00338 realError = devError; 00339 gammamax = config.read<float>("LASERMAXANGLE")*PI/180.0; 00340 aperture = 0.0; 00341 maxDist = config.read<float>("LASERMAXDIST"); 00342 minDist = config.read<float>("LASERMINDIST"); 00343 00344 sample_time = sampletime; 00345 00346 //robots_lines = new std::vector<line>[nBots]; 00347 robots_lines.clear(); 00348 robots_lines.reserve(maxNumRobots); 00349 00350 endth =true; 00351 idCounter=0; 00352 00353 // width=config.read<int>("SIMULATORWIDTH"); 00354 // height=config.read<int>("SIMULATORHEIGHT"); 00355 // showsimulation = config.read<bool>("SHOWSIMULATION"); 00356 00357 width=800; 00358 height=600; 00359 showsimulation = false; 00360 00361 //groupInitialPoses=false; 00362 //maxInitialPoseDist=0; 00363 numfeat=0; 00364 mapLoaded=false; 00365 00366 //--------- 00367 00368 string robotpos = config.read<string>("FOOTPRINT"); 00369 StringTokenizer st(&robotpos[0]); 00370 robot_footprint.clear(); 00371 for (int t = 0; t < st.countTokens(); t++){ 00372 float pt = atof(st.nextToken()); 00373 robot_footprint.push_back(pt); 00374 } 00375 00376 for (int r=0; r<maxNumRobots; r++){ 00377 std::vector<line> v(robot_footprint.size()); 00378 robots_lines.push_back(v); 00379 } 00380 00381 reset(); 00382 00383 // Matriz de covarianza del sensor 00384 Scam.clear(); 00385 Scam.set(0,0,sigma2c); // S = [sigma2c 0 0 0 0 0 0 0 ] 00386 Scam.set(1,1,sigma2r); // [ 0 sigma2r 0 0 0 0 0 0 ] 00387 Scam.set(2,2,sigma2cp); // [ 0 0 sigma2cp 0 0 0 0 0 ] 00388 Scam.set(3,3,sigma2Cx); // [ 0 0 0 sigma2Cx 0 0 0 0 ] 00389 Scam.set(4,4,sigma2Cy); // [ 0 0 0 0 sigma2Cy 0 0 0 ] 00390 Scam.set(5,5,sigma2Cxp);// [ 0 0 0 0 0 sigma2Cxp 0 0 ] 00391 Scam.set(6,6,sigma2f); // [ 0 0 0 0 0 0 sigma2f 0 ] 00392 Scam.set(7,7,sigma2I); // [ 0 0 0 0 0 0 0 sigma2I ] 00393 Scam.set(8,8,sigma2d); 00394 00395 loadMapFile(config); 00396 00397 printf("simulated model initialized\n"); 00398 00399 } 00400 00401 void simulatedModel::setLogName(const char* str){ 00402 if (logstr) delete[] logstr; 00403 logstr = new char[strlen(str)+1]; 00404 strcpy(logstr,str); 00405 } 00406 00407 void simulatedModel::update_footprint(int r){ 00408 robots_lines[r].clear(); 00409 int total_lines2 = robot_footprint.size(); 00410 for (int l = 0; l < robot_footprint.size(); l+=2){ 00411 float x1 = robot_footprint[l]; 00412 float y1 = robot_footprint[l+1]; 00413 float x2 = robot_footprint[(l+2)%total_lines2]; 00414 float y2 = robot_footprint[(l+3)%total_lines2]; 00415 line lin( gt[r].x+x1*cos(gt[r].th)-y1*sin(gt[r].th), 00416 gt[r].y+x1*sin(gt[r].th)+y1*cos(gt[r].th), 00417 gt[r].x+x2*cos(gt[r].th)-y2*sin(gt[r].th), 00418 gt[r].y+x2*sin(gt[r].th)+y2*cos(gt[r].th)); 00419 robots_lines[r].push_back(lin); 00420 } 00421 } 00422 00423 int simulatedModel::setup(){ 00424 prio = 50; 00425 return 0; 00426 } 00427 00428 void simulatedModel::onStop(){ 00429 //printf("[SIM] Simulator on stop...\n"); 00430 if(!endth){ 00431 endth = true; 00432 closing.lock(); 00433 closing.unlock(); 00434 } 00435 } 00436 00437 void simulatedModel::execute(){ 00438 printf("[SIM] \t\t\t\t\t\t\t Simulation Running\n"); 00439 closing.lock(); 00440 endth = false; 00441 00442 speed speedconst; 00443 speedconst.v=0.5f; 00444 speedconst.w=0.0f; 00445 00446 for (int r = 0; r< nBots; r++){ 00447 rbase[r]->beginProduction(); 00448 odo[r] = gt[r]; 00449 // printf("[SIM] generating initial state for robot %d...\n",r); 00450 simRangeAdquisition(gt[r], rsData[r],r); // leemos sonar 00451 lmData[r].clear(); 00452 simCamAdquisition(gt[r], lmData[r],r); // leemos landmarks 00453 lastgt[r] = gt[r]; 00454 lastodo[r] = odo[r]; 00455 // printf("[SIM] produced initial state for robot %d\n",r); 00456 rbase[r]->endProduction(); 00457 } 00458 00459 // printf("Parameters>>>>>>\n"); 00460 // printf("f = %f (%f)\n",Realf, f); 00461 // printf("I = %f (%f)\n",RealI, I); 00462 // printf("Cx = %f (%f)\n",RealCx, Cx); 00463 // printf("Cy = %f (%f)\n",RealCy, Cy); 00464 // printf("Cxp = %f (%f)\n",RealCxp, Cxp); 00465 // printf(">>>>>>>>>>>>>>>>>>\n"); 00466 00467 // open the log file 00468 FILE* vworldlog=0; 00469 if (logstr){ 00470 char myfilestr[100]; 00471 sprintf(myfilestr,"%s.m",logstr); 00472 vworldlog = fopen(myfilestr,"w"); 00473 fprintf(vworldlog,"ground_truth = [",logstr); 00474 } 00475 00476 char* wname= "Simulator"; 00477 IplImage* background = 0; 00478 if (showsimulation){ 00479 background = getMapImage(); 00480 cvNamedWindow(wname,0); 00481 } 00482 int capNum=0; 00483 char filestr[100]; 00484 00485 elapsedTime = 0.0f; 00486 int step=1; 00487 do{ 00488 //printf("[SIM] sleeping\n"); 00489 sleepms(100); 00490 for (int r = 0; r< nBots; r++){ 00491 if (robotsEnabled[r]){ 00492 //printf("[SIM] waiting to produce step %d for robot %d...\n", step,r); 00493 rbase[r]->beginProduction(); 00494 //printf("[SIM] generating step %d for robot %d...\n", step,r); 00495 if (robotsEnabled[r]){ 00496 if(step>2) robotMotion(gt[r], velo[r], sample_time); // move robots 00497 update_footprint(r); 00498 //gt[r].print("\t\t\t\t\t\t\t\t\tground truth="); 00499 //robotMotion(gt[r], speedconst, sample_time); // move robots 00500 motionSample(lastgt[r], gt[r], lastodo[r], odo[r]); // leemos odometria 00501 //odo[r].print("\t\t\t\t\t\t\t\t\todo="); 00502 simRangeAdquisition(gt[r], rsData[r],r); // leemos sonar 00503 lmData[r].clear(); 00504 simCamAdquisition(gt[r], lmData[r],r); // leemos landmarks 00505 lastgt[r] = gt[r]; 00506 lastodo[r] = odo[r]; 00507 } 00508 //printf("[SIM] produced data for step %d and robot %d\n",step,r); 00509 } 00510 rbase[r]->endProduction(); 00511 } 00512 step++; 00513 // write logs 00514 if (logstr){ 00515 fprintf(vworldlog,"%f",elapsedTime); 00516 for (int r=0; r<nBots;r++){ 00517 fprintf(vworldlog,", %f, %f, %f",gt[r].x, gt[r].y, gt[r].th); 00518 } 00519 fprintf(vworldlog,"\n"); 00520 } 00521 elapsedTime+=sample_time; 00522 redrawing(); 00523 // if (showsimulation){ 00524 // IplImage* img = cvCloneImage(background); 00525 // drawRobots(img); 00526 // cvShowImage(wname,img); 00527 // int key = cvWaitKey(2); 00528 // if (key=='c'){ 00529 // sprintf(filestr,"simcap%d.png",capNum); 00530 // cvSaveImage(filestr,img); 00531 // capNum++; 00532 // } 00533 // cvReleaseImage(&img); 00534 // } 00535 } while (!endth); 00536 00537 if (showsimulation){ 00538 cvDestroyWindow(wname); 00539 cvReleaseImage(&background); 00540 } 00541 00542 if (logstr){ 00543 fprintf(vworldlog,"];"); 00544 fclose(vworldlog); 00545 // save img 00546 } 00547 00548 //printf("[SIM] closing unlock\n"); 00549 closing.unlock(); 00550 } 00551 00552 // TODO: Include error checking, it is likely to crash with an erroneous map file 00553 void simulatedModel::loadMapFile(const ConfigFile& config){ 00554 printf("[SIM] loading map...\n"); 00555 //ConfigFile config(mapfile); 00556 00557 // initial poses 00558 char entrada[20]; 00559 00560 // walls / obstacles 00561 int numwalls = config.read<int>("NUMWALLS"); 00562 mapWall.clear(); 00563 mapWall.reserve(numwalls); 00564 for (int i = 0; i< numwalls; i++){ 00565 sprintf(entrada,"WALL%i",i+1); 00566 string wallstr = config.read<string>(entrada); 00567 StringTokenizer st(&(wallstr[0])); 00568 float x1 = atof(st.nextToken()); 00569 float y1 = atof(st.nextToken()); 00570 float x2 = atof(st.nextToken()); 00571 float y2 = atof(st.nextToken()); 00572 line wall( x1, y1, x2, y2 ); 00573 mapWall.push_back(wall); 00574 } 00575 00576 // features 00577 numfeat = config.read<int>("NUMFEATURES"); 00578 desclength = config.read<int>("DESCRIPTORLENGTH"); 00579 float* desc = new float[desclength]; 00580 landmarks.clear(); 00581 landmarks.reserve(numfeat); 00582 for (int i = 0; i< numfeat; i++){ 00583 sprintf(entrada,"FEAT%i",i+1); 00584 string featstr = config.read<string>(entrada); 00585 StringTokenizer st(&(featstr[0])); 00586 float x = atof(st.nextToken()); 00587 float y = atof(st.nextToken()); 00588 float z = atof(st.nextToken()); 00589 for (int j=0; j < desclength; j++){ 00590 // desc[j] = atof(st.nextToken()); 00591 desc[j] = i; 00592 } 00593 landmarks.push_back(feature(pos3d(x,y,z),desc,desclength)); 00594 } 00595 delete[] desc; 00596 00597 //initial poses 00598 for (int r = 0; r< maxNumRobots; r++){ 00599 sprintf(entrada,"R%i",r+1); 00600 string robotpos = config.read<string>(entrada); 00601 StringTokenizer st(&robotpos[0]); 00602 00603 float x = atof(st.nextToken()); 00604 float y = atof(st.nextToken()); 00605 float th = atof(st.nextToken()); 00606 pose pos(x,y,th); 00607 odo[r] = pos; 00608 lastodo[r] = pos; 00609 gt[r] = pos; 00610 lastgt[r] = pos; 00611 update_footprint(r); 00612 } 00613 00614 // if (config.read<bool>("RANDOM")){ 00615 if (omap) delete omap; 00616 omap = gridMapFactory::Instance().CreateObject(config.read<int>("GRIDMAPTYPE"),0.0,0.0,0.0,0.0,0.0); 00617 strcpy(omapfilename, ((QDir::homePath()+="/.mrxt/maps/")+=config.read<string>("GRIDMAP").c_str()).toStdString().c_str()); 00618 omap->loadMapFromFile(omapfilename); 00619 // } 00620 00621 // cvNamedWindow("OMAP"); 00622 // omap->showMap("OMAP"); 00623 // cvWaitKey(5000); 00624 00625 // groupInitialPoses = true; //config.read<bool>("GROUPED"); 00626 // maxInitialPoseDist = 6.0/omap->getResolution(); // config.read<float>("MAXGROUPDIST")/omap->getResolution(); 00627 // minInitialPoseDist = 0.85; //config.read<float>("MINGROUPDIST"); 00628 00629 printf("[SIM] map loaded\n"); 00630 00631 mapLoaded = true; 00632 } 00633 00634 void simulatedModel::randomPoses(bool groupInitialPoses, double max, double min){ 00635 binMap visibleArea; 00636 00637 double maxInitialPoseDist = max/omap->getResolution(); // config.read<float>("MAXGROUPDIST")/omap->getResolution(); 00638 double minInitialPoseDist = min; //config.read<float>("MINGROUPDIST"); 00639 00640 // if (config.read<bool>("RANDOM")){ 00641 if(mapLoaded){ 00642 // printf("aqui\n"); 00643 binMap accessible; 00644 // printf("aqui\n"); 00645 point p = omap->toCell(odo[0].x, odo[0].y); 00646 // printf("aqui\n"); 00647 omap->countAccessible(&p, 1, accessible); 00648 // printf("pose robot 1: (%f, %f), in cells (%d, %d)\n", odo[0].x, odo[0].y, p.x, p.y); 00649 point basePoint; 00650 std::vector<point> positives; 00651 bool vis; 00652 int maxIter = 10000; 00653 int countIter=0; 00654 bool error=false; 00655 00656 do{ 00657 for (int r = 0; r< maxNumRobots; r++){ 00658 int x,y; 00659 bool testRange=true; 00660 00661 countIter=0; 00662 error = false; 00663 pointf pos; 00664 do{ 00665 countIter++; 00666 if (countIter>maxIter){ 00667 //printf("Solution not found, trying again\n"); 00668 error=true; 00669 break; 00670 } 00671 vis=false; 00672 if (!groupInitialPoses){ 00673 x = rand() % omap->getWidth(); 00674 y = rand() % omap->getHeight(); 00675 vis = true; 00676 } 00677 else if (r==0){ 00678 x = rand() % omap->getWidth(); 00679 y = rand() % omap->getHeight(); 00680 basePoint.x = x; 00681 basePoint.y = y; 00682 visibleArea.clear(); 00683 positives.clear(); 00684 omap->esz(x,y,visibleArea, 0,maxInitialPoseDist); 00685 if (visibleArea.getPositives(positives)<30) vis = false; 00686 else vis = true; 00687 } 00688 else{ 00689 int idx = rand() % positives.size(); 00690 x = positives[idx].x; 00691 y = positives[idx].y; 00692 vis = visibleArea.get(x,y); 00693 } 00694 00695 pos = omap->toCoords(x,y); 00696 testRange=true; 00697 for(int rr = 0; rr < r; rr++){ 00698 if( sqrt( pow(pos.x-gt[rr].x ,2) + pow(pos.y-gt[rr].y,2) ) < minInitialPoseDist ) testRange = false; 00699 } 00700 } while (!accessible.get(x,y) || !omap->isfree(x,y,4) || !vis || !testRange); 00701 00702 if (error) break; 00703 landmarksData lma; 00704 lma.reserve(numfeat); 00705 pose newpos(pos.x,pos.y,0); 00706 do{ 00707 lma.clear(); 00708 newpos.th = (rand() % 628)/100.0f-3.14f; 00709 simCamAdquisition(newpos, lma, r); 00710 // printf("th =%f, marks = %d\n",newpos.th, lma.getNLandmarks()); 00711 } while(lma.getNLandmarks() < 4); 00712 00713 //printf("[SIM] new robot position for robot %d: cells (%d,%d), coords (%f,%f)\n", r, x, y, pos.x, pos.y); 00714 odo[r] = newpos; 00715 lastodo[r] = newpos; 00716 gt[r] = newpos; 00717 lastgt[r] = newpos; 00718 update_footprint(r); 00719 } 00720 00721 } while(error); 00722 } 00723 } 00724 00725 00726 void simulatedModel::redrawing(){ 00727 //QPixmap* pixmap = getPixmap(); 00728 //emit redraw(*pixmap); 00729 //delete pixmap; 00730 00731 //emit () 00732 00733 //printf("emit poses\n"); 00734 rposes poses; 00735 for(int r = 0; r < nBots; r++){ 00736 poses.push_back(gt[r]); 00737 } 00738 emit changedPositions(poses); 00739 } 00740 00741 QPixmap* simulatedModel::getPixmap(){ 00742 IplImage* img = getMapImage(); 00743 drawRobots(img); 00744 cvSaveImage("imgtmp.png",img); 00745 cvReleaseImage(&img); 00746 QPixmap* pix = new QPixmap("imgtmp.png"); 00747 return pix; 00748 } 00749 00750 rposes simulatedModel::getPoses() const{ 00751 rposes poses; 00752 for(int r = 0; r < nBots; r++){ 00753 poses.push_back(gt[r]); 00754 } 00755 return poses; 00756 } 00757 00758 void simulatedModel::drawRobots(IplImage*& img){ 00759 CvScalar redcolor = CV_RGB(255,0,0); 00760 CvScalar bluecolor = CV_RGB(0,0,255); 00761 CvScalar blackcolor = CV_RGB(0,0,0); 00762 CvFont font; 00763 cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1, 1); 00764 char numstr[3]; 00765 00766 std::vector<line>::iterator lineit; 00767 for (int r = 0; r < nBots; r++){ 00768 for ( lineit = robots_lines[r].begin(); lineit < robots_lines[r].end(); lineit++ ){ 00769 CvPoint pt1 = cvPoint((int)((lineit->x1-minx)*scalex), height-(int)((lineit->y1-miny)*scaley) ); 00770 CvPoint pt2 = cvPoint((int)((lineit->x2-minx)*scalex), height-(int)((lineit->y2-miny)*scaley) ); 00771 //printf("(%d, %d) - (%d, %d)\n", pt1.x, pt1.y, pt2.x, pt2.y); 00772 //if (rbase[r]){ 00773 // if (rbase[r]->isCaptured()) 00774 // cvLine(img, pt1, pt2, bluecolor); 00775 // else 00776 cvLine(img, pt1, pt2, redcolor); 00777 //} 00778 } 00779 sprintf(numstr,"%d",r); 00780 CvPoint ptA = cvPoint((int)((gt[r].x-minx)*scalex), height-(int)((gt[r].y-miny)*scaley) ); 00781 CvPoint ptB = cvPoint(ptA.x+10*cos(gt[r].th),ptA.y-10*sin(gt[r].th)); 00782 CvPoint ptT = cvPoint(ptA.x+10,ptA.y+10); 00783 cvPutText(img, numstr, ptT, &font, blackcolor); 00784 //if (rbase[r]){ 00785 //if (rbase[r]->isCaptured()) 00786 // cvLine(img,ptA,ptB,bluecolor); 00787 //else 00788 cvLine(img,ptA,ptB,redcolor); 00789 //} 00790 } 00791 } 00792 00793 IplImage* simulatedModel::getMapImage() { 00794 00795 CvScalar blackcolor = CV_RGB(0,0,0); 00796 CvScalar whitecolor = CV_RGB(255,255,255); 00797 00798 IplImage* img = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, 3); 00799 cvSet(img,whitecolor); 00800 00801 std::vector<line>::iterator lineit; 00802 00803 // buscamos maximo y minimo 00804 // printf("\t\t\t\tnum walls = %d\n",mapWall.size()); 00805 maxx=FLT_MIN; maxy=FLT_MIN; minx=FLT_MAX; miny=FLT_MAX; 00806 for ( lineit = mapWall.begin(); lineit < mapWall.end(); lineit++ ){ 00807 if (maxx < lineit->x1) maxx= lineit->x1; 00808 if (maxx < lineit->x2) maxx= lineit->x2; 00809 if (maxy < lineit->y1) maxy= lineit->y1; 00810 if (maxy < lineit->y2) maxy= lineit->y2; 00811 if (minx > lineit->x1) minx= lineit->x1; 00812 if (minx > lineit->x2) minx= lineit->x2; 00813 if (miny > lineit->y1) miny= lineit->y1; 00814 if (miny > lineit->y2) miny= lineit->y2; 00815 } 00816 scalex = width/(maxx-minx); 00817 scaley = height/(maxy-miny); 00818 00819 // printf("xrange: [%f-%f], yrange: [%f-%f]\n", minx, maxx, miny, maxy); 00820 // printf("scalex: %f, scaley: %f", scalex, scaley); 00821 00822 for ( lineit = mapWall.begin(); lineit < mapWall.end(); lineit++ ){ 00823 CvPoint pt1 = cvPoint((int)((lineit->x1-minx)*scalex), height-(int)((lineit->y1-miny)*scaley) ); 00824 CvPoint pt2 = cvPoint((int)((lineit->x2-minx)*scalex), height-(int)((lineit->y2-miny)*scaley) ); 00825 // printf("[SIM] (%d, %d) - (%d, %d)\n", pt1.x, pt1.y, pt2.x, pt2.y); 00826 cvLine(img, pt1, pt2, blackcolor); 00827 } 00828 00829 return img; 00830 00831 } 00832 00833 // Hace avanzar al robot durante un tiempo sample_time a velocidad vel 00834 void simulatedModel::robotMotion(pose &pos, const speed& vel, float st){ 00835 float vt = st*vel.v; 00836 float wt = st*vel.w; 00837 float meanang = pos.th + wt/2.0f; 00838 pos.x += vt*cos(meanang); 00839 pos.y += vt*sin(meanang); 00840 pos.th+= wt; 00841 if (pos.th>M_PI) pos.th -= PIx2; 00842 else if (pos.th <= -M_PI) pos.th += PIx2; 00843 } 00844 00845 // Modelo de odometria 00846 void simulatedModel::motionSample(const pose& lastPose, const pose& newPose, const pose& lastodo, pose& newodo){ 00847 00848 float diffy = newPose.y-lastPose.y; 00849 float diffx = newPose.x-lastPose.x; 00850 float diffth = newPose.th-lastPose.th; 00851 if (!(diffx == 0 && diffy == 0 && diffth ==0)){ 00852 float deltarot1; 00853 //if (!(fabs(diffx) < 0.000001 && fabs(diffy) < 0.000001)) 00854 deltarot1 = atan2(diffy, diffx) - lastPose.th; // cuanto ha rotado 00855 //else 00856 // deltarot1 = 0; 00857 float deltatrans = drifttrans*sqrt((diffx*diffx + diffy*diffy)); // distancia avanzada 00858 float deltarot2 = diffth - deltarot1; // incremento de orientacion aparte de la rotacion 00859 00860 // float dtheta = fabs(atan2(sin(diffth),cos(diffth))); 00861 00862 // float aux = (alfa1*dtheta + alfa2*deltatrans); 00863 // float deltarot1g = (float)(normrnd(deltarot1, aux)); 00864 // float deltatransg = (float)(normrnd(deltatrans, alfa3*deltatrans + alfa4*dtheta)); 00865 // float deltarot2g = (float)(normrnd(deltarot2, aux)); 00866 00867 if (deltarot1>M_PI) deltarot1 -= PIx2; 00868 else if (deltarot1 <= -M_PI) deltarot1 += PIx2; 00869 if (deltarot2>M_PI) deltarot2 -= PIx2; 00870 else if (deltarot2 <= -M_PI) deltarot2 += PIx2; 00871 00872 float rot1n = alfa1*fabs(deltarot1) + alfa2*deltatrans; 00873 float trann = alfa3*deltatrans + alfa4*(fabs(deltarot1+deltarot2)); 00874 float rot2n = alfa1*fabs(deltarot2) + alfa2*deltatrans; 00875 float deltarot1g = (float)(normrnd(deltarot1, rot1n)); 00876 float deltatransg = (float)(normrnd(deltatrans, trann)); 00877 float deltarot2g = (float)(normrnd(deltarot2, rot2n)); 00878 00879 float aux2 = lastodo.th+deltarot1g; 00880 00881 newodo.x = lastodo.x + deltatransg * cos(aux2); 00882 newodo.y = lastodo.y + deltatransg * sin(aux2); 00883 newodo.th = lastodo.th + deltarot1g + deltarot2g; 00884 00885 if (newodo.th>M_PI) newodo.th -= PIx2; 00886 else if (newodo.th <= -M_PI) newodo.th += PIx2; 00887 } 00888 else{ 00889 newodo.x = lastodo.x; 00890 newodo.y = lastodo.y; 00891 newodo.th = lastodo.th; 00892 } 00893 00894 } 00895 00896 // TODO: incluir una probabilidad de que una landmark no se detecte aun estando en el rango de vision 00897 void simulatedModel::simCamAdquisition(const pose& robotpos, landmarksData& lmData, int nr){ 00898 00899 std::vector<feature>::iterator markit; 00900 pose3d campos = camPose(robotpos); 00901 //printf("robot pose x=%f, y=%f, th=%f\n", robotpos.x, robotpos.y, robotpos.th); 00902 for ( markit = landmarks.begin(); markit != landmarks.end(); markit++ ){ //comprobar la distancia a todas las landmarks del mapa 00903 pos3d v = base2cam(global2base(markit->pos, robotpos)); // posicion relativa de la marca a la camara 00904 float r = sqrt(v.getX()*v.getX()+v.getY()*v.getY()); // distancia de la camara a la marca 00905 00906 double gamma = atan2(v.getY(), v.getX()); 00907 double beta = atan2(v.getZ(), v.getX()); 00908 if (gamma >= PI) gamma-=PIx2; 00909 if (gamma < -PI) gamma+=PIx2; 00910 if (beta >= PI) beta-=PIx2; 00911 if (beta < -PI) beta+=PIx2; 00912 00913 //Si esta dentro del FOV del robot comprobamos su visibilidad dentro del mapa 00914 if ((r < distMAX) && (r > distMIN) && (fabs(gamma) < gammaMAX) && (fabs(beta) < betaMAX)){ 00915 00916 bool visibility = testVisibility(campos.pos, markit->pos, nr); 00917 00918 //printf("vis= %d || r = %f [%f - %f], gamma = %f (%f), beta = %f (%f)\n", visibility, r,distMAX,distMIN, gamma, gammaMAX, beta, betaMAX); 00919 00920 // si cae dentro del radio de accion del robot y es visible 00921 // Si cae dentro del FOV entonces recogemos la medida, anyadimos en simulacion un error a la medida segun 00922 // una ley de propagacion del error... ver lineas de investigacion 00923 if (visibility){ 00924 00925 // proyectamos el punto real en la camara 00926 float aux1 = Realf*RealI; 00927 double c = -Realf*v.getY() / v.getX() + RealCx; 00928 double r = Realf*v.getZ() / v.getX() + RealCy; 00929 //double cp = -Realf*(RealI+v.getY())/ v.getX() + RealCxp; 00930 double d = aux1/v.getX() ;//(c - RealCx) - (cp - RealCxp); 00931 double d2 = d*d; 00932 00933 if(c<0 || r<0 || c>2*Cx || r>2*Cy ) continue; 00934 //printf("sigmas: %f, %f, %f\n",sigmac, sigmar, sigmad); 00935 00936 // Añadimos ruido a (Xc, Yc, Zc) (Ruido gaussiano en r,c,d y propagamos) 00937 double cprev = c; 00938 do{ 00939 c = normrnd(cprev,sigmac); 00940 }while(fabs(c-cprev)>3*sigmac); 00941 00942 double rprev = r; 00943 do{ 00944 r = normrnd(rprev,sigmar); 00945 }while(fabs(r-rprev)>3*sigmar); 00946 00947 // cp = normrnd(cp,sigmacp); 00948 00949 //d = (c - Cx) - (cp - Cxp); 00950 double dprev = d; 00951 do{ 00952 d = normrnd(dprev,sigmad); 00953 }while(fabs(d-dprev)>3*sigmad); 00954 d2 = d*d; 00955 double d2prev = dprev*dprev; 00956 00957 // v.print("VW MARK = "); 00958 00959 // Obtenemos la pose a partir de las medidas simuladas 00960 aux1 = f*I; 00961 float aux3 = I/d; 00962 v.getX() = aux3*f; 00963 v.getY() = aux3*(Cx-c); 00964 v.getZ() = aux3*(r-Cy); 00965 00966 /* 00967 // Jacobiano 00968 matrix J(3,8); 00969 J.set(0,0, -aux1/d2); 00970 J.set(0,2, aux1/d2); 00971 J.set(0,3, aux1/d2); 00972 J.set(0,5, -aux1/d2); 00973 J.set(0,6, I/d); 00974 J.set(0,7, f/d); 00975 00976 J.set(1,0, -I/d - I*(Cx-c)/d2); 00977 J.set(1,2, I*(Cx-c)/d2); 00978 J.set(1,3, I/d + I*(Cx-c)/d2); 00979 J.set(1,5, -I*(Cx-c)/d2); 00980 J.set(1,7, (Cx-c)/d); 00981 00982 J.set(2,0, -I*(r-Cy)/d2); 00983 J.set(2,1, I/d); 00984 J.set(2,2, I*(r-Cy)/d2); 00985 J.set(2,3, I*(r-Cy)/d2); 00986 J.set(2,4, -I/d); 00987 J.set(2,5, -I*(r-Cy)/d2); 00988 J.set(2,7, (r-Cy)/d); 00989 */ 00990 // printf("Cx=%f, Cy=%f, Cxp=%f, f=%f, I=%f\n",Cx,Cy,Cxp,f,I); 00991 // printf("c=%f, r=%f, cp=%f, d=%f d2=%f\n",c,r,cp,d,d2); 00992 00993 matrix J(3,9); 00994 J.set(0,8, -aux1/d2); 00995 J.set(1,0, -I/d); 00996 J.set(1,8, I*(c-Cx)/d2); 00997 J.set(2,1, I/d); 00998 J.set(2,8, -I*(r-Cy)/d2); 00999 01000 // Covarianza de la medida 01001 // v.print("V="); 01002 // printf("c= %f, r= %f, d=%f\n",c,r,d); 01003 // printf("sigmac = %f, sigmar = %f, sigmad = %f\n", sigmac, sigmar, sigmad); 01004 // printf("sigma2c = %e, sigma2r = %e, sigma2d = %e\n", sigma2c, sigma2r, sigma2d); 01005 // J.print("J="); 01006 // Scam.print("Scam="); 01007 matrix cov = J*(Scam*J.transpose()); 01008 // cov.print("cov="); 01009 // cov*=1.5; 01010 01011 //printf("c=%f, r=%f, cp=%f, d=%f\n",c,r,cp,d); 01012 //v.print("VW MARK CON RUIDO = "); 01013 // cov.print("COV="); 01014 01015 // añadimos una marca a lmdata 01016 landmark lmark(v,cov,markit->desc,desclength,0); 01017 //printf("voy a anyadir\n"); 01018 lmData.addLandmark(lmark); 01019 //printf("anyadida\n"); 01020 //if( lmData.getNLandmarks() > 10) break; 01021 } // visible 01022 } // in the FOV 01023 }// for each landmark 01024 //printf("[VIRTUALWORLD] observed features: %d\n", lmData.getNLandmarks()); 01025 } 01026 01027 // TODO: use the sensor pose information 01028 void simulatedModel::simRangeAdquisition(const pose& realPose, rangeSensorData& sonarData, int r){ 01029 pose dest; 01030 for (int i = 0; i < sonarData.getNumSensors(); i++ ) { 01031 float ang = realPose.th+ sonarData.getSensorPose(i).th + aperture/2; 01032 dest.x = realPose.x + sonarData.getMaxDist()*cos(ang); 01033 dest.y = realPose.y + sonarData.getMaxDist()*sin(ang); 01034 float dist1 = visibilityDistance(realPose, dest,r); 01035 01036 ang = realPose.th+ sonarData.getSensorPose(i).th - aperture/2; 01037 dest.x = realPose.x + sonarData.getMaxDist()*cos(ang); 01038 dest.y = realPose.y + sonarData.getMaxDist()*sin(ang); 01039 float dist2 = visibilityDistance(realPose, dest,r); 01040 01041 ang = realPose.th+ sonarData.getSensorPose(i).th; 01042 dest.x = realPose.x + sonarData.getMaxDist()*cos(ang); 01043 dest.y = realPose.y + sonarData.getMaxDist()*sin(ang); 01044 float dist3 = visibilityDistance(realPose, dest,r); 01045 01046 float dist = (dist1<dist2)? ((dist1<dist3)? dist1: dist3) : ((dist2<dist3)? dist2: dist3) ; 01047 sonarData.setSensorValue(i,normrnd(dist, pow(realError*dist/3.0f,2))); 01048 } 01049 } 01050 01051 bool simulatedModel::testVisibility(const pos3d& pos, const pos3d& mark, int nr){ 01052 01053 int suma = 0; 01054 pointf crosspoint; 01055 line ray(pos.getX(),pos.getY(),mark.getX(),mark.getY()); 01056 01057 //Comprobamos las veces que corta con alguna de las rectas del mapa 01058 std::vector<line>::iterator lineit; 01059 for ( lineit = mapWall.begin(); lineit < mapWall.end(); lineit++ ){ 01060 int inter = intersect(ray, *lineit, crosspoint); 01061 if (!(fabs(crosspoint.x-mark.getX())<0.05 && fabs(crosspoint.y -mark.getY())<0.05 )) suma+=inter; 01062 } 01063 // for (int r = 0; r < nBots; r++){ 01064 // if (r == nr) continue; 01065 // for ( lineit = robots_lines[r].begin(); lineit < robots_lines[r].end(); lineit++ ){ 01066 // int inter = intersect(ray, *lineit, crosspoint); 01067 // if (!(fabs(crosspoint.x-mark.getX())<0.05 && fabs(crosspoint.y -mark.getY())<0.05 )) suma+=inter; 01068 // } 01069 // } 01070 // si unicamente hemos detectado un corte, entonces es visible. Si corta 2 o 01071 // mas veces, entonces el punto atraviesa alguna pared 01072 // se supone q las marcas estan sobre las paredes por lo tanto hay un corte 01073 if (suma < 1 ) 01074 return true; 01075 else 01076 return false; 01077 } 01078 01079 float simulatedModel::visibilityDistance(const pose& ori, const pose& dest, int nr){ 01080 pointf crosspoint; 01081 01082 01083 01084 line ray(ori.x,ori.y,dest.x,dest.y); 01085 float diffx = ori.x-dest.x; 01086 float diffy = ori.y-dest.y; 01087 float dist = diffx*diffx+diffy*diffy; 01088 01089 //Comprobamos las veces que corta con alguna de las rectas del mapa 01090 std::vector<line>::iterator lineit; 01091 01092 for ( lineit = mapWall.begin(); lineit < mapWall.end(); lineit++ ){ 01093 if (intersect(ray, *lineit, crosspoint)){ 01094 diffx = ori.x-crosspoint.x; 01095 diffy = ori.y-crosspoint.y; 01096 float aux = diffx*diffx+diffy*diffy; 01097 if (aux < dist) dist = aux; 01098 } 01099 } 01100 // for (int r = 0; r < nBots; r++){ 01101 // if (r == nr) continue; 01102 // for ( lineit = robots_lines[r].begin(); lineit < robots_lines[r].end(); lineit++ ){ 01103 // if (intersect(ray, *lineit, crosspoint)){ 01104 // diffx = ori.x-crosspoint.x; 01105 // diffy = ori.y-crosspoint.y; 01106 // float aux = diffx*diffx+diffy*diffy; 01107 // if (aux < dist) dist = aux; 01108 // } 01109 // } 01110 // } 01111 return (sqrt(dist)); 01112 } 01113 01114 // TODO: consider rotation angles rx, ry, rz 01115 pose3d simulatedModel::camPose(const pose& robotpose){ 01116 float cth = cos(robotpose.th); 01117 float sth = sin(robotpose.th); 01118 return pose3d( robotpose.x + camx*cth+camy*sth, robotpose.y + camx*sth+camy*cth, camz, robotpose.th); 01119 } 01120 01121 // TODO: use calibration rx, ry, rz 01122 // translates a position in the camera frame of reference to the robot's frame of reference 01123 pos3d simulatedModel::cam2base(const pos3d& p){ 01124 return pos3d(p.getX() + camx, 01125 p.getY() + camy, 01126 p.getZ() + camz); 01127 } 01128 01129 // translates a position in the robot's frame of reference to the camera frame of reference 01130 pos3d simulatedModel::base2cam(const pos3d& p){ 01131 return pos3d(p.getX() - camx, 01132 p.getY() - camy, 01133 p.getZ() - camz); 01134 } 01135 01136 robotBase* simulatedModel::createNewPlatform(){ 01137 robotBase* res; 01138 newIdsMutex.lock(); 01139 if (idCounter<nBots){ 01140 rbase[idCounter] = new robotBase(idCounter); 01141 rbase[idCounter]->setWorldModel(this); 01142 res = rbase[idCounter]; 01143 idCounter++; 01144 } 01145 else res= 0; 01146 newIdsMutex.unlock(); 01147 //printf("the rbase created is at pointer %d",res); 01148 return res; 01149 } 01150 01151 void simulatedModel::disablePlatform(const robotBase& r){ 01152 int id = r.getNumber(); 01153 //printf("[SIM] Disabling robot...%d\n",id); 01154 if (robotsEnabled[id]){ 01155 rbase[id]->beginConsumition(); 01156 robotsEnabled[id]=false; 01157 rbase[id]->endConsumition(); 01158 } 01159 //printf("[SIM] robot %d disabled\n",id); 01160 } 01161 01162 int simulatedModel::fire(int robot){ 01163 int res = 0; 01164 pointf crosspoint; 01165 for (int r = 0; r < nBots; r++){ 01166 if (r == robot) continue; 01167 if (!rbase[r]) continue; 01168 01169 if (rbase[r]->isCaptured()) continue; 01170 01171 line ray(gt[robot].x,gt[robot].y,gt[r].x,gt[r].y); 01172 std::vector<line>::iterator lineit; 01173 bool visibility = true; 01174 for ( lineit = mapWall.begin(); lineit < mapWall.end(); lineit++ ){ 01175 if (intersect(ray, *lineit, crosspoint)){ 01176 visibility = false; 01177 break; 01178 } 01179 } 01180 01181 if (visibility){ 01182 float distx = gt[robot].x-gt[r].x; 01183 float disty = gt[robot].y-gt[r].y; 01184 float dist = sqrt(distx*distx+disty*disty); 01185 if (dist < maxDist){ 01186 res++; 01187 rbase[r]->setCaptured(); 01188 } 01189 } 01190 } 01191 return res; 01192 } 01193 01194 double simulatedModel::evaluateVMap(visualMap& vm) const{ 01195 double error =0; 01196 double suma=0; 01197 int N=vm.getNLandmarks(); 01198 for (int l = 0; l<N; l++){ 01199 landmark* m = vm.getLandmarkById(l); 01200 suma += sqrt( pow( landmarks[m->descriptor[0]].pos.getX() - m->pos.getX() ,2) + 01201 pow( landmarks[m->descriptor[0]].pos.getY() - m->pos.getY() ,2) + 01202 pow( landmarks[m->descriptor[0]].pos.getZ() - m->pos.getZ() ,2) ); 01203 delete m; 01204 } 01205 error = sqrt(suma/N); 01206 01207 return error; 01208 01209 } 01210 01211