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



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at lun oct 28 00:14:14 CET 2019