JoyStick.C

Go to the documentation of this file.
00001 /*!@file Devices/JoyStick.C simple driver for a Linux joystick */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00005 // by the 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/JoyStick.C $
00035 // $Id: JoyStick.C 13071 2010-03-28 16:24:18Z beobot $
00036 //
00037 
00038 #ifdef HAVE_LINUX_JOYSTICK_H
00039 
00040 #include "Devices/JoyStick.H"
00041 #include <fcntl.h>
00042 #include <linux/joystick.h>
00043 #include <sys/stat.h>
00044 #include <sys/types.h>
00045 
00046 // ######################################################################
00047 JoyStickListener::~JoyStickListener()
00048 {  }
00049 
00050 // ######################################################################
00051 void *JoyStick_run(void *c);
00052 
00053 // ######################################################################
00054 void *JoyStick_run(void *c)
00055 {
00056   JoyStick *d = (JoyStick *)c;
00057   d->run();
00058   return NULL;
00059 }
00060 
00061 // ######################################################################
00062 JoyStick::JoyStick(OptionManager& mgr, const std::string& descrName,
00063                    const std::string& tagName, const char *dev) :
00064   ModelComponent(mgr, descrName, tagName),
00065   itsDevName(tagName+"DevName", this, dev), itsFd(-1), itsPlugged(false), itsKeepGoing(false), itsAxes(), itsButtons(), itsListener(NULL)
00066 {
00067   pthread_mutex_init(&itsMutex, NULL);
00068   //itsFd = open(itsDevName.getVal().c_str(), O_RDONLY);
00069   //itsPlugged = (itsFd >= 0);
00070   //if (itsFd >= 0) { close(itsFd); itsFd = -1; }
00071 }
00072 
00073 // ######################################################################
00074 void JoyStick::setListener(rutz::shared_ptr<JoyStickListener>& listener)
00075 { itsListener = listener; }
00076 
00077 // ######################################################################
00078 JoyStick::~JoyStick()
00079 { pthread_mutex_destroy(&itsMutex); }
00080 
00081 // ######################################################################
00082 void JoyStick::start1()
00083 {
00084   // Open joystick device:
00085   itsFd = open(itsDevName.getVal().c_str(), O_RDONLY);
00086   if (itsFd < 0) { LINFO("Cannot open %s", itsDevName.getVal().c_str()); return;}
00087   //LINFO("Joystick plugged in");
00088   itsPlugged = true;
00089   // Get number of joystick axes:
00090   char c;
00091   int ret = ioctl(itsFd, JSIOCGAXES, &c);
00092   if (ret < 0) PLFATAL("ioctl(JSIOCGAXES) failed");
00093   itsAxes.resize(int(c));
00094 
00095   // Get number of joystick buttons:
00096   ret = ioctl(itsFd, JSIOCGBUTTONS, &c);
00097   if (ret < 0) PLFATAL("ioctl(JSIOCGBUTTONS) failed");
00098   itsButtons.resize(c);
00099 
00100   // get our thread going:
00101   itsKeepGoing = true;
00102   pthread_create(&itsRunner, NULL, &JoyStick_run, (void *)this);
00103 }
00104 
00105 // ######################################################################
00106 void JoyStick::stop1()
00107 {
00108   itsKeepGoing = false;
00109   usleep(300000); // make sure thread exits
00110   if (itsFd >= 0) { close(itsFd); itsFd = -1; }
00111 }
00112 
00113 // ######################################################################
00114 uint JoyStick::getNumAxes() const
00115 { return itsAxes.size(); }
00116 
00117 // ######################################################################
00118 uint JoyStick::getNumButtons() const
00119 { return itsButtons.size(); }
00120 
00121 // ######################################################################
00122 int16 JoyStick::getAxisValue(const uint num) const
00123 {
00124   if (num >= itsAxes.size())
00125     LFATAL("Axis number %d out of range [0..%"ZU"]", num, itsAxes.size()-1);
00126 
00127   pthread_mutex_lock(const_cast<pthread_mutex_t*>(&itsMutex));
00128   int16 val = itsAxes[num];
00129   pthread_mutex_unlock(const_cast<pthread_mutex_t*>(&itsMutex));
00130 
00131   return val;
00132 }
00133 
00134 // ######################################################################
00135 bool JoyStick::getButtonState(const uint num) const
00136 {
00137   if (num >= itsButtons.size())
00138     LFATAL("Button number %d out of range [0..%"ZU"]", num, itsButtons.size()-1);
00139 
00140   pthread_mutex_lock(const_cast<pthread_mutex_t*>(&itsMutex));
00141   bool val = itsButtons[num];
00142   pthread_mutex_unlock(const_cast<pthread_mutex_t*>(&itsMutex));
00143 
00144   return val;
00145 }
00146 
00147 // ######################################################################
00148 void JoyStick::run()
00149 {
00150   js_event event;
00151 
00152   while(itsKeepGoing)
00153     {
00154       // get the next event:
00155       int bytes_read = read(itsFd, &event, sizeof(js_event));
00156       if (bytes_read < 0) PLERROR("Read error");
00157 
00158       // decode the event:
00159       if (event.type & JS_EVENT_AXIS)
00160         {
00161           if (event.number >= itsAxes.size())
00162             LERROR("Bogus axis event received -- IGNORED");
00163           else
00164             {
00165               pthread_mutex_lock(&itsMutex);
00166               itsAxes[event.number] = event.value;
00167               pthread_mutex_unlock(&itsMutex);
00168 
00169               // activate our listener if we have one:
00170               if (itsListener.get())
00171                 itsListener->axis(event.number, event.value);
00172             }
00173         }
00174       else if (event.type & JS_EVENT_BUTTON)
00175         {
00176           if (event.number >= itsButtons.size())
00177             LERROR("Bogus button event received -- IGNORED");
00178           else
00179             {
00180               pthread_mutex_lock(&itsMutex);
00181               itsButtons[event.number] = (event.value == 1);
00182               pthread_mutex_unlock(&itsMutex);
00183 
00184               // activate our listener if we have one:
00185               if (itsListener.get())
00186                 itsListener->button(event.number, (event.value == 1));
00187             }
00188         }
00189     }
00190 }
00191 
00192 #endif // HAVE_LINUX_JOYSTICK_H
00193 
00194 // ######################################################################
00195 /* So things look consistent in everyone's emacs... */
00196 /* Local Variables: */
00197 /* indent-tabs-mode: nil */
00198 /* End: */
Generated on Sun May 8 08:04:45 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3