BeeStemTiny.C

Go to the documentation of this file.
00001 /*!@file Devices/BeeStemTiny.C Simple interface to beestem */
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: Lior Elazary <elazary@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/BeeStemTiny.C $
00035 // $Id: BeeStemTiny.C 10794 2009-02-08 06:21:09Z itti $
00036 //
00037 
00038 #include "Devices/BeeStemTiny.H"
00039 
00040 #include "Component/OptionManager.H"
00041 #include "Devices/Serial.H"
00042 #include <string>
00043 
00044 #define BS_CMD_DELAY 5000000
00045 
00046 // ######################################################################
00047 BeeStemTiny::BeeStemTiny(OptionManager& mgr, const std::string& descrName,
00048          const std::string& tagName, const char *defdev, const char *defdev2) :
00049   ModelComponent(mgr, descrName, tagName),
00050   itsPort(new Serial(mgr)),
00051   itsCompassPort(new Serial(mgr))
00052 {
00053 
00054 
00055   // set a default config for our serial port:
00056   itsPort->configure(defdev, 38400, "8N1", false, false, 1);
00057 
00058   itsCompassPort->configure(defdev2, 2400, "8N1", false, false, 1);
00059 
00060   // attach our port as a subcomponent:
00061   addSubComponent(itsPort);
00062   addSubComponent(itsCompassPort);
00063 
00064         for (int i=0; i<5; i++)
00065                 itsLastMotorCmd[i] = 0;
00066 
00067 
00068   pthread_mutex_init(&itsSerialLock, NULL);
00069 }
00070 
00071 // ######################################################################
00072 BeeStemTiny::~BeeStemTiny()
00073 {
00074   pthread_mutex_destroy(&itsSerialLock);
00075 }
00076 
00077 // ######################################################################
00078 //The crappyCompass functionality can map crappy compass values to real headings as long as the crappy input is consistent.
00079 //  It does this by running a calibration routined which reads in as many value as possible and stores them in a
00080 //  vector. Then, when a user asks the crappyCompass class for a real heading, they can pass in a crappy value, and
00081 //  the BeeStem will map it to a point in its crappy vector, returning the index.
00082 //Just make sure to start the calibration at a value that doesn't get ever get crappy.
00083 //A better way to do this is to prompts for user input
00084 bool BeeStemTiny::calibrateCrappyCompass() {
00085 
00086 
00087   int starting_point;
00088   char sensor_reports[3];
00089   char cmd = 102;
00090 
00091   //char* values = NULL;
00092   pthread_mutex_lock(&itsSerialLock);
00093   itsCompassPort->write(&cmd, 1);
00094   pthread_mutex_unlock(&itsSerialLock);
00095 
00096   if( itsCompassPort->read(sensor_reports, 3) != 3 ) {
00097     return false;
00098   }
00099 
00100   //Get our starting point
00101   starting_point = sensor_reports[0];
00102 
00103   return true;
00104 
00105 }
00106 
00107 
00108 // ######################################################################
00109 bool BeeStemTiny::setThrusters(int &m1, int &m2, int &m3,
00110                 int &m4, int &m5)
00111 {
00112   // Command Buffer:
00113   // [0] is start character
00114   // [1..5] is m1 m5
00115 
00116   pthread_mutex_lock(&itsSerialLock);
00117 
00118   if (m1 > MOTOR_MAX) m1 = MOTOR_MAX; if (m1 < -MOTOR_MAX) m1 = -MOTOR_MAX;
00119   if (m2 > MOTOR_MAX) m2 = MOTOR_MAX; if (m2 < -MOTOR_MAX) m2 = -MOTOR_MAX;
00120   if (m3 > MOTOR_MAX) m3 = MOTOR_MAX; if (m3 < -MOTOR_MAX) m3 = -MOTOR_MAX;
00121   if (m4 > MOTOR_MAX) m4 = MOTOR_MAX; if (m4 < -MOTOR_MAX) m4 = -MOTOR_MAX;
00122   if (m5 > MOTOR_MAX) m5 = MOTOR_MAX; if (m5 < -MOTOR_MAX) m5 = -MOTOR_MAX;
00123 
00124 
00125 
00126   if (abs(itsLastMotorCmd[0] - m1) > 60 && itsLastMotorCmd[0]*m1 < 0) m1 = 0;
00127   if (abs(itsLastMotorCmd[1] - m2) > 60 && itsLastMotorCmd[1]*m2 < 0) m2 = 0;
00128   if (abs(itsLastMotorCmd[2] - m3) > 60 && itsLastMotorCmd[2]*m3 < 0) m3 = 0;
00129   if (abs(itsLastMotorCmd[3] - m4) > 60 && itsLastMotorCmd[3]*m4 < 0) m4 = 0;
00130   if (abs(itsLastMotorCmd[4] - m5) > 60 && itsLastMotorCmd[4]*m5 < 0) m5 = 0;
00131 
00132   //LINFO("%i %i %i %i %i", m1, m2, m3, m4, m5);
00133 
00134   itsLastMotorCmd[0] = m1;
00135   itsLastMotorCmd[1] = m2;
00136   itsLastMotorCmd[2] = m3;
00137   itsLastMotorCmd[3] = m4;
00138   itsLastMotorCmd[4] = m5;
00139 
00140 
00141 
00142   char command[6];
00143   command[0] = 101;
00144   command[1] = (signed char)m1;
00145   command[2] = (signed char)m2;
00146   command[3] = (signed char)m3;
00147   command[4] = (signed char)m4;
00148   command[5] = (signed char)m5;
00149 
00150 //        LINFO("%i %i %i %i %i",
00151 //                                                                        command[0], command[1], command[2], command[3], command[4], command[5]);
00152 
00153   for(int i = 0; i<6; i++) {
00154     itsPort->write(&command[i], 1);
00155     //usleep(BS_CMD_DELAY);
00156  }
00157 
00158   pthread_mutex_unlock(&itsSerialLock);
00159 
00160   return true;
00161 
00162 
00163   /*
00164   // write command buffer
00165   if (itsPort->write(command, 6) == 6)
00166           return true;
00167   else
00168   return false;*/
00169 }
00170 
00171 // ######################################################################
00172 bool BeeStemTiny::getSensors(int &heading, int &pitch, int &roll, int &ext_pressure, int &int_pressure)
00173 {
00174 
00175 
00176   //First let's handle incoming compass data (not actually related to the BeeStem
00177   //at this point, but whatever.
00178   float h,p,r;
00179   static std::string compassValues;
00180   char compassBuffer[50];
00181 
00182   //Read as many bytes from the serial buffer as are available
00183   int size = itsCompassPort->read(&compassBuffer, 50);
00184 
00185   if (size > 0) //only update if we have any values
00186   {
00187       compassBuffer[size] = 0;
00188       compassValues+=std::string(compassBuffer);
00189   }
00190 
00191   //Once we have at least 30 bytes we know that we have a frame, so we can parse it.
00192   if(compassValues.size() > 30) {
00193 //    LINFO("COMPASS VALUES: %s", compassValues.c_str());
00194     int frameBegin = compassValues.find('\n');
00195     int frameEnd = compassValues.find('\n', frameBegin+1);
00196     std::string compassFrame = compassValues.substr(frameBegin, frameEnd-frameBegin);
00197     sscanf(compassValues.substr(frameBegin).c_str(), "\r%f,%f,%f", &h, &p, &r);
00198 
00199     heading = (int)h;
00200     pitch = (int)p;
00201     roll = (int)r;
00202 
00203     compassValues.clear();
00204   }
00205 
00206 
00207   //Now we deal with the actual BeeStem
00208   // Command Buffer:
00209   // [0] is start character
00210   // [1..5] is the data
00211   pthread_mutex_lock(&itsSerialLock);
00212   char cmd = 102;
00213   unsigned char presBuff[10];
00214   itsPort->write(&cmd, 1);
00215   int presSize = itsPort->read(presBuff, 10);
00216 
00217   if(presSize == 4) {
00218     itsAvgDepth.push_back(((unsigned int)presBuff[2] | ((unsigned int)presBuff[3] << 8)));
00219 
00220     if (itsAvgDepth.size() > 40)
00221       {
00222         long avg = 0;
00223         for(std::list<int>::iterator itr=itsAvgDepth.begin();
00224             itr != itsAvgDepth.end(); ++itr)
00225           avg += *itr;
00226         itsAvgDepth.pop_front();
00227 
00228         ext_pressure = (unsigned int)(avg/itsAvgDepth.size());
00229       }
00230 
00231     //ext_pressure = ((unsigned int)presBuff[2] | ((unsigned int)presBuff[3] << 8));
00232   }
00233 
00234   int_pressure = ((unsigned int)presBuff[0] | ((unsigned int)presBuff[1] << 8));
00235 
00236 
00237   // for(int i=0; i<presSize; i++)
00238   //  LINFO("presBuff[%d] = %d", i, presBuff[i]);
00239 
00240   /*if (presSize > 4)
00241     {
00242       unsigned char val = ((unsigned char)presBuff[3])-227;
00243       int_pressure = val;
00244 
00245       itsAvgDepth.push_back((unsigned char)presBuff[4]);
00246       if (itsAvgDepth.size() > 40)
00247         {
00248           long avg = 0;
00249           for(std::list<int>::iterator itr=itsAvgDepth.begin();
00250               itr != itsAvgDepth.end(); ++itr)
00251             avg += *itr;
00252           itsAvgDepth.pop_front();
00253 
00254           ext_pressure = (int)(avg/itsAvgDepth.size());
00255         }
00256         }*/
00257   //LINFO("Ext Pressure: %d, Int Pressure: %d, presSize %d\n", ext_pressure, int_pressure, presSize);
00258   pthread_mutex_unlock(&itsSerialLock);
00259 
00260 
00261 
00262   return true;
00263 }
00264 
00265 bool BeeStemTiny::setHeartBeat()
00266 {
00267   pthread_mutex_lock(&itsSerialLock);
00268   char cmd = 103;
00269 
00270   // write command buffer
00271   bool ret = (itsPort->write(&cmd, 1) == 1);
00272 
00273   pthread_mutex_unlock(&itsSerialLock);
00274 
00275   return ret;
00276 
00277 }
00278 
00279 
00280 
00281 // ######################################################################
00282 /* So things look consistent in everyone's emacs... */
00283 /* Local Variables: */
00284 /* indent-tabs-mode: nil */
00285 /* End: */
Generated on Sun May 8 08:40:37 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3