BeeStem3.C

Go to the documentation of this file.
00001 /*!@file Devices/BeeStem3.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/BeeStem3.C $
00035 // $Id: BeeStem3.C 13312 2010-04-26 02:16:07Z beobot $
00036 //
00037 
00038 #include "Devices/BeeStem3.H"
00039 
00040 #include "Component/OptionManager.H"
00041 #include <string>
00042 
00043 #define BS_CMD_DELAY 5000000
00044 
00045 // ######################################################################
00046 BeeStem3::BeeStem3(OptionManager& mgr, const std::string& descrName,
00047          const std::string& tagName, const char *defdev) :
00048   ModelComponent(mgr, descrName, tagName),
00049   itsPort(new Serial(mgr))
00050 {
00051   // set a default config for our serial port:
00052   itsPort->configure(defdev, 57600, "8N1", false, false, 1);
00053   //  itsPort->setBlocking(true);
00054 
00055   // attach our port as a subcomponent:
00056   addSubComponent(itsPort);
00057 
00058   mMotorControllerState.resize(NUM_MOTOR_CONTROLLERS);
00059 
00060   for(int i = 0; i < mMotorControllerState.size(); i ++)
00061   {
00062           mMotorControllerState[i] = 0;
00063   }
00064 
00065   pthread_mutex_init(&itsSerialLock, NULL);
00066 }
00067 
00068 // ######################################################################
00069 BeeStem3::~BeeStem3()
00070 {
00071   pthread_mutex_destroy(&itsSerialLock);
00072 }
00073 
00074 // ######################################################################
00075 bool BeeStem3::getSensors(int &accelX,int &accelY,int &accelZ,
00076                           int &compassHeading, int &compassPitch, int &compassRoll,
00077                           int &internalPressure, int &externalPressure,
00078                           int &desiredHeading, int &desiredDepth, int &desiredSpeed,
00079                           int &headingK, int &headingP, int &headingD, int &headingI, int &headingOutput,
00080                           int &depthK, int &depthP, int &depthD, int &depthI, int &depthOutput, char &killSwitch)//,
00081                           //                          int &thruster1, int &thruster2,int &thruster3,
00082                           //int &thruster4,int &thruster5,int &thruster6)
00083 {
00084   char readCmd = 0x00;
00085   char accel_data[3];
00086   unsigned char adc_data[32];
00087   char desired_heading[2];
00088   char desired_depth[2];
00089   char desired_speed;
00090   char marker_drop[2];
00091   char comp_accel[6];
00092   char comp_mag[6];
00093   char comp_heading[6];
00094   char comp_tilt[6];
00095   char battery[4];
00096   char pid[12];
00097   char kill_switch;
00098   char temp;
00099 
00100 
00101   //clear serial buffer
00102   while(itsPort->read(&temp,1));
00103 
00104   // send read command to Propeller
00105   itsPort->write(&readCmd, 1);
00106   usleep(40000);
00107 
00108   //read accelerometer
00109   int size = itsPort->read(&accel_data, 3);
00110 
00111   if(size <= 0)
00112     {
00113       LERROR("Couldn't read accel_data.");
00114       return false;
00115     }
00116 
00117   accelX = accel_data[0];
00118   accelY = accel_data[1];
00119   accelZ = accel_data[2];
00120 
00121   //read adc data
00122   size = itsPort->read(&adc_data, 32);
00123 
00124   if(size <= 0)
00125     {
00126       LERROR("Couldn't read adc_data.");
00127       return false;
00128     }
00129 
00130   internalPressure = adc_data[14];
00131   internalPressure += adc_data[15]<<8;
00132 
00133   externalPressure = adc_data[12];
00134   externalPressure += adc_data[13]<<8;
00135 
00136   /*  thruster1 = adc_data[16];
00137   thruster1 += adc_data[17]<<8;
00138 
00139   thruster2 = adc_data[18];
00140   thruster2 += adc_data[19]<<8;
00141 
00142   thruster3 = adc_data[20];
00143   thruster3 += adc_data[21]<<8;
00144 
00145   thruster4 = adc_data[22];
00146   thruster4 += adc_data[23]<<8;
00147 
00148   thruster5 = adc_data[24];
00149   thruster5 += adc_data[25]<<8;
00150 
00151   thruster6 = adc_data[26];
00152   thruster6 += adc_data[27]<<8;*/
00153 
00154   //read desired heading
00155   size = itsPort->read(&desired_heading, 2);
00156 
00157   if(size <= 0)
00158     {
00159       LERROR("Couldn't read desired_heading.");
00160       return false;
00161     }
00162 
00163   desiredHeading = desired_heading[0];
00164   desiredHeading += desired_heading[1]<<8;
00165 
00166   //read desired depth
00167   size = itsPort->read(&desired_depth, 2);
00168 
00169   if(size <= 0)
00170     {
00171       LERROR("Couldn't read desired_depth.");
00172       return false;
00173     }
00174 
00175   desiredDepth = (255 & desired_depth[0]);
00176   desiredDepth |= (255 & desired_depth[1]<<8) & 65280;
00177 
00178   //read desired speed
00179   size = itsPort->read(&desired_speed, 1);
00180 
00181   if(size <= 0)
00182     {
00183       LERROR("Couldn't read desired_speed.");
00184       return false;
00185     }
00186 
00187   desiredSpeed = desired_speed;
00188 
00189   //read marker droppers
00190   size = itsPort->read(&marker_drop, 2);
00191 
00192   if(size <= 0)
00193     {
00194       LERROR("Couldn't read marker_drop.");
00195       return false;
00196     }
00197 
00198   //read compass acceleration
00199   size = itsPort->read(&comp_accel, 6);
00200 
00201   if(size <= 0)
00202     {
00203       LERROR("Couldn't read comp_accel.");
00204       return false;
00205     }
00206 
00207  //read compass magnetic field
00208   size = itsPort->read(&comp_mag, 6);
00209 
00210   if(size <= 0)
00211     {
00212       LERROR("Couldn't read comp_mag.");
00213       return false;
00214     }
00215 
00216   //read compass heading
00217   size = itsPort->read(&comp_heading, 6);
00218 
00219   if(size <= 0)
00220     {
00221       LERROR("Couldn't read comp_heading.");
00222       return false;
00223     }
00224 
00225 
00226   compassHeading = (unsigned char) comp_heading[0];
00227   compassHeading += (unsigned char) (comp_heading[1])<<8;
00228 
00229   compassPitch = comp_heading[2];
00230   compassPitch += comp_heading[3]<<8;
00231 
00232   compassRoll = comp_heading[4];
00233   compassRoll += comp_heading[5]<<8;
00234 
00235   //read compass tilt
00236   size = itsPort->read(&comp_tilt, 6);
00237 
00238   if(size <= 0)
00239     {
00240       LERROR("Couldn't read comp_tilt.");
00241       return false;
00242     }
00243 
00244   //read battery values
00245   size = itsPort->read(&battery,4);
00246 
00247   if(size <= 0)
00248     {
00249       LERROR("Couldn't read battery.");
00250       return false;
00251     }
00252 
00253   //read pid values
00254   size = itsPort->read(&pid,12);
00255 
00256   if(size <= 0)
00257     {
00258       LERROR("Couldn't read pid.");
00259       return false;
00260     }
00261 
00262   headingK = pid[0];
00263   headingP = pid[1];
00264   headingD = pid[2];
00265   headingI = pid[3];
00266 
00267   headingOutput = (0x00ff & pid[4]);
00268   headingOutput |= pid[5] << 8;
00269 
00270   depthK = pid[6];
00271   depthP = pid[7];
00272   depthD = pid[8];
00273   depthI = pid[9];
00274   depthOutput = (0x00ff & pid[10]);
00275   depthOutput |= pid[11] << 8;
00276 
00277   //read killswitch value
00278   size = itsPort->read(&kill_switch,1);
00279 
00280   if(size <= 0)
00281     {
00282       LERROR("Couldn't read kill switch.");
00283       return false;
00284     }
00285 
00286   killSwitch = kill_switch;
00287 
00288   /*  LINFO("desired_depth[0] = %x, desired_depth[1] = %x, depthOutput= %x",
00289         (0x00ff & pid[10]),
00290         ((0x00ff & pid[11]) << 8) & 0x0ff00,
00291         depthOutput); */
00292 
00293   return true;
00294 }
00295 
00296 bool BeeStem3::setPID(int pidMode, float k, float p, float i, float d)
00297 {
00298   LINFO("pidMode: %d, k %f, p %f, i %f, %f",pidMode,k,p,i,d);
00299 
00300   char pidCmdK;
00301   char pidCmdP;
00302   char pidCmdI;
00303   char pidCmdD;
00304   char pidDepthEn = 0x61;
00305   char pidHeadingEn = 0x60;
00306   char en = 0x01;
00307   char dis = 0x00;
00308 
00309   int16 kv, pv, iv, dv;
00310   kv = k*100;
00311   pv = p*100;
00312   iv = i*100;
00313   dv = d*100;
00314 
00315   char temp;
00316 
00317   //clear serial buffer
00318   while(itsPort->read(&temp,1));
00319 
00320   switch(pidMode)
00321     {
00322     case PID_DEPTH:
00323       pidCmdK = 0x20;
00324       pidCmdP = 0x21;
00325       pidCmdI = 0x22;
00326       pidCmdD = 0x23;
00327       break;
00328     case PID_HEADING:
00329       pidCmdK = 0x30;
00330       pidCmdP = 0x31;
00331       pidCmdI = 0x32;
00332       pidCmdD = 0x33;
00333       break;
00334    case PID_DISABLE:
00335      LINFO("Disable PID.");
00336       itsPort->write(&pidDepthEn, 1);
00337       itsPort->write(&dis, 1);
00338       itsPort->write(&pidHeadingEn, 1);
00339       itsPort->write(&dis, 1);
00340       return true;
00341       break;
00342    case PID_ENABLE:
00343      LINFO("Enable PID.");
00344       itsPort->write(&pidDepthEn, 1);
00345       itsPort->write(&en, 1);
00346       //itsPort->write(&pidHeadingEn, 1);
00347       //itsPort->write(&en, 1);
00348       return true;
00349       break;
00350     default:
00351       LERROR("Invalid PID mode specified.");
00352       return false;
00353     }
00354 
00355 
00356   // send set update K cmd upper lower
00357   itsPort->write(&pidCmdK, 1);
00358 
00359   temp =(kv & 0xff00) >> 8;
00360   itsPort->write(&temp,1);
00361   temp =(kv & 0x00ff);
00362   itsPort->write(&temp,1);
00363 
00364   // send set update P cmd
00365   itsPort->write(&pidCmdP, 1);
00366   temp =(pv & 0xff00) >> 8;
00367   itsPort->write(&temp,1);
00368   temp =(pv & 0x00ff);
00369   itsPort->write(&temp,1);
00370 
00371   // send set update K cmd
00372   itsPort->write(&pidCmdI, 1);
00373   temp =(iv & 0xff00) >> 8;
00374   itsPort->write(&temp,1);
00375   temp =(iv & 0x00ff);
00376   itsPort->write(&temp,1);
00377 
00378   // send set update K cmd
00379   itsPort->write(&pidCmdD, 1);
00380   temp =(dv & 0xff00) >> 8;
00381   itsPort->write(&temp,1);
00382   temp =(dv & 0x00ff);
00383   itsPort->write(&temp,1);
00384 
00385   return true;
00386 }
00387 
00388 void BeeStem3::setThruster(int num, int val)
00389 {
00390         if(val == mMotorControllerState[num]) //don't bother setting it if it's already at this value
00391         {
00392                 return;
00393         }
00394         mMotorControllerState[num] = val; //save the new state
00395         printf("Set thruster [%d]:%d\n", num, val);
00396   char thrusterCmd = 0xff;
00397   //char temp;
00398 
00399   //clear serial buffer
00400   //  while(itsPort->read(&temp,1));
00401 
00402   // send set thruster command to Propeller
00403   itsPort->write(&thrusterCmd, 1);
00404 
00405   //  while(itsPort->read(&temp, 1) != 0)
00406   // std::cout << temp;
00407   // std::cout << std::endl;
00408 
00409   // send set thruster command to Propeller
00410   itsPort->write(&num, 1);
00411   //while(itsPort->read(&temp, 1) != 0)
00412   //  printf("%c", temp);
00413   //std::cout << std::endl;
00414 
00415   // send set thruster command to Propeller
00416   itsPort->write(&val, 1);
00417 }
00418 
00419 /*bool BeeStem3::setDesiredValues(int16 heading, int16 depth, char speed,
00420                                 char markerDropper)
00421 {
00422   char setDesiredHeadingCmd = 0x0b;
00423   char setDesiredDepthCmd = 0x0c;
00424   char temp;
00425 
00426   //clear serial buffer
00427   while(itsPort->read(&temp,1));
00428 
00429   // send set desired values command to Propeller
00430   itsPort->write(&setDesiredHeadingCmd, 1);
00431 
00432   char headingUpper = ((0x00ff00 & heading) >> 8) & 0x00ff;
00433   char headingLower = (heading & 0x00ff);
00434 
00435   char depthUpper = ((0x00ff00 &depth) >> 8) & 0x00ff;
00436   char depthLower = (depth & 0x00ff);
00437 
00438   LINFO("Writing Heading Upper %x", headingUpper);
00439   itsPort->write(&headingUpper,1);
00440   LINFO("Writing Heading Lower %x", headingLower);
00441   itsPort->write(&headingLower,1);
00442 
00443   itsPort->write(&setDesiredDepthCmd, 1);
00444 
00445   itsPort->write(&depthUpper,1);
00446   itsPort->write(&depthLower,1);
00447 
00448   itsPort->write(&speed,1);
00449   itsPort->write(&markerDropper,1);
00450   itsPort->write(&markerDropper,1);
00451 
00452   return true;
00453 }*/
00454 
00455 bool BeeStem3::setDesiredHeading(int16 heading)
00456 {
00457   char setDesiredHeadingCmd = 0x0b;
00458   char temp;
00459 
00460   //clear serial buffer
00461   while(itsPort->read(&temp,1));
00462 
00463   // send set desired values command to Propeller
00464   itsPort->write(&setDesiredHeadingCmd, 1);
00465 
00466   char headingUpper = ((0x00ff00 & heading) >> 8) & 0x00ff;
00467   char headingLower = (heading & 0x00ff);
00468 
00469   LINFO("Writing Heading Upper %x", headingUpper);
00470   itsPort->write(&headingUpper,1);
00471   LINFO("Writing Heading Lower %x", headingLower);
00472   itsPort->write(&headingLower,1);
00473 
00474   return true;
00475 }
00476 
00477 bool BeeStem3::setDesiredDepth(int16 depth)
00478 {
00479   char setDesiredDepthCmd = 0x0c;
00480   char temp;
00481 
00482   //clear serial buffer
00483   while(itsPort->read(&temp,1));
00484 
00485   // send set desired values command to Propeller
00486   itsPort->write(&setDesiredDepthCmd, 1);
00487 
00488   char depthUpper = ((0x00ff00 & depth) >> 8) & 0x00ff;
00489   char depthLower = (depth & 0x00ff);
00490 
00491   LINFO("Writing Depth Upper %x", depthUpper);
00492   itsPort->write(&depthUpper,1);
00493   LINFO("Writing Depth Lower %x", depthLower);
00494   itsPort->write(&depthLower,1);
00495 
00496   return true;
00497 }
00498 
00499 bool BeeStem3::setDesiredSpeed(char speed)
00500 {
00501   char setDesiredSpeedCmd = 0x0d;
00502   char temp;
00503 
00504   //clear serial buffer
00505   while(itsPort->read(&temp,1));
00506 
00507   // send set desired values command to Propeller
00508   itsPort->write(&setDesiredSpeedCmd, 1);
00509 
00510   LINFO("Setting speed: %d\n",speed);
00511   itsPort->write(&speed,1);
00512 
00513   return true;
00514 }
00515 
00516 void BeeStem3::startCompassCalibration()
00517 {
00518   char startCalibCmd = 0xe0;
00519   char temp;
00520 
00521   //clear serial buffer
00522   while(itsPort->read(&temp,1));
00523 
00524   // send set desired values command to Propeller
00525   itsPort->write(&startCalibCmd, 1);
00526 }
00527 
00528 void BeeStem3::endCompassCalibration()
00529 {
00530   char endCalibCmd = 0xe1;
00531   char temp;
00532 
00533   //clear serial buffer
00534   while(itsPort->read(&temp,1));
00535 
00536   // send set desired values command to Propeller
00537   itsPort->write(&endCalibCmd, 1);
00538 }
00539 
00540 // ######################################################################
00541 /* So things look consistent in everyone's emacs... */
00542 /* Local Variables: */
00543 /* indent-tabs-mode: nil */
00544 /* End: */
Generated on Sun May 8 08:40:37 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3