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



Page generated by Doxygen 1.8.14 for MRPT 2.0.0 Git: b38439d21 Tue Mar 31 19:58:06 2020 +0200 at miƩ abr 1 00:50:30 CEST 2020