JoystickReaderLinux.cpp
Go to the documentation of this file.
00001 /* 
00002  * File:   Joystick.cpp
00003  * Author: tomislav Lugaric
00004  * 
00005  * Created on July 13, 2010, 12:04 PM
00006  * Tested and approved on August 17, 2010, 09:00 AM
00007  */
00008 
00009 
00010 
00011 
00012 #include <fstream>
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <sstream>
00016 #include <fcntl.h>
00017 #include <linux/joystick.h>
00018 #include <cstring>
00019 #include <exception>
00020 #include <iosfwd>
00021 #include <labust/xml/XMLReader.hpp>
00022 #include <boost/foreach.hpp>
00023 
00024 #include "JoystickReader.h"
00025 
00026 using namespace std;
00027 
00028 namespace LABUST
00029 {
00034 
00035     JoystickReader::JoystickReader(const std::string& path, std::string configToUse)
00036     {
00037         labust::xml::Reader reader(path,true);
00038         std::string configQuery;
00039         if (configToUse.empty())
00040         {
00041             configQuery = "//peripheralConfig[@type='joystick']";
00042         }
00043         else
00044         {
00045             configQuery = "//peripheralConfig[@type='joystick' and @name='" + configToUse + "']";
00046         }
00047 
00048         int deviceNumber;
00049         bool loadButtonsCount = false, loadAxesCount = false;
00050 
00051         reader.useRootNode();
00052         _xmlNode* configNode = NULL;
00053         if (reader.try_value(configQuery, &configNode))
00054         {
00055             reader.useNode(configNode);
00056 
00057             if (!reader.try_value("param[@name='DeviceNumber']/@value", &deviceNumber))
00058             {
00059                 throw std::runtime_error("Missing joystick number");
00060             }
00061             if(!reader.try_value("param[@name='Axes']/@value", &axes))
00062             {
00063                 loadAxesCount = true;
00064             }
00065             if(!reader.try_value("param[@name='Buttons']/@value", &buttons))
00066             {
00067                 loadButtonsCount = true;
00068             }
00069         }
00070         else
00071         {
00072             throw std::runtime_error("Unable to open joystick, missing config");
00073         }
00074 
00075         //generate joystick name
00076         stringstream joystickPath;
00077         joystickPath << "/dev/input/js" << deviceNumber;
00078 
00079 
00080         //load number of buttons/axes from driver
00081         if ((deviceDescriptor = open(joystickPath.str().c_str(), O_RDONLY)) >= 0)
00082         {
00083             if(loadButtonsCount)
00084             {
00085                 ioctl(deviceDescriptor, JSIOCGBUTTONS, &buttons);
00086             }
00087 
00088             if(loadAxesCount)
00089             {
00090                 ioctl(deviceDescriptor, JSIOCGAXES, &axes);
00091             }
00092 
00093                         axisGains.resize(axes);
00094                          for(int i=0; i<axes; i++)
00095                          {
00096                                  axisGains[i] = 1;
00097                          }
00098                          using namespace labust::xml;
00099 
00100                          NodeCollectionPtr gains = reader.value<NodeCollectionPtr>("param[@name='AxisGain']");
00101 
00102                          _xmlNode* curr=reader.currentNode();
00103                          BOOST_FOREACH(_xmlNode* axisGain, *gains)
00104                          {
00105                                 int axisNumber;
00106                                 float gain;
00107                                 reader.useNode(axisGain);
00108                                 std::string axisGainPair = reader.value<std::string>("@value");
00109                                 std::replace(axisGainPair.begin(),axisGainPair.end(),':',' ');
00110                                 std::stringstream buffer;
00111                                 buffer << axisGainPair;
00112                                 buffer >> axisNumber >> gain;
00113                                 axisGains[axisNumber] = gain;                           
00114                          }
00115 
00116                          reader.useNode(curr);
00117                                                  axisGains.resize(axes);
00118             joystickData.axes.resize(axes);
00119             joystickData.buttons.resize(buttons);
00120 
00121 
00122         }
00123         else
00124         {
00125             std::stringstream buffer;
00126             buffer<<"Error opening joystick "<<joystickPath;
00127             throw std::runtime_error(buffer.str());
00128         }
00129         running = true;
00130         joystickThread = boost::thread(boost::bind(&JoystickReader::ThreadFunction,this));
00131 
00132     }
00133 
00138 
00139     JoystickReader::JoystickReader(const labust::xml::Reader& reader, std::string configToUse)
00140     {
00141         std::string configQuery;
00142         if (configToUse.empty())
00143         {
00144             configQuery = "peripheralConfig[@type='joystick']";
00145         }
00146         else
00147         {
00148             configQuery = "peripheralConfig[@type='joystick' and @name='" + configToUse + "']";
00149         }
00150 
00151         int deviceNumber;
00152         bool loadButtonsCount = false, loadAxesCount = false;
00153 
00154         _xmlNode* configNode = NULL;
00155         if (reader.try_value(configQuery, &configNode))
00156         {
00157             const_cast<labust::xml::Reader&>(reader).useNode(configNode);
00158 
00159             if (!reader.try_value("param[@name='DeviceNumber']/@value", &deviceNumber))
00160             {
00161                 throw std::runtime_error("Missing joystick number");
00162             }
00163             if(!reader.try_value("param[@name='Axes']/@value", &axes))
00164             {
00165                 loadAxesCount = true;
00166             }
00167             if(!reader.try_value("param[@name='Buttons']/@value", &buttons))
00168             {
00169                 loadButtonsCount = true;
00170             }
00171         }
00172         else
00173         {
00174             throw std::runtime_error("Unable to open joystick, missing config");
00175         }
00176 
00177 
00178         //generate joystick name
00179         stringstream joystickPath;
00180         joystickPath << "/dev/input/js" << deviceNumber;
00181 
00182 
00183         //load number of buttons/axes from driver
00184         if ((deviceDescriptor = open(joystickPath.str().c_str(), O_RDONLY)) >= 0)
00185         {
00186             if(loadButtonsCount)
00187             {
00188                 ioctl(deviceDescriptor, JSIOCGBUTTONS, &buttons);
00189             }
00190 
00191             if(loadAxesCount)
00192             {
00193                 ioctl(deviceDescriptor, JSIOCGAXES, &axes);
00194             }
00195             joystickData.axes.resize(axes);
00196             joystickData.buttons.resize(buttons);
00197         }
00198         else
00199         {
00200             std::stringstream buffer;
00201             buffer<<"Error opening joystick "<<joystickPath;
00202             throw std::runtime_error(buffer.str());
00203         }
00204         running = true;
00205         joystickThread = boost::thread(boost::bind(&JoystickReader::ThreadFunction,this));
00206     }
00207 
00208     JoystickReader::~JoystickReader()
00209     {
00210         //std::cout<<"Joystick destructor.";
00211         running = false;
00212         //joystickPort.close();
00213         //OS specific break
00214         pthread_cancel(joystickThread.native_handle());
00215         pthread_join(joystickThread.native_handle(),NULL);
00216         close(deviceDescriptor);
00217     }
00218 
00221 
00222     JoystickData JoystickReader::ReadJoystickData()
00223     {
00224         boost::mutex::scoped_lock lockJoystickData(joystickMutex);
00225         return joystickData;
00226     }
00227 
00228     void JoystickReader::ThreadFunction()
00229     {
00230         while(running)
00231         {
00232             js_event event;
00233             if (read(deviceDescriptor, &event, sizeof (event)) > 0)
00234             {
00235                 boost::mutex::scoped_lock lockJoystickData(joystickMutex);
00236                 switch (event.type)
00237                 {
00238                     case JS_EVENT_AXIS:
00239                           std::cout<<"Event number:"<<int(event.number)<<","<<joystickData.axes.size()<<","<<axisGains.size()<<std::endl;
00240                         joystickData.axes[event.number] = event.value;// * axisGains[event.number];
00241                         break;
00242 
00243                     case JS_EVENT_BUTTON:
00244                         //joystickData.buttons[event.number] = event.value;
00245                         break;
00246 
00247                     case JS_EVENT_INIT:
00248                         break;
00249 
00250                     default:
00251                         break;
00252                 }
00253             }
00254         }
00255     }
00256 }


acoustic_vr
Author(s):
autogenerated on Fri Feb 7 2014 11:37:09