beobot-BeobotControl.C

Go to the documentation of this file.
00001 /*!@file Beobot/beobot-BeobotControl.C
00002   controls the Beobot motion input can be from both remote and Board A  */
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-BeobotControl.C $
00035 // $Id: beobot-BeobotControl.C 7063 2006-08-29 18:26:55Z rjpeters $
00036 //
00037 
00038 #include "Component/ModelManager.H"
00039 #include "Devices/BeoChip.H"
00040 #include "Devices/DeviceOpts.H"
00041 #include "Beobot/BeobotConfig.H"
00042 #include "Beobot/BeobotControl.H"
00043 #include "Util/MathFunctions.H"
00044 
00045 #include <cstdlib>
00046 
00047 #include "Beowulf/Beowulf.H"
00048 #include "Util/Types.H"
00049 #include "Util/log.H"
00050 
00051 #include <cstring>
00052 #include <signal.h>
00053 #include <time.h>
00054 #include <unistd.h>
00055 
00056 static bool goforever = true;
00057 // ######################################################################
00058 void terminate(int s) { LERROR("*** INTERRUPT ***"); goforever = false; exit(1);}
00059 
00060 // ######################################################################
00061 //! Our own little BeoChipListener
00062 class MyBeoChipListener : public BeoChipListener
00063 {
00064 public:
00065   MyBeoChipListener(nub::soft_ref<BeoChip> bc) :
00066     itsBeoChip(bc), minp0(9999), maxp0(0), minp1(9999), maxp1(0),
00067     counter0(0), counter1(0), kbd(0x1f)
00068   {
00069     performCommand = false;
00070   }
00071 
00072   virtual ~MyBeoChipListener() { }
00073 
00074   virtual void event(const BeoChipEventType t, const int valint,
00075                      const float valfloat)
00076   {
00077     LDEBUG("Event: %d val = %d, fval = %f", int(t), valint, valfloat);
00078     switch(t)
00079       {
00080       case PWM0:
00081         if (valint < minp0) minp0 = valint;
00082         else if (valint > maxp0) maxp0 = valint;
00083         itsBeoChip->setServo(0, valfloat);
00084 
00085         if(performCommand)
00086           {
00087             if (++counter0 >= 10)
00088               {
00089                 itsBeoChip->lcdPrintf(5, 2, "%04d  %04d-%04d",
00090                                       valint, minp0, maxp0);
00091                 itsBeoChip->lcdPrintf(6, 1, "%03d",
00092                                   itsBeoChip->getServoRaw(0));
00093                 counter0 = 0;
00094               }
00095           }
00096         break;
00097       case PWM1:
00098         if (valint < minp1) minp1 = valint;
00099         else if (valint > maxp1) maxp1 = valint;
00100 
00101         if(performCommand)
00102           {
00103             itsBeoChip->setServo(1, valfloat);
00104             if (++counter1 >= 10)
00105               {
00106                 itsBeoChip->lcdPrintf(5, 3, "%04d  %04d-%04d",
00107                                       valint, minp1, maxp1);
00108                 itsBeoChip->lcdPrintf(17, 1, "%03d",
00109                                       itsBeoChip->getServoRaw(1));
00110                 counter1 = 0;
00111               }
00112           }
00113         break;
00114       case KBD: kbd = valint;  break;
00115       case RESET: LERROR("BeoChip RESET occurred!"); break;
00116       case ECHOREP: LINFO("BeoChip Echo reply received."); break;
00117       case INOVERFLOW: LERROR("BeoChip input overflow!"); break;
00118       case SERIALERROR: LERROR("BeoChip serial error!"); break;
00119       case OUTOVERFLOW: LERROR("BeoChip output overflow!"); break;
00120       default: LERROR("Unknown event %d received!", int(t)); break;
00121       }
00122   }
00123 
00124   nub::soft_ref<BeoChip> itsBeoChip;
00125   int minp0, maxp0, minp1, maxp1;
00126   int counter0, counter1;
00127   int kbd;
00128   bool performCommand;
00129 };
00130 
00131 // ######################################################################
00132 //! Drive the Beobot under remote control and Board A
00133 /*! This simple test program demonstrate how to capture PWM signals
00134   from the Beochip, which on the Beobot correspond to steering and
00135   speed inputs from the remote control. The captured signals are then
00136   directly fed into the Beobot's steering and speed servos controlled
00137   by BeobotControl class (which has the BeoChip). */
00138 int main(const int argc, const char* argv[])
00139 {
00140   MYLOGVERB = LOG_INFO;
00141 
00142   // instantiate a model manager:
00143   ModelManager manager("beobot-BeobotControl");
00144 
00145   // Instantiate our various ModelComponents:
00146   BeobotConfig bbc;
00147   nub::soft_ref<BeoChip> b(new BeoChip(manager));
00148   manager.addSubComponent(b);
00149 
00150   nub::soft_ref<BeobotControl> bc(new BeobotControl(b, manager));
00151   manager.addSubComponent(bc);
00152 
00153   nub::soft_ref<Beowulf>
00154     beo(new Beowulf(manager, "Beowulf Slave", "BeowulfSlave", false));
00155   manager.addSubComponent(beo);
00156 
00157   // Parse command-line:
00158   if (manager.parseCommandLine(argc, argv, "<serdev>", 1, 1) == false)
00159     return(1);
00160 
00161   // let's configure our serial device:
00162   b->setModelParamVal("BeoChipDeviceName", manager.getExtraArg(0));
00163 
00164   // let's register our listener:
00165   rutz::shared_ptr<MyBeoChipListener> lis(new MyBeoChipListener(b));
00166   rutz::shared_ptr<BeoChipListener> lis2; lis2.dynCastFrom(lis); // cast down
00167   b->setListener(lis2);
00168 
00169   // setup signal handling:
00170   signal(SIGHUP, terminate); signal(SIGINT, terminate);
00171   signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00172 
00173   TCPmessage rmsg;            // message being received and to process
00174   TCPmessage smsg;            // message being sent
00175 
00176   // let's get all our ModelComponent instances started:
00177   manager.start();
00178 
00179   // reset the beochip:
00180   LINFO("Resetting BeoChip...");
00181   b->resetChip(); sleep(1);
00182 
00183   // keep the gear at the lowest speed/highest torque
00184   b->setServoRaw(bbc.gearServoNum, bbc.gearMinVal);
00185 
00186   // turn on the keyboard
00187   b->debounceKeyboard(true);
00188   b->captureKeyboard(true);
00189 
00190   // calibrate the PWMs:
00191   b->calibratePulse(0,
00192                     bbc.pwm0NeutralVal,
00193                     bbc.pwm0MinVal,
00194                     bbc.pwm0MaxVal);
00195   b->calibratePulse(1,
00196                     bbc.pwm1NeutralVal,
00197                     bbc.pwm1MinVal,
00198                     bbc.pwm1MaxVal);
00199   b->capturePulse(0, true);
00200   b->capturePulse(1, true);
00201 
00202   // let's play with the LCD:
00203   b->lcdClear();   // 01234567890123456789
00204   b->lcdPrintf(0, 0, "BEOBOT-CONTROL: 0000");
00205   b->lcdPrintf(0, 1, "STEER=XXX  SPEED=XXX");
00206   b->lcdPrintf(0, 2, "PWM0=0000  0000-0000");
00207   b->lcdPrintf(0, 3, "PWM1=0000  0000-0000");
00208 
00209   // wait for keyboard and board A process it:
00210   int32 rframe, raction, rnode = -1;  // receive from any node
00211   int ct = 0;
00212   while(goforever) {
00213 
00214     // print keyboard values:
00215     char kb[6]; kb[5] = '\0';
00216     for (int i = 0; i < 5; i ++) kb[i] = (lis->kbd>>(4-i))&1 ? '1':'0';
00217 
00218     // quit if both extreme keys pressed simultaneously:
00219     if (kb[0] == '0' && kb[4] == '0') {
00220       b->lcdPrintf(15, 0, "QUIT ");
00221       goforever = false; break;
00222     }
00223 
00224     // wait up to 5ms to see if we receive a command from Board A
00225     if( beo->receive( rnode, rmsg, rframe, raction, 5 ) )
00226     {
00227       // check what the command is through raction
00228 
00229       // if UPDATE_IMAGE_COLOR: get the PixRGB<byte> image
00230 
00231       // if UPDATE_IMAGE_BW: get the <float> image
00232 
00233       // if SET_CONTROL: 0 remote, 1 Board A
00234 
00235       // if SET_ACTION: steer, speed, gear
00236 
00237       // set the motor to the passed in values
00238       float steerVal = rmsg.getElementFloat();
00239       float speedVal = rmsg.getElementFloat();
00240       float  gearVal = rmsg.getElementFloat();
00241       LINFO( "Received steer: %f speed: %f gear: %f",
00242              steerVal, speedVal, gearVal);
00243       bc->setSteer(steerVal);
00244       bc->setSpeed(speedVal);
00245       rmsg.reset(rframe, raction);
00246 
00247       if(++ct >= 10)
00248         {
00249           b->lcdPrintf(6,  1, "%03d", b->getServoRaw(0));
00250           b->lcdPrintf(17, 1, "%03d", b->getServoRaw(1));
00251           ct = 0;
00252         }
00253       // if SET_STEER_PID
00254 
00255       // if SET_SPEED_PID
00256     }
00257     usleep(5000);
00258   }
00259 
00260   manager.stop();
00261   return 0;
00262 }
00263 
00264 // ######################################################################
00265 /* So things look consistent in everyone's emacs... */
00266 /* Local Variables: */
00267 /* indent-tabs-mode: nil */
00268 /* End: */
Generated on Sun May 8 08:04:24 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3