TOBI SignalServer  0.1
/home/breidi/Dropbox/signalserver/src/hardware/jstick.cpp
Go to the documentation of this file.
00001 /*
00002     This file is part of the TOBI SignalServer.
00003 
00004     Commercial Usage
00005     Licensees holding valid Graz University of Technology Commercial
00006     licenses may use this file in accordance with the Graz University
00007     of Technology Commercial License Agreement provided with the
00008     Software or, alternatively, in accordance with the terms contained in
00009     a written agreement between you and Graz University of Technology.
00010 
00011     --------------------------------------------------
00012 
00013     GNU General Public License Usage
00014     Alternatively, this file may be used under the terms of the GNU
00015     General Public License version 3.0 as published by the Free Software
00016     Foundation and appearing in the file gpl.txt included in the
00017     packaging of this file.  Please review the following information to
00018     ensure the GNU General Public License version 3.0 requirements will be
00019     met: http://www.gnu.org/copyleft/gpl.html.
00020 
00021     In case of GNU General Public License Usage ,the TOBI SignalServer
00022     is distributed in the hope that it will be useful,
00023     but WITHOUT ANY WARRANTY; without even the implied warranty of
00024     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025     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 TOBI SignalServer. If not, see <http://www.gnu.org/licenses/>.
00029 
00030     Copyright 2010 Graz University of Technology
00031     Contact: SignalServer@tobi-project.org
00032 */
00033 
00038 #include "hardware/jstick.h"
00039 
00040 #include "SDL/SDL.h"
00041 
00042 namespace tobiss
00043 {
00044 
00045 using std::vector;
00046 using std::string;
00047 using std::pair;
00048 using std::cout;
00049 using std::endl;
00050 using std::make_pair;
00051 using std::set;
00052 
00053 set<boost::uint16_t> JStick::used_ids_;
00054 
00055 
00056 const HWThreadBuilderTemplateRegistratorWithoutIOService<JStick> JStick::FACTORY_REGISTRATOR_ ("jstick", "joystick", "joycable");
00057 
00058 //-----------------------------------------------------------------------------
00059 JStick::JStick(ticpp::Iterator<ticpp::Element> hw)
00060   : HWThread()
00061 {
00062   #ifdef DEBUG
00063     cout << "JStick: Constructor" << endl;
00064   #endif
00065 
00066   setType("Joystick");
00067   checkMandatoryHardwareTags(hw);
00068   if(mode_ != APERIODIC)
00069     throw(std::invalid_argument("Joystick has to be started as aperiodic device!"));
00070 
00071   initJoystick();
00072   setDeviceSettings(0);
00073 
00074   data_.init(1, channel_types_.size() , channel_types_);
00075 
00076   vector<boost::uint32_t> v;
00077   empty_block_.init(0,0, v);
00078 //  cout << " * Joystick sucessfully initialized -- running as aperiodic: ";
00079 //  cout << (mode_ == APERIODIC) << ";  ";
00080   cout << " --> Jostick ID: " << id_ << ",  Name: " << name_ << endl;
00081   cout << " ... buttons: " << buttons_;
00082   cout << ", axes: " << axes_;
00083   cout << ", balls: " << balls_ << endl;
00084 }
00085 
00086 //-----------------------------------------------------------------------------
00087 
00088 JStick::~JStick()
00089 {
00090   if(SDL_JoystickOpened(id_))
00091     SDL_JoystickClose(static_cast<SDL_Joystick*>(joy_));
00092 }
00093 
00094 //-----------------------------------------------------------------------------
00095 
00096 void JStick::setDeviceSettings(ticpp::Iterator<ticpp::Element>const&)
00097 {
00098   #ifdef DEBUG
00099     cout << "JStick: setDeviceSettings" << endl;
00100   #endif
00101 
00102   string naming;
00103   string type;
00104 
00105   if(buttons_)
00106     channel_types_.push_back(SIG_BUTTON);
00107   for(boost::uint32_t n = 0; n < buttons_; n++)
00108     channel_types_.push_back(SIG_BUTTON);
00109 
00110   if(axes_)
00111     channel_types_.push_back(SIG_JOYSTICK);
00112   for(boost::uint32_t n = 0; n < axes_; n++)
00113     channel_types_.push_back(SIG_JOYSTICK);
00114 
00115   if(balls_)
00116     channel_types_.push_back(SIG_JOYSTICK);
00117   for(boost::int32_t n = 0; n < 2*balls_; n++)
00118     channel_types_.push_back(SIG_JOYSTICK);
00119 
00120   nr_ch_= channel_types_.size();
00121 
00122   boost::uint16_t n = 1;
00123   if(buttons_)
00124     for( ; n <= buttons_ +1; n++)
00125       channel_info_.insert(pair<boost::uint16_t, pair<string, boost::uint32_t> >(n, pair<string, boost::uint32_t>(naming, SIG_BUTTON)));
00126 
00127   if(axes_)
00128     for( ; n <= axes_ + buttons_ +2; n++)
00129       channel_info_.insert(pair<boost::uint16_t, pair<string, boost::uint32_t> >(n, pair<string, boost::uint32_t>(naming, SIG_JOYSTICK)));
00130 
00131   if(balls_)
00132     for( ; n <= (2*balls_)+ axes_ + buttons_ +3; n++)
00133       channel_info_.insert(pair<boost::uint16_t, pair<string, boost::uint32_t> >(n, pair<string, boost::uint32_t>(naming, SIG_JOYSTICK)));
00134 
00135   homogenous_signal_type_ = 0;
00136 
00137 }
00138 
00139 //---------------------------------------------------------------------------------------
00140 
00141 void JStick::setChannelSettings(ticpp::Iterator<ticpp::Element>const& )
00142 {
00143   #ifdef DEBUG
00144     cout << "JStick: setChannelSettings" << endl;
00145   #endif
00146 
00147 }
00148 
00149 //---------------------------------------------------------------------------------------
00150 
00151 SampleBlock<double> JStick::getAsyncData()
00152 {
00153   #ifdef DEBUG
00154     cout << "JStick: getAsyncData" << endl;
00155   #endif
00156 
00157   bool dirty = 0;
00158 
00159   if(!SDL_JoystickOpened(id_) )
00160     throw(std::runtime_error("JStick::getAsyncData -- Joystick not opened any more -- ID: " + id_) );
00161 
00162 
00163   SDL_JoystickUpdate();
00164 
00165   for(boost::uint8_t n = 0; n < buttons_values_.size(); n++)
00166     if(SDL_JoystickGetButton(static_cast<SDL_Joystick*>(joy_), n) != buttons_values_[n])
00167     {
00168       dirty = 1;
00169       buttons_values_[n] = SDL_JoystickGetButton(static_cast<SDL_Joystick*>(joy_), n);
00170     }
00171 
00172   for(boost::uint8_t n = 0; n < axes_values_.size(); n++)
00173     if(SDL_JoystickGetAxis(static_cast<SDL_Joystick*>(joy_), n) != axes_values_[n])
00174     {
00175       dirty = 1;
00176       axes_values_[n] = SDL_JoystickGetAxis(static_cast<SDL_Joystick*>(joy_), n);
00177     }
00178 
00179   for(boost::uint8_t n = 0; n < balls_values_.size(); n++)
00180   {
00181     int dx = 0;
00182     int dy = 0;
00183     SDL_JoystickGetBall(static_cast<SDL_Joystick*>(joy_), n, &dx, &dy);
00184     pair<int,int> dxy = make_pair(dx,dy);
00185     if(dxy != balls_values_[n])
00186     {
00187       dirty = 1;
00188       balls_values_[n] = dxy;
00189     }
00190   }
00191 
00192   if(!dirty)
00193     return(empty_block_);
00194 
00195   vector<double> v;
00196 
00197   if(buttons_)
00198     v.push_back(id_);
00199   for(boost::uint8_t n = 0; n < buttons_values_.size(); n++)
00200       v.push_back(buttons_values_[n]);
00201 
00202   if(axes_)
00203     v.push_back(id_);
00204   for(boost::uint8_t n = 0; n < axes_values_.size(); n++)
00205     v.push_back(axes_values_[n]);
00206 
00207   if(balls_)
00208     v.push_back(id_);
00209   for(boost::uint8_t n = 0; n < balls_values_.size(); n++)
00210   {
00211     v.push_back(balls_values_[n].first);
00212     v.push_back(balls_values_[n].second);
00213   }
00214 
00215   data_.setSamples(v);
00216   return(data_);
00217 }
00218 
00219 //-----------------------------------------------------------------------------
00220 
00221 void JStick::run()  { }
00222 
00223 //-----------------------------------------------------------------------------
00224 
00225 void JStick::stop() { }
00226 
00227 //-----------------------------------------------------------------------------
00228 
00229 void JStick::initJoystick()
00230 {
00231   set<boost::uint16_t>::iterator it(used_ids_.begin());
00232 
00233   boost::int16_t nr_of_jsticks = 0;
00234   if ( SDL_Init(SDL_INIT_JOYSTICK) < 0 )
00235   {
00236     string error_msg(SDL_GetError());
00237     throw(std::runtime_error("JStick::Constructor -- Unable to init SDL: " + error_msg ));
00238   }
00239   if( (nr_of_jsticks = SDL_NumJoysticks()) <= 0 )
00240     throw(std::runtime_error("JStick::initJoystick -- No Joysticks found!"));
00241 
00242   for(boost::uint8_t n = 0; n < nr_of_jsticks;  n++)
00243     if(used_ids_.find(n) == used_ids_.end())
00244     {
00245       joy_ = SDL_JoystickOpen(n);
00246       if(!static_cast<SDL_Joystick*>(joy_))
00247         throw(std::runtime_error("JStick::initJoystick -- Unable to open joystick at position: " + n));
00248       name_= SDL_JoystickName(n);
00249       id_ = n;
00250       used_ids_.insert(n);
00251       break;
00252     }
00253 
00254   if(!static_cast<SDL_Joystick*>(joy_))
00255     throw(std::runtime_error("JStick::initJoystick -- Joystick already opened!"));
00256 
00257   axes_    = SDL_JoystickNumAxes(static_cast<SDL_Joystick*>(joy_));
00258   buttons_ = SDL_JoystickNumButtons(static_cast<SDL_Joystick*>(joy_));
00259   balls_   = SDL_JoystickNumBalls(static_cast<SDL_Joystick*>(joy_));
00260 
00261   axes_values_.resize(axes_,0);
00262   balls_values_.resize(balls_, make_pair(0,0) );
00263   buttons_values_.resize(buttons_,0);
00264 
00265   SDL_JoystickEventState(SDL_ENABLE);
00266   SDL_JoystickUpdate();
00267 }
00268 
00269 //-----------------------------------------------------------------------------
00270 
00271 } // Namespace tobiss
All Data Structures Files Functions Variables