Main MRPT website > C++ reference for MRPT 1.5.7
CJoystick.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #include "hwdrivers-precomp.h" // Precompiled headers
11 
12 
13 #include <mrpt/config.h>
14 
15 #ifdef MRPT_OS_WINDOWS
16  #include <windows.h>
17  #include <mmsystem.h>
18 
19  #if !defined(__GNUC__)
20  # pragma comment (lib,"WINMM.LIB")
21  #endif
22 #endif
23 
24 #if defined(MRPT_OS_LINUX) || defined(MRPT_OS_APPLE)
25  // Linux
26  #include <sys/ioctl.h>
27  #include <sys/time.h>
28  #include <sys/types.h>
29  #include <stdlib.h>
30  #include <fcntl.h>
31  #include <unistd.h>
32  #include <stdio.h>
33  #include <errno.h>
34  #include <string.h>
35  #include <stdlib.h>
36  #include <stdint.h>
37 
38  #if defined(MRPT_OS_LINUX) && defined(HAVE_LINUX_INPUT_H)
39  #include <linux/input.h>
40  #include <linux/joystick.h>
41  #endif
42 #endif
43 
45 
46 using namespace mrpt::hwdrivers;
47 
48 /*---------------------------------------------------------------
49  Constructor
50  ---------------------------------------------------------------*/
52 #if defined(MRPT_OS_LINUX) && defined(HAVE_LINUX_INPUT_H)
53  :
54  m_joy_fd (-1),
55  m_joy_index (-1)
56 #endif
57 {
58  setLimits();
59 }
60 
61 /*---------------------------------------------------------------
62  Destructor
63  ---------------------------------------------------------------*/
65 {
66 #if defined(MRPT_OS_LINUX) && defined(HAVE_LINUX_INPUT_H)
67  // Close joystick, if open:
68  if (m_joy_fd>0)
69  {
70  close(m_joy_fd);
71  m_joy_fd = -1;
72  }
73 #endif
74 }
75 
76 /*---------------------------------------------------------------
77  getJoysticksCount
78  Returns the number of Joysticks in the computer.
79  ---------------------------------------------------------------*/
81 {
83 #ifdef MRPT_OS_WINDOWS
84  return joyGetNumDevs();
85 #elif defined(MRPT_OS_LINUX) && defined(HAVE_LINUX_INPUT_H)
86  // Try to open several joy devs:
87  int joy_fd=-1;
88  int nJoys = 0;
89 
90  do
91  {
92  if ( -1 != (joy_fd=open(format("/dev/input/js%i",nJoys).c_str(),O_RDONLY)) )
93  {
94  nJoys++;
95  close(joy_fd);
96  }
97  } while (joy_fd!=-1);
98 
99  return nJoys;
100 #else
101  // Apple:
102  return 0;
103 #endif
104  MRPT_END
105 }
106 
107 
108 /*---------------------------------------------------------------
109  Gets joystick information.
110 
111  \return Returns true if successfull, false on error, for example, if joystick is not present.
112  ---------------------------------------------------------------*/
114  int nJoy,
115  float &x,
116  float &y,
117  float &z,
118  std::vector<bool> &buttons,
119  int *raw_x_pos,
120  int *raw_y_pos,
121  int *raw_z_pos )
122 {
123  MRPT_START
124 #ifdef MRPT_OS_WINDOWS
125  JOYINFO jinfo;
126 
127  int ID = JOYSTICKID1 + nJoy;
128 
129  // Get joy pos:
130  if (JOYERR_NOERROR != joyGetPos( ID, &jinfo ) )
131  return false; // Error.
132 
133  // Output data:
134  x = ( jinfo.wXpos - m_x_min ) / (float)( m_x_max-m_x_min );
135  y = ( jinfo.wYpos - m_y_min ) / (float)( m_y_max-m_y_min );
136  z = ( jinfo.wZpos - m_z_min ) / (float)( m_z_max-m_z_min );
137 
138  x = 2*x-1;
139  y = 2*y-1;
140  z = 2*z-1;
141 
142  buttons.resize(4);
143 
144  buttons[0] = 0 != (jinfo.wButtons & JOY_BUTTON1);
145  buttons[1] = 0 != (jinfo.wButtons & JOY_BUTTON2);
146  buttons[2] = 0 != (jinfo.wButtons & JOY_BUTTON3);
147  buttons[3] = 0 != (jinfo.wButtons & JOY_BUTTON4);
148 
149  if (raw_x_pos) *raw_x_pos=jinfo.wXpos;
150  if (raw_y_pos) *raw_y_pos=jinfo.wYpos;
151  if (raw_z_pos) *raw_z_pos=jinfo.wZpos;
152 
153  return true;
154 #elif defined(MRPT_OS_LINUX) && defined(HAVE_LINUX_INPUT_H)
155  // Already open?
156  if ( m_joy_index == nJoy && m_joy_fd!=-1)
157  {
158  // Ok
159  }
160  else
161  {
162  // Close previous opened joy?
163  if (m_joy_fd!=-1)
164  close(m_joy_fd);
165 
166  // Go, try open joystick:
167  if ((m_joy_fd = open( format("/dev/input/js%i",nJoy).c_str() , O_RDONLY)) < 0)
168  return false;
169 
170  // Perfect!
171  m_joy_index = nJoy;
172 
173  // Read in non-blocking way: **** Refer to sources of "jstest"!!!! ***
174  fcntl(m_joy_fd, F_SETFL, O_NONBLOCK);
175  }
176 
177  struct js_event js;
178 
179  while (read(m_joy_fd, &js, sizeof(struct js_event)) == sizeof(struct js_event))
180  {
181  // Button?
182  if (js.type & JS_EVENT_BUTTON)
183  {
184  // js.number: Button number
185  if (m_joystate_btns.size() < (size_t)js.number+1) m_joystate_btns.resize( js.number+1 );
186  m_joystate_btns[js.number] = js.value!=0;
187  }
188 
189  // Axes?
190  if (js.type & JS_EVENT_AXIS)
191  {
192  //std::cout << "joy: event axis" << std::endl;
193  if (m_joystate_axes.size()<(size_t)js.number+1) m_joystate_axes.resize( js.number+1 );
194  m_joystate_axes[js.number] = js.value;
195  }
196  }
197 
198  if (errno != EAGAIN)
199  {
200  // Joystick disconnected?
201  m_joy_fd = -1;
202  m_joy_index = -1;
203  return false;
204  }
205 
206 
207  // Fill out data:
208  const size_t nAxis = m_joystate_axes.size();
209  if (nAxis>=1)
210  {
211  x = -1+2*( m_joystate_axes[0] - m_x_min ) / (float)( m_x_max-m_x_min );
212  if (raw_x_pos) *raw_x_pos = m_joystate_axes[0];
213  }
214 
215  if (nAxis>=2)
216  {
217  y = -1+2*( m_joystate_axes[1] - m_y_min ) / (float)( m_y_max-m_y_min );
218  if (raw_y_pos) *raw_y_pos = m_joystate_axes[1];
219  }
220 
221  if (nAxis>=3)
222  {
223  z = -1+2*( m_joystate_axes[2] - m_z_min ) / (float)( m_z_max-m_z_min );
224  if (raw_z_pos) *raw_z_pos = m_joystate_axes[2];
225  }
226  else
227  {
228  z=0;
229  }
230 
231  buttons = m_joystate_btns;
232 
233  return true;
234 #else
235  // Apple.
236  return false;
237 #endif
238  MRPT_END
239 }
240 
241 /** Set the axis limit values, for computing a [-1,1] position index easily.
242 * It seems that these values must been calibrated for each joystick model.
243 *
244 * \sa getJoystickPosition
245 */
246 void CJoystick::setLimits( int x_min ,int x_max , int y_min,int y_max ,int z_min,int z_max )
247 {
248  m_x_max = x_max;
249  m_x_min = x_min;
250 
251  m_y_max = y_max;
252  m_y_min = y_min;
253 
254  m_z_max = z_max;
255  m_z_min = z_min;
256 }
257 
GLdouble GLdouble z
Definition: glext.h:3734
Contains classes for various device interfaces.
#define MRPT_END
int m_x_min
The axis limits:
Definition: CJoystick.h:30
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:21
#define MRPT_START
bool getJoystickPosition(int nJoy, float &x, float &y, float &z, std::vector< bool > &buttons, int *raw_x_pos=NULL, int *raw_y_pos=NULL, int *raw_z_pos=NULL)
Gets joystick information.
Definition: CJoystick.cpp:113
static int getJoysticksCount()
Returns the number of Joysticks in the computer.
Definition: CJoystick.cpp:80
void setLimits(int x_min=-32767, int x_max=32767, int y_min=-32767, int y_max=32767, int z_min=-32767, int z_max=32767)
Set the axis limit values, for computing a [-1,1] position index easily (Only required to calibrate a...
Definition: CJoystick.cpp:246
GLenum GLint GLint y
Definition: glext.h:3516
GLenum GLint x
Definition: glext.h:3516
CJoystick()
Constructor.
Definition: CJoystick.cpp:51
virtual ~CJoystick()
Destructor.
Definition: CJoystick.cpp:64



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019