Pololu.C

Go to the documentation of this file.
00001 /*!@file Devices/Pololu.C Interface to poloau Serial Servo Controller */
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/Pololu.C $
00035 // $Id: Pololu.C 8524 2007-06-28 20:37:05Z rjpeters $
00036 //
00037 
00038 #include "Devices/Pololu.H"
00039 
00040 #include "Component/OptionManager.H"
00041 #include "Devices/Serial.H"
00042 
00043 // ######################################################################
00044 Pololu::Pololu(OptionManager& mgr, const std::string& descrName,
00045          const std::string& tagName, const char *defdev) :
00046   ModelComponent(mgr, descrName, tagName),
00047   itsPort(new Serial(mgr))
00048 {
00049   // set a default config for our serial port:
00050   itsPort->configure(defdev, 57600 , "8N1", false, false, 1);
00051 
00052   // attach our port as a subcomponent:
00053   addSubComponent(itsPort);
00054 
00055   // Initialize our internals:
00056   zero = new rutz::shared_ptr<NModelParam<float> >[PololuNUMSERVOS];
00057   posmult = new rutz::shared_ptr<NModelParam<float> >[PololuNUMSERVOS];
00058   negmult = new rutz::shared_ptr<NModelParam<float> >[PololuNUMSERVOS];
00059   pos = new byte[PololuNUMSERVOS];
00060   for (uint i = 0; i < PololuNUMSERVOS; i ++)
00061     {
00062       pos[i] = 127; char buf[20];
00063 
00064       sprintf(buf, "Zero%d", i);
00065       zero[i] = NModelParam<float>::make(buf, this, 0.0F);
00066 
00067       sprintf(buf, "PosMult%d", i);
00068       posmult[i] = NModelParam<float>::make(buf, this, 1.0F);
00069 
00070       sprintf(buf, "NegMult%d", i);
00071       negmult[i] = NModelParam<float>::make(buf, this, 1.0F);
00072     }
00073 }
00074 
00075 // ######################################################################
00076 Pololu::~Pololu()
00077 {
00078   delete [] pos;
00079   delete [] negmult;
00080   delete [] posmult;
00081   delete [] zero;
00082 }
00083 
00084 // ######################################################################
00085 bool Pololu::move(const int servo, const float position)
00086 { return moveRaw(servo, calibToRaw(servo, position)); }
00087 
00088 // ######################################################################
00089 float Pololu::getPosition(const int servo) const
00090 {
00091   if (servo < 0 || servo >= PololuNUMSERVOS)
00092     LFATAL("Invalid servo number %d", servo);
00093   return rawToCalib(servo, pos[servo]);
00094 }
00095 
00096 // ######################################################################
00097 void Pololu::calibrate(const int servo, const byte neutralval, const byte minval,
00098                     const byte maxval)
00099 {
00100   if (servo < 0 || servo >= PololuNUMSERVOS)
00101     LFATAL("Invalid servo number %d", servo);
00102 
00103   zero[servo]->setVal(float(neutralval));
00104   negmult[servo]->setVal(1.0F / (float(neutralval) - float(minval)));
00105   posmult[servo]->setVal(1.0F / (float(maxval) - float(neutralval)));
00106 }
00107 
00108 // ######################################################################
00109 bool Pololu::moveRaw(const int servo, const byte rawpos)
00110 {
00111   char command[5];
00112   command[0] = 128; //sync
00113   command[1] = 1; //device #
00114   command[2] = 2; //set position 7-bit command
00115   command[3] = servo; //servo num
00116   command[4] = rawpos; //data
00117 
00118 
00119   // write command buffer
00120   if (itsPort->write(command, 5) == 5)
00121     {
00122       // update our position:
00123       pos[servo] = rawpos;
00124       return true;
00125     }
00126   else
00127       return false;
00128 }
00129 
00130 // ######################################################################
00131 bool Pololu::setSpeed(const int servo, const byte speed)
00132 {
00133   char command[5];
00134   command[0] = 128; //sync
00135   command[1] = 1; //device #
00136   command[2] = 1; //set speed command
00137   command[3] = servo; //servo num
00138   command[4] = speed; //data
00139 
00140 
00141   // write command buffer
00142   if (itsPort->write(command, 5) == 5)
00143       return true;
00144   else
00145       return false;
00146 
00147 }
00148 
00149 // ######################################################################
00150 bool Pololu::setNeutral(const int servo, const short int pos)
00151 {
00152   char command[6];
00153   command[0] = 128; //sync
00154   command[1] = 1; //device #
00155   command[2] = 5; //set neutral command
00156   command[3] = servo; //servo num
00157   command[4] = pos >> 7; //data MSB
00158   command[5] = (pos & 0x7F); //data LSB
00159 
00160   // write command buffer
00161   if (itsPort->write(command, 6) == 6)
00162       return true;
00163   else
00164       return false;
00165 
00166 }
00167 
00168 // ######################################################################
00169 bool Pololu::setParam(const int servo,
00170     bool on_off, bool direction, char range)
00171 {
00172   char command[5];
00173   command[0] = 128; //sync
00174   command[1] = 1; //device #
00175   command[2] = 0; //set param command
00176   command[3] = servo; //servo num
00177   command[4] = 0x00;
00178   command[4] |= (on_off << 6);
00179   command[4] |= (direction << 5);
00180   command[4] |= (range & 0x1f);
00181 
00182   // write command buffer
00183   if (itsPort->write(command, 5) == 5)
00184       return true;
00185   else
00186       return false;
00187 
00188 }
00189 
00190 // ######################################################################
00191 bool Pololu::moveRawHack(const int servo, const byte rawpos, const int port)
00192 {
00193   // Command Buffer:
00194   // [0] is start character
00195   // [1] is which servo to move
00196   // [2] is position to move servo to (0 to MAX_POSITION)
00197   char command[3];
00198   command[0] = 255;
00199   command[1] = servo;
00200   command[2] = rawpos;
00201   int fd;
00202   if(port == 1)
00203     fd = open("/dev/ttyS0", O_RDWR);
00204   else
00205     fd = open("/dev/ttyS1", O_RDWR);
00206   if(fd==-1) LFATAL("open failed");
00207   if(write(fd, command, 3)==-1){
00208     perror("open");
00209     LFATAL("write failed");
00210   }
00211   close(fd);
00212   return true;
00213 }
00214 
00215 // ######################################################################
00216 byte Pololu::getPositionRaw(const int servo) const
00217 {
00218   if (servo < 0 || servo >= PololuNUMSERVOS)
00219     LFATAL("Invalid servo number %d", servo);
00220 
00221   return pos[servo];
00222 }
00223 
00224 // ######################################################################
00225 float Pololu::rawToCalib(const int servo, const byte rawpos) const
00226 {
00227   if (servo < 0 || servo >= PololuNUMSERVOS)
00228     LFATAL("Invalid servo number %d", servo);
00229 
00230   float position;
00231   if (rawpos >= byte(zero[servo]->getVal()))
00232     position = (float(rawpos) - zero[servo]->getVal()) *
00233       posmult[servo]->getVal();
00234   else
00235     position = (float(rawpos) - zero[servo]->getVal()) *
00236       negmult[servo]->getVal();
00237 
00238   if (position < -1.0F) position = -1.0F;
00239   else if (position > 1.0F) position = 1.0F;
00240 
00241   return position;
00242 }
00243 
00244 // ######################################################################
00245 byte Pololu::calibToRaw(const int servo, const float position) const
00246 {
00247   if (servo < 0 || servo >= PololuNUMSERVOS)
00248     LFATAL("Invalid servo number %d", servo);
00249 
00250   if (position > 1.0F || position < -1.0F)
00251     LFATAL("Invalid position %f (range -1.0..1.0)", position);
00252 
00253   int rawpos;
00254   if (position < 0.0F)
00255     rawpos = int(position / negmult[servo]->getVal() +
00256                  zero[servo]->getVal() + 0.49999F);
00257   else
00258     rawpos = int(position / posmult[servo]->getVal() +
00259                  zero[servo]->getVal() + 0.49999F);
00260 
00261   if (rawpos < 0) rawpos = 0; else if (rawpos > 255) rawpos = 255;
00262 
00263   return byte(rawpos);
00264 }
00265 
00266 // ######################################################################
00267 /* So things look consistent in everyone's emacs... */
00268 /* Local Variables: */
00269 /* indent-tabs-mode: nil */
00270 /* End: */
Generated on Sun May 8 08:04:45 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3