test-FollowPipe.C

Go to the documentation of this file.
00001 /*!@file SeaBee/test-FollowPipe.C test submarine pipe following  */
00002 // //////////////////////////////////////////////////////////////////// //
00003 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00004 // University of Southern California (USC) and the iLab at USC.         //
00005 // See http://iLab.usc.edu for information about this project.          //
00006 // //////////////////////////////////////////////////////////////////// //
00007 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00008 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00009 // in Visual Environments, and Applications'' by Christof Koch and      //
00010 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00011 // pending; application number 09/912,225 filed July 23, 2001; see      //
00012 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00013 // //////////////////////////////////////////////////////////////////// //
00014 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00015 //                                                                      //
00016 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00017 // redistribute it and/or modify it under the terms of the GNU General  //
00018 // Public License as published by the Free Software Foundation; either  //
00019 // version 2 of the License, or (at your option) any later version.     //
00020 //                                                                      //
00021 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00022 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00023 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00024 // PURPOSE.  See the GNU General Public License for more details.       //
00025 //                                                                      //
00026 // You should have received a copy of the GNU General Public License    //
00027 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00028 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00029 // Boston, MA 02111-1307 USA.                                           //
00030 // //////////////////////////////////////////////////////////////////// //
00031 //
00032 // Primary maintainer for this file: Michael Montalbo <montalbo@usc.edu>
00033 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/SeaBee/test-FollowPipe.C $
00034 // $Id: test-FollowPipe.C 10794 2009-02-08 06:21:09Z itti $
00035 
00036 #include "Component/ModelManager.H"
00037 
00038 #include "Media/FrameSeries.H"
00039 #include "Transport/FrameIstream.H"
00040 #include "Media/MediaOpts.H"
00041 
00042 #include "Image/Image.H"
00043 #include "Image/Pixels.H"
00044 #include "Raster/Raster.H"
00045 #include "Image/CutPaste.H"
00046 
00047 #include "BeoSub/IsolateColor.H"
00048 #include "Image/DrawOps.H"
00049 #include "Image/ColorOps.H"
00050 
00051 #include "GUI/XWinManaged.H"
00052 
00053 #include "SeaBee/PipeRecognizer.H"
00054 #include "BeoSub/BeoSubBin.H"
00055 #include "SeaBee/BinRecognizer.H"
00056 
00057 
00058 #include "SeaBee/SubController.H"
00059 
00060 #include "SeaBee/SubGUI.H"
00061 
00062 //whether or not to run the simulator
00063 #define SIM_MODE true
00064 
00065 #define CREATE_MOVIE true
00066 
00067 int main(int argc, char* argv[])
00068 {
00069 
00070   MYLOGVERB = LOG_INFO;
00071 
00072   ModelManager manager("PipeRecognizer Tester");
00073 
00074 
00075   nub::soft_ref<InputFrameSeries> ifs;
00076 #if SIM_MODE == false
00077     ifs.reset(new InputFrameSeries(manager));
00078     manager.addSubComponent(ifs);
00079 #endif
00080 
00081     nub::soft_ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00082     manager.addSubComponent(ofs);
00083 
00084 
00085   nub::soft_ref<SubGUI> subGUI(new SubGUI(manager));
00086   manager.addSubComponent(subGUI);
00087 
00088   nub::soft_ref<SubController> subController(new SubController(manager, "SubController", "SubController", SIM_MODE));
00089   manager.addSubComponent(subController);
00090 
00091   manager.exportOptions(MC_RECURSE);
00092 
00093   // Parse command-line:
00094   if (manager.parseCommandLine(argc, argv,
00095                                "[image {*.ppm}]",
00096                                0, 1)
00097       == false) return(1);
00098 
00099   int w, h;
00100 
00101 #if SIM_MODE == false
00102     w = ifs->getWidth();
00103     h = ifs->getHeight();
00104 #else
00105     w = 320;
00106     h = 240;
00107 #endif
00108 
00109   std::string dims = convertToString(Dims(w, h));
00110   LINFO("image size: [%dx%d]", w, h);
00111   manager.setOptionValString(&OPT_InputFrameDims, dims);
00112 
00113   manager.setModelParamVal("InputFrameDims", Dims(w, h),
00114                            MC_RECURSE | MC_IGNORE_MISSING);
00115 
00116   manager.start();
00117 
00118   bool goforever = true;
00119 
00120   rutz::shared_ptr<XWinManaged> dispWin;
00121   dispWin.reset(new XWinManaged(Dims(w*2,h*2), 0, 0, "Pipe Recognizer Display"));
00122 
00123   rutz::shared_ptr<PipeRecognizer> pipeRecognizer(new PipeRecognizer());
00124   //rutz::shared_ptr<BeoSubBin> binRecognizer(new BeoSubBin());
00125   rutz::shared_ptr<Point2D<int> > pipeCenter(new Point2D<int>(0,0));
00126 
00127   rutz::shared_ptr<BinRecognizer> binRecognizer(new BinRecognizer());
00128   rutz::shared_ptr<Point2D<int> > binCenter(new Point2D<int>(0,0));
00129 
00130 
00131   Point2D<int> projPoint(Point2D<int>(0,0));
00132 //   Point2D<int> projPoint2(Point2D<int>(0,0));
00133 
00134   rutz::shared_ptr<double> pipeAngle(new double);
00135 //   rutz::shared_ptr<double> pipeAngleSmooth(new double);
00136 
00137 
00138   subGUI->startThread(ofs);
00139   subGUI->setupGUI(subController.get(), true);
00140   subGUI->addMeter(subController->getIntPressurePtr(),
00141                    "Int Pressure", 500, PixRGB<byte>(255, 0, 0));
00142   subGUI->addMeter(subController->getHeadingPtr(),
00143                    "Heading", 360, PixRGB<byte>(192, 255, 0));
00144   subGUI->addMeter(subController->getPitchPtr(),
00145                    "Pitch", 256, PixRGB<byte>(192, 255, 0));
00146   subGUI->addMeter(subController->getRollPtr(),
00147                    "Roll", 256, PixRGB<byte>(192, 255, 0));
00148   subGUI->addMeter(subController->getDepthPtr(),
00149                    "Depth", 300, PixRGB<byte>(192, 255, 0));
00150 
00151   subGUI->addMeter(subController->getThruster_Up_Left_Ptr(),
00152                    "Motor_Up_Left", -100, PixRGB<byte>(0, 255, 0));
00153   subGUI->addMeter(subController->getThruster_Up_Right_Ptr(),
00154                    "Motor_Up_Right", -100, PixRGB<byte>(0, 255, 0));
00155   subGUI->addMeter(subController->getThruster_Up_Back_Ptr(),
00156                    "Motor_Up_Back", -100, PixRGB<byte>(0, 255, 0));
00157   subGUI->addMeter(subController->getThruster_Fwd_Left_Ptr(),
00158                    "Motor_Fwd_Left", -100, PixRGB<byte>(0, 255, 0));
00159   subGUI->addMeter(subController->getThruster_Fwd_Right_Ptr(),
00160                    "Motor_Fwd_Right", -100, PixRGB<byte>(0, 255, 0));
00161 
00162 
00163   subGUI->addImage(subController->getSubImagePtr());
00164   subGUI->addImage(subController->getPIDImagePtr());
00165 
00166   // input and output images
00167 
00168   rutz::shared_ptr<Image< PixRGB<byte> > > img;
00169   img.reset(new Image< PixRGB<byte> >(w,h, ZEROS));
00170 
00171   // Image< PixRGB<byte> > img(w,h, ZEROS);
00172   rutz::shared_ptr<Image<byte> > orangeIsoImage(new Image<byte>(w,h, ZEROS));
00173   Image< PixRGB<byte> > dispImg(w*2,h*2, ZEROS);
00174 
00175   rutz::shared_ptr<Image< PixRGB<byte> > > pipelineOutputImg(new Image<PixRGB<byte> >(w,h, ZEROS));
00176   rutz::shared_ptr<Image< PixRGB<byte> > > outputImg(new Image<PixRGB<byte> >(w,h, ZEROS));
00177 
00178 
00179 
00180   Point2D<int> centerOfMass;
00181   std::vector<Point2D<int> > avgCenter;
00182 
00183 
00184 #if SIM_MODE == true
00185   uint staleCount = 0;
00186 #endif
00187 
00188   while(goforever)
00189     {
00190       // subController->runSimLoop();
00191       orangeIsoImage.reset(new Image<byte>(w,h, ZEROS));
00192       outputImg.reset(new Image<PixRGB<byte> >(w,h, ZEROS));
00193 
00194 #if SIM_MODE == false
00195           ifs->updateNext(); *img = ifs->readRGB();
00196           if(!img->initialized()) {Raster::waitForKey(); break; }
00197 #else
00198           //get sim image from bottom camera
00199           *img = subController->getImage(2);
00200 #endif
00201 
00202       inplacePaste(dispImg, *img, Point2D<int>(0,0));
00203 
00204       orangeIsoImage->resize(w,h);
00205       isolateOrange(*img, *orangeIsoImage);
00206 
00207       inplacePaste(dispImg, toRGB(*orangeIsoImage), Point2D<int>(w,0));
00208 
00209       //Perform PipeLine Recognition
00210       //get all the orange lines in the image
00211       std::vector<LineSegment2D> pipelines = pipeRecognizer->getPipeLocation(orangeIsoImage,
00212                                                                              pipelineOutputImg,
00213                                                                              PipeRecognizer::HOUGH);
00214 
00215 
00216 #if SIM_MODE == true
00217 
00218       binRecognizer->getBinLocation(img,
00219                                     outputImg,
00220                                     BinRecognizer::CONTOUR,
00221                                     binCenter,
00222                                     staleCount);
00223 
00224       drawCircle(*outputImg, *binCenter,  2, PixRGB <byte> (255, 0,0), 3);
00225 #endif
00226       inplacePaste(dispImg, *outputImg, Point2D<int>(w,h));
00227 
00228 
00229       dispWin->drawImage(dispImg, 0, 0);
00230 
00231 
00232 //       if(binCenter->i > 0 && binCenter->j > 0 && staleCount < 25)// && binCenter->i < 320 && binCenter->j < 240)
00233 //         {
00234 //           int xErr = (binCenter->i-(160));
00235 //           int yErr = (binCenter->j-(120));
00236 //           int desiredHeading = (int)(xErr*-1);
00237 
00238 //           LINFO("xErr:%d,yErr:%d",binCenter->i,binCenter->j);
00239 
00240 //           if(xErr > .15 * 320)
00241 //             {
00242 //               subController->setHeading(subController->getHeading()
00243 //                                         + desiredHeading);
00244 //             }
00245 //           else if(xErr < .15 * 320)
00246 //             {
00247 //               subController->setHeading(subController->getHeading());
00248 //               subController->setSpeed(50);
00249 //             }
00250 //           else if(yErr < .15 * 240)
00251 //             {
00252 //               subController->setSpeed(0);
00253 //             }
00254 //         }
00255 //       else
00256 
00257       int minY = -1; //minimum midpoint y coordinate found
00258       int followLineIndex = -1; //index of pipeline with minimum y coordinate
00259 
00260       //iterates through pipelines and finds the topmost one in the image
00261       for(uint i = 0; i < pipelines.size(); i++)
00262         {
00263           LineSegment2D pipeline = pipelines[i];
00264           Point2D<int> midpoint = (pipeline.point1() + pipeline.point2())/2;
00265 
00266           if(midpoint.j < minY || minY == -1)
00267             {
00268               minY = midpoint.j;
00269               followLineIndex = i;
00270             }
00271         }
00272 
00273       //if we found a pipeline
00274       if(followLineIndex != -1)
00275         {
00276 
00277           LineSegment2D followLine = pipelines[followLineIndex];
00278           Point2D<int> midpoint = (followLine.point1() + followLine.point2())/2;
00279 
00280           projPoint.i = (int)(midpoint.i+30*cos(followLine.angle()));
00281           projPoint.j = (int)(midpoint.j+30*sin(followLine.angle()));
00282 
00283           drawLine(*pipelineOutputImg, midpoint, projPoint, PixRGB <byte> (255, 255,0), 3);
00284 
00285 
00286           inplacePaste(dispImg, *pipelineOutputImg, Point2D<int>(0,h));
00287 
00288 
00289           int desiredHeading = ((int)((followLine.angle()) * 180 / M_PI));
00290 
00291           if(desiredHeading > 360) desiredHeading = desiredHeading - 360;
00292           if(desiredHeading < 0) desiredHeading = desiredHeading + 360;
00293 
00294           int absHeading = (subController->getHeading() + desiredHeading) % 360;
00295           subController->setHeading(absHeading);
00296 
00297           //Wait for new heading to get to heading
00298           if(!((desiredHeading >= 270 && desiredHeading <= 275) || (desiredHeading <= 90 && desiredHeading >= 85)))
00299             {
00300               usleep(100000);
00301             }
00302           else
00303             {
00304               subController->setHeading(subController->getHeading());
00305               subController->setSpeed(75);
00306             }
00307 
00308         }
00309       else
00310         {
00311           subController->setHeading(subController->getHeading());
00312         }
00313     }
00314 
00315   // get ready to terminate:
00316   manager.stop();
00317   return 0;
00318 }
00319 
00320 // ######################################################################
00321 /* So things look consistent in everyone's emacs... */
00322 /* Local Variables: */
00323 /* indent-tabs-mode: nil */
00324 /* End: */
Generated on Sun May 8 08:42:15 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3