test-gistNav-master.C

Go to the documentation of this file.
00001 /*! @file Beobot/test-gistNav-master.C -- An autonomous visual navigation
00002   using image intensity amplitude spectrum components FFT (fast and free
00003   from fftw.com) via object FFTWWrapper. Computes outputs with a back-prop
00004   network (FFN.H&.C) and online learning.
00005   -- Christopher Ackerman, 7/30/2003                                    */
00006 // //////////////////////////////////////////////////////////////////// //
00007 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00008 // University of Southern California (USC) and the iLab at USC.         //
00009 // See http://iLab.usc.edu for information about this project.          //
00010 // //////////////////////////////////////////////////////////////////// //
00011 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00012 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00013 // in Visual Environments, and Applications'' by Christof Koch and      //
00014 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00015 // pending; application number 09/912,225 filed July 23, 2001; see      //
00016 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00017 // //////////////////////////////////////////////////////////////////// //
00018 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00019 //                                                                      //
00020 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00021 // redistribute it and/or modify it under the terms of the GNU General  //
00022 // Public License as published by the Free Software Foundation; either  //
00023 // version 2 of the License, or (at your option) any later version.     //
00024 //                                                                      //
00025 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00026 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00027 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00028 // PURPOSE.  See the GNU General Public License for more details.       //
00029 //                                                                      //
00030 // You should have received a copy of the GNU General Public License    //
00031 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00032 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00033 // Boston, MA 02111-1307 USA.                                           //
00034 // //////////////////////////////////////////////////////////////////// //
00035 //
00036 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Beobot/test-gistNav-master.C $
00037 // $Id: test-gistNav-master.C 13712 2010-07-28 21:00:40Z itti $
00038 
00039 #include "Beowulf/Beowulf.H"
00040 #include "Beowulf/BeowulfOpts.H"
00041 #include "Component/ModelManager.H"
00042 #include "Devices/DeviceOpts.H"
00043 #include "Devices/FrameGrabberConfigurator.H"
00044 #include "Devices/KeyBoard.H"
00045 #include "Devices/RadioDecoder.H"
00046 #include "Devices/lcd.H"
00047 #include "Gist/FFN.H"
00048 #include "Image/FFTWWrapper.H"
00049 #include "Image/Image.H"
00050 #include "Image/Pixels.H"
00051 #include "Transport/FrameIstream.H"
00052 #include "Util/Timer.H"
00053 #include "Util/log.H"
00054 
00055 #include <math.h>
00056 #include <pthread.h>
00057 #include <signal.h>
00058 #include <stdio.h>
00059 #include <stdlib.h>
00060 
00061 #define OUTPATH "/home/tmp/7/gistNav/"
00062   // Current directory to write to for this grab
00063 
00064 char dir[10];
00065 
00066 // tell writer thread when to write a new image:
00067 bool doWrite;
00068 
00069 // tell grabber it is okay to grab
00070 bool grabOk;
00071 
00072 // tell writer thread to quit:
00073 bool doQuit;
00074 
00075 // tell grabbing loop that the user has pushed quit
00076 bool quitGrab;
00077 
00078 // current frame number:
00079 int frame=0;
00080 
00081 //!< Will turn false on interrupt signal
00082 static bool goforever = true;
00083 
00084 // ######################################################################
00085 //! Signal handler (e.g., for control-C)
00086 void terminate(int s)
00087 {  LERROR("*** INTERRUPT ***"); goforever = false; exit(1); }
00088 
00089 #define HBLOCKS 4
00090 #define WBLOCKS 4
00091 #define DIMSINALL 640
00092 #define DIMSIN 40
00093 #define DIMSHID 90
00094 #define DIMS1HID 40
00095 #define DIMS2HID 40
00096 #define DIMSOUT 13
00097 #define IMAGEHEIGHT 120
00098 #define IMAGEWIDTH 160
00099 #define IMAGESIZE IMAGEHEIGHT*IMAGEWIDTH
00100 #define WINDOWHEIGHT 30
00101 #define WINDOWWIDTH 40
00102 #define WINDOWSIZE WINDOWHEIGHT*WINDOWWIDTH
00103 #define LEARNRATE 0.5
00104 #define MOMENTUM 0.0
00105 
00106 double compsteer, compspeed;
00107 Image< PixRGB<byte> > ima(IMAGEWIDTH,IMAGEHEIGHT, NO_INIT);
00108 
00109 // ######################################################################
00110 void gzWriteFrame(int frameNum, Image< PixRGB<byte> >& imag)
00111 {
00112   char temp[256];
00113   char head[256];
00114 
00115   head[0] = '\0';
00116   temp[0] = '\0';
00117 
00118   //  gzFile gzOut;
00119   FILE *fp;
00120 
00121   //To copy the RC data
00122   float taccel, tsteer;
00123   taccel = compspeed;
00124   tsteer = compsteer;
00125 
00126   // sprintf(temp, "./frame%06d.ppm.gz", frameNum);
00127   sprintf(temp, "./frame%06d.ppm", frameNum);
00128   LDEBUG("Filename: %s", temp);
00129 
00130   // Open the file using zlib gzopen routine
00131   // gzOut = gzopen (temp, "wb");
00132   fp = fopen(temp, "wb");
00133 
00134   // if( gzOut == NULL )    //Check status of file open operation
00135   if( fp == NULL )    //Check status of file open operation
00136     LFATAL("There was an error opening the gzip file for writing");
00137 
00138   // Write out the header information
00139   sprintf(temp, "P6\n");
00140 
00141   strcpy(head, temp);
00142 
00143   sprintf(temp, "#ACCEL:%-10f STEER:%-10f\n", taccel, tsteer);
00144   strcat(head, temp);
00145   sprintf(temp, "%d %d\n255\n", imag.getWidth(), imag.getHeight() );
00146   strcat(head, temp);
00147 
00148   // if( !gzwrite(gzOut, head, strlen(head)) )
00149   if( !fwrite(head, 1, strlen(head), fp) )
00150     LFATAL("There was an error gzwriting %"ZU" bytes", strlen(head));
00151 
00152   if( !fwrite(reinterpret_cast<void*>(imag.getArrayPtr()), 1,
00153               3*imag.getSize(), fp))
00154     // if( !gzwrite(gzOut, reinterpret_cast<void*>(imag.getArrayPtr()),
00155     //               3*imag.getSize()))
00156     LFATAL("There was an error gzwriting %d bytes", 3*imag.getSize());
00157 
00158   //  gzclose(gzOut);
00159   fclose(fp);
00160 }
00161 
00162 // ######################################################################
00163 void* imageWriterThread(void *junk)
00164 {
00165   ////  while(doQuit == false){
00166   if (doWrite)
00167     {
00168       Image< PixRGB<byte> > currFrame = ima;
00169       // for a deep copy of the image data:
00170       Image< PixRGB<byte> >::iterator data = currFrame.beginw();
00171       data ++; // keep g++ happy
00172       grabOk = true;
00173 
00174       gzWriteFrame(frame++, currFrame);
00175 
00176       doWrite = false;
00177     }
00178   else
00179     usleep(500);
00180   ////    }
00181 
00182   // quit the thread:
00183   ////  pthread_exit(0);
00184   return NULL;
00185 }
00186 
00187 // ######################################################################
00188 void grabCycleInit( KeyBoard& myKB, nub::soft_ref<lcd> lcdDisp,
00189                     nub::soft_ref<FrameIstream>& gb )
00190 {
00191   char tmp[100];
00192   int i = 0;
00193 
00194   //We want to create a new directory to put frames in
00195   //But make sure that we don't overwrite any directories
00196   //That already exist
00197 
00198   if( chdir( OUTPATH ) ) //If there's a problem cding to ouput dir
00199     {
00200       LINFO("There was an error changing to directory: %s", OUTPATH);
00201       lcdDisp->clear();
00202       lcdDisp->printf(0, 0, " Output directory" );
00203       lcdDisp->printf(0, 1, " Does not exist!" );
00204       lcdDisp->printf(0, 2, " Trying to create. ");
00205       sleep(1);
00206 
00207       if( mkdir( OUTPATH, S_IRUSR | S_IWUSR ) != 0 )
00208         {
00209           LINFO("There was an error creating directory: %s", OUTPATH);
00210           lcdDisp->clear();
00211           lcdDisp->printf(0, 0, " mkdir() failed! ");
00212           lcdDisp->printf(0, 1, " bailing out... ");
00213           sleep(1);
00214           return;
00215         }
00216       if (chdir( OUTPATH )) LFATAL("chdir error");
00217     }
00218 
00219   i = 0;
00220   do
00221     {
00222       sprintf( tmp, "%d", i++ );
00223     }
00224   while ( mkdir(tmp, S_IRUSR | S_IWUSR | S_IEXEC ) != 0 );
00225   sprintf( tmp, "%s%d", OUTPATH, i-1 );
00226   if (chdir( tmp )) LFATAL("chdir error");
00227 
00228   char * ptr = getcwd( NULL, 0 );
00229   LDEBUG( "Working directory is %s", ptr);
00230   free( ptr );
00231 
00232   frame = 0; doQuit = false;
00233   doWrite = false; grabOk = true; quitGrab = false;  // start writer thread:
00234 
00235   ////  pthread_t runner;
00236   ////  pthread_create(&runner, NULL, &imageWriterThread, NULL);
00237 }
00238 
00239 // ######################################################################
00240 void grabCycle( KeyBoard& myKB, nub::soft_ref<lcd> lcdDisp,
00241                 nub::soft_ref<FrameIstream>& gb )
00242 {
00243   // wait for writer thread to be ready and tell it to write frame:
00244   while (doWrite) usleep(500);
00245   grabOk = false;  // not okay to grab until writer thread authorizes us
00246   doWrite = true;  // trigger write of current frame
00247   imageWriterThread(NULL);
00248   while(grabOk == false) usleep(500);
00249 }
00250 
00251 // ######################################################################
00252 int main(const int argc, const char **argv)
00253 {
00254   int i, j, h, l;
00255   bool updateweights = false;
00256   double steer, speed;
00257   double rcspeed, rcsteer;
00258 
00259   // Choose steering probabilisticly,
00260   // with the probabilities coming from the relative strengths
00261   // of the network outputs
00262   srand((unsigned)time(0));
00263 
00264   int flag=0;
00265   long ctr=0;
00266   double total,mean,std;
00267   //double orient,open,expand,obstacle,avgsteer=0.0,laststeer=0.0;
00268   //double safety=0.5;
00269 
00270   /**************** 0: Setup *********************/
00271   Image<double> trueout(1, DIMSOUT, ZEROS);
00272   double masks[DIMSIN][WINDOWSIZE];
00273   Image<double> meanarr(1, DIMSIN, ZEROS); // normalizer
00274   Image<double> stdarr(1, DIMSIN,ZEROS);  // normalizer
00275   //double minarr[DIMSIN];// normalizer
00276   //double maxarr[DIMSIN];// normalizer
00277   //double range[DIMSIN]; // normalizer
00278   double evecs[DIMSIN][DIMSINALL];
00279   Image<double> allfeatures(1, DIMSINALL, ZEROS);
00280   Image<double> features(1, DIMSIN, ZEROS);// amp-dims input
00281 
00282   double **magspec = (double **)malloc((WINDOWHEIGHT)*sizeof(double *));
00283   if(magspec == NULL)
00284     LINFO("Error allocating memory for magspec");
00285   for(i = 0; i < WINDOWHEIGHT; i++)
00286   {
00287     magspec[i] = (double *)malloc((WINDOWWIDTH/2+1)*sizeof(double));
00288     if(magspec[i] == NULL)
00289       LINFO("Error allocating memory for magspec[i]");
00290   }
00291 
00292   double *bwimage = (double *)malloc(IMAGESIZE*sizeof(double));
00293   if(bwimage == NULL)
00294     LINFO("Error allocating memory for bwimage");
00295   else
00296     LINFO("okay");
00297 
00298   double *bwimage_sm = (double *)malloc(WINDOWSIZE*sizeof(double));
00299 
00300   FeedForwardNetwork *ffn_dm = new FeedForwardNetwork();
00301 
00302   // I was going to do a command line thing
00303   // where you could tell it to initialize with random weights in a range
00304   // instead of using a weight file
00305   /*(if (argc==2)
00306     if(strcmp(argv[1],"-i")==0)
00307     ffn_dm->init(atof(argv[1]),DIMSIN,DIMSHID,DIMSOUT,LEARNRATE);
00308     else{
00309     LERROR("Invalid switch");
00310     exit(1);
00311     }
00312     else*/
00313 
00314   // But when I tried the manager business choked on the new parameters.
00315   // So now it will initialize randomly within a hard-coded range
00316   // if it doesn't find the appropriately named weight files
00317   // if I am using a weight file computed offline in Matlab,
00318   // I pass it in a .mat file.
00319   // I also have to make some changes (uncomment some code)
00320   // in FFN.C to handle to Matlab file format. That kind of sucks.
00321   // If it's too much of a pain, then just convert the Matlab file to the
00322   // appropriate format and name in .dat.
00323   //ffn_dm->init("/lab/bb/data/nnwhdm-T.mat","/lab/bb/data/nnwodm-T.mat",
00324   //DIMSIN,DIMSHID,DIMSOUT,LEARNRATE,MOMENTUM);
00325   //ffn_dm->init("/lab/bb/data/nnwhdm.dat","/lab/bb/data/nnwodm.dat",
00326   //DIMSIN,DIMSHID,DIMSOUT,LEARNRATE,MOMENTUM);
00327   //ffn_dm->init3L("/lab/bb/data/nnwh1dm-T.mat","/lab/bb/data/nnwh2dm-T.mat",
00328   //"/lab/bb/data/nnwodm-T.mat",DIMSIN,DIMS1HID,DIMS2HID,DIMSOUT,LEARNRATE);
00329   ffn_dm->init3L("/lab/bb/data/nnwh1dm.dat","/lab/bb/data/nnwh2dm.dat",
00330     "/lab/bb/data/nnwodm.dat",DIMSIN,DIMS1HID,DIMS2HID,DIMSOUT,LEARNRATE,0.0);
00331 
00332   FFTWWrapper *fftw = new FFTWWrapper( WINDOWWIDTH,WINDOWHEIGHT);
00333   fftw->init(bwimage_sm);
00334 
00335   FILE *fp=fopen("/lab/bb/data/meanarrall.mat","rb");
00336   if(fp==NULL) LFATAL("Mean file not found");
00337 
00338   fseek(fp, 0, SEEK_END);
00339   long pos = ftell(fp);
00340   fseek(fp,pos-(DIMSIN*sizeof(double)), SEEK_SET);
00341   // FIX below
00342   //for(i = 0; i < DIMSIN; i++) fread(&meanarr[i],sizeof(double),1,fp);
00343   fclose(fp);
00344 
00345   // These four are Matlab-created files.
00346   // Note the way to find the beginning of the data
00347   fp = fopen("/lab/bb/data/stdarrall.mat","rb");
00348   if(fp == NULL) LFATAL("STD file not found");
00349   fseek(fp, 0, SEEK_END);
00350   pos=ftell(fp);
00351   fseek(fp,pos-(DIMSIN*sizeof(double)), SEEK_SET);
00352   // FIX below
00353   //  for(i = 0; i < DIMSIN; i++) fread(&stdarr[i],sizeof(double),1,fp);
00354   fclose(fp);
00355 
00356   //for(i = 0; i < DIMSIN; i++)
00357   //        range[i] = maxarr[i]-minarr[i];
00358 
00359   fp = fopen("/lab/bb/data/G2small.mat","rb");
00360   //G = fftshift(reshape(H:,i)...G2=reshape(G(:,:,i)'
00361   //...must have super low values from matlab trimmed
00362   if(fp == NULL) LFATAL("Mask file not found");
00363   fseek(fp, 0, SEEK_END);
00364   pos = ftell(fp);
00365   fseek(fp,pos-(DIMSIN*WINDOWSIZE*sizeof(double)), SEEK_SET);
00366   for(i = 0; i < DIMSIN; i++)
00367     if (fread(masks[i],sizeof(double),WINDOWSIZE,fp) != WINDOWSIZE) LFATAL("fread error");
00368   fclose(fp);
00369 
00370   fp=fopen("/lab/bb/data/evec40all.mat","rb");
00371   if(fp==NULL) LFATAL("Eigenvector file not found");
00372   fseek(fp, 0, SEEK_END);
00373   pos=ftell(fp);
00374   fseek(fp,pos-(DIMSIN*DIMSINALL*sizeof(double)), SEEK_SET);
00375   for(i=0;i<DIMSIN;i++)
00376     if (fread(evecs[i],sizeof(double),DIMSINALL,fp) != DIMSINALL) LFATAL("fread error");
00377   fclose(fp);
00378 
00379   double *iptr = NULL;
00380 
00381   TCPmessage smsg;      // buffer to send messages to nodes;
00382   // in my case speed and steering...
00383   // when the ethernet was working, counter and status stuff for lcd display now
00384 
00385   KeyBoard myKB;
00386   LINFO("Press A to do initialization"); // this is to get the beobot outside
00387     // before you start camera so it adjust to luminance properly
00388   while (myKB.getKey( true ) != KBD_KEY1) // actually that's no longer true.
00389     // Mostly it's to make sure you're ready.
00390     // As it happens, the camera adjusts itself well with time anyway
00391   LINFO("\a"); // beep
00392 
00393   // instantiate a model manager:
00394   ModelManager manager("Gist Navigator - Master");
00395 
00396   // Instantiate our various ModelComponents:
00397   nub::soft_ref<FrameGrabberConfigurator>
00398     gbc(new FrameGrabberConfigurator(manager));
00399   manager.addSubComponent(gbc);
00400 
00401   //uncomment when ethernet is fixed --changed bb1bg to bb1ag
00402   nub::soft_ref<Beowulf>
00403     beo(new Beowulf(manager, "Beowulf Master", "BeowulfMaster", true));
00404   manager.addSubComponent(beo);
00405   manager.setOptionValString(&OPT_BeowulfSlaveNames, "bb1ag");
00406 
00407   nub::soft_ref<RadioDecoder> rd(new RadioDecoder(manager));
00408   manager.addSubComponent(rd);
00409 
00410   nub::soft_ref<lcd> lcdDisp(new lcd(manager));
00411   lcdDisp->setModelParamString("SerialPortDevName",
00412                                "/dev/ttyS0", MC_RECURSE);
00413   manager.addSubComponent(lcdDisp);
00414 
00415   // choose an IEEE1394grabber by default, and a few custom grabbing
00416   // defaults, for backward compatibility with an older version of
00417   // this program:
00418   manager.setOptionValString(&OPT_FrameGrabberType, "1394");
00419   manager.setOptionValString(&OPT_FrameGrabberDims, "160x120");
00420   manager.setOptionValString(&OPT_FrameGrabberMode, "YUV444");
00421   manager.setOptionValString(&OPT_FrameGrabberNbuf, "20");
00422 
00423   // Parse command-line:
00424   if (manager.parseCommandLine(argc, argv, "", 0, 0) == false) return(1);
00425 
00426   nub::soft_ref<FrameIstream> gb = gbc->getFrameGrabber();
00427   if (gb.isInvalid())
00428     LFATAL("No grabber. Why does god hate me?");
00429   LINFO("GB width = %d height = %d\n",gb->getWidth(),gb->getHeight());
00430 
00431   // catch signals and redirect them to terminate for clean exit:
00432   signal(SIGHUP,  terminate);  signal(SIGINT,  terminate);
00433   signal(SIGQUIT, terminate);  signal(SIGTERM, terminate);
00434   signal(SIGALRM, terminate);
00435 
00436   // let's get all our ModelComponent instances started:
00437   manager.start();
00438 
00439   // Calibrate the controls' 0 position
00440   lcdDisp->clear();
00441   lcdDisp->printf(0, 1, "Calibrate Controls");
00442   lcdDisp->printf(0, 2, "Rest Controls NOW!");
00443   rd->zeroCalibrate();
00444 
00445   // Calibrate range of control swing
00446   lcdDisp->clear();
00447   lcdDisp->printf(0, 1, "Calibrate Controls");
00448   lcdDisp->printf(0, 2, "Full Swing NOW!");
00449   rd->rangeCalibrate();
00450 
00451   // Save our configuration data so we don't have to calibrate again (Ha!)
00452   manager.saveConfig();
00453 
00454   lcdDisp->clear();
00455   lcdDisp->printf(0, 2, "Press 2 (B) to Start");
00456   smsg.reset(ctr, 0);
00457   smsg.addInt32(0);
00458   beo->send(0, smsg);
00459   while (myKB.getKey( true ) != KBD_KEY2)
00460     printf("\a"); // beep
00461   lcdDisp->clear();
00462   printf("\a\a\a"); // beep
00463 
00464   grabCycleInit( myKB, lcdDisp, gb );
00465   /*******************************************************/
00466 
00467   Timer tim(1000000);
00468   tim.reset();
00469   uint64 end, start=tim.get();
00470   uint64 endpause, startpause=0, totalpause=0;
00471   double elapsed;
00472   double lastspeed = 0.4; // this is the default speed it starts out with.
00473   double totspeed = 0.0;
00474   unsigned long speedctr = 0;
00475   bool setspeed = false;
00476   int keypress = KBD_NONE;
00477   bool paused = false;
00478   while(!flag && goforever)
00479   {
00480     // this is to allow me to stop and change batteries,
00481     // etc w/o shutting down or causing it to learn to stop
00482     if( myKB.getKey( false ) == KBD_KEY3 || keypress == KBD_KEY3)
00483     {
00484       printf("pause\n");
00485       keypress=KBD_NONE;
00486       usleep(500);//to avoid double hits
00487       if(paused)
00488       {
00489         paused=false;
00490         endpause=tim.get();
00491         totalpause+=endpause-startpause;
00492       }
00493       else
00494       {
00495         smsg.reset(ctr, 0);  //when ethernet is fixed,
00496         //remove these 3 line and update lcd here
00497         smsg.addInt32(-1);
00498         beo->send(0, smsg);
00499         paused=true;
00500         startpause=tim.get();
00501       }
00502     }
00503     if(paused) continue;
00504 
00505     /****************** 1: Grab Frame ******************/
00506     ima = gb->readRGB();
00507     Image< PixRGB<byte> >::const_iterator data = ima.begin();//w();
00508     /***************************************************/
00509 
00510     /************** 2: Do Image Preproc ****************/
00511     // extract Value (brightness/luminance/intensity/whatever) from HSV
00512     total = 0.0;
00513     iptr  = bwimage;
00514     while (data != ima.end())
00515     {
00516       double max = 0.0;
00517       if (data->red()   > max) max = data->red();
00518       if (data->green() > max) max = data->green();
00519       if (data->blue()  > max) max = data->blue();
00520       *iptr = max;
00521       data++;
00522       total += *iptr++;
00523     }
00524 
00525     //normalize
00526     mean = total / ((double)IMAGESIZE);
00527     std = 0.0;
00528     for(i = 0; i < IMAGESIZE; i++)
00529       std += pow(bwimage[i]-mean,2);
00530     std /= IMAGESIZE-1;
00531     std = sqrt(std);
00532     for(i = 0; i < IMAGESIZE; i++)
00533     {
00534       bwimage[i] -= mean;
00535       bwimage[i] /= std;
00536     }
00537 
00538     /****************************************************/
00539 
00540     /***** 3: Do FFT and convolution for each block *****/
00541     for(h = 0; h < HBLOCKS; h++)
00542     {
00543       for(l = 0; l < WBLOCKS; l++)
00544       {
00545         //FFT
00546         iptr = bwimage_sm;
00547         for(i = 0; i < WINDOWHEIGHT; i++)
00548           for(j = 0; j < WINDOWWIDTH; j++)
00549             *iptr++ = bwimage[h*WINDOWHEIGHT*IMAGEWIDTH+
00550                               l*WINDOWWIDTH + i*IMAGEWIDTH + j];
00551         fftw->compute(magspec);
00552 
00553         // Convolve with masks
00554         // This looks a bit more complicated than you might think
00555         // because I'm saving some time by not multiplying by the
00556         // whole image. The masks only cover a bit over half the image.
00557         for(i=0;i<DIMSIN;i++)
00558         {
00559           const int halfwidth=WINDOWWIDTH/2+1;
00560           const int halfheight=WINDOWHEIGHT/2;
00561 
00562           int heighttop=halfheight;
00563           switch (i%8)
00564           {
00565           case 0:
00566             heighttop = halfheight;
00567             break;
00568           case 1:
00569           case 7:
00570             heighttop = (int)((double)halfheight*0.75);
00571             break;
00572           case 2:
00573           case 6:
00574             heighttop = (int)((double)halfheight*0.5);
00575             break;
00576           case 3:
00577           case 5:
00578             heighttop = (int)((double)halfheight*0.25);
00579             break;
00580           case 4:
00581             heighttop = 0;
00582             break;
00583           }
00584 
00585           //some portion of top half
00586           for(int j = 0; j < heighttop; j++)
00587           {//left side
00588             for(int k = 0; k < halfwidth; k++)
00589             {
00590               int index =  h*WBLOCKS*DIMSIN+l*DIMSIN+i;
00591               allfeatures.setVal
00592                 (0, index, allfeatures.getVal(0, index) +
00593                  magspec[j][k]*masks[i][j*WINDOWWIDTH+k]);
00594             }
00595           }
00596           if(heighttop>0)
00597             for(int k = halfwidth; k < WINDOWWIDTH; k++)//top row
00598               {
00599                 int index = h*WBLOCKS*DIMSIN+l*DIMSIN+i;
00600                 allfeatures.setVal
00601                   (0, index, allfeatures.getVal(0,index) +
00602                    magspec[0][WINDOWWIDTH-k]*masks[i][k]);
00603               }
00604 
00605           for(int j = 1; j < heighttop; j++)
00606           {//right side
00607             for(int k = halfwidth; k < WINDOWWIDTH; k++)
00608             {
00609               int index = h*WBLOCKS*DIMSIN+l*DIMSIN+i;
00610               allfeatures.setVal
00611                 (0, index, allfeatures.getVal(0,index)  +
00612                  magspec[WINDOWHEIGHT-j][WINDOWWIDTH-k]*
00613                  masks[i][j*WINDOWWIDTH+k] );
00614             }
00615           }
00616 
00617           //bottom half
00618           for(int j = halfheight; j < WINDOWHEIGHT; j++)
00619           {//left side
00620             for(int k = 0; k < halfwidth; k++)
00621             {
00622               int index = h*WBLOCKS*DIMSIN+l*DIMSIN+i;
00623               allfeatures.setVal
00624                 (0, index, allfeatures.getVal(0,index) +
00625                  magspec[j][k]*masks[i][j*WINDOWWIDTH+k]);
00626             }
00627           }
00628 
00629           for(int j = halfheight; j < WINDOWHEIGHT; j++)
00630           {//right side
00631             for(int k = halfwidth; k < WINDOWWIDTH; k++)
00632             {
00633               int index = h*WBLOCKS*DIMSIN+l*DIMSIN+i;
00634               allfeatures.setVal
00635                 (0, index, allfeatures.getVal(0, index) +
00636                  magspec[halfheight-(j-halfheight)][WINDOWWIDTH-k]*
00637                  masks[i][j*WINDOWWIDTH+k]);
00638             }
00639           }
00640         }
00641       }
00642     }
00643     /************************************************/
00644 
00645     /********** 4: Project onto eigenvectors ********/
00646     for(i = 0; i < DIMSIN; i++)
00647       for(j = 0; j < DIMSINALL; j++)
00648         features.setVal
00649           (0, i, features.getVal(0,i) + evecs[i][j]*allfeatures.getVal(0,j));
00650     /************************************************/
00651 
00652     /****************** 5: FFN for Dims *************/
00653     features = (features - meanarr)/stdarr;
00654     ffn_dm->run3L(features);
00655     /************************************************/
00656 
00657     /************ 6: Compute Motor Commands *********/
00658     ////        speed=ffn_dm->out[DIMSOUT-1]*2.0-1.0;
00659     // eh, make when I was computing speed to, rather than hacking it
00660     /* speed hack: if I'm giving it a speed command with the remote,
00661        it goes with that, otherwise it uses it's last speed value
00662       which is either the default (if I haven't given any speed commands yet)
00663       or the average of all the speed commands I gave last time*/
00664     rcspeed = rd->getVal(0);
00665     if(fabs(rcspeed) > 0.1)
00666     {
00667       setspeed = true;
00668       lastspeed = rcspeed;
00669       totspeed += rcspeed;
00670       speedctr++;
00671     }
00672     else
00673     {
00674       if(setspeed)
00675       {
00676         setspeed = false;
00677         lastspeed = totspeed/(double)speedctr;
00678         totspeed = 0.0;
00679         speedctr = 0;
00680       }
00681     }
00682     speed = lastspeed;
00683 
00684     /*  // I could just choose the average output, but...
00685         double mysum=0.0;steer=0.0;
00686         for(i=0;i<DIMSOUT-1;i++){
00687         mysum+=ffn_dm->out[i];
00688         steer+=((double)(i+1))*ffn_dm->out[i];
00689         }
00690         steer=steer/mysum;
00691         steer=((steer-1.0)/((double)DIMSOUT-1.0[2.0])*2.0-1.0)*-1.0;
00692     */
00693 
00694     // I choose the output probabilisticly
00695     double target=(double)rand()/(double)RAND_MAX;
00696     double mysum=0.0;double tprob=0.0;
00697     for(i=0;i<DIMSOUT-1;i++)
00698       mysum+=ffn_dm->getOutput().getVal(0,i);
00699     for(i=0;i<DIMSOUT-1;i++)
00700     {
00701       tprob+=ffn_dm->getOutput().getVal(0,i)/mysum;
00702       if (tprob>target)
00703         break;
00704     }
00705     steer=((((double)i+1.0)-1.0)/((double)DIMSOUT-1.0/*2.0*/)*2.0-1.0)*-1.0;
00706     //the commented 2 is left over from when speed was the last output
00707 
00708     /***********************************************/
00709 
00710     /************ 7: Execute Motor Control *********/
00711     compspeed = speed; //this is what gets written to the image file
00712     compsteer = steer;
00713     printf("computed speed=%f, steer=%f ctr=%ld\n",speed,steer,ctr+1);
00714 
00715     updateweights=false;
00716     rcsteer=rd->getVal(1);
00717     if(fabs(rcspeed)>0.1 || fabs(rcsteer)>0.1){
00718       printf("big rc signal\n");
00719       updateweights=true;
00720       /*if(fabs(rcspeed)>0.1)*///speed=rcspeed;
00721       /*if(fabs(rcsteer)>0.1)*/steer=rcsteer;
00722     }
00723     printf("rc speed=%f, steer=%f ctr=%ld\n",rcspeed,rcsteer,ctr+1);
00724 
00725     // call servo controller
00726     smsg.reset(ctr, 0);
00727     ////      steer=steer-steer*fabs(steer)/5;
00728     smsg.addDouble(steer);
00729     //        smsg.addDouble((speed*safety));
00730     //        speed=speed-speed*fabs(speed)/1.6666666667;//2;//max of 4
00731     smsg.addDouble(speed-speed*fabs(speed)/1.6666666667);
00732     beo->send(0, smsg);  // send off to slave
00733 
00734     // backprop
00735     if(updateweights==true){
00736       trueout.clear(0.0);
00737       int on;
00738       on=(int)round(((steer*-1.0+1.0)/2.0)*((double)DIMSOUT-1.0/*2.0*/)+1.0);
00739       trueout.setVal(0, on-1, 1.0);
00740       if (on>1)
00741         trueout.setVal(0, on-2, 0.5);//give some weight to nearby orientations.
00742         // My thinking is this suppies a little bit of ordering to a system
00743       if (on>2)
00744         trueout.setVal(0, on-3, 0.25);//assuming choosing probabilisticly
00745         // rather than averaging) that regards eg hard right as equally distant
00746       if (on<DIMSOUT)
00747         trueout.setVal(0, on, 0.5);//from slightly less hard right as from left
00748       if (on<DIMSOUT-1)
00749         trueout.setVal(0, on+1, 0.25);
00750       /////             trueout[DIMSOUT-1]=(speed+1.0)/2.0;
00751       ffn_dm->backprop3L(trueout);
00752     }
00753 
00754     // administrative stuff
00755     if(ctr%90==0 && ctr!=0)grabCycle( myKB, lcdDisp, gb );
00756     // I save weights occasionally to prevent
00757     // the obligatory battery deaths from becoming catastrophic
00758     if(ctr%5000==0 && ctr!=0)
00759       ffn_dm->write3L("/lab/bb/data/nnwh1dm.dat",
00760                       "/lab/bb/data/nnwh2dm.dat", "/lab/bb/data/nnwodm.dat");
00761       // so I don't lose my work when it crashes
00762 
00763     keypress=myKB.getKey( false );
00764     if( keypress == KBD_KEY4 ){
00765       flag=1;
00766       doQuit=true;
00767       LDEBUG("quit = true;");
00768     }
00769     ctr++;
00770     if(ctr==0)flag=1;
00771     lcdDisp->clear();
00772     lcdDisp->printf(0, 2, "%ld",ctr);
00773     smsg.reset(ctr, 0);
00774     smsg.addInt32(ctr);
00775     beo->send(0, smsg);
00776     /**************************************************/
00777   }
00778 
00779   /**************** 8: Cleanup...sort of ************/
00780   end=tim.get();
00781   elapsed=((end-start)-totalpause)/(double)1000000;
00782   printf("time=%f secs; processed %ld pics\n",elapsed,ctr);
00783 
00784   //write weights
00785   ffn_dm->write3L("/lab/bb/data/nnwh1dm.dat", "/lab/bb/data/nnwh2dm.dat",
00786     "/lab/bb/data/nnwodm.dat");
00787   delete ffn_dm;
00788   manager.stop();
00789   /*************************************************/
00790 
00791   return 0;
00792 }
00793 
00794 // ######################################################################
00795 /* So things look consistent in everyone's emacs... */
00796 /* Local Variables: */
00797 /* indent-tabs-mode: nil */
00798 /* End: */
Generated on Sun May 8 08:40:15 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3