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: */