MRXT: The Multi-Robot eXploration Tool
Multi-Robot autonomous exploration and mapping simulator.
|
00001 #include "reactiveGauss.h" 00002 #include <math.h> 00003 #include <fstream> 00004 #include <stdio.h> 00005 #include <opencv2/opencv.hpp> 00006 #ifndef WIN32 00007 #include <sys/time.h> 00008 #endif 00009 00010 00011 // Para registrar la clase en la factoria 00012 namespace reactiveLayers{ 00013 reactive* CreateReactiveGauss(const ConfigFile& conf){ 00014 return new reactiveGauss(conf); 00015 }; 00016 const int REACTIVEGAUSS = 0; 00017 const bool registered = reactiveFactory::Instance().Register(REACTIVEGAUSS, reactiveCreator(CreateReactiveGauss)); 00018 } 00019 00020 using namespace std; 00021 00022 reactiveGauss::reactiveGauss(const ConfigFile& config): 00023 reactive (config), 00024 useesz (config.read<bool>("USEESZ")), 00025 eszdilationradius (config.read<int>("ESZDILATIONRADIUS")), 00026 actionradius (config.read<float>("ESZRADIUS")), 00027 endReactive (true), 00028 lzwidth (config.read<int>("LOCALPOTENTIALWIDTH")), 00029 lzheight (config.read<int>("LOCALPOTENTIALHEIGHT")), 00030 total (lzwidth,lzheight) 00031 { 00032 00033 } 00034 00035 reactiveGauss::~reactiveGauss(){ 00036 stop(); 00037 } 00038 00039 // codigo del hilo se arranca/para con run/stop 00040 00041 // si no devuelve 0 el hilo no empieza 00042 int reactiveGauss::setup(){ 00043 prio = 50; 00044 return 0; 00045 } 00046 00047 // se ejecuta al cancelar la ejecucion del hilo por el metodo stop 00048 void reactiveGauss::onStop(){ 00049 if (!endReactive){ 00050 endReactive = true; 00051 closing.lock(); 00052 closing.unlock(); 00053 } 00054 printf("[REACTIVEGAUSS] [robot %d] Stopped\n", rbase->getNumber()); 00055 if (rbase) rbase->setSpeed(0,0); 00056 } 00057 00058 // el codigo a ejecutar por el hilo 00059 void reactiveGauss::execute(){ 00060 printf("[REACTIVEGAUSS] \t\t\t\t\t REACTIVEGAUSS (%d) running\n", rbase->getNumber()); 00061 00062 closing.lock(); 00063 endReactive=false; 00064 00065 int nextStep; 00066 #ifdef SHOWPOTENTIAL 00067 char mystr[250]; 00068 char mystr2[250]; 00069 sprintf(mystr,"POT%d",number); 00070 sprintf(mystr2,"POT%d.jpg",number); 00071 cvNamedWindow(mystr,0); 00072 #endif 00073 nextStep=0; 00074 00075 while(!endReactive){ 00076 00077 nextStep = mySlam->getStep() +1; 00078 //printf("[REACTIVEGAUSS] [robot %d reactive] waiting for step %d\n", rbase->getNumber(), nextStep); 00079 mySlam->waitForStep(nextStep); 00080 updateField(total); 00081 pointf f = getResponse(total); 00082 speed vel = regulator(currentPos,f); 00083 rbase->setSpeed(vel.v, vel.w); 00084 //usleep(100000); // simulate command transmision delay 00085 00086 //printf("[REACTIVEGAUSS] [robot %d] vel: %f, %f \n", rbase->getNumber(), vel.v, vel.w); 00087 00088 #ifdef SHOWPOTENTIAL 00089 total.savePotentialAsImage(mystr2); 00090 IplImage* im = cvLoadImage(mystr2,3); 00091 cvShowImage(mystr,im); 00092 cvWaitKey(10); 00093 cvReleaseImage(&im); 00094 #endif 00095 00096 } 00097 00098 #ifdef SHOWPOTENTIAL 00099 cvDestroyWindow(mystr); 00100 #endif 00101 00102 //printf("[REACTIVEGAUSS] [robot %d reac] Stopping reactive...\n", rbase->getNumber()); 00103 closing.unlock(); 00104 //printf("[REACTIVEGAUSS] \t\t\t\t\t\t\t [robot %d] reac stopped\n", rbase->getNumber()); 00105 00106 } 00107 00108 void reactiveGauss::updateField (localPotentialField& global){ 00109 00110 global.reset(); 00111 00112 gridMapInterface* omap = mySlam->getOMap(); 00113 binMap *ppmap = mySlam->getPreMap(); 00114 int numrobots = mySlam->getNumRobots(); 00115 point poscell = mySlam->getCell(number); 00116 currentPos = mySlam->getPos(number); 00117 00118 point* robotcells = new point[numrobots](); 00119 for(int r=0; r<numrobots; r++) 00120 robotcells[r] = mySlam->getCell(r); 00121 binMap esz; 00122 00123 int actionradius_cells = ((int)floor(actionradius/omap->getResolution()+0.5)); 00124 00125 if (useesz){ 00126 omap->esz(poscell.x, poscell.y, esz, eszdilationradius,actionradius_cells); 00127 } 00128 else{ 00129 esz.initialize(omap->getWidth(), omap->getHeight(), omap->getResolution(), omap->getXOrigin(), omap->getYOrigin()); 00130 for(int i=poscell.x-actionradius_cells; i < poscell.x+actionradius_cells; i++){ 00131 for(int j=poscell.y-actionradius_cells; j < poscell.y+actionradius_cells; j++){ 00132 esz.set(i,j,true); 00133 } 00134 } 00135 RoI roi; 00136 roi.x = (poscell.x-actionradius_cells>0)? poscell.x-actionradius_cells : roi.x = 0; 00137 roi.width = (poscell.x+actionradius_cells<omap->getWidth())? poscell.x+actionradius_cells - roi.x : omap->getWidth() - roi.x; 00138 roi.y = (poscell.y-actionradius_cells>0)? roi.y = poscell.y-actionradius_cells : roi.y = 0; 00139 roi.height = (poscell.y+actionradius_cells< omap->getHeight())? roi.height = poscell.y+actionradius_cells - roi.y : roi.height = omap->getHeight() - roi.y; 00140 esz.setRoi(roi); 00141 } 00142 00143 //printf("[REACTIVEGAUSS] ESZ ROI: %i, %i, %i, %i\n", esz.getRoi().x, esz.getRoi().y, esz.getRoi().width, esz.getRoi().height); 00144 00145 localPotentialField* avObs = new localPotentialField(lzwidth,lzheight); 00146 localPotentialField* goFro = new localPotentialField(lzwidth,lzheight); 00147 localPotentialField* goUZ = new localPotentialField(lzwidth,lzheight); 00148 00149 processOMap(poscell, *omap, esz, *avObs, *goFro, *goUZ); 00150 00151 global += *avObs * avoidObstaclesWeight; 00152 global += *goFro * goToFrontierWeight; 00153 global += *goUZ * goToUnexploredZonesWeight; 00154 00155 delete avObs; 00156 delete goFro; 00157 delete goUZ; 00158 00159 localPotentialField* avRob = new localPotentialField(lzwidth,lzheight); 00160 processAvRob(numrobots, robotcells, esz, *avRob); 00161 global += *avRob * avoidOtherRobotsWeight; 00162 delete avRob; 00163 00164 localPotentialField* goPre = new localPotentialField(lzwidth,lzheight); 00165 processGoPre(poscell, *ppmap, esz, *goPre); 00166 global += *goPre * goToPrecisePosesWeight; 00167 delete goPre; 00168 00169 localPotentialField* goGoal = new localPotentialField(lzwidth,lzheight); 00170 processGoGoal(poscell, goal, esz, *goGoal); 00171 global += *goGoal * goToGoalWeight; 00172 delete goGoal; 00173 00174 delete[] robotcells; 00175 delete omap; 00176 delete ppmap; 00177 00178 } 00179 00180 void reactiveGauss::processOMap(point& pos, gridMapInterface& omap, binMap& esz, localPotentialField& avObs, localPotentialField& goFro, localPotentialField& goUZ){ 00181 00182 if(goToUnexploredZonesEnabled || goToFrontierEnabled || avoidObstaclesEnabled){ 00183 00184 int i,j,ci,cj,x,y; 00185 int wws = (lzwidth-1)/2; 00186 int whs = (lzheight-1)/2; 00187 //printf("[REACTIVEGAUSS] %d, %d, %d, %d\n", esz.getRoi().x, esz.getRoi().y,esz.getRoi().width,esz.getRoi().height); 00188 for (i = esz.getRoi().x-1; i <= esz.getRoi().x + esz.getRoi().width ; i++){ 00189 for (j = esz.getRoi().y-1; j <= esz.getRoi().y + esz.getRoi().height ; j++){ 00190 00191 if(omap.isunknown(i,j) && goToUnexploredZonesEnabled) { // unexplored 00192 if (esz.get(i,j)){ // if esz 00193 00194 for (x = 0, ci = pos.x - wws ; ci <= pos.x + wws ; ci++, x++){ 00195 for (y = 0, cj = pos.y - whs ; cj <= pos.y + whs ; cj++, y++){ // for each local cell 00196 00197 goUZ.set(x,y, goUZ.get(x,y)-gauss(ci,cj, (float)i,(float)j, goToUnexploredZonesWidth_cells)); 00198 } 00199 } 00200 } 00201 } 00202 else if(omap.isfrontier(i,j) && goToFrontierEnabled) { // frontier 00203 if (esz.get(i,j)){ // if esz 00204 for (x = 0, ci = pos.x - wws ; ci <= pos.x + wws ; ci++, x++){ 00205 for (y = 0, cj = pos.y - whs ; cj <= pos.y + whs ; cj++, y++){ // for each local cell 00206 goFro.set(x,y, goFro.get(x,y)-gauss(ci,cj,(float) i,(float)j, goToFrontierWidth_cells)); 00207 } 00208 } 00209 } 00210 } 00211 else if (omap.isoccupied(i,j) && avoidObstaclesEnabled) { // occupied 00212 if (esz.isOver(i,j,eszdilationradius)){ // if next to esz 00213 for (x = 0, ci = pos.x - wws ; ci <= pos.x + wws ; ci++, x++){ 00214 for (y = 0, cj = pos.y - whs ; cj <= pos.y + whs ; cj++, y++){ // for each local cell 00215 avObs.set(x,y, avObs.get(x,y)+ gauss(ci,cj,(float) i,(float)j, avoidObstaclesWidth_cells)); 00216 } 00217 } 00218 } 00219 } 00220 } 00221 } 00222 } 00223 00224 avObs.normalize(); 00225 goFro.normalize(); 00226 goUZ.normalize(); 00227 } 00228 00229 void reactiveGauss::processGoPre(point& pos, binMap& ppmap, binMap& esz, localPotentialField& goPre){ 00230 00231 if(goToPrecisePosesEnabled){ 00232 int i,j,ci,cj,x,y; 00233 int wws = (lzwidth-1)/2; 00234 int whs = (lzheight-1)/2; 00235 00236 for (i = esz.getRoi().x ; i < esz.getRoi().x + esz.getRoi().width-1 ; i++){ 00237 for (j = esz.getRoi().y ; j < esz.getRoi().y + esz.getRoi().height-1 ; j++){ 00238 00239 if(ppmap.get(i,j) && esz.get(i,j)) { 00240 for (x = 0, ci = pos.x - wws ; ci <= pos.x + wws ; ci++, x++){ 00241 for (y = 0, cj = pos.y - whs ; cj <= pos.y + whs ; cj++, y++){ // for each local cell 00242 goPre.set(x,y, goPre.get(x,y)-gauss(ci,cj, (float)i,(float)j, goToPrecisePosesWidth_cells)); 00243 } 00244 } 00245 } 00246 } 00247 } 00248 } 00249 goPre.normalize(); 00250 } 00251 00252 void reactiveGauss::processGoGoal(point& pos, point& goal, binMap& esz, localPotentialField& goGoal){ 00253 if(goToGoalEnabled){ 00254 int ci,cj,x,y; 00255 int wws = (lzwidth-1)/2; 00256 int whs = (lzheight-1)/2; 00257 // if(esz.get(goal.x,goal.y)) { 00258 for (x = 0, ci = pos.x - wws ; ci <= pos.x + wws ; ci++, x++){ 00259 for (y = 0, cj = pos.y - whs ; cj <= pos.y + whs ; cj++, y++){ // for each local cell 00260 goGoal.set(x,y, goGoal.get(x,y)-gauss(ci,cj, goal.x,goal.y, goToGoalWidth_cells)); 00261 } 00262 } 00263 // } 00264 } 00265 goGoal.normalize(); 00266 } 00267 00268 void reactiveGauss::processAvRob(int numrobots, point* robotcells, binMap& esz, localPotentialField& avRob){ 00269 if(avoidOtherRobotsEnabled){ 00270 00271 if (numrobots>1){ 00272 00273 int r, r2, ci,cj, x,y; 00274 00275 int wws = (lzwidth-1)/2; 00276 int whs = (lzheight-1)/2; 00277 00278 r=number; 00279 for (r2 = 0; r2<numrobots; r2++){ // for each other robot r2 00280 if (r2 != r){ 00281 if (esz.get(robotcells[r2].x, robotcells[r2].y)){ 00282 for (x = 0, ci = robotcells[r].x - wws ; ci <= robotcells[r].x + wws ; ci++, x++){ 00283 for ( y = 0, cj = robotcells[r].y - whs ; cj <= robotcells[r].y + whs ; cj++, y++){ // for each local cell 00284 avRob.set(x,y, avRob.get(x,y)+gauss(ci,cj, robotcells[r2].x, robotcells[r2].y, avoidOtherRobotsWidth_cells)); 00285 } 00286 } // local cell j 00287 } 00288 }// r2 != r 00289 } // other robot 00290 } 00291 } 00292 avRob.normalize(); 00293 } 00294 00295 void reactiveGauss::setGoal(point goal) {this->goal = goal;} 00296