Roomba.C

Go to the documentation of this file.
00001 /*!@file Roomba.C Simple roomba class to interact with irobot create  */
00002 
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: Farhan Baluch <fbaluch@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/IRobot/Roomba.C $
00035 // $Id: Roomba.C 12962 2010-03-06 02:13:53Z irock $
00036 //
00037 
00038 
00039 #include "Robots/IRobot/Roomba.H"
00040 #include "Devices/Serial.H"
00041 #include "Component/OptionManager.H"
00042 #include "Util/Timer.H"
00043 #include <vector>
00044 
00045 
00046 #define SERIAL_TIMEOUT 1.0 //The maximum number of seconds to wait for a serial response
00047 
00048 // ######################################################################
00049 Roomba::Roomba(OptionManager& mgr, const std::string& descrName,
00050                      const std::string& tagName, const char *defdev) :
00051   ModelComponent(mgr, descrName, tagName),itsPort(new Serial(mgr,"roomba-serial","roomba-serial"))
00052 {
00053 
00054   // set a default config for our serial port:
00055   itsPort->configure(defdev, 57600, "8N1", false, false, 1);
00056   // attach our port as a subcomponent:
00057   addSubComponent(itsPort);
00058   itsSpeed = 0;
00059   itsRadius =0;
00060   itsAngle=0;
00061   itsDist = 0;
00062 }
00063 
00064 
00065 // ######################################################################
00066 Roomba::~Roomba()
00067 {}
00068 
00069 
00070 // ######################################################################
00071 int Roomba::getSpeed()
00072 {
00073     return itsSpeed;
00074 }
00075 
00076 // ######################################################################
00077 int Roomba::getRadius()
00078 {
00079     return itsRadius;
00080 }
00081 
00082 
00083 // ######################################################################
00084 int Roomba::getAngle()
00085 {
00086     return itsAngle;
00087 }
00088 
00089 // ######################################################################
00090 int Roomba::getDist()
00091 {
00092     return itsDist;
00093 }
00094 
00095 // ######################################################################
00096 void Roomba::setSpeed(const int speed)
00097 {
00098     if(!robotStarted)
00099         LFATAL("You must send start command first");
00100 
00101     itsSpeed = speed;
00102     sendDriveCommand();
00103 }
00104 
00105 // ######################################################################
00106 void Roomba::setRadius(const int radius)
00107 {
00108     if(!robotStarted)
00109         LFATAL("You must send start command first");
00110 
00111     itsRadius = radius;
00112     sendDriveCommand();
00113 }
00114 
00115 // ######################################################################
00116 void Roomba::sendDriveCommand()
00117 {
00118     if(!robotStarted)
00119         LFATAL("You must send start command first");
00120 
00121     unsigned char cmd[5];
00122     cmd[0] = 137; //drive command
00123     cmd[1] = ((short int)itsSpeed&0x00FF00)>>8; //velocity high byte
00124     cmd[2] = ((short int)itsSpeed&0x0000FF); //velocity low byte
00125 
00126     if (itsRadius == 0) //drive striaght
00127     {
00128         cmd[3] = 0x7F; //Radius high byte
00129         cmd[4] = 0xFF; //Radius low byte
00130     }
00131     else {
00132         cmd[3] = ((short int)itsRadius&0x00FF00)>>8; //Radius high byte
00133         cmd[4] = ((short int)itsRadius&0x0000FF); //Radius low byte
00134   }
00135 
00136 
00137     itsPort->write(cmd, 5);
00138     usleep(15*1000);
00139 
00140 }
00141 
00142 // ######################################################################
00143 void Roomba::sendStart()
00144 {
00145      unsigned char cmd[1];
00146      cmd[0] = 128;
00147      itsPort->write(cmd,1);
00148      usleep(15*1000);
00149      robotStarted = 1;
00150 }
00151 // ######################################################################
00152 void Roomba::setMode(const int mode)
00153 {
00154     unsigned char cmd[1];
00155     cmd[0] = 0;
00156 
00157     switch(mode)
00158     {
00159         case 1: cmd[0] = 131; break;     //safemode
00160         case 2: cmd[0] = 132; break;     //fullmode
00161     default: LFATAL("bad mode bye");
00162     };
00163 
00164     itsPort->write(cmd, 1);
00165     usleep(15*1000);
00166 }
00167 
00168 // ######################################################################
00169 void Roomba::setDemo(const short demo)
00170 {
00171     unsigned char cmd[2];
00172     cmd[0] = 136;
00173     cmd[1] = demo;
00174 
00175     itsPort->write(cmd,1);
00176 
00177 }
00178 
00179 // ######################################################################
00180 void Roomba::setLED(const short led, const short color, const short intensity)
00181 {
00182     unsigned char cmd[4];
00183     cmd[0] = 139;
00184 
00185     switch(led)
00186     {
00187         case 1: cmd[1] = 8; break; //Advance LED
00188         case 2: cmd[1] = 2; break; //Play Led
00189         case 3: cmd[1] = 10; break; //Both Led
00190         default: cmd[1] = 0; //default to turn off
00191     };
00192 
00193     cmd[2] = color;
00194     cmd[3] = intensity;
00195 
00196     itsPort->write(cmd,4);
00197 
00198 }
00199 
00200 // ######################################################################
00201 void Roomba::playSong(int song)
00202 {
00203      // The imperial March Song
00204   // G  G  G  E  Bb  G  E  Bb  G  2D  2D  2D  2Eb  Bb  F#  E  Bb  G
00205   // 55 55 55 52 58 55 52 58  55  62  62  62  63   58  54  51 58  55
00206   unsigned char s1[21] = {140, 0, 9, 55, 30, 55, 30, 55, 30, 51, 30, 58, 12, 55, 30, 51, 30, 58, 12, 55, 30};
00207   //unsigned char s2[21] = {140, 0, 9, 55, 30, 55, 30, 55, 30, 51, 30, 58, 12, 55, 30, 51, 30, 58, 12, 55, 30};
00208   unsigned char s2[21] = {140, 1, 9, 62, 30, 62, 30, 62, 30, 63, 30, 58, 12, 54, 30, 51, 30, 58, 12, 55, 30};
00209 
00210   unsigned char cmd[2] ;
00211 
00212   itsPort->write(s1,21);
00213   itsPort->write(s2,21);
00214 
00215   cmd[0] = 141;
00216   cmd[1] = (short)song;
00217 
00218   itsPort->write(cmd,2);
00219 }
00220 
00221 
00222 // ######################################################################
00223 void Roomba::getDistanceAngle(int& dist,int& ang)
00224 {
00225 
00226   unsigned char buff[255];
00227   int len = itsPort->read(buff,255);
00228   printf("%d bytes cleared\n",len);
00229 
00230   //Query the distance and angle sensors
00231   unsigned char cmd[4];
00232   unsigned char data[255];
00233   cmd[0] = 149; //Query list opcode
00234   cmd[1] = 2; //we need two sensors
00235   cmd[2] = 19; //distance
00236   cmd[3] = 20; //angle
00237 
00238   itsPort->write(cmd,4);
00239 
00240   usleep(10*1000);
00241 
00242   //get the data
00243   len = itsPort->read(data, 4);
00244         std::vector<byte> data_rcvd;
00245         for(int i=0; i<len; i++) data_rcvd.push_back(data[i]);
00246 
00247         Timer serialTimeout;
00248         serialTimeout.reset();
00249         while(data_rcvd.size() < 4 && serialTimeout.getSecs() < SERIAL_TIMEOUT)
00250         {
00251                 len = itsPort->read(data, 4);
00252                 for(int i=0; i<len; i++) data_rcvd.push_back(data[i]);
00253         }
00254         double timeToRcv = serialTimeout.getSecs();
00255 
00256 
00257 
00258   printf("Read dist angle bytes %i\n", data_rcvd.size());
00259   short int rDist = 0, rAng = 0;
00260   if (data_rcvd.size() == 4)
00261   {
00262           //printf("%i %i %i %i\n\n",
00263           //data[0], data[1], data[2], data[3]);
00264 
00265     rDist = (int16_t)((data_rcvd[0]<<8) | data_rcvd[1]);
00266     rAng = (int16_t)((data_rcvd[2]<<8) | data_rcvd[3]);
00267 
00268   }
00269   else
00270       LERROR("Read return = %d bytes -- took %fs", data_rcvd.size(), timeToRcv);
00271 
00272   LINFO("Read Took %fs", timeToRcv);
00273   dist= rDist;
00274   ang = rAng;
00275   itsDist = dist;
00276   itsAngle = ang;
00277 }
00278 
00279 // ######################################################################
00280 void Roomba::sendRawCmd(const std::string& data)
00281 {
00282 }
00283 
00284 // ######################################################################
00285 void Roomba::sendDirectDriveCommand(float itsCurrentSteering)
00286 {
00287 
00288     int rightWheel = (int)((itsSpeed*500) + (itsCurrentSteering*500));
00289     int leftWheel = (int)((itsSpeed*500) - (itsCurrentSteering*500));
00290 
00291     if (rightWheel > 500) rightWheel = 500;
00292     if (rightWheel < -500) rightWheel = -500;
00293 
00294     if (leftWheel > 500) leftWheel = 500;
00295     if (leftWheel < -500) leftWheel = -500;
00296 
00297     unsigned char cmd[5];
00298     cmd[0] = 145; //Direct drive command
00299     cmd[1] = ((short int)rightWheel&0xFFFF)>>8; //Right Wheel high byte
00300     cmd[2] = ((short int)rightWheel&0xFF); //Right Wheel low byte
00301 
00302     cmd[3] = ((short int)leftWheel&0xFFFF)>>8; //Left Wheel high byte
00303     cmd[4] = ((short int)leftWheel&0xFF); //Left Wheel low byte
00304 
00305     itsPort->write(cmd,5);
00306 }
00307 
00308 // ######################################################################
00309 /* So things look consistent in everyone's emacs... */
00310 /* Local Variables: */
00311 /* indent-tabs-mode: nil */
00312 /* End: */
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
Generated on Sun May 8 08:41:22 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3