BeoChip.H

Go to the documentation of this file.
00001 /*!@file Devices/BeoChip.H Interface to Brian Hudson's BeoChip interface device.*/
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: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/BeoChip.H $
00035 // $Id: BeoChip.H 6990 2006-08-11 18:13:51Z rjpeters $
00036 //
00037 
00038 #ifndef BEOCHIP_H_DEFINED
00039 #define BEOCHIP_H_DEFINED
00040 
00041 #include "Component/ModelComponent.H"
00042 #include "Component/ModelParam.H"
00043 #include "Devices/Serial.H"
00044 #include "Util/Types.H"
00045 #include "rutz/shared_ptr.h"
00046 
00047 #include <pthread.h>
00048 #include <stdarg.h>
00049 
00050 //! BeoChip event types
00051 enum BeoChipEventType {
00052   NONE = 0, PWM0 = 1, PWM1 = 2, KBD = 3, ADC0 = 4, ADC1 = 5,
00053   RESET = 6, ECHOREP = 7,
00054   INOVERFLOW = 8, SERIALERROR = 9, OUTOVERFLOW = 10 };
00055 
00056 //! BeoChip event listener
00057 /*! The BeoChipListener gets called each time an event is received
00058   from the BeoChip. The BeoChipEventType is passed to the listener,
00059   allowing the user to determine the type of event received and to
00060   then interpret the event data also passed to the listener. By
00061   default, there is no listener, and users can just asynchronously
00062   query the BeoChip for its current internal state. If those queries
00063   come in too slowly, however, they may miss some events (e.g., a
00064   briefly pressed key). So, production code should define a derived
00065   class for BeoChipListener and register it with the BeoChip object,
00066   so that it will take action as soon as an event is received. */
00067 class BeoChipListener {
00068 public:
00069   //! Destructor
00070   virtual ~BeoChipListener();
00071 
00072   //! An event was received
00073   /*! This function will be called by the BeoChip once you have
00074     registered your BeoChipListener derivative with the BeoChip using
00075     BeoChip::setListener(). Beware that the call to event() will ve
00076     from a thread running in the BeoChip and thus will operate in
00077     parallel with your main thread and main loop. See test-BeoChip.C
00078     for an example of how to synchronize a main loop with these
00079     asynchronous event calls. The following data will be passed along
00080     with the event type:
00081     <PRE>
00082 
00083     Type            valint                        valfloat
00084     ----------------------------------------------------------------------
00085     NONE         0                             0.0F
00086     PWM0         pulse 0 width, 1.6us units    calibrated width in [-1..1]
00087     PWM1         pulse 1 width, 1.6us units    calibrated width in [-1..1]
00088     KBD          5 LSB show the 5 keys         0.0F
00089     ADC0         A/D 0 value                   calibrated value in [-1..1]
00090     ADC1         A/D 0 value                   calibrated value in [-1..1]
00091     all others   0                             0.0F
00092 
00093     </PRE>
00094   */
00095   virtual void event(const BeoChipEventType t, const int valint,
00096                      const float valfloat) = 0;
00097 };
00098 
00099 //! BeoChip.H Interface to Brian Hudson's BeoChip device
00100 /*! Hardware interface Class. Contains interfaces to display to an
00101 LCD, read servo pulse values (2), set servo positions (8), get
00102 A/D conversion values (2), manipulate four digital outs,
00103 and finally, get some intput from 5 pushbuttons. */
00104 class BeoChip : public ModelComponent
00105 {
00106 public:
00107   // ############################################################
00108   /*! @name Constructors, destructors and debugging */
00109   //@{
00110 
00111   //! Default constructor. See ModelComponent.H
00112   BeoChip(OptionManager& mgr,
00113           const std::string& descrName = "BeoChip",
00114           const std::string& tagName = "BeoChip");
00115 
00116   //! Destructor
00117   ~BeoChip();
00118 
00119   //! Install a callback (listener) for BeoChip events
00120   /*! This callback will be called with the corresponding
00121     BeoChipEvenType each time an event is received from the BeoChip. */
00122   void setListener(rutz::shared_ptr<BeoChipListener>& listener);
00123 
00124   //! Send an echo request
00125   /*! The BeoChip should reply with an EchoReply event if it is alive */
00126   bool echoRequest();
00127 
00128   //! Turn debug mode on/off
00129   /*! When in debug mode, the BeoChip sends an EchoReply for each command
00130     it receives. */
00131   bool debugMode(const bool on);
00132 
00133   //! Reset the BeoChip
00134   bool resetChip();
00135 
00136   //@}
00137 
00138   // ############################################################
00139   /*! @name LCD functions */
00140   //@{
00141 
00142   //! Go to given cursor position
00143   bool lcdGotoXY(const int x = 0, const int y = 0);
00144 
00145   //! Go to given cursor position
00146   bool lcdGoto(const int i = 0);
00147 
00148   //! Print some text
00149   /*! syntax is the same as printf(). Returns true on success. */
00150   bool lcdPrintf(const char *fmt, ...)
00151     // NOTE: this __attribute__ tells gcc that it should issue
00152     // printf-style warnings when compiling calls to
00153     // BeoChip::lcdPrintf(), treating the 2nd argument (fmt) as the
00154     // format string, and the 3rd and subsequent arguments as the
00155     // printf-style parameters (SUBNOTE: because this is a member
00156     // function, there is a hidden 'this' parameter that counts as arg
00157     // 1, so the listed arguments are counted starting from 2)
00158     __attribute__((format(__printf__, 2, 3)));
00159     ;
00160 
00161   //! Print some text starting at given cursor position
00162   /*! syntax is the same as printf(), plus the x, y
00163     coordinates. Returns true on success. */
00164   bool lcdPrintf(const int x, const int y, const char *fmt, ...)
00165     // NOTE: this __attribute__ tells gcc that it should issue
00166     // printf-style warnings when compiling calls to
00167     // BeoChip::lcdPrintf(), treating the 3rd argument (fmt) as the
00168     // format string, and the 4th and subsequent arguments as the
00169     // printf-style parameters (SUBNOTE: because this is a member
00170     // function, there is a hidden 'this' parameter that counts as arg
00171     // 1, so the listed arguments are counted starting from 2)
00172     __attribute__((format(__printf__, 4, 5)));
00173     ;
00174 
00175   //! Clear LCD screen
00176   bool lcdClear();
00177 
00178   //! Scroll display left by i positions
00179   bool lcdScrollLeft(const int i = 1);
00180 
00181   //! Scroll display right by i positions
00182   bool lcdScrollRight(const int i = 1);
00183 
00184   //! Move cursor left by i positions
00185   bool lcdMoveCursorLeft(const int i = 1);
00186 
00187   //! Move cursor right by i positions
00188   bool lcdMoveCursorRight(const int i = 1);
00189 
00190   //! Make cursor a blinking block
00191   bool lcdCursorBlock();
00192 
00193   //! Make cursor a blinking underline
00194   bool lcdCursorUnderline();
00195 
00196   //! Make cursor invisible (not recommended)
00197   bool lcdCursorInvisible();
00198 
00199   //! Load one of the pre-programmed custom fonts
00200   /*! Valid font values are [0..7]. Font 0 is an all-blank font. */
00201   bool lcdLoadFont(const int font);
00202 
00203   //! Load a new font from an array of 64 bytes
00204   bool lcdLoadFont(const byte data[64]);
00205 
00206   //! Select an LCD animation and start it
00207   /*! Valid anim values are [0..7]. Anim 0 is no animation. */
00208   bool lcdSetAnimation(const int anim = 0);
00209 
00210   //! Send a raw byte to the LCD
00211   bool lcdSendRaw(const byte val, const bool RS, const bool uselock = true);
00212 
00213   //@}
00214 
00215   // ############################################################
00216   /*! @name Servo control functions */
00217   //@{
00218 
00219   //! Shim the BeoChip's servo pulses
00220   /*! Valid shim values are [0..7]. The default at bootup of the
00221     BeoChip is 4. Higher values will increase pulse length and lower
00222     values will decrease them. This may allow you to shim the pulses
00223     so as to maximally exploit the range of your servos. */
00224   bool shimServos(const byte shim);
00225 
00226   //! Calibrate a servo
00227   /*! Calibration will be made so that setServo(servo, 0.0F) will send the
00228     value 'neutralval' to the servo, setServo(servo, -1.0F) will send
00229     minval and setServo(servo, 1.0F) will send maxval. */
00230   void calibrateServo(const int servo, const byte neutralval,
00231                       const byte minval, const byte maxval);
00232 
00233   //! Moves servo # to given position in [-1.0 .. 1.0]
00234   /*! Returns true on success, false if some serial error occurred. */
00235   bool setServo(const int servo, const float position);
00236 
00237   //! Gets the current position of given servo
00238   float getServo(const int servo) const;
00239 
00240   //! Sets servo number servo to value val
00241   bool setServoRaw(const int servo, const byte val);
00242 
00243   //! Gets the current raw position of given servo
00244   byte getServoRaw(const int servo) const;
00245 
00246   //@}
00247 
00248   // ############################################################
00249   /*! @name Pulse acquisition functions */
00250   //@{
00251 
00252   //! Turn pulse captures on/off
00253   bool capturePulse(const int whichone, const bool on);
00254 
00255   //! Calibrate a pulse
00256   /*! Calibration will be made so that getPulse() returns 0.0F when
00257     raw pulse width is 'neutralval', returns -1.0F when the raw pulse
00258     value is minval and returns 1.0F when the raw pulse value is
00259     maxval. */
00260   void calibratePulse(const int whichone, const int neutralval,
00261                       const int minval, const int maxval);
00262 
00263   //! Get current pulse value, between [-1.0..1.0]
00264   float getPulse(const int whichone);
00265 
00266   //! Get current pulse value, raw uncalibrated
00267   short int getPulseRaw(const int whichone);
00268 
00269   //@}
00270 
00271   // ############################################################
00272   /*! @name Analog acquisition functions */
00273   //@{
00274 
00275   //! Turn A/D captures on/off
00276   bool captureAnalog(const int whichone, const bool on);
00277 
00278   //! Calibrate an A/D converter
00279   /*! Calibration will be made so that getAnalog() returns 0.0F when
00280     raw value width is 'neutralval', returns -1.0F when the raw value
00281     is minval and returns 1.0F when the raw value is maxval. */
00282   void calibrateAnalog(const int whichone, const int neutralval,
00283                        const int minval, const int maxval);
00284 
00285   //! Get current calibrated Analog value
00286   float getAnalog(const int whichone);
00287 
00288   //! Get current raw Analog value
00289   byte getAnalogRaw(const int whichone);
00290 
00291   //@}
00292 
00293   // ############################################################
00294   /*! @name Keyboard acquisition functions */
00295   //@{
00296 
00297   //! Turn keyboard capture on/off
00298   bool captureKeyboard(const bool on);
00299 
00300   //! Turn keyboard debouncing on/off
00301   bool debounceKeyboard(const bool on);
00302 
00303   //! Get current Keyboard value
00304   int getKeyboard();
00305 
00306   //@}
00307 
00308   // ############################################################
00309   /*! @name Digital output function */
00310   //@{
00311 
00312   //! Turn a given digital output on/off
00313   /*! Valid range for outnum is [0..3] */
00314   bool setDigitalOut(const int outnum, const bool on);
00315 
00316   //@}
00317 
00318   //! This is our main running thread - don't call directly
00319   /*! Should have been protected, but is not because of pthread hack. */
00320   void run();
00321 
00322   //! send a byte to the BeoChip
00323   /*! You should never have to use this, use the other functions
00324     instead.  This function is made public just for testing the chip's
00325     robustness against a flood of random junk hitting it... See
00326     test-BeoChip.C */
00327   bool writeByte(const byte val, const bool uselock = true);
00328 
00329 protected:
00330   NModelParam<std::string> itsDevName; //!< name of our serial device
00331   NModelParam<int> itsLCDrows; //!< number of rows of LCD screen (lines of text)
00332   NModelParam<int> itsLCDcols; //!< number of columns of LCD screen
00333 
00334   rutz::shared_ptr<NModelParam<int> >* zeroS; //!< zero calibration value, for 0.0F (servo)
00335   rutz::shared_ptr<NModelParam<int> >* minS;  //!< minimum raw value, for -1.0F (servo)
00336   rutz::shared_ptr<NModelParam<int> >* maxS;  //!< maximum raw value, for 1.0F (servo)
00337   byte *servopos;                      //!< raw servo positions [0..255]
00338 
00339   rutz::shared_ptr<NModelParam<int> >* zeroP; //!< zero calibration value, for 0.0F (pulse)
00340   rutz::shared_ptr<NModelParam<int> >* minP;  //!< minimum raw value, for -1.0F (pulse)
00341   rutz::shared_ptr<NModelParam<int> >* maxP;  //!< maximum raw value, for 1.0F (pulse)
00342   short int *pulseval;                 //!< raw pulse values (11bit int)
00343 
00344   rutz::shared_ptr<NModelParam<int> >* zeroA; //!< zero calibration value, for 0.0F (pulse)
00345   rutz::shared_ptr<NModelParam<int> >* minA;  //!< minimum raw value, for -1.0F (servo)
00346   rutz::shared_ptr<NModelParam<int> >* maxA;  //!< maximum raw value, for 1.0F (servo)
00347 
00348   NModelParam<bool> itsUseRTSCTS;      //!< Use RTS/CTS flow control
00349 
00350   byte *adcval;                        //!< raw adc values [0..255]
00351 
00352   byte keyboard;                       //!< our current keyboard state
00353 
00354   //! Convert from raw (int) to calibrated (-1.0..1.0) position
00355   float rawToCalib(const int raw, const int zero, const int mini,
00356                    const int maxi) const;
00357 
00358   //! Convert from calibrated (-1.0..1.0) to raw (int) position
00359   int calibToRaw(const float calibrated, const int zero, const int mini,
00360                  const int maxi, const int bits = 8) const;
00361 
00362   //! open the port and get started
00363   void start1();
00364 
00365   //! close the port and get stopped
00366   void stop2();
00367 
00368 private:
00369   struct termios itsOldtio;  //!< our old terminal io settings
00370   int itsFd;                 //!< our serial port file descriptor
00371   rutz::shared_ptr<BeoChipListener> itsListener;
00372 
00373   pthread_t runner;
00374   pthread_mutex_t lock, serlock;
00375   bool keepgoing;
00376 };
00377 
00378 #endif
00379 
00380 // ######################################################################
00381 /* So things look consistent in everyone's emacs... */
00382 /* Local Variables: */
00383 /* indent-tabs-mode: nil */
00384 /* End: */
Generated on Sun May 8 08:40:37 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3