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



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019