YARP
Yet Another Robot Platform
IJoypadController.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
10 #include <yarp/os/LogStream.h>
11 #include <cmath>
12 using namespace std;
13 using namespace yarp::dev;
14 using namespace yarp::os;
15 #define MESSAGE_PREFIX "IJoypadController:"
16 #define myInfo() yInfo() << MESSAGE_PREFIX
17 #define myError() yError() << MESSAGE_PREFIX
18 #define myDebug() yDebug() << MESSAGE_PREFIX
19 #define myWarning() yWarning() << MESSAGE_PREFIX
20 #define buttActionGroupName "BUTTON_EXECUTE"
21 
22 #define JoyData yarp::dev::IJoypadEvent::joyData
23 
25 
26 #ifndef YARP_NO_DEPRECATED // Since YARP 3.0.0
28 #endif
30  m_event(nullptr),
31  EventDrivenEnabled(false)
32 {
33 }
34 
35 
36 bool isEqual(const float& a, const float& b, const float& tolerance)
37 {
38  return fabs(a - b) < tolerance;
39 }
40 
41 bool isEqual(const double& a, const double& b, const double& tolerance)
42 {
43  return fabs(a - b) < tolerance;
44 }
45 
46 bool isEqual(const yarp::sig::Vector& a, const yarp::sig::Vector& b, const double& tolerance)
47 {
48  if (a.size() != b.size()) return false;
49 
50  for (size_t i = 0; i < a.size(); i++)
51  {
52  if (fabs(a[i] - b[i]) > tolerance)
53  {
54  return false;
55  }
56  }
57  return true;
58 }
59 
61 {
62  unsigned int count;
63  if(getRawButtonCount(count) && count)
64  {
65  float value = 0;
66  for(unsigned int i = 0; i < count; i++)
67  {
68  getRawButton(i, value);
69  old_buttons.push_back(value);
70  }
71  }
72 
73  if(getRawAxisCount(count) && count)
74  {
75  double value = 0;
76  for(unsigned int i = 0; i < count; i++)
77  {
78  getRawAxis(i, value);
79  old_axes.push_back(value);
80  }
81  }
82 
83  if(getRawHatCount(count) && count)
84  {
85  unsigned char value = 0;
86  for(unsigned int i = 0; i < count; i++)
87  {
88  getRawHat(i, value);
89  old_hats.push_back(value);
90  }
91  }
92 
93  if(getRawTrackballCount(count) && count)
94  {
95  yarp::sig::Vector value;
96  for(unsigned int i = 0; i < count; i++)
97  {
98  getRawTrackball(i, value);
99  old_trackballs.push_back(value);
100  }
101  }
102 
103  if(getRawStickCount(count) && count)
104  {
105  yarp::sig::Vector value;
106  for(unsigned int i = 0; i < count; i++)
107  {
108  getRawStick(i, value, IJoypadController::JypCtrlcoord_CARTESIAN);
109  old_sticks.push_back(value);
110 
111  }
112  }
113 
114  if(getRawTouchSurfaceCount(count) && count)
115  {
116  yarp::sig::Vector value;
117  for(unsigned int i = 0; i < count; i++)
118  {
119  getRawTouch(i, value);
120  old_touches.push_back(value);
121  }
122  }
123  return true;
124 }
125 
127 {
128  bool perform = false;
129  if(!m_event)
130  {
131  return;
132  }
133 
134  unsigned int count;
135  std::vector<JoyData<float> > buttons;
136  std::vector<JoyData<double> > axes;
137  std::vector<JoyData<unsigned char> > hats;
138  std::vector<JoyData<yarp::sig::Vector> > trackBalls;
139  std::vector<JoyData<yarp::sig::Vector> > sticks;
140  std::vector<JoyData<yarp::sig::Vector> > Touch;
141 
142  if(getRawButtonCount(count) && count)
143  {
144  float value = 0;
145  for(unsigned int i = 0; i < count; i++)
146  {
147  getRawButton(i, value);
148  if(!isEqual(value, old_buttons[i], 0.00001f))
149  {
150  perform = true;
151  buttons.emplace_back(i, value);
152  old_buttons[i] = value;
153  }
154  }
155  }
156 
157  if(getRawAxisCount(count) && count)
158  {
159  double value = 0;
160  for(unsigned int i = 0; i < count; i++)
161  {
162  getRawAxis(i, value);
163  if(!isEqual(value, old_axes[i], 0.00001))
164  {
165  perform = true;
166  axes.emplace_back(i, value);
167  old_axes[i] = value;
168  }
169  }
170  }
171 
172  if(getRawHatCount(count) && count)
173  {
174  unsigned char value = 0;
175  for(unsigned int i = 0; i < count; i++)
176  {
177  getRawHat(i, value);
178  if(value != old_hats[i])
179  {
180  perform = true;
181  hats.emplace_back(i, value);
182  old_hats[i] = value;
183  }
184  }
185  }
186 
187  if(getRawTrackballCount(count) && count)
188  {
189  yarp::sig::Vector value;
190  for(unsigned int i = 0; i < count; i++)
191  {
192  getRawTrackball(i, value);
193  if(!isEqual(value, old_trackballs[i], 0.00001))
194  {
195  perform = true;
196  trackBalls.emplace_back(i, value);
197  old_trackballs[i] = value;
198  }
199  }
200  }
201 
202  if(getRawStickCount(count) && count)
203  {
204  yarp::sig::Vector value;
205  for(unsigned int i = 0; i < count; i++)
206  {
207  getRawStick(i, value, IJoypadController::JypCtrlcoord_CARTESIAN);
208  if(!isEqual(value, old_sticks[i], 0.00001))
209  {
210  perform = true;
211  sticks.emplace_back(i, value);
212  old_sticks[i] = value;
213  }
214  }
215  }
216 
217  if(getRawTouchSurfaceCount(count) && count)
218  {
219  yarp::sig::Vector value;
220  for(unsigned int i = 0; i < count; i++)
221  {
222  getRawTouch(i, value);
223  if(!isEqual(value, old_touches[i], 0.00001))
224  {
225  perform = true;
226  Touch.emplace_back(i, value);
227  old_touches[i] = value;
228  }
229  }
230  }
231 
232  if(perform)
233  {
234  m_event->action(buttons, axes, hats, trackBalls, sticks, Touch);
235  }
236 }
237 
239 {
240  if (enable)
241  {
242  if (event)
243  {
244  if(isRunning())
245  {
246  stop();
247  }
248 
249  m_event = event;
250  EventDrivenEnabled = true;
251  start();
252 
253  return true;
254  }
255  else
256  {
257  if(isRunning())
258  {
259  yError() << "IJoypadController: event thread is already running";
260  return false;
261  }
262 
263  if (m_event)
264  {
265  EventDrivenEnabled = true;
266  start();
267  return true;
268  }
269  else
270  {
271  yError() << "IJoypadController: you must provide a valid event to start the event thread";
272  return false;
273  }
274  }
275  }
276 
277  if(isRunning())
278  {
279  stop();
280  EventDrivenEnabled = false;
281  return true;
282  }
283 
284  return false;
285 }
286 
287 bool yarp::dev::IJoypadEventDriven::getAxisCount(unsigned int& axis_count)
288 {
289  return getRawAxisCount(axis_count);
290 }
291 
292 bool yarp::dev::IJoypadEventDriven::getButtonCount(unsigned int& button_count)
293 {
294  return getRawButtonCount(button_count);
295 }
296 
297 bool yarp::dev::IJoypadEventDriven::getTrackballCount(unsigned int& Trackball_count)
298 {
299  return getRawTrackballCount(Trackball_count);
300 }
301 
302 bool yarp::dev::IJoypadEventDriven::getHatCount(unsigned int& Hat_count)
303 {
304  return getRawHatCount(Hat_count);
305 }
306 
308 {
309  return getRawTouchSurfaceCount(touch_count);
310 }
311 
312 bool yarp::dev::IJoypadEventDriven::getStickCount(unsigned int& stick_count)
313 {
314  return getRawStickCount(stick_count);
315 }
316 
317 bool yarp::dev::IJoypadEventDriven::getStickDoF(unsigned int stick_id, unsigned int& DoF)
318 {
319  if (EventDrivenEnabled)
320  {
321  yError() << "EventDriven is enable.. you can't poll the joypad state";
322  return false;
323  }
324  return getRawStickDoF(stick_id, DoF);
325 }
326 
327 bool yarp::dev::IJoypadEventDriven::getButton(unsigned int button_id, float& value)
328 {
329  if (EventDrivenEnabled)
330  {
331  yError() << "EventDriven is enable.. you can't poll the joypad state";
332  return false;
333  }
334  return getRawButton(button_id, value);
335 }
336 
337 bool yarp::dev::IJoypadEventDriven::getTrackball(unsigned int trackball_id, yarp::sig::Vector& value)
338 {
339  if (EventDrivenEnabled)
340  {
341  yError() << "EventDriven is enable.. you can't poll the joypad state";
342  return false;
343  }
344 
345  return getRawTrackball(trackball_id, value);
346 }
347 
348 bool yarp::dev::IJoypadEventDriven::getHat(unsigned int hat_id, unsigned char& value)
349 {
350  if (EventDrivenEnabled)
351  {
352  yError() << "EventDriven is enable.. you can't poll the joypad state";
353  return false;
354  }
355 
356  return getRawHat(hat_id, value);
357 }
358 
359 bool yarp::dev::IJoypadEventDriven::getAxis(unsigned int axis_id, double& value)
360 {
361  if (EventDrivenEnabled)
362  {
363  yError() << "EventDriven is enable.. you can't poll the joypad state";
364  return false;
365  }
366 
367  return getRawAxis(axis_id, value);
368 }
369 
370 bool yarp::dev::IJoypadEventDriven::getStick(unsigned int stick_id, yarp::sig::Vector& value, JoypadCtrl_coordinateMode coordinate_mode)
371 {
372  if (EventDrivenEnabled)
373  {
374  yError() << "EventDriven is enable.. you can't poll the joypad state";
375  return false;
376  }
377 
378  return getRawStick(stick_id, value, coordinate_mode);
379 }
380 
382 {
383  if (EventDrivenEnabled)
384  {
385  yError() << "EventDriven is enable.. you can't poll the joypad state";
386  return false;
387  }
388 
389  return getRawTouch(touch_id, value);
390 }
391 
393 {
394  if (m_actions.find(action_id) != m_actions.end())
395  {
396  myInfo() << "executing script" << action_id << ":" << m_actions[action_id];
397  system(m_actions[action_id].c_str());
398  }
399  else
400  {
401  myWarning() << "no scripts associated to button" << action_id;
402  return false;
403  }
404  return true;
405 }
406 
408 {
409  int dummy = 0;
410  size_t i;
411  int& actCount = count ? *count : dummy;
412  if(!cfg.check(buttActionGroupName))
413  {
414  myInfo() << "no actions found in the configuration file (no" << buttActionGroupName << "group found)";
415  actCount = 0;
416  return true;
417  }
418  Bottle& actionsGroup = cfg.findGroup(buttActionGroupName);
419 
420  if(!actionsGroup.size())
421  {
422  myError() << "no action found under" << buttActionGroupName << "group";
423  actCount = 0;
424  return false;
425  }
426 
427  for(i = 1; i < actionsGroup.size(); i++)
428  {
429  if(!actionsGroup.get(i).isList())
430  {
431  yDebug() << "error parsing cfg";
432  return false;
433  }
434 
435  Bottle& keyvalue = *actionsGroup.get(i).asList();
436  yDebug() << keyvalue.toString();
437  unsigned int buttonCount;
438  if(!this->getButtonCount(buttonCount))
439  {
440  myError() << "unable to get button count while parsing the actions";
441  actCount = 0;
442  return false;
443  }
444  if(!keyvalue.get(0).isInt32() ||
445  keyvalue.get(0).asInt32() < 0 ||
446  (unsigned int) keyvalue.get(0).asInt32() > buttonCount-1 ||
447  !keyvalue.get(1).isString())
448  {
449  myError() << "Button's actions parameters must be in the format 'unsigned int string' and the button id must be in range";
450  actCount = 0;
451  return false;
452  }
453  myInfo() << "assigning actions" << keyvalue.get(1).asString() << "to button" << keyvalue.get(0).asInt32();
454  m_actions[keyvalue.get(0).asInt32()] = keyvalue.get(1).asString();
455  }
456 
457  actCount = i;
458  myInfo() << actCount << "action parsed successfully";
459  return true;
460 }
461 
LogStream.h
yarp::dev::IJoypadController::JoypadCtrl_coordinateMode
JoypadCtrl_coordinateMode
Definition: IJoypadController.h:37
yarp::os::Bottle
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
yarp::dev::IJoypadEventDriven::getStickCount
bool getStickCount(unsigned int &stick_count) override final
get the number of the sticks
Definition: IJoypadController.cpp:312
yarp::dev::IJoypadEventDriven::eventDriven
bool eventDriven(bool enable, yarp::dev::IJoypadEvent *event=nullptr) override
Activate event Driven mode.
Definition: IJoypadController.cpp:238
yarp::os::Bottle::toString
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition: Bottle.cpp:214
yarp::os::Searchable
A base class for nested structures that can be searched.
Definition: Searchable.h:69
yarp::os::Bottle::size
size_type size() const
Gets the number of elements in the bottle.
Definition: Bottle.cpp:254
yarp::dev::IJoypadController::parseActions
virtual bool parseActions(const yarp::os::Searchable &cfg, int *count=nullptr)
Definition: IJoypadController.cpp:407
yarp::dev::IJoypadEventDriven::getTouchSurfaceCount
bool getTouchSurfaceCount(unsigned int &touch_count) override final
get the number of touch surface.
Definition: IJoypadController.cpp:307
yarp::os::Searchable::findGroup
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
yarp::dev::IJoypadEventDriven::run
void run() override final
Loop function.
Definition: IJoypadController.cpp:126
yarp::dev::IJoypadEventDriven::getStick
bool getStick(unsigned int stick_id, yarp::sig::Vector &value, JoypadCtrl_coordinateMode coordinate_mode) override final
Get the value of a stick if present, return false otherwise.
Definition: IJoypadController.cpp:370
yarp::dev::IJoypadEventDriven::IJoypadEventDriven
IJoypadEventDriven()
Definition: IJoypadController.cpp:24
yarp::dev::IJoypadEventDriven
Definition: IJoypadController.h:209
yarp::dev::IJoypadEventDriven::threadInit
bool threadInit() override final
Initialization method.
Definition: IJoypadController.cpp:60
isEqual
bool isEqual(const float &a, const float &b, const float &tolerance)
Definition: IJoypadController.cpp:36
yError
#define yError(...)
Definition: Log.h:282
yarp::dev
An interface for the device drivers.
Definition: audioBufferSizeData.cpp:17
yarp::dev::IJoypadEventDriven::getHat
bool getHat(unsigned int hat_id, unsigned char &value) override final
Get the value of an Hat.
Definition: IJoypadController.cpp:348
yarp::dev::IJoypadEventDriven::getTrackballCount
bool getTrackballCount(unsigned int &Trackball_count) override final
Get number of trackballs.
Definition: IJoypadController.cpp:297
yarp::sig::VectorOf< double >
yarp::os::Value::isString
virtual bool isString() const
Checks if value is a string.
Definition: Value.cpp:159
myWarning
#define myWarning()
Definition: IJoypadController.cpp:19
yarp::os::Bottle::get
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:249
yarp::dev::IJoypadEventDriven::getStickDoF
bool getStickDoF(unsigned int stick_id, unsigned int &DoF) override final
Get the Degree Of Freedom count for desired stick.
Definition: IJoypadController.cpp:317
yarp::os::Value::asString
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
yarp::os::Searchable::check
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
yarp::dev::IJoypadEvent::~IJoypadEvent
virtual ~IJoypadEvent()
yarp::dev::IJoypadController::executeAction
virtual bool executeAction(int action_id)
Definition: IJoypadController.cpp:392
yarp::os::PeriodicThread
An abstraction for a periodic thread.
Definition: PeriodicThread.h:25
buttActionGroupName
#define buttActionGroupName
Definition: IJoypadController.cpp:20
yarp::dev::IJoypadEventDriven::getHatCount
bool getHatCount(unsigned int &Hat_count) override final
Get number of Hats.
Definition: IJoypadController.cpp:302
yarp::os::Value::isList
virtual bool isList() const
Checks if value is a list.
Definition: Value.cpp:165
yarp::dev::IJoypadController::JypCtrlcoord_CARTESIAN
@ JypCtrlcoord_CARTESIAN
Definition: IJoypadController.h:37
yarp::os::Value::asInt32
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:207
yarp::dev::IJoypadEventDriven::getButtonCount
bool getButtonCount(unsigned int &button_count) override final
Get number of Buttons.
Definition: IJoypadController.cpp:292
myError
#define myError()
Definition: IJoypadController.cpp:17
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yarp::dev::IJoypadEventDriven::getAxis
bool getAxis(unsigned int axis_id, double &value) override final
Get the value of an axis if present, return false otherwise.
Definition: IJoypadController.cpp:359
yDebug
#define yDebug(...)
Definition: Log.h:237
yarp::os::Value::asList
virtual Bottle * asList() const
Get list value.
Definition: Value.cpp:243
yarp::dev::IJoypadEventDriven::getTrackball
bool getTrackball(unsigned int trackball_id, yarp::sig::Vector &value) override final
Get the axes change of a Trackball.
Definition: IJoypadController.cpp:337
myInfo
#define myInfo()
Definition: IJoypadController.cpp:16
yarp::sig::VectorOf::size
size_t size() const
Definition: Vector.h:355
yarp::dev::IJoypadEventDriven::getAxisCount
bool getAxisCount(unsigned int &axis_count) override final
Get number of Axes.
Definition: IJoypadController.cpp:287
yarp::dev::IJoypadEventDriven::getButton
bool getButton(unsigned int button_id, float &value) override final
Get the value of a button.
Definition: IJoypadController.cpp:327
yarp::dev::IJoypadEventDriven::getTouch
bool getTouch(unsigned int touch_id, yarp::sig::Vector &value) override final
Get the value of a touch if present, return false otherwise.
Definition: IJoypadController.cpp:381
IJoypadController.h
yarp::dev::IJoypadEvent
Definition: IJoypadController.h:181
yarp::os::Value::isInt32
virtual bool isInt32() const
Checks if value is a 32-bit integer.
Definition: Value.cpp:135