beobot-driveStraight-master.C

Go to the documentation of this file.
00001 /*!@file Beobot/beobot-driveStraight-master.C color drive straight - master
00002   adapted from RCBot/driveStraight.C                               */
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file:  Christian Siagian <siagian@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Beobot/beobot-driveStraight-master.C $
00035 // $Id: beobot-driveStraight-master.C 9412 2008-03-10 23:10:15Z farhan $
00036 //
00037 
00038 #include "Beowulf/Beowulf.H"
00039 #include "Component/ModelManager.H"
00040 #include "Component/OptionManager.H"
00041 #include "Controllers/PID.H"
00042 #include "Devices/FrameGrabberConfigurator.H"
00043 #include "Devices/DeviceOpts.H"
00044 #include "GUI/XWindow.H"
00045 #include "Image/ColorOps.H"
00046 #include "Image/CutPaste.H"
00047 #include "Image/DrawOps.H"
00048 #include "Image/Image.H"
00049 #include "Image/MathOps.H"
00050 #include "Image/Pixels.H"
00051 #include "Image/ShapeOps.H"
00052 #include "RCBot/Motion/MotionEnergy.H"
00053 #include "Raster/Raster.H"
00054 #include "Media/FrameSeries.H"
00055 #include "Transport/FrameIstream.H"
00056 #include "Util/Timer.H"
00057 #include "Util/Types.H"
00058 #include "Util/log.H"
00059 #include <math.h>
00060 #include <signal.h>
00061 
00062 #include "Devices/BeoChip.H"
00063 #include "Beobot/BeobotConfig.H"
00064 #include "Controllers/PID.H"
00065 #include "Beobot/BeobotBeoChipListener.H"
00066 
00067 // number of frames over which framerate info is averaged:
00068 #define NAVG 20
00069 
00070 static bool goforever = true;
00071 BeobotConfig bbc;
00072 
00073 // ######################################################################
00074 void resetBeoChip(nub::soft_ref<BeoChip> b);
00075 
00076 // ######################################################################
00077 void terminate(int s)
00078 { LERROR("*** INTERRUPT ***"); goforever = false; exit(1); }
00079 
00080 // ######################################################################
00081 int main(const int argc, const char **argv)
00082 {
00083   MYLOGVERB = LOG_INFO;
00084 
00085   // instantiate a model manager:
00086   ModelManager manager("Beobot - Drive Straight");
00087 
00088   // Instantiate our various ModelComponents:
00089   nub::soft_ref<BeoChip> b(new BeoChip(manager));
00090   manager.addSubComponent(b);
00091 
00092   nub::soft_ref<InputFrameSeries> ifs(new InputFrameSeries(manager));
00093   manager.addSubComponent(ifs);
00094 
00095   manager.exportOptions(MC_RECURSE);
00096 
00097   // Parse command-line:
00098   if (manager.parseCommandLine(argc, argv, "steer P I D speed P I D", 6, 6) == false)
00099     return(1);
00100 
00101   // do post-command-line configs:
00102 
00103   // configure the BeoChip
00104   b->setModelParamVal("BeoChipDeviceName", std::string("/dev/ttyS0"));
00105 
00106   // let's register our listener:
00107   rutz::shared_ptr<BeobotBeoChipListener> lis(new BeobotBeoChipListener(b));
00108   rutz::shared_ptr<BeoChipListener> lis2; lis2.dynCastFrom(lis); // cast down
00109   b->setListener(lis2);
00110 
00111   int w = ifs->getWidth(), h = ifs->getHeight();
00112   XWindow winoH(Dims(w, 4*h), 2*w+20, 0, "test-output H");
00113   XWindow winoV(Dims(w, 4*h), 3*w+30, 0, "test-output V");
00114   XWindow wini (Dims(w, 4*h), w+10  , 0, "test-input windowL");
00115   XWindow wini2(Dims(w, 4*h), 0     , 0, "test-input windowC");
00116 
00117   // let's get all our ModelComponent instances started:
00118   manager.start();
00119 
00120   // reset BeoChip
00121   resetBeoChip(b);
00122 
00123   // create the motion pyramid
00124   MotionEnergyPyrBuilder<byte> motionPyr(Gaussian5);
00125 
00126   // catch signals and redirect them to terminate for clean exit:
00127   signal(SIGHUP, terminate);  signal(SIGINT, terminate);
00128   signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00129   signal(SIGALRM, terminate);
00130 
00131   PID<float> steer_pid(4.0, 0.0, 0.0, -1.0, 1.0);
00132   PID<float> speed_pid(1.6, 0.3, 0.3, -0.6, 0.6);
00133   steer_pid.setPIDPgain(manager.getExtraArgAs<float>(0));
00134   steer_pid.setPIDIgain(manager.getExtraArgAs<float>(1));
00135   steer_pid.setPIDDgain(manager.getExtraArgAs<float>(2));
00136   speed_pid.setPIDPgain(manager.getExtraArgAs<float>(3));
00137   speed_pid.setPIDIgain(manager.getExtraArgAs<float>(4));
00138   speed_pid.setPIDDgain(manager.getExtraArgAs<float>(5));
00139 
00140   // timer initialization
00141   Timer tim(1000000); uint64 t[NAVG]; int frame = 0;
00142   // ########## MAIN LOOP: grab, process, display:
00143   while(goforever)
00144   {
00145     tim.reset();
00146 
00147     // grab an image:
00148     ifs->updateNext();
00149     Image< PixRGB<byte> > ima = ifs->readRGB();
00150     if(!ima.initialized()) {goforever = false; break;}
00151     wini2.drawImage(ima,0,0);
00152 //     Image< PixRGB<byte> > tmp2 = decXY(ima);
00153 //     wini2.drawImage(tmp2,0,h);
00154 //     tmp2 = decXY(tmp2);
00155 //     wini2.drawImage(tmp2,0,h+h/2);
00156 //     tmp2 = decXY(tmp2);
00157 //     wini2.drawImage(tmp2,0,h+h/2+h/4);
00158 
00159     //Image<byte> lum(320,240,ZEROS);
00160     //drawPatch(lum, Point2D<int>(160, int(120-frame*.5)),10, byte(255));
00161     //drawPatch(lum, Point2D<int>(int(120-frame*.5), 120),10, byte(255));
00162     Image<byte> lum = luminance(ima);
00163     wini.drawImage(lum,0,0);
00164 //     Image<byte> tmp = decXY(lum);
00165 //     wini.drawImage(tmp,0,h);
00166 //     tmp = decXY(tmp);
00167 //     wini.drawImage(tmp,0,h+h/2);
00168 //     tmp = decXY(tmp);
00169 //     wini.drawImage(tmp,0,h+h/2+h/4);
00170 
00171     // build the motion pyramid
00172     // FIX: the second arg is depth of the pyramid
00173     //      figure out how to combine each depth info later
00174     motionPyr.updateMotion(lum, 1); // start: 1
00175     ImageSet<float> hpyr = motionPyr.buildHorizontalMotion();
00176     ImageSet<float> vpyr = motionPyr.buildVerticalMotion();
00177 
00178     // draw the images
00179     int sc = 1; float mn,mx, mn2, mx2;
00180     for(uint i = 0; i < hpyr.size(); i++)
00181       {
00182         Image<float> tmp = hpyr[i]; getMinMax(tmp,mn,mx);
00183         for(uint j = 0; j < i; j++) tmp = intXY(tmp, true);
00184         winoH.drawImage(tmp, 0, h*i);
00185 
00186         tmp = vpyr[i]; getMinMax(tmp,mn2,mx2);
00187         for(uint j = 0; j < i; j++) tmp = intXY(tmp,true);
00188         winoV.drawImage(tmp, 0, h*i);
00189         sc *=2;
00190 
00191 //         LINFO("%4d| m(h): [%7.4f %7.4f %7.4f] m(v): [%7.4f %7.4f %7.4f]", frame,
00192 //               mn,  mean(hpyr[i]), mx,
00193 //               mn2, mean(vpyr[i]), mx2);
00194       }
00195 
00196 
00197     // ######################################################################
00198     // Obstacle avoidance
00199     // ######################################################################
00200 //     Image<float> motion = vpyr[0];
00201 //     float motionLeft = 0, motionRight = 0;
00202 //     Image<float>::iterator motionPtr = motion.beginw();
00203 //     Image<float>::const_iterator motionPtrStop = motion.end();
00204 
00205 //     // find the motion energy on the left and right side
00206 //     int inx = 0;
00207 //     while (motionPtr != motionPtrStop) {
00208 //       int y = inx / motion.getWidth();
00209 //       int x = inx - (y*motion.getWidth());
00210 
00211 //       if (y > 1){
00212 //         if (x < (motion.getWidth()/2))
00213 //           motionLeft  += fabs(*motionPtr);
00214 //         else
00215 //           motionRight += fabs(*motionPtr);
00216 //       }
00217 //       motionPtr++;
00218 //       inx++;
00219 //     }
00220 
00221 //     double val = motionRight + motionLeft;
00222 //     LINFO("Right: %0.4f Left: %0.4f Total: %0.4f",
00223 //           motionRight, motionLeft, val);
00224 
00225 //     if (val > 20)
00226 //     {
00227 //       if (motionLeft > motionRight)
00228 //       {
00229 //         drawLine(lum, Point2D<int>(64,64), Point2D<int>(64+30,64-30), (byte)0, 2);
00230 //         b->setServo(bbc.steerServoNum, -1.0); //sc8000->move(1, -1);
00231 //       }
00232 //       else
00233 //       {
00234 //         drawLine(lum, Point2D<int>(64,64), Point2D<int>(64-30,64-30), (byte)0, 2);
00235 //         b->setServo(bbc.steerServoNum, 1.0);  //sc8000->move(1, 1);
00236 //       }
00237 //     }
00238 //     else
00239 //       b->setServo(bbc.steerServoNum, 0.0); //sc8000->move(1, 0);
00240 
00241 //     if (val > 4000)
00242 //     {
00243 //       LINFO("\n\nSTOP STOP STOP STOP \n");
00244 //       b->setServo(bbc.speedServoNum, 0.0); //sc8000->move(3, 0);
00245 //       sleep(2);
00246 //     }
00247 //     else
00248 //       b->setServo(bbc.speedServoNum, -0.270); //sc8000->move(3, -0.270);
00249 
00250 //     inplaceNormalize(motion, 0.0F, 255.0F);
00251 //     winoV.drawImage((Image<byte>)motion, lum.getWidth()+2, 0);
00252 
00253     // ######################################################################
00254     // drive straight
00255     // ######################################################################
00256 
00257     double speed = fabs(mean(vpyr[0]));
00258     double dir   = -mean(hpyr[0]);
00259     if(dir > 0.0) LINFO("GO RIGHT"); else LINFO("GO LEFT");
00260     //    Raster::waitForKey();
00261 
00262 //     drawLine(lum, Point2D<int>(w/2, h/2),
00263 //              Point2D<int>( (int)(w/2 + 75*cos(dir)),
00264 //                       (int)(h/2 - 75*sin(dir)) ),
00265 //              (byte)0, 3);
00266 //     window1.drawImage(rescale(lum, 256, 256));
00267 
00268     double st = steer_pid.update(0.0  , dir);
00269     double sp = speed_pid.update(0.175, speed);
00270     if(st > 1.0) st = 1.0; else if (st < -1.0) st = -1.0;
00271     if(sp > 0.6) sp = 0.6; else if (sp <  0.0) sp =  0.0;
00272     LINFO("%4d STEER: %11.7f -> %11.7f  SPEED: %11.7f -> %11.7f", frame,
00273           dir , st, speed, sp);
00274     sp = 0.4f;
00275 
00276     // execute action command
00277     b->setServo(bbc.steerServoNum, st);
00278     b->setServo(bbc.speedServoNum, sp);
00279 
00280     // ######################################################################
00281     // ######################################################################
00282 
00283     // compute and show framerate over the last NAVG frames:
00284     t[frame % NAVG] = tim.get();
00285     if (frame % NAVG == 0 && frame > 0)
00286       {
00287         uint64 avg = 0; for (int i = 0; i < NAVG; i ++) avg += t[i];
00288         float avg2 = 1000000.0 / (float)avg * NAVG;
00289         LINFO("Framerate: %5.2f fps", avg2);
00290       }
00291     frame++;
00292   }
00293 
00294   // got interrupted; let's cleanup and exit:
00295   manager.stop();
00296   return 0;
00297 }
00298 
00299 // ######################################################################
00300 void resetBeoChip(nub::soft_ref<BeoChip> b)
00301 {
00302   // reset the beochip:
00303   LINFO("Resetting BeoChip...");
00304   b->resetChip(); sleep(1);
00305 
00306   // calibrate the servos
00307   b->calibrateServo(bbc.steerServoNum, bbc.steerNeutralVal,
00308                     bbc.steerMinVal, bbc.steerMaxVal);
00309   b->calibrateServo(bbc.speedServoNum, bbc.speedNeutralVal,
00310                     bbc.speedMinVal, bbc.speedMaxVal);
00311   b->calibrateServo(bbc.gearServoNum, bbc.gearNeutralVal,
00312                     bbc.gearMinVal, bbc.gearMaxVal);
00313 
00314   // keep the gear at the lowest speed/highest torque
00315   b->setServoRaw(bbc.gearServoNum, bbc.gearMinVal);
00316 
00317   // turn on the keyboard
00318   b->debounceKeyboard(true);
00319   b->captureKeyboard(true);
00320 
00321   // calibrate the PWMs:
00322   b->calibratePulse(0,
00323                     bbc.pwm0NeutralVal,
00324                     bbc.pwm0MinVal,
00325                     bbc.pwm0MaxVal);
00326   b->calibratePulse(1,
00327                     bbc.pwm1NeutralVal,
00328                     bbc.pwm1MinVal,
00329                     bbc.pwm1MaxVal);
00330   b->capturePulse(0, true);
00331   b->capturePulse(1, true);
00332 
00333   // let's play with the LCD:
00334   b->lcdClear();   // 01234567890123456789
00335   b->lcdPrintf(0, 0, "collectFrames: 00000");
00336   b->lcdPrintf(0, 1, "STEER=XXX  SPEED=XXX");
00337   b->lcdPrintf(0, 2, "PWM0=0000  0000-0000");
00338   b->lcdPrintf(0, 3, "PWM1=0000  0000-0000");
00339 }
00340 
00341 // ######################################################################
00342 /* So things look consistent in everyone's emacs... */
00343 /* Local Variables: */
00344 /* indent-tabs-mode: nil */
00345 /* End: */
Generated on Sun May 8 08:40:11 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3