beobot-GSnav-master.C

Go to the documentation of this file.
00001 /*!@file Beobot/beobot-GSnav-master.C Robot navigation using a
00002   combination saliency and gist.
00003   Run beobot-GSnav-master at CPU_A to run Gist-Saliency model
00004   Run beobot-GSnav        at CPU_B to run SIFT object recognition       */
00005 // //////////////////////////////////////////////////////////////////// //
00006 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00007 // University of Southern California (USC) and the iLab at USC.         //
00008 // See http://iLab.usc.edu for information about this project.          //
00009 // //////////////////////////////////////////////////////////////////// //
00010 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00011 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00012 // in Visual Environments, and Applications'' by Christof Koch and      //
00013 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00014 // pending; application number 09/912,225 filed July 23, 2001; see      //
00015 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00016 // //////////////////////////////////////////////////////////////////// //
00017 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00018 //                                                                      //
00019 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00020 // redistribute it and/or modify it under the terms of the GNU General  //
00021 // Public License as published by the Free Software Foundation; either  //
00022 // version 2 of the License, or (at your option) any later version.     //
00023 //                                                                      //
00024 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00025 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00026 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00027 // PURPOSE.  See the GNU General Public License for more details.       //
00028 //                                                                      //
00029 // You should have received a copy of the GNU General Public License    //
00030 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00031 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00032 // Boston, MA 02111-1307 USA.                                           //
00033 // //////////////////////////////////////////////////////////////////// //
00034 //
00035 // Primary maintainer for this file: Christian Siagian <siagian@usc.edu>
00036 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Beobot/beobot-GSnav-master.C $
00037 // $Id: beobot-GSnav-master.C 12962 2010-03-06 02:13:53Z irock $
00038 //
00039 //////////////////////////////////////////////////////////////////////////
00040 // beobot-GSnav-Master.C  <operation mode> <environment file>
00041 //                        [number of segments] [current Segment Number]
00042 //
00043 //
00044 // This is an on-going project for biologically-plausible
00045 // mobile-robotics navigation.
00046 // It accepts any inputs: video  clip <input.mpg>, camera feed, frames.
00047 //
00048 // The system uses Gist to recognize places and saliency
00049 // to get better localization within the place.
00050 // The program also is made to be streamline for fast processing using
00051 // parallel computation of the different the V1 feature channels
00052 //
00053 // It is able to recognize places through the use of gist features.
00054 // The place classifier uses a neural networks,
00055 // passed in a form of <input_train.txt> -
00056 // the same file is used in the training phase by train-FFN.C.
00057 //
00058 // In parallel we use saliency to obtain salient objects for better
00059 // spatial location accuracy.
00060 // We use ShapeEstimator algorithm to segment out
00061 // the sub-region to get a landmark and SIFT toidentify the object,
00062 // create a database, etc.
00063 //
00064 // for localization, we use particle filter/Monte Carlo Localization
00065 // for path planning we perform landmark-hopping to get to the destination
00066 
00067 #include "Beowulf/Beowulf.H"
00068 #include "Component/ModelManager.H"
00069 #include "Media/FrameSeries.H"
00070 #include "Transport/FrameIstream.H"
00071 #include "Neuro/SaccadeController.H"
00072 #include "Neuro/SaccadeControllers.H"
00073 #include "Neuro/SaccadeControllerConfigurator.H"
00074 #include "Neuro/NeuroOpts.H"
00075 #include "Image/Image.H"
00076 #include "Image/Pixels.H"
00077 #include "Raster/Raster.H"
00078 #include "GUI/XWinManaged.H"
00079 #include "Media/MediaOpts.H"
00080 #include "Util/Timer.H"
00081 #include "Simulation/SimEventQueue.H"
00082 #include "Simulation/SimEventQueueConfigurator.H"
00083 #include "Devices/DeviceOpts.H"
00084 
00085 #include "Beobot/BeobotBrainMT.H"
00086 #include "Beobot/BeobotConfig.H"
00087 #include "Beobot/BeobotControl.H"
00088 #include "Beobot/BeobotBeoChipListener.H"
00089 
00090 #include "RCBot/Motion/MotionEnergy.H"
00091 #include "Controllers/PID.H"
00092 
00093 #include "Image/MathOps.H"      // for findMax
00094 #include "Image/CutPaste.H"     // for inplacePaste()
00095 #include "Image/DrawOps.H"
00096 #include "Image/FilterOps.H"
00097 #include "Image/PyramidOps.H"
00098 #include "Image/ShapeOps.H"
00099 #include "Image/Transforms.H"
00100 
00101 #include "Beobot/beobot-GSnav-def.H"
00102 #include "Beobot/GSnavResult.H"
00103 
00104 #include <signal.h>
00105 
00106 #include <errno.h>
00107 
00108 #define ERR_INTERVAL 5000
00109 
00110 static bool goforever = true;
00111 
00112 // ######################################################################
00113 // ######################################################################
00114 //! get the input prefix to save the intermdeiate results
00115 std::string getInputPrefix(nub::soft_ref<InputFrameSeries> ifs,
00116                            int &inputType);
00117 
00118 //! get the operation mode of the current run
00119 int getOpMode(std::string opmodestr);
00120 
00121 //! setup the BeoChip
00122 void setupBeoChip(nub::soft_ref<BeoChip> b, BeobotConfig bbc);
00123 
00124 //! process beoChip input
00125 int beoChipProc
00126 (rutz::shared_ptr<BeobotBeoChipListener> lis, nub::soft_ref<BeoChip> b);
00127 
00128 //! get all the necessary information from the visual cortex
00129 void getBbmtResults
00130 ( nub::ref<BeobotBrainMT> bbmt,
00131   Image<PixRGB<byte> > &currIma, Image<double> &cgist,
00132   Image<float> &currSalMap, ImageSet<float> &cmap,
00133   std::vector<Point2D<int> > &salpt, std::vector<std::vector<double> > &feat,
00134   std::vector<Rectangle> &objRect);
00135 
00136 //! display results
00137 void dispResults
00138 ( Image< PixRGB<byte> > disp, rutz::shared_ptr<XWinManaged> win,
00139   Image< PixRGB<byte> > ima, Image< PixRGB<byte> > prevIma,
00140   std::vector<Point2D<int> > clmpt, std::vector<Point2D<int> > nlmpt,
00141   Image<float> currSalMap,
00142   std::vector<Point2D<int> > salpt, std::vector<Rectangle> objRect);
00143 
00144 //! check to see if the node have returned results
00145 bool checkNode
00146 ( int opMode, nub::soft_ref<Beowulf> beo,
00147   int32 &rnode, TCPmessage &rmsg, int32 &raction, int32 &rframe);
00148 
00149 //! check to see if the new input should be processed
00150 bool checkInput(int opMode, bool resetNextLandmark,
00151                 uint64 inputFrameRate, uint64 inputTime);
00152 
00153 //! setup the packat containing the salient region information
00154 //! to be recognized by the ventral module
00155 void setupVentralPacket
00156 ( TCPmessage  &smsg, int rframe,
00157   bool resetVentralSearch, Image< PixRGB<byte> > currIma,
00158   Image<double> cgist, std::vector<Point2D<int> > salpt,
00159   std::vector<std::vector<double> > feat, std::vector<Rectangle> objRect,
00160   float dx, float dy, uint snumGT, float ltravGT);
00161 
00162 //! setup the packet containing cmaps for tracking
00163 void setupDorsalPacket
00164 ( TCPmessage  &smsg, int rframe, ImageSet<float> cmap,
00165   bool resetCurrLandmark, std::vector<Point2D<int> > clmpt,
00166   bool resetNextLandmark, std::vector<Point2D<int> > nlmpt);
00167 
00168 //! get the proper motor command to run the robot
00169 void processDorsalResult
00170 ( TCPmessage &rmsg, int32 raction, int32 rframe,
00171   std::vector<Point2D<int> > &clmpt, std::vector<Point2D<int> > &nlmpt,
00172   bool &resetNextLandmark, float &sp, float &st);
00173 
00174 //! setup for the next search
00175 void processVentralResult
00176 ( TCPmessage &rmsg, int32 raction, int32 rframe,
00177   std::vector<Point2D<int> >  &clmpt, std::vector<Point2D<int> > &nlmpt,
00178   bool &resetCurrLandmark, bool &resetNextLandmark);
00179 
00180 //! get the odometry information
00181 void getOdometry(float &dx, float &dy);
00182 
00183 //! execute the motor command from Dorsal
00184 void executeMotorCommand(int opMode, float st, float sp);
00185 
00186 //! feed in the current ground truth
00187 Image<double>
00188 getGroundTruth(uint fNum, uint &snumGT, float &ltravGT, float &dx, float &dy);
00189 
00190 //! report the results of the current run
00191 void reportResults(std::string resultPrefix, uint nsegment);
00192 
00193 // ######################################################################
00194 //! Signal handler (e.g., for control-C)
00195 void terminate(int s)
00196 { LERROR("*** INTERRUPT ***"); goforever = false; exit(1); }
00197 
00198 // ######################################################################
00199 int main(const int argc, const char **argv)
00200 {
00201   MYLOGVERB = LOG_INFO;
00202 
00203   // instantiate a model manager:
00204   ModelManager manager("beobot Navigation using Gist and Saliency - Master");
00205 
00206   // Instantiate our various ModelComponents:
00207   //BeobotConfig bbc;
00208   //nub::soft_ref<BeoChip> b(new BeoChip(manager));
00209   //manager.addSubComponent(b);
00210 
00211   nub::soft_ref<InputFrameSeries> ifs(new InputFrameSeries(manager));
00212   manager.addSubComponent(ifs);
00213 
00214   nub::ref<BeobotBrainMT> bbmt(new BeobotBrainMT(manager));
00215   manager.addSubComponent(bbmt);
00216 
00217   nub::soft_ref<Beowulf>
00218     beo(new Beowulf(manager, "Beowulf Master", "BeowulfMaster", true));
00219   manager.addSubComponent(beo);
00220 
00221   manager.exportOptions(MC_RECURSE);
00222 
00223   // Parse command-line:
00224   // if (manager.parseCommandLine
00225   //     (argc, argv,
00226   //      "<operation mode: train/trainX/test> <environment file> "
00227   //      "[TR: number of segments     |TX: NodeNumber        |TS: delay] "
00228   //      "[TR: current Segment Number |TX: startEdge,endEdge |TS: fstart] "
00229   //      "[test run file prefix] ",
00230   //      2, 5)
00231   if (manager.parseCommandLine(argc, argv,
00232                                "<operation mode> <environment file> "
00233                                "[TR: number of segments | TS: delay] "
00234                                "[current Segment Number | TS: fstart] "
00235                                "[test run file prefix] ",
00236                                2, 5)
00237       == false) return(1);
00238 
00239   // do post-command-line configs:
00240 
00241   // let's configure our serial device:
00242   //b->setModelParamVal("BeoChipDeviceName", std::string("/dev/ttyS0"));
00243 
00244   // let's register our listener:
00245   //rutz::shared_ptr<BeobotBeoChipListener> lis(new BeobotBeoChipListener(b));
00246   //rutz::shared_ptr<BeoChipListener> lis2; lis2.dynCastFrom(lis); // cast down
00247   //b->setListener(lis2);
00248 
00249   // inputs: number of segments and current segment number
00250   // is needed for initial training, otherwise it is reset later on
00251   int nSegment = 0, currSegNum  = -1;
00252   //int currNodeNum = -1, startEdge = -1, endEdge = -1;
00253 
00254   // get the environment file and folder to save
00255   std::string envFName = manager.getExtraArg(1);
00256   std::string saveFilePath = "";
00257   std::string::size_type lspos = envFName.find_last_of('/');
00258   int ldpos = envFName.find_last_of('.');
00259   std::string envPrefix;
00260   if(lspos != std::string::npos)
00261     {
00262       saveFilePath = envFName.substr(0, lspos+1);
00263       envPrefix =  envFName.substr(lspos+1, ldpos - lspos - 1);
00264     }
00265   else
00266     envPrefix =  envFName.substr(0, ldpos - 1);
00267 
00268   // get the the input type and prefix to name the salient objects, gistfile
00269   int inputType;
00270   std::string testRunFPrefix =
00271     std::string("results_") + getInputPrefix(ifs, inputType);
00272   if(manager.numExtraArgs() > 4)
00273     testRunFPrefix = manager.getExtraArgAs<std::string>(4);
00274 
00275   std::string testRunFolder =
00276     saveFilePath + testRunFPrefix + std::string("/");
00277   std::string resultPrefix = testRunFolder + envPrefix;
00278 
00279   // get the operation mode
00280   int opMode = getOpMode(manager.getExtraArg(0));
00281 
00282   // means next frame will be processed once Ventral is done
00283   uint64 inputFrameRate = 0;
00284   uint fstart = 0;
00285 
00286   // handle the command line inputs
00287   LINFO("opmode: %d", opMode);
00288   if(opMode == TRAIN_MODE)
00289     {
00290       if(manager.numExtraArgs() < 4)
00291         LFATAL("Training needs at least 4 params");
00292       nSegment = manager.getExtraArgAs<int>(2);
00293       currSegNum = manager.getExtraArgAs<int>(3);
00294       LINFO("number of segments: %d", nSegment);
00295       LINFO("current segment: %d", currSegNum);
00296     }
00297   // else if(opMode == TRAIN_X_MODE)
00298   //   {
00299   //     if(manager.numExtraArgs() < 4)
00300   //       LFATAL("Junction training needs at least 4 params");
00301 
00302   //     currNodeNum = manager.getExtraArgAs<int>(2);
00303   //     std::string tempRange = manager.getExtraArg(3);
00304   //     std::string::size_type lspos = tempRange.size()-1;
00305   //     std::string::size_type lcpos = tempRange.find_last_of(',');
00306   //     startEdge = atoi(tempRange.substr(1, lcpos-1).c_str());
00307   //     endEdge   = atoi(tempRange.substr(lcpos+1, lspos).c_str());
00308 
00309   //     LINFO("Junction Node: %d", currNodeNum);
00310   //     LINFO("Start Edge: %d",    startEdge);
00311   //     LINFO("End   Edge: %d",    endEdge);
00312   //   }
00313   else if(opMode == TEST_MODE)
00314     {
00315       if(manager.numExtraArgs() >  2)
00316         inputFrameRate = manager.getExtraArgAs<uint>(2);
00317 
00318       if(manager.numExtraArgs() >  3)
00319         fstart = manager.getExtraArgAs<uint>(3);
00320     }
00321   else LFATAL("invalid opmode");
00322 
00323   LINFO("Environment file: %s", envFName.c_str());
00324   LINFO("Save file to this folder: %s", saveFilePath.c_str());
00325   LINFO("envPrefix: %s", envPrefix.c_str());
00326   LINFO("test run prefix: %s", testRunFPrefix.c_str());
00327   LINFO("test run folder: %s", testRunFolder.c_str());
00328   LINFO("result prefix: %s", resultPrefix.c_str());
00329   LINFO("frame frequency: %f ms/frame", inputFrameRate/1000.0F);
00330 
00331   // create the session result folder
00332   if (mkdir(testRunFolder.c_str(), 0777) == -1 && errno != EEXIST)
00333     {
00334       LFATAL("Cannot create log folder: %s", testRunFolder.c_str());
00335     }
00336 
00337   // HACK: results for paper
00338   //reportResults(resultPrefix, 9);  Raster::waitForKey();
00339 
00340   int w = ifs->getWidth(),  h = ifs->getHeight();
00341   std::string dims = convertToString(Dims(w, h));
00342   LINFO("image size: [%dx%d]", w, h);
00343   manager.setOptionValString(&OPT_InputFrameDims, dims);
00344 
00345   manager.setModelParamVal("InputFrameDims", Dims(w, h),
00346                            MC_RECURSE | MC_IGNORE_MISSING);
00347 
00348   TCPmessage rmsg;     // buffer to receive messages
00349   TCPmessage smsg;     // buffer to send messages
00350   int32 rframe = 0, raction = 0, rnode = 0;
00351 
00352   // catch signals and redirect them to terminate for clean exit:
00353   signal(SIGHUP, terminate); signal(SIGINT, terminate);
00354   signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00355   signal(SIGALRM, terminate);
00356 
00357   // let's do it!
00358   manager.start();
00359 
00360   // send params to dorsal and ventral node to initialize contact:
00361   smsg.reset(0, INIT_COMM);
00362   smsg.addInt32(int32(fstart));
00363   smsg.addInt32(int32(w));
00364   smsg.addInt32(int32(h));
00365   smsg.addInt32(int32(opMode));
00366   smsg.addInt32(int32(nSegment));
00367   smsg.addInt32(int32(currSegNum));
00368   smsg.addString(envFName.c_str());
00369   smsg.addString(testRunFPrefix.c_str());
00370   smsg.addString(saveFilePath.c_str());
00371   smsg.addString(resultPrefix.c_str());
00372 
00373   // send the same initial values message to both nodes
00374   beo->send(DORSAL_NODE, smsg);
00375   beo->send(VENTRAL_NODE, smsg);
00376 
00377   // saliency map
00378   Image<float> currSalMap(w >> sml, h >> sml, ZEROS);
00379 
00380   // image buffer and window for display:
00381   Image<PixRGB<byte> > disp(w * 5, h, ZEROS);
00382   //rutz::shared_ptr<XWinManaged> mwin
00383   //  (new XWinManaged(disp.getDims(), w*2 + 10, 0, "Master window"));
00384 
00385   // setup the configuration of BeoChip
00386   //setupBeoChip(b,bbc);
00387 
00388   // if we are on training mode
00389   // the remote control can be used to steer
00390   //if(opMode == TRAIN_MODE) lis->moveServo = true;
00391 
00392   ImageSet<float> cmap(NUM_CHANNELS);
00393   Point2D<int> lastwin(-1,-1); Point2D<int> lastwinsc(-1,-1);
00394 
00395   // SYNCHRONIZATION: wait until the other board is ready
00396   LINFO("waiting until Ventral and Dorsal is ready to go");
00397   rnode = VENTRAL_NODE;
00398   while(!beo->receive(rnode, rmsg, rframe, raction, 5));
00399   LINFO("%d is ready", rnode);
00400   rnode = DORSAL_NODE;
00401   while(!beo->receive(rnode, rmsg, rframe, raction, 5));
00402   LINFO("%d is ready", rnode);
00403   rmsg.reset(rframe, raction);
00404   LINFO("Ventral and Dorsal are ready to go");
00405   Raster::waitForKey();
00406 
00407   // time result file
00408   std::string resFName = resultPrefix + sformat("_M_results.txt");
00409 
00410   // MAIN LOOP
00411   bool resetCurrLandmark = false;
00412   std::vector<Point2D<int> > clmpt;     // landmarks that are currently followed
00413   bool resetNextLandmark = true;
00414   std::vector<Point2D<int> > nlmpt;     // landmarks that are currently searched
00415 
00416   float sp = 0.0f; float st = 0.0f;
00417 
00418   Timer inputTimer(1000000); uint64 t[NAVG]; float frate = 0.0f;
00419   Timer ventralTimer(1000000); Timer dorsalTimer(1000000);
00420   float vTime = -1.0F; float dTime = -1.0F;
00421 
00422   // feed an initial image to get the ball rolling
00423   bool dorsalReplied  = false; std::vector<float> procTime;
00424   bool resetVentralSearch = false;
00425   bool stopSent = false;
00426   Image<PixRGB<byte> > ima; int32 fNum = fstart;
00427   Image<PixRGB<byte> > prevIma; inputTimer.reset();
00428   ifs->updateNext(); ima = ifs->readRGB();
00429   if(!ima.initialized()) { goforever = false; }
00430   else { bbmt->input(ima);} //mwin->drawImage(ima,0,0); }
00431   while(goforever || !dorsalReplied)
00432     {
00433       // ADD GUI HANDLER HERE
00434 
00435       // beoChip procedures
00436       //int bcCom = beoChipProc(lis, b);
00437       //if(bcCom == BC_QUIT_SIGNAL) { goforever = false; break; }
00438 
00439 //       // keyboard input
00440 //       // FIX: figure out the mapping from just printing it
00441 //       //      get the 1 - 0 - enter sequence
00442 //       int tPress = mwin->getLastKeyPress();
00443 //       if(tPress != -1 && tPress >= 10 && tPress <= 18)
00444 //         currSegNum = tPress - 10;
00445 
00446       // if Dorsal computation is ready
00447       rnode = DORSAL_NODE; int32 rDframe;
00448       if(checkNode(opMode, beo, rnode, rmsg, raction, rDframe))
00449         {
00450           LINFO("IN DORSAL: %d", rDframe);
00451           processDorsalResult(rmsg, raction, rframe, clmpt, nlmpt,
00452                               resetNextLandmark, sp, st);
00453           dTime = dorsalTimer.get()/1000.0F;
00454           LDEBUG("Dorsal time[%d]: %f", rDframe, dTime);
00455           dorsalReplied = true;
00456         }
00457 
00458       // if ventral computation is ready
00459       //    & dorsal replied at least once
00460       rnode = VENTRAL_NODE; int32 rVframe;
00461       if(dorsalReplied &&
00462          checkNode(opMode, beo, rnode, rmsg, raction, rVframe))
00463         {
00464           processVentralResult(rmsg, raction, rframe, clmpt, nlmpt,
00465                                resetCurrLandmark, resetNextLandmark);
00466           LINFO("IN VENTRAL: %d ::: %d",  rVframe, resetNextLandmark);
00467 
00468           vTime = ventralTimer.get()/1000.0F;
00469           LDEBUG("Ventral time[%d]: %f", rVframe, vTime);
00470           stopSent = false;
00471         }
00472 
00473       // get odometry information
00474       float dx, dy; getOdometry(dx, dy);
00475 
00476       // execute the motor command
00477       executeMotorCommand(opMode, sp, st);
00478 
00479       // when the saliency and gist computation is ready
00480       // AND input timing is right
00481       uint64 inputTime = inputTimer.get();
00482       if(checkInput(opMode, resetNextLandmark, inputFrameRate, inputTime)
00483          && bbmt->outputReady())
00484         {
00485           t[fNum % NAVG] = inputTime; inputTimer.reset();
00486           Timer t1(1000000); t1.reset();
00487           float bbmtTime = bbmt->getProcessTime();
00488           rframe = fNum;
00489 
00490           // get all the necesary information from V1:
00491           Image<PixRGB<byte> > currIma; Image<float> currSalMap;
00492           Image<double> cgist;
00493           std::vector<Point2D<int> > salpt;
00494           std::vector<std::vector<double> >feat;
00495           std::vector<Rectangle> objRect;
00496           getBbmtResults(bbmt, currIma, cgist, currSalMap,
00497                          cmap, salpt, feat, objRect);
00498 
00499           // get the next frame and start processing
00500           FrameState fState = ifs->updateNext(); ima = ifs->readRGB();
00501           if(!ima.initialized() || fState == FRAME_COMPLETE)
00502             { goforever = false; }
00503           else bbmt->input(ima);
00504           uint snumGT = 0; float ltravGT = -1.0F;
00505 
00506           // get ground truth
00507           if(opMode == TEST_MODE)
00508             {
00509               getGroundTruth(fNum, snumGT, ltravGT, dx, dy);
00510               //cgist = getGroundTruth(fNum, snumGT, ltravGT, dx, dy);
00511               LINFO("GT: (%d, %f) d (%f, %f)", snumGT, ltravGT, dx, dy);
00512             }
00513 
00514           // if timer goes past the time limit and robot is moving
00515           // FIX: maybe we still discard search even if robot is stationary
00516           if(resetNextLandmark) ventralTimer.reset();
00517           if(inputFrameRate != 0 &&
00518              ventralTimer.get() > (inputFrameRate * SEARCH_TIME_LIMIT) &&
00519              !stopSent && sp != 0.0)
00520             {
00521               resetVentralSearch = true;
00522               LINFO("ventral time: %f ms. STOP", ventralTimer.get()/1000.0f);
00523               stopSent = true;
00524             }
00525 
00526           // set up the salient region packet and send to ventral
00527           setupVentralPacket
00528             (smsg, rframe, resetVentralSearch, currIma,
00529              cgist, salpt, feat, objRect, dx, dy, snumGT, ltravGT);
00530           beo->send(VENTRAL_NODE, smsg);
00531           resetVentralSearch = false;
00532           LINFO("send ventral done");
00533 
00534           // setup the tracking packet and send to dorsal
00535           setupDorsalPacket(smsg, rframe, cmap,
00536                             resetCurrLandmark, clmpt,
00537                             resetNextLandmark, salpt);
00538           beo->send(DORSAL_NODE, smsg);
00539           dorsalTimer.reset();
00540           dorsalReplied = false;
00541 
00542           // once landmarks are reset, we don't do it over again
00543           bool rCL = resetCurrLandmark;
00544           bool rNL = resetNextLandmark;
00545           if(resetCurrLandmark) resetCurrLandmark = false;
00546           if(resetNextLandmark) resetNextLandmark = false;
00547 
00548           // display the results
00549           //mwin->setTitle(sformat("fNum: %d",fNum).c_str());
00550           //dispResults(disp, mwin, currIma, prevIma, clmpt, nlmpt,
00551           //           currSalMap, salpt, objRect);
00552           prevIma = currIma;
00553           //Raster::waitForKey();
00554 
00555           // compute and show framerate over the last NAVG frames:
00556           float iTime = t[fNum % NAVG]/1000.0F;
00557           FILE *rFile = fopen(resFName.c_str(), "at");
00558           if (rFile != NULL)
00559             {
00560               // if ventral search has not returned
00561               float dispVTime = vTime;
00562               if(!rNL) dispVTime = ventralTimer.get()/1000.0F;
00563 
00564               std::string line =
00565                 sformat("%5d %11.5f %d %d %11.5f %11.5f %11.5f",
00566                         fNum, bbmtTime, rCL, rNL, dTime, dispVTime, iTime);
00567               LINFO("%s", line.c_str());
00568               line += std::string("\n");
00569               fputs(line.c_str(), rFile);
00570               fclose (rFile);
00571             }
00572           else LFATAL("can't create result file: %s", resFName.c_str());
00573 
00574           fNum++;
00575           if (fNum % NAVG == 0 && fNum > 0)
00576             {
00577               uint64 sum = 0ULL; for(int i = 0; i < NAVG; i ++) sum += t[i];
00578               frate = 1000000.0F / float(sum) * float(NAVG);
00579               LINFO("Fr: %6.3f fps -> %8.3f ms/f\n", frate, 1000.0/frate);
00580             }
00581           uint64 ptime = t1.get(); float ptime2 = ptime/1000.0;
00582           procTime.push_back(ptime2);
00583           LDEBUG("total proc time: %f", ptime2);
00584           t1.reset();
00585         }
00586       //else{ usleep(10); }
00587     }
00588 
00589   // wait for the ventral response for one more time step
00590   uint64 inputTime = inputTimer.get();
00591   while(!checkInput(opMode, resetNextLandmark, inputFrameRate, inputTime))
00592     {
00593       rnode = VENTRAL_NODE; int32 rVframe;
00594       if(checkNode(opMode, beo, rnode, rmsg, raction, rVframe))
00595         {
00596           processVentralResult(rmsg, raction, rframe, clmpt, nlmpt,
00597                                resetCurrLandmark, resetNextLandmark);
00598           vTime = ventralTimer.get()/1000.0F;
00599           LINFO("Ventral time[%d]: %f", rVframe, vTime);
00600         }
00601 
00602       usleep(1000);
00603       inputTime = inputTimer.get();
00604     }
00605 
00606   // save last time step performance
00607   FILE *rFile = fopen(resFName.c_str(), "at");
00608   if (rFile != NULL)
00609     {
00610       float dispVTime = vTime;
00611       if(!resetNextLandmark) dispVTime = ventralTimer.get()/1000.0F;
00612 
00613       std::string line =
00614         sformat("%5d %11.5f %d %d %11.5f %11.5f %11.5f",
00615                 fNum, -1.0F, resetCurrLandmark, resetNextLandmark,
00616                 dTime, dispVTime, inputTime/1000.0);
00617       LINFO("%s", line.c_str());
00618       line += std::string("\n");
00619       fputs(line.c_str(), rFile);
00620       fclose (rFile);
00621     }
00622   else LFATAL("can't create result file: %s", resFName.c_str());
00623 
00624   // signal the other processors to stop working
00625   LINFO("sending ABORT to Dorsal");
00626   rframe = fNum;
00627   smsg.reset(rframe, ABORT);
00628   beo->send(DORSAL_NODE, smsg);
00629   //rnode = DORSAL_NODE;
00630   //while(!beo->receive(rnode, rmsg, rframe, raction, 5));
00631   //LINFO("rec Dorsal");
00632   //rmsg.reset(rframe,raction);
00633 
00634   LINFO("sending ABORT to ventral");
00635   beo->send(VENTRAL_NODE, smsg);
00636   rnode = VENTRAL_NODE;
00637   while(!beo->receive(rnode, rmsg, rframe, raction, 5));
00638   LINFO("rec Ventral");
00639   rmsg.reset(rframe,raction);
00640 
00641   // ending operations
00642   // this needs both XXX_M_results.txt and XXX_results.txt
00643   switch(opMode)
00644     {
00645     case TRAIN_MODE: break;
00646 
00647     case TEST_MODE:
00648       {
00649         // report some statistical data
00650         reportResults(resultPrefix, 9);
00651 
00652         float min = 0.0f, max = 0.0f;
00653         if(procTime.size() > 0){ min = procTime[0]; max = procTime[0]; }
00654         for(uint i = 1; i < procTime.size(); i++)
00655           {
00656             if (min > procTime[i]) min = procTime[i];
00657             if (max < procTime[i]) max = procTime[i];
00658           }
00659         LINFO("proc Time: %f - %f", min, max);
00660       }
00661       break;
00662 
00663     default: LERROR("Unknown operation mode");
00664     }
00665 
00666   LINFO("we can now exit");
00667   Raster::waitForKey();
00668 
00669   // get ready to terminate:
00670   manager.stop();
00671   return 0;
00672 }
00673 
00674 // ######################################################################
00675 std::string getInputPrefix(nub::soft_ref<InputFrameSeries> ifs,
00676                            int &inputType)
00677 {
00678   std::string input =
00679     ifs->getModelParamVal<std::string>("InputFrameSource");
00680   std::string prefix;
00681 
00682   // if it camera input
00683   std::string camInput("ieee1394");
00684   if(!input.compare(camInput))
00685     {
00686       inputType = CAMERA_INPUT;
00687       // use the time of day
00688       time_t rawtime; struct tm * timeinfo;
00689       time ( &rawtime );
00690       timeinfo = localtime ( &rawtime );
00691       std::string cTime(asctime (timeinfo));
00692       cTime = cTime.substr(4); // take out the day
00693 
00694       for(uint i = 0; i < cTime.length(); i++)
00695         if(cTime[i] == ' ' || cTime[i] == ':') cTime[i] = '_';
00696       prefix = std::string("cam_") + cTime;
00697       LINFO("Camera input, prefix: %s", prefix.c_str());
00698     }
00699   // if it is a frame series input
00700   else if(input.find_last_of('#') == (input.length() - 5))
00701     {
00702       inputType = FILE_INPUT;
00703 
00704       prefix = input.substr(0, input.length() - 5);
00705       std::string::size_type spos = prefix.find_last_of('/');
00706       if(spos != std::string::npos)
00707         prefix = prefix.substr(spos+1);
00708 
00709       // if the last part of the prefix is an '_'
00710       if(prefix.find_last_of('_') == prefix.length() - 1)
00711         {
00712           // take it out
00713           prefix = prefix.substr(0, prefix.length() - 1);
00714         }
00715 
00716       LINFO("Frame series input, prefix: %s", prefix.c_str());
00717     }
00718   // it is an mpeg
00719   else
00720     {
00721       inputType = FILE_INPUT;
00722 
00723       prefix = input.substr(0, input.length() - 4);
00724       std::string::size_type spos = prefix.find_last_of('/');
00725       if(spos != std::string::npos)
00726         prefix = prefix.substr(spos+1);
00727 
00728       LINFO("mpeg Input, prefix: %s", prefix.c_str());
00729     }
00730 
00731   return prefix;
00732 }
00733 
00734 // ######################################################################
00735 int getOpMode(std::string opmodestr)
00736 {
00737   // compare returns zero if they are equal
00738   std::string trainMode("train");  int op;
00739   //std::string trainXMode("trainX");
00740   if(!opmodestr.compare(trainMode)) op = TRAIN_MODE;
00741   //else if(!opmodestr.compare(trainXMode)) op = TRAIN_X_MODE;
00742   else op = TEST_MODE;
00743   return op;
00744 }
00745 
00746 // ######################################################################
00747 void setupBeoChip(nub::soft_ref<BeoChip> b, BeobotConfig bbc)
00748 {
00749   // reset the beochip:
00750   LINFO("Resetting BeoChip...");
00751   b->resetChip(); sleep(1);
00752 
00753   // calibrate the servos
00754   b->calibrateServo(bbc.steerServoNum, bbc.steerNeutralVal,
00755                     bbc.steerMinVal, bbc.steerMaxVal);
00756   b->calibrateServo(bbc.speedServoNum, bbc.speedNeutralVal,
00757                     bbc.speedMinVal, bbc.speedMaxVal);
00758   b->calibrateServo(bbc.gearServoNum, bbc.gearNeutralVal,
00759                     bbc.gearMinVal, bbc.gearMaxVal);
00760 
00761   // keep the gear at the lowest speed/highest Ntorque
00762   b->setServoRaw(bbc.gearServoNum, bbc.gearMinVal);
00763 
00764   // zero out the speed
00765   //b->setServoRaw(bbc.speedServoNum, bbc.speedNeutralVal);
00766 
00767   // turn on the keyboard
00768   b->debounceKeyboard(true);
00769   b->captureKeyboard(true);
00770 
00771   // calibrate the PWMs:
00772   b->calibratePulse(0,
00773                     bbc.pwm0NeutralVal,
00774                     bbc.pwm0MinVal,
00775                     bbc.pwm0MaxVal);
00776   b->calibratePulse(1,
00777                     bbc.pwm1NeutralVal,
00778                     bbc.pwm1MinVal,
00779                     bbc.pwm1MaxVal);
00780   b->capturePulse(0, true);
00781   b->capturePulse(1, true);
00782 
00783   // let's play with the LCD:
00784   b->lcdClear();   // 01234567890123456789
00785   b->lcdPrintf(0, 0, "collectFrames: 00000");
00786   b->lcdPrintf(0, 1, "STEER=XXX  SPEED=XXX");
00787   b->lcdPrintf(0, 2, "PWM0=0000  0000-0000");
00788   b->lcdPrintf(0, 3, "PWM1=0000  0000-0000");
00789 }
00790 
00791 // ######################################################################
00792 void getOdometry(float &dx, float &dy)
00793 {
00794   dx = 0.0F;
00795   dy = 0.0F;
00796 }
00797 
00798 // ######################################################################
00799 void executeMotorCommand(int opMode, float st, float sp)
00800 {
00801   switch(opMode)
00802     {
00803     case TRAIN_MODE:
00804     case TEST_MODE:
00805       // a remote controller to train the robot
00806 
00807       // have a point to pursue
00808 
00809       // or to close to it
00810 
00811       // execute action command
00812       //b->setServo(bbc.steerServoNum, st);
00813       //b->setServo(bbc.speedServoNum, sp);
00814       break;
00815     default:
00816       LERROR("Unknown operation mode");
00817     }
00818 }
00819 
00820 // ######################################################################
00821 void dispResults
00822 ( Image< PixRGB<byte> > disp, rutz::shared_ptr<XWinManaged> win,
00823   Image< PixRGB<byte> > ima, Image< PixRGB<byte> > prevIma,
00824   std::vector<Point2D<int> > clmpt, std::vector<Point2D<int> > nlmpt,
00825   Image<float> currSalMap,
00826   std::vector<Point2D<int> > salpt, std::vector<Rectangle> objRect)
00827 {
00828   int w = ima.getWidth();
00829   int h = ima.getHeight();
00830   const int foa_size = std::min(w, h) / 12;
00831 
00832   // display input image:
00833   inplacePaste(disp, ima, Point2D<int>(0, 0));
00834 
00835   // display the saliency map
00836   Image<float> dispsm = quickInterpolate(currSalMap * SMFAC, 1 << sml);
00837   inplaceNormalize(dispsm, 0.0f, 255.0f);
00838   Image<PixRGB<byte> > sacImg = Image<PixRGB<byte> >(toRGB(dispsm));
00839   for(uint i = 0; i < objRect.size(); i++)
00840     drawRect(sacImg,objRect[i],PixRGB<byte>(255,0,0));
00841   inplacePaste(disp, sacImg, Point2D<int>(w, 0));
00842 
00843   // draw coordinates of fixation for both input and sal image
00844   for(uint i = 0; i < salpt.size(); i++)
00845     {
00846       Point2D<int> salpt2(salpt[i].i + w, salpt[i].j);
00847       drawDisk(disp, salpt[i], foa_size/6+2, PixRGB<byte>(20, 50, 255));
00848       drawDisk(disp, salpt[i], foa_size/6,   PixRGB<byte>(255, 255, 20));
00849       drawDisk(disp, salpt2,   foa_size/6+2, PixRGB<byte>(20, 50, 255));
00850       drawDisk(disp, salpt2,   foa_size/6,   PixRGB<byte>(255, 255, 20));
00851     }
00852 
00853   // draw the SE bounding box
00854   Image< PixRGB<byte> > roiImg = ima;
00855   for(uint i = 0; i < objRect.size(); i++)
00856     {
00857       drawRect(roiImg, objRect[i], PixRGB<byte>(255,255,0));
00858       drawDisk(roiImg, salpt[i], 3, PixRGB<byte>(255,0,0));
00859       std::string ntext(sformat("%d", i));
00860       writeText(roiImg, salpt[i], ntext.c_str());
00861     }
00862   inplacePaste(disp, roiImg, Point2D<int>(w*2, 0));
00863 
00864   // if there is a previous image
00865   if(prevIma.initialized())
00866     {
00867       // display the current landmark tracked
00868       Image< PixRGB<byte> > clmDisp = prevIma;
00869         for(uint i = 0; i < clmpt.size(); i++)
00870           {
00871             if(clmpt[i].isValid())
00872               {
00873                 drawDisk(clmDisp, clmpt[i], 3, PixRGB<byte>(0,255,0));
00874                 std::string ntext(sformat("%d", i));
00875                 writeText(clmDisp, clmpt[i], ntext.c_str());
00876               }
00877           }
00878         inplacePaste(disp, clmDisp, Point2D<int>(w*3, 0));
00879 
00880         // display the next landmark tracked
00881         Image< PixRGB<byte> > nlmDisp = prevIma;
00882         for(uint i = 0; i < nlmpt.size(); i++)
00883           {
00884             if(nlmpt[i].isValid())
00885               {
00886                 drawDisk(nlmDisp, nlmpt[i], 3, PixRGB<byte>(0,255,255));
00887                 std::string ntext(sformat("%d", i));
00888                 writeText(nlmDisp, nlmpt[i], ntext.c_str());
00889               }
00890           }
00891         inplacePaste(disp, nlmDisp, Point2D<int>(w*4, 0));
00892     }
00893 
00894   // display the image
00895   win->drawImage(disp,0,0);
00896   //Raster::waitForKey();
00897 }
00898 
00899 // ######################################################################
00900 int beoChipProc(rutz::shared_ptr<BeobotBeoChipListener> lis,
00901                 nub::soft_ref<BeoChip> b)
00902 {
00903   // print keyboard values:
00904   char kb[6]; kb[5] = '\0';
00905   for (int i = 0; i < 5; i ++) kb[i] = (lis->kbd>>(4-i))&1 ? '1':'0';
00906 
00907   // quit if both extreme keys pressed simultaneously:
00908   if (kb[0] == '0' && kb[4] == '0') {
00909     b->lcdPrintf(15, 0, "QUIT ");
00910 
00911     // return QUIT signal
00912     return BC_QUIT_SIGNAL;
00913   }
00914 
00915   return BC_NO_SIGNAL;
00916 }
00917 
00918 // ######################################################################
00919 void getBbmtResults
00920 ( nub::ref<BeobotBrainMT> bbmt,
00921   Image<PixRGB<byte> > &currIma, Image<double> &cgist,
00922   Image<float> &currSalMap, ImageSet<float> &cmap,
00923   std::vector<Point2D<int> > &salpt,  std::vector<std::vector<double> > &feat,
00924   std::vector<Rectangle> &objRect)
00925 {
00926   // current image, gist vector, and saliency map
00927   currIma    = bbmt->getCurrImage();
00928   cgist      = bbmt->getGist();
00929   currSalMap = bbmt->getSalMap();
00930 
00931   // current conspicuity maps
00932   for(uint i = 0; i < NUM_CHANNELS; i++) cmap[i] = bbmt->getCurrCMap(i);
00933 
00934   salpt.clear(); objRect.clear();
00935   uint numpt = bbmt->getNumSalPoint();
00936   for(uint i = 0; i < numpt; i++)
00937     {
00938       salpt.push_back(bbmt->getSalPoint(i));
00939       objRect.push_back(bbmt->getObjRect(i));
00940 
00941       std::vector<double> features; bbmt->getSalientFeatures(i, features);
00942       feat.push_back(features);
00943 
00944     }
00945 }
00946 
00947 // ######################################################################
00948 bool checkNode
00949 ( int opMode, nub::soft_ref<Beowulf> beo,
00950   int32 &rnode, TCPmessage &rmsg, int32 &raction, int32 &rframe)
00951 {
00952   // non-blocking call
00953   if(beo->receive(rnode, rmsg, rframe, raction))  return true;
00954   // && (rmsg.getSize() == 0));
00955   return false;
00956 }
00957 
00958 // ######################################################################
00959 bool checkInput(int opMode, bool resetNextLandmark, uint64 inputFrameRate,
00960                 uint64 inputTime)
00961 {
00962   // if train mode: need to have a ventral reset signal
00963   if(opMode == TRAIN_MODE && resetNextLandmark) return true;
00964 
00965   // if test mode and using infinite time: need reset signal
00966   if(opMode == TEST_MODE && inputFrameRate == 0 &&
00967      resetNextLandmark) return true;
00968 
00969   // else test mode and need to get in after time is up
00970   if(opMode == TEST_MODE && inputFrameRate != 0 &&
00971      (inputFrameRate - ERR_INTERVAL) < inputTime) return true;
00972 
00973   return false;
00974 }
00975 
00976 // ######################################################################
00977 void setupVentralPacket
00978 ( TCPmessage  &smsg, int rframe,
00979   bool resetVentralSearch, Image< PixRGB<byte> > currIma,
00980   Image<double> cgist, std::vector<Point2D<int> > salpt,
00981   std::vector<std::vector<double> > feat, std::vector<Rectangle> objRect,
00982   float dx, float dy, uint snumGT, float ltravGT)
00983 {
00984   // FIX SEND TO VENTRAL
00985   // put a label that we are trying to track
00986   // and recognize the current tracked object
00987   // while we also want to track a new location for next
00988 
00989   // signal if we need to reset the landmark search
00990   smsg.reset(rframe, SEARCH_LM);
00991   smsg.addInt32(int32(resetVentralSearch));
00992 
00993   // send the full image (cropping done on the other side)
00994   smsg.addImage(currIma);
00995 
00996   // send the gist vector
00997   smsg.addInt32(int32(cgist.getSize()));
00998   Image<double>::iterator aptr = cgist.beginw();
00999   for(int i = 0; i < cgist.getSize(); i++) smsg.addDouble(*aptr++);
01000 
01001   // send the number of salient points included
01002   smsg.addInt32(int32(salpt.size()));
01003   for(uint i = 0; i < salpt.size(); i++)
01004     {
01005       // salient point
01006       smsg.addInt32(int32(salpt[i].i));
01007       smsg.addInt32(int32(salpt[i].j));
01008 
01009       // top, left, bottom, right
01010       smsg.addInt32(int32(objRect[i].top()));
01011       smsg.addInt32(int32(objRect[i].left()));
01012       smsg.addInt32(int32(objRect[i].bottomO()));
01013       smsg.addInt32(int32(objRect[i].rightO()));
01014       smsg.addInt32(int32(feat[i].size()));
01015       LDEBUG("[%u] salpt:(%s) r:[%s]", i,
01016              convertToString(salpt[i]).c_str(),
01017              convertToString(objRect[i]).c_str());
01018       for(uint j = 0; j < feat[i].size(); j++)
01019           smsg.addDouble(feat[i][j]);
01020     }
01021 
01022   // pass in the odometry information
01023   smsg.addFloat(dx);
01024   smsg.addFloat(dy);
01025 
01026   // pass in the ground truth
01027   smsg.addInt32(int32(snumGT));
01028   smsg.addFloat(ltravGT);
01029 
01030   LINFO("setup VENTRAL %d", rframe );
01031 }
01032 
01033 // ######################################################################
01034 void setupDorsalPacket
01035 ( TCPmessage  &smsg, int rframe, ImageSet<float> cmap,
01036   bool resetCurrLandmark, std::vector<Point2D<int> > clmpt,
01037   bool resetNextLandmark, std::vector<Point2D<int> > nlmpt)
01038 {
01039   // tracking packet: always have the cmap
01040   smsg.reset(rframe, TRACK_LM);
01041   smsg.addImageSet(cmap);
01042   smsg.addInt32(int32(resetCurrLandmark));
01043   smsg.addInt32(int32(resetNextLandmark));
01044   smsg.addInt32(int32(clmpt.size()));
01045   LDEBUG("[%4d] reset currLM? %d nextLM? %d",
01046          rframe, resetCurrLandmark, resetNextLandmark);
01047 
01048   for(uint i = 0; i < clmpt.size(); i++)
01049     {
01050       smsg.addInt32(int32(clmpt[i].i));
01051       smsg.addInt32(int32(clmpt[i].j));
01052       LDEBUG("curr[%d]: (%3d, %3d)", i, clmpt[i].i, clmpt[i].j);
01053     }
01054 
01055   smsg.addInt32(int32(nlmpt.size()));
01056   for(uint i = 0; i < nlmpt.size(); i++)
01057     {
01058       smsg.addInt32(int32(nlmpt[i].i));
01059       smsg.addInt32(int32(nlmpt[i].j));
01060       LDEBUG("next[%d]: (%3d, %3d)", i, nlmpt[i].i, nlmpt[i].j);
01061     }
01062 }
01063 
01064 // ######################################################################
01065 void processVentralResult
01066 ( TCPmessage &rmsg, int32 raction, int32 rframe,
01067   std::vector<Point2D<int> > &clmpt, std::vector<Point2D<int> > &nlmpt,
01068   bool &resetCurrLandmark, bool &resetNextLandmark)
01069 {
01070   if(raction == SEARCH_LM_RES)
01071     {
01072       LDEBUG("Packet size: %d", rmsg.getSize());
01073       bool isLocalized = true;
01074       int searchFrame = int(rmsg.getElementInt32());
01075       int sentAt      = int(rmsg.getElementInt32());
01076       rmsg.reset(rframe, raction);
01077       LINFO("Ventral processing[%d]: SEARCH_LM_RES: %d sent at %d\n",
01078             rframe, searchFrame, sentAt);
01079 
01080       // check the return type:
01081       // CURR_LM, NEXT_LM, BOTH_LM
01082       // CURR_LM: for feedback for current landmark dorsal tracking
01083       // NEXT_LM: for feedback for next landmark dorsal tracking
01084       // BOTH_LM: for feedback for both landmarks dorsal tracking
01085 
01086       // NEW FUNKY IDEA:
01087       // TRACKED_OBJ_W_BIAS, TRACKED_OBJECT_WO_BIAS
01088       // when the object is about to be passed
01089       // use the frame num of the DB
01090 
01091       // get the object setup the tracking:
01092 
01093       // if current landmark is identified
01094       //   we can keep tracking
01095       // -> note that it also returns the proper location in the memory
01096       //    that is, at which side of the corridor it was located & how far away
01097       //    we can use the getAffineDiff
01098       //  horizontal comp: - val: move right, + val: move left
01099       // otherwise tracking is lost
01100 
01101       // if next landmark is identified
01102       if(isLocalized)
01103         {
01104           // usually we make the new Landmark be the current one
01105           clmpt.clear();
01106           for(uint i = 0; i < nlmpt.size(); i++)
01107             clmpt.push_back(nlmpt[i]);
01108           resetCurrLandmark = true;
01109           // also try to bias to the next landmark
01110         }
01111       else
01112         {
01113           // otherwise, nothing to do
01114           //we'll just start a new search
01115         }
01116       resetNextLandmark = true;
01117     }
01118 }
01119 
01120 // ######################################################################
01121 void processDorsalResult
01122 (TCPmessage &rmsg,  int32 raction, int32 rframe,
01123  std::vector<Point2D<int> > &clmpt, std::vector<Point2D<int> > &nlmpt,
01124  bool &resetNextLandmark, float &sp, float &st)
01125 {
01126   if(raction == TRACK_LM_RES)
01127     {
01128       LDEBUG("Dorsal TRACK_LM_RES[%4d]", rframe);
01129       uint nClmpt = (rmsg.getElementInt32());
01130       clmpt.clear();
01131       for(uint i = 0; i < nClmpt; i++)
01132         {
01133           uint cI = int(rmsg.getElementInt32());
01134           uint cJ = int(rmsg.getElementInt32());
01135           clmpt.push_back(Point2D<int>(cI,cJ));
01136           if(clmpt[i].isValid())
01137             LDEBUG("track currLM[%d]: (%3d, %3d)",
01138                    i, clmpt[i].i, clmpt[i].j);
01139           else
01140             LINFO("track currLM[%d]: (%3d, %3d) LOST",
01141                   i, clmpt[i].i, clmpt[i].j);
01142         }
01143 
01144       uint nNlmpt = (rmsg.getElementInt32());
01145       nlmpt.clear();
01146       for(uint i = 0; i < nNlmpt; i++)
01147         {
01148           uint nI = int(rmsg.getElementInt32());
01149           uint nJ = int(rmsg.getElementInt32());
01150           nlmpt.push_back(Point2D<int>(nI,nJ));
01151           if(nlmpt[i].isValid())
01152             LDEBUG("track nextLM[%d]: (%3d, %3d)",
01153                    i, nlmpt[i].i, nlmpt[i].j);
01154           else
01155             LINFO("track nextLM[%d]: (%3d, %3d) LOST",
01156                   i, nlmpt[i].i, nlmpt[i].j);
01157         }
01158       rmsg.reset(rframe, raction);
01159 
01160       //FIX: there is a time where tracking would fail
01161 
01162       // scenarios:
01163       // track currlm only: when the segment is about to end
01164       // track nextlm only: when starting a segment
01165       // track both: in between 2 landmarks
01166 
01167       // if current landmark is lost
01168       //if(false)//!clmptFound)
01169       //  {
01170           // stop motor:
01171           // have to wait for SEARCH_LM to return an answer
01172           // tell them to take all the time it needs
01173       //    sp = 0.0f; st = 0.0f;
01174       //  }
01175 
01176       // if next landmark is lost
01177       //if(!nlmptFound)
01178       //  {
01179           // stop DB search in Ventral
01180           // there's no use, it's already past
01181       //    resetNextLandmark = true;
01182       //    LINFO("stop Ventral Search");
01183       //  }
01184 
01185       // if both points are found
01186       //if(clmptFound && nlmptFound)
01187       //  {
01188           // process for best motor command
01189           // that keeps all points within sight
01190 
01191           // FIX: how do we home location in this case ??
01192       //  }
01193 
01194       // RESEARCH: if both tracked landmarks are lost:
01195       // add motion energy - run straight slowly
01196       // need special exploration stuff: scan in place 180 degrees
01197     }
01198 }
01199 
01200 // ######################################################################
01201 Image<double>
01202 getGroundTruth(uint fNum, uint &snumGT, float &ltravGT, float &dx, float &dy)
01203 {
01204 //   // ACB IROS 07 test
01205 //   uint sfnum [9] = {  377,  496,  541,  401,  304,  555,  486,  327,  307 };
01206 //   uint ssfnum[9] = {    0,  377,  873, 1414, 1815, 2119, 2674, 3160, 3487 };
01207 
01208 //   // AnFpark IROS 07 test
01209 //   uint sfnum [9] = {  866,  569,  896,  496,  769, 1250,  588,  844,  919 };
01210 //   uint ssfnum[9] = {    0,  866, 1435, 2331, 2827, 3596, 4846, 5434, 6278 };
01211 
01212 //   // FDFpark IROS 07 test
01213 //   uint sfnum [9] = {  782,  813,  869,  795,  857, 1434,  839, 1149,  749 };
01214 //   uint ssfnum[9] = {    0,  782, 1595, 2464, 3259, 4116, 5550, 6389, 7538 };
01215 
01216   // =====================================================================
01217 //   // ACB_1 IEEE-TR 07 test T_A
01218 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/ACB/gist/ACB");
01219 //   uint sfnum [9] = {  387,  440,  465,  359,  307,  556,  438,  290,  341 };
01220 //   uint ssfnum[9] = {    0,  387,  827, 1292, 1651, 1958, 2514, 2952, 3242 };
01221 
01222 //   // ACB_2 IEEE-TR 07 test T_B
01223 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/ACB/gist/ACB");
01224 //   uint sfnum [9] = {  410,  436,  485,  321,  337,  495,  445,  247,  373 };
01225 //   uint ssfnum[9] = {    0,  410,  846, 1331, 1652, 1989, 2484, 2929, 3176 };
01226 
01227   // // ACB_3 IEEE-TR 07 test T_E
01228   // std::string stem("/lab/tmpib/u/siagian/PAMI07/ACB/gist/ACB");
01229   // uint sfnum [9] = {  388,  461,  463,  305,  321,  534,  398,  274,  313 };
01230   // uint ssfnum[9] = {    0,  388,  849, 1312, 1617, 1938, 2472, 2870, 3144 };
01231 
01232 //   // ACB_4 IEEE-TR 07 test T_F
01233 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/ACB/gist/ACB");
01234 //   uint sfnum [9] = {  411,  438,  474,  249,  319,  502,  400,  288,  296 };
01235 //   uint ssfnum[9] = {    0,  411,  849, 1323, 1572, 1891, 2393, 2793, 3081 };
01236 
01237 //   // AnFpark_1 IEEE-TR 07 test D
01238 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/AnFpark/gist/AnFpark");
01239 //   uint sfnum [9] = {  698,  570,  865,  488,  617, 1001,  422,  598,  747 };
01240 //   uint ssfnum[9] = {    0,  698, 1268, 2133, 2621, 3238, 4239, 4661, 5259 };
01241 
01242 //   // AnFpark_2 IEEE-TR 07 test J
01243 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/AnFpark/gist/AnFpark");
01244 //   uint sfnum [9] = {  802,  328,  977,  597,  770, 1122,  570,  692,  809 };
01245 //   uint ssfnum[9] = {    0,  802, 1130, 2107, 2704, 3474, 4596, 5166, 5858 };
01246 
01247 //   // AnFpark_3 IEEE-TR 07 test T_A
01248 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/AnFpark/gist/AnFpark");
01249 //   uint sfnum [9] = {  891,  474,  968,  688,  774, 1003,  561,  797,  862 };
01250 //   uint ssfnum[9] = {    0,  891, 1365, 2333, 3021, 3795, 4798, 5359, 6156 };
01251 
01252 //   // AnFpark_4 IEEE-TR 07 test T_B
01253 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/AnFpark/gist/AnFpark");
01254 //   uint sfnum [9] = {  746,  474,  963,  632,  777, 1098,  399,  768,  849 };
01255 //   uint ssfnum[9] = {    0,  746, 1220, 2183, 2815, 3592, 4690, 5089, 5857 };
01256 
01257 //   // FDFpark_1 IEEE-TR 07 test T_C
01258 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/FDFpark/gist/FDFpark");
01259 //   uint sfnum [9] = {  881,  788,  858,  837,  831, 1680, 1037, 1172,  739 };
01260 //   uint ssfnum[9] = {    0,  881, 1669, 2527, 3364, 4195, 5875, 6912, 8084 };
01261 
01262 //   // FDFpark_2 IEEE-TR 07 test T_D
01263 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/FDFpark/gist/FDFpark");
01264 //   uint sfnum [9] = {  670,  740,  696,  740,  748, 1565,  923, 1211,  825 };
01265 //   uint ssfnum[9] = {    0,  670, 1410, 2106, 2846, 3594, 5159, 6082, 7293 };
01266 
01267 //   // FDFpark_3 IEEE-TR 07 test T_H
01268 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/FDFpark/gist/FDFpark");
01269 //   uint sfnum [9] = {  847,  797,  922,  837,  694, 1712,  857, 1355,  794 };
01270 //   uint ssfnum[9] = {    0,  847, 1644, 2566, 3403, 4097, 5809, 6666, 8021 };
01271 
01272 //   // FDFpark_4 IEEE-TR 07 test T_I
01273 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/FDFpark/gist/FDFpark");
01274 //   uint sfnum [9] = {  953,  878,  870,  821,  854, 1672,  894, 1270,  743 };
01275 //   uint ssfnum[9] = {    0,  953, 1831, 2701, 3522, 4376, 6048, 6942, 8212 };
01276 
01277   // =====================================================================
01278 //   // ACB_1 ICRA 08 test T_A
01279 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/ACB/gist/ACB");
01280 //   uint sfnum [9] = {  387,  440,  465,  359,  307,  556,  438,  290,  341 };
01281 //   uint ssfnum[9] = {    0,  387,  827, 1292, 1651, 1958, 2514, 2952, 3242 };
01282 
01283 //   // AnFpark_1 IEEE-TR 07 test D
01284 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/AnFpark/gist/AnFpark");
01285 //   uint sfnum [9] = {  698,  570,  865,  488,  617, 1001,  422,  598,  747 };
01286 //   uint ssfnum[9] = {    0,  698, 1268, 2133, 2621, 3238, 4239, 4661, 5259 };
01287 
01288 //   // FDFpark_1 IEEE-TR 07 test T_C
01289 //   std::string stem("/lab/tmpib/u/siagian/PAMI07/FDFpark/gist/FDFpark");
01290 //   uint sfnum [9] = {  881,  788,  858,  837,  831, 1680, 1037, 1172,  739 };
01291 //   uint ssfnum[9] = {    0,  881, 1669, 2527, 3364, 4195, 5875, 6912, 8084 };
01292 
01293   // HNB testing for Loc & Nav
01294   std::string stem("../data/HNB_T/gist/");
01295   uint sfnum [4] = { 655,  653,  521,  353 };
01296   uint ssfnum[4] = {   0,  655, 1308, 1829 };
01297   //uint ssfnum[4] = { 21696, 22351, 23004, 23525 };
01298 
01299   //FILE *gfp;
01300   int afnum = 0;
01301   //for(uint i = 0; i < 9; i++)
01302   for(uint i = 0; i < 4; i++)
01303     {
01304       if((fNum >= ssfnum[i]) && (fNum < ssfnum[i]+sfnum[i]))
01305         {
01306           stem = stem + sformat("_T_%dE", i+1);
01307           afnum = fNum - ssfnum[i];
01308           dx = 1.0/float(sfnum[i]); dy = 0.0F;
01309           snumGT = i; ltravGT = float(afnum)/float(sfnum[i]);
01310           break;
01311         }
01312     }
01313 
01314 //   ltravGT = fNum/866.0; dx = 1/866.0; afnum = fNum;
01315 //   stem = sformat("/lab/tmpib/u/siagian/PAMI07/ACB/gist/ACB1B");
01316 
01317   // std::string gfname = stem + sformat("_%03d.gist", afnum);
01318   Image<double> cgist(1, 714, NO_INIT);
01319   // if((gfp = fopen(gfname.c_str(),"rb")) != NULL)
01320   //   {
01321   //     Image<double>::iterator aptr = cgist.beginw();
01322   //     for(uint i = 0; i < 714; i++)
01323   //       {
01324   //         double val;  fread(&val, sizeof(double), 1, gfp);
01325   //         *aptr++ = val;
01326   //       }
01327   //     LDEBUG("gist file found: %s ground truth: %d %f",
01328   //            gfname.c_str(), snumGT, ltravGT);
01329 
01330   //     fclose(gfp);
01331   //   }
01332   // else LFATAL("gist file NOT found: %s", gfname.c_str());
01333 
01334   //Image<double> tempGist(1,544, NO_INIT); uint tcount = 0;
01335   // for(uint i = 0; i < 714; i++)
01336   //   {
01337   //     //if(i%21 >= 5)
01338   //       {
01339   //         tempGist.setVal(0, tcount, cgist.getVal(i)); tcount++;
01340   //       }
01341   //   }
01342 
01343   // add random error to the robot movement
01344   dy =+ 0.0F; //FIX
01345 
01346   return cgist;
01347 }
01348 
01349 // ######################################################################
01350 void reportResults(std::string resultPrefix, uint nsegment)
01351 {
01352   // NOTE: for crash recovery
01353   //  resultPrefix = std::string("/lab/tmpib/u/siagian/PAMI07/FDFpark/envComb/RES/FDFpark_T_C_track/AAAI/FDFpark_500");
01354   //GSnavResult r1; r1.combine(resultPrefix);
01355   //r1.read(resultPrefix, nsegment);
01356   //r1.createSummaryResult();
01357 
01358   // read and print the timing information
01359   GSnav_M_Result r2;  r2.read(resultPrefix);
01360 
01361 //   std::string resCfName = savePrefix + sformat("_comb_results.txt");
01362 //   FILE *rFile = fopen(resCfName.c_str(), "at");
01363 //   if (rFile == NULL) LFATAL("can't create res file: %s", resCfName.c_str());
01364 
01365   LINFO("bbmtTime: %f (%f - %f) std: %f",
01366         r2.meanBbmtTime, r2.minBbmtTime, r2.maxBbmtTime,
01367         r2.stdevBbmtTime);
01368 
01369   LINFO("Dorsal Time: %f (%f - %f) std: %f",
01370         r2.meanDorsalTime, r2.minDorsalTime, r2.maxDorsalTime,
01371         r2.stdevDorsalTime);
01372 
01373   LINFO("Ventral Time: %f (%f - %f) std: %f",
01374         r2.meanVentralSearchTime, r2.minVentralSearchTime,
01375         r2.maxVentralSearchTime, r2.stdevVentralSearchTime);
01376 
01377   LINFO("Input Time: %f (%f - %f) std: %f",
01378         r2.meanInputTime, r2.minInputTime, r2.maxInputTime,
01379         r2.stdevInputTime);
01380 //   fputs(temp.c_str(), rFile);
01381 //   fclose (rFile);
01382 }
01383 
01384 // ######################################################################
01385 /* So things look consistent in everyone's emacs... */
01386 /* Local Variables: */
01387 /* indent-tabs-mode: nil */
01388 /* End: */
Generated on Sun May 8 08:40:12 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3