ssc.C

Go to the documentation of this file.
00001 /*!@file Devices/ssc.C Interface to a 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: Jen Ng <jsn@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/ssc.C $
00035 // $Id: ssc.C 6990 2006-08-11 18:13:51Z rjpeters $
00036 //
00037 
00038 #include "Devices/ssc.H"
00039 
00040 #include "Component/OptionManager.H"
00041 #include "Devices/Serial.H"
00042 
00043 // ######################################################################
00044 SSC::SSC(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, 9600, "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> >[SSCNUMSERVOS];
00057   posmult = new rutz::shared_ptr<NModelParam<float> >[SSCNUMSERVOS];
00058   negmult = new rutz::shared_ptr<NModelParam<float> >[SSCNUMSERVOS];
00059   pos = new byte[SSCNUMSERVOS];
00060   for (uint i = 0; i < SSCNUMSERVOS; 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 SSC::~SSC()
00077 { }
00078 
00079 // ######################################################################
00080 bool SSC::move(const int servo, const float position)
00081 { return moveRaw(servo, calibToRaw(servo, position)); }
00082 
00083 // ######################################################################
00084 float SSC::getPosition(const int servo) const
00085 {
00086   if (servo < 0 || servo >= SSCNUMSERVOS)
00087     LFATAL("Invalid servo number %d", servo);
00088   return rawToCalib(servo, pos[servo]);
00089 }
00090 
00091 // ######################################################################
00092 void SSC::calibrate(const int servo, const byte neutralval, const byte minval,
00093                     const byte maxval)
00094 {
00095   if (servo < 0 || servo >= SSCNUMSERVOS)
00096     LFATAL("Invalid servo number %d", servo);
00097 
00098   zero[servo]->setVal(float(neutralval));
00099   negmult[servo]->setVal(1.0F / (float(neutralval) - float(minval)));
00100   posmult[servo]->setVal(1.0F / (float(maxval) - float(neutralval)));
00101 }
00102 
00103 // ######################################################################
00104 bool SSC::moveRaw(const int servo, const byte rawpos)
00105 {
00106   // Command Buffer:
00107   // [0] is start character
00108   // [1] is which servo to move
00109   // [2] is position to move servo to (0 to MAX_POSITION)
00110   char command[3];
00111   command[0] = 255;
00112   command[1] = servo;
00113   command[2] = rawpos;
00114 
00115   // write command buffer
00116   if (itsPort->write(command, 3) == 3)
00117     {
00118       // update our position:
00119       pos[servo] = rawpos;
00120       return true;
00121     }
00122   else
00123       return false;
00124 }
00125 
00126 // ######################################################################
00127 bool SSC::moveRawHack(const int servo, const byte rawpos, const int port)
00128 {
00129   // Command Buffer:
00130   // [0] is start character
00131   // [1] is which servo to move
00132   // [2] is position to move servo to (0 to MAX_POSITION)
00133   char command[3];
00134   command[0] = 255;
00135   command[1] = servo;
00136   command[2] = rawpos;
00137   int fd;
00138   if(port == 1)
00139     fd = open("/dev/ttyS0", O_RDWR);
00140   else
00141     fd = open("/dev/ttyS1", O_RDWR);
00142   if(fd==-1) LFATAL("open failed");
00143   if(write(fd, command, 3)==-1){
00144     perror("open");
00145     LFATAL("write failed");
00146   }
00147   close(fd);
00148   return true;
00149 }
00150 
00151 // ######################################################################
00152 byte SSC::getPositionRaw(const int servo) const
00153 {
00154   if (servo < 0 || servo >= SSCNUMSERVOS)
00155     LFATAL("Invalid servo number %d", servo);
00156 
00157   return pos[servo];
00158 }
00159 
00160 // ######################################################################
00161 float SSC::rawToCalib(const int servo, const byte rawpos) const
00162 {
00163   if (servo < 0 || servo >= SSCNUMSERVOS)
00164     LFATAL("Invalid servo number %d", servo);
00165 
00166   float position;
00167   if (rawpos >= byte(zero[servo]->getVal()))
00168     position = (float(rawpos) - zero[servo]->getVal()) *
00169       posmult[servo]->getVal();
00170   else
00171     position = (float(rawpos) - zero[servo]->getVal()) *
00172       negmult[servo]->getVal();
00173 
00174   if (position < -1.0F) position = -1.0F;
00175   else if (position > 1.0F) position = 1.0F;
00176 
00177   return position;
00178 }
00179 
00180 // ######################################################################
00181 byte SSC::calibToRaw(const int servo, const float position) const
00182 {
00183   if (servo < 0 || servo >= SSCNUMSERVOS)
00184     LFATAL("Invalid servo number %d", servo);
00185 
00186   if (position > 1.0F || position < -1.0F)
00187     LFATAL("Invalid position %f (range -1.0..1.0)", position);
00188 
00189   int rawpos;
00190   if (position < 0.0F)
00191     rawpos = int(position / negmult[servo]->getVal() +
00192                  zero[servo]->getVal() + 0.49999F);
00193   else
00194     rawpos = int(position / posmult[servo]->getVal() +
00195                  zero[servo]->getVal() + 0.49999F);
00196 
00197   if (rawpos < 0) rawpos = 0; else if (rawpos > 255) rawpos = 255;
00198 
00199   return byte(rawpos);
00200 }
00201 
00202 // ######################################################################
00203 /* So things look consistent in everyone's emacs... */
00204 /* Local Variables: */
00205 /* indent-tabs-mode: nil */
00206 /* End: */
Generated on Sun May 8 08:40:38 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3