BeoSubIMU.C

Go to the documentation of this file.
00001 /*!@file BeoSub/BeoSubIMU.C class for interfacing with the IMU */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00005 // by the 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 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/BeoSub/BeoSubIMU.C $
00034 // $Id: BeoSubIMU.C 6990 2006-08-11 18:13:51Z rjpeters $
00035 //
00036 
00037 #include "BeoSub/BeoSubIMU.H"
00038 #include <string>
00039 
00040 void *IMU_run(void *c);
00041 
00042 // ######################################################################
00043 void *IMU_run(void *c)
00044 {
00045   BeoSubIMU *d = (BeoSubIMU *) c;
00046   d ->run();
00047   return NULL;
00048 }
00049 
00050 // ######################################################################
00051 BeoSubIMUListener::~BeoSubIMUListener()
00052 { }
00053 
00054 // ######################################################################
00055 BeoSubIMU::BeoSubIMU(OptionManager& mgr, const std::string& descrName,
00056                      const std::string& tagName, const char *dev) :
00057   ModelComponent(mgr, descrName, tagName),
00058   itsSerial(new Serial(mgr, descrName+" Serial Port", tagName+"SerialPort")),
00059   itsKeepgoing(true)
00060 {
00061   itsSerial->configure(dev, 115200, "8N1", false, true, 0);
00062   addSubComponent(itsSerial);
00063   pthread_mutex_init(&itsLock, NULL);
00064 }
00065 
00066 // ######################################################################
00067 void BeoSubIMU::start2()
00068 { pthread_create(&itsRunner, NULL, &IMU_run, (void *) this); }
00069 
00070 // ######################################################################
00071 void BeoSubIMU::stop1()
00072 {
00073   itsKeepgoing = false;
00074   usleep(300000); // make sure thread has exited
00075 }
00076 
00077 // ######################################################################
00078 void BeoSubIMU::setListener(rutz::shared_ptr<BeoSubIMUListener> listener)
00079 { itsListener = listener; }
00080 
00081 // ######################################################################
00082 BeoSubIMU::~BeoSubIMU()
00083 {
00084   pthread_mutex_destroy(&itsLock);
00085 }
00086 
00087 // ######################################################################
00088 void BeoSubIMU::run()
00089 {
00090   while(itsKeepgoing)
00091     {
00092       const int psize = 22;
00093       unsigned char packet[psize];
00094       packet[0] = 0x7F; packet[1] = 0xFF;
00095       int checksum;
00096 
00097       do
00098         {
00099           // initialize variables:
00100           int count = 2; checksum = 0x7FFF;
00101           bool tagFound = false, FFFound = false;
00102 
00103           while (count < psize)
00104             {
00105               // read one byte from serial port:
00106               unsigned char c; int size = itsSerial->read(&c, 1);
00107               if (size != 1) { PLERROR("Serial port read error"); continue; }
00108 
00109               // if we have already found the tag, just fill the packet in:
00110               if (tagFound)
00111                 {
00112                   packet[count] = c;
00113                   if (count % 2 == 0) checksum += int(c);
00114                   else checksum += ((int(c)) << (sizeof(char)*8));
00115                   ++ count;
00116                 }
00117 
00118               // finding the first byte of the tag:
00119               if (c == 0xFF) FFFound = true;
00120 
00121               // trigger tag found when a complete tag is detected:
00122               if (FFFound && c == 0x7F) tagFound = true;
00123             }
00124         } while ((checksum & 0x0000FFFF)); // exit iff checksum correct
00125 
00126       // get the data:
00127       pthread_mutex_lock(&itsLock);
00128       itsXaccel = accelConvert((packet[5] << 8) + packet[4]);
00129       itsYaccel = accelConvert((packet[9] << 8) + packet[8]);
00130       itsZaccel = accelConvert((packet[13] << 8) + packet[12]);
00131       itsXvel = rateConvert((packet[7] << 8) + packet[6]);
00132       itsYvel = rateConvert((packet[11] << 8) + packet[10]);
00133       itsZvel = rateConvert((packet[15] << 8) + packet[14]);
00134 
00135       // if we have a listener, let's notify it:
00136       if (itsListener.is_valid())
00137         itsListener->newData(itsXaccel, itsYaccel, itsZaccel,
00138                              itsXvel, itsYvel, itsZvel);
00139       pthread_mutex_unlock(&itsLock);
00140     }
00141 
00142   pthread_exit(0);
00143 }
00144 
00145 // ######################################################################
00146 float BeoSubIMU::accelConvert(int data)
00147 {
00148   if (data > 0x7FFF)
00149     {
00150       int temp = (((~data)+1) & 0x0000FFFF);
00151       return -temp / 326.3F;
00152     }
00153   else return data / 326.3F; // scale factor
00154 }
00155 
00156 // ######################################################################
00157 float BeoSubIMU::rateConvert(int data)
00158 {
00159   if (data > 0x7FFF)
00160     {
00161       int temp = (((~data)+1) & 0x0000FFFF); // 2's complement
00162       return -temp / 100.0F;
00163     }
00164   else return data / 100.0F; // scale factor
00165 }
00166 
00167 // ######################################################################
00168 float BeoSubIMU::getXaccel()
00169 {
00170   pthread_mutex_lock(&itsLock);
00171   const float ret = itsXaccel;
00172   pthread_mutex_unlock(&itsLock);
00173   return ret;
00174 }
00175 
00176 // ######################################################################
00177 float BeoSubIMU::getYaccel()
00178 {
00179   pthread_mutex_lock(&itsLock);
00180   const float ret = itsYaccel;
00181   pthread_mutex_unlock(&itsLock);
00182   return ret;
00183 }
00184 
00185 // ######################################################################
00186 float BeoSubIMU::getZaccel()
00187 {
00188   pthread_mutex_lock(&itsLock);
00189   const float ret = itsZaccel;
00190   pthread_mutex_unlock(&itsLock);
00191   return ret;
00192 }
00193 
00194 // ######################################################################
00195 Angle BeoSubIMU::getXvel()
00196 {
00197   pthread_mutex_lock(&itsLock);
00198   const Angle ret = itsXvel;
00199   pthread_mutex_unlock(&itsLock);
00200   return ret;
00201 }
00202 
00203 // ######################################################################
00204 Angle BeoSubIMU::getYvel()
00205 {
00206   pthread_mutex_lock(&itsLock);
00207   const Angle ret = itsYvel;
00208   pthread_mutex_unlock(&itsLock);
00209   return ret;
00210 }
00211 
00212 // ######################################################################
00213 Angle BeoSubIMU::getZvel()
00214 {
00215   pthread_mutex_lock(&itsLock);
00216   const Angle ret = itsZvel;
00217   pthread_mutex_unlock(&itsLock);
00218   return ret;
00219 }
00220 
00221 // ######################################################################
00222 /* So things look consistent in everyone's emacs... */
00223 /* Local Variables: */
00224 /* indent-tabs-mode: nil */
00225 /* End: */
Generated on Sun May 8 08:04:32 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3