MRXT: The Multi-Robot eXploration Tool
Multi-Robot autonomous exploration and mapping simulator.
src/architecture/reactive/reactiveGauss.cpp
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 
 All Classes Functions Variables Typedefs