sc8000.C

Go to the documentation of this file.
00001 /*!@file sc8000.C Interface to a Serial Servo Controller sc8000
00002  derived from ssc*/
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00006 // University of Southern California (USC) and the iLab at USC.         //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: Lior Elazary <elazary@usc.edu>
00035 //
00036 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/sc8000.C $
00037 // $Id: sc8000.C 6990 2006-08-11 18:13:51Z rjpeters $
00038 //
00039 
00040 #include "Devices/sc8000.H"
00041 
00042 #include "Component/OptionManager.H"
00043 #include "Devices/Serial.H"
00044 
00045 // ######################################################################
00046 SC8000::SC8000(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, 9600, "8N1", false, false, 1);
00053 
00054   // attach our port as a subcomponent:
00055   addSubComponent(itsPort);
00056 
00057   // Initialize our internals:
00058   zero = new rutz::shared_ptr<NModelParam<float> >[SSCNUMSERVOS];
00059   posmult = new rutz::shared_ptr<NModelParam<float> >[SSCNUMSERVOS];
00060   negmult = new rutz::shared_ptr<NModelParam<float> >[SSCNUMSERVOS];
00061   pos = new short[SSCNUMSERVOS];
00062   for (uint i = 0; i < SSCNUMSERVOS; i ++)
00063     {
00064       pos[i] = 32768; char buf[20];
00065                 sprintf(buf, "Zero%d", i);
00066       zero[i] = NModelParam<float>::make(buf, this, 0.0F);
00067 
00068       sprintf(buf, "PosMult%d", i);
00069       posmult[i] = NModelParam<float>::make(buf, this, 1.0F);
00070 
00071       sprintf(buf, "NegMult%d", i);
00072       negmult[i] = NModelParam<float>::make(buf, this, 1.0F);
00073     }
00074 }
00075 
00076 // ######################################################################
00077 SC8000::~SC8000()
00078 { }
00079 
00080 // ######################################################################
00081 bool SC8000::move(const int servo, const float position)
00082 { return moveRaw(servo, calibToRaw(servo, position)); }
00083 
00084 // ######################################################################
00085 float SC8000::getPosition(const int servo) const
00086 {
00087   if (servo < 0 || servo >= SSCNUMSERVOS)
00088     LFATAL("Invalid servo number %d -- ABORT", servo);
00089   return rawToCalib(servo, pos[servo]);
00090 }
00091 
00092 // ######################################################################
00093 void SC8000::calibrate(const int servo, const short neutralval, const short minval,
00094                     const short maxval)
00095 {
00096   if (servo < 0 || servo >= SSCNUMSERVOS)
00097     LFATAL("Invalid servo number %d -- ABORT", servo);
00098 
00099   zero[servo]->setVal(float(neutralval));
00100   negmult[servo]->setVal(1.0F / (float(neutralval) - float(minval)));
00101   posmult[servo]->setVal(1.0F / (float(maxval) - float(neutralval)));
00102 }
00103 
00104 // ######################################################################
00105 bool SC8000::moveRaw(const int servo, const short rawpos)
00106 {
00107   // Command Buffer:
00108   // [0] is start character
00109   // [1] is start character
00110   // [2] is which servo to move (servo mask)
00111   // [3] digital mask
00112   // [4] is position to move servo to (high order)
00113   // [5] is position to move servo to (low order)
00114 
00115   char command[6];
00116   command[0] = 126;
00117   command[1] = 126;
00118   command[2] = 1 << (servo-1); //set servo mask to only one servo (1 index base)
00119   command[3] = 48;        //ascii for 0 (digital ports off)
00120 
00121   //servo positions are 2 bytes
00122   command[4] = (unsigned char)((rawpos >> 8) & 0xFF);
00123   command[5] = (unsigned char)(rawpos);
00124 
00125 
00126   // write command buffer
00127   if (itsPort->write(command, 6) == 6)
00128     {
00129       // update our position:
00130       pos[servo] = rawpos;
00131       return true;
00132     }
00133   else
00134       return false;
00135 }
00136 
00137 // ######################################################################
00138 short SC8000::getPositionRaw(const int servo) const
00139 {
00140   if (servo < 0 || servo >= SSCNUMSERVOS)
00141     LFATAL("Invalid servo number %d -- ABORT", servo);
00142 
00143   return pos[servo];
00144 }
00145 
00146 // ######################################################################
00147 float SC8000::rawToCalib(const int servo, const short rawpos) const
00148 {
00149   if (servo < 0 || servo >= SSCNUMSERVOS)
00150     LFATAL("Invalid servo number %d -- ABORT", servo);
00151 
00152   float position;
00153   if (rawpos >= short(zero[servo]->getVal()))
00154     position = (float(rawpos) - zero[servo]->getVal()) *
00155       posmult[servo]->getVal();
00156   else
00157     position = (float(rawpos) - zero[servo]->getVal()) *
00158       negmult[servo]->getVal();
00159 
00160   if (position < -1.0F) position = -1.0F;
00161   else if (position > 1.0F) position = 1.0F;
00162 
00163   return position;
00164 }
00165 
00166 // ######################################################################
00167 short SC8000::calibToRaw(const int servo, const float position) const
00168 {
00169   if (servo < 0 || servo >= SSCNUMSERVOS)
00170     LFATAL("Invalid servo number %d -- ABORT", servo);
00171 
00172   if (position > 1.0F || position < -1.0F)
00173     LFATAL("Invalid position %f (range -1.0..1.0) -- ABORT", position);
00174 
00175   int rawpos;
00176   if (position < 0.0F)
00177     rawpos = int(position / negmult[servo]->getVal() +
00178                  zero[servo]->getVal() + 0.49999F);
00179   else
00180     rawpos = int(position / posmult[servo]->getVal() +
00181                  zero[servo]->getVal() + 0.49999F);
00182 
00183   if (rawpos < 0) rawpos = 0; else if (rawpos > 65535) rawpos = 65535;
00184 
00185   return short(rawpos);
00186 }
00187 
00188 // ######################################################################
00189 /* So things look consistent in everyone's emacs... */
00190 /* Local Variables: */
00191 /* indent-tabs-mode: nil */
00192 /* End: */
Generated on Sun May 8 08:40:38 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3