Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
JoystickInterface.cpp
1 
2 /***************************************************************************
3  * JoystickInterface.cpp - Fawkes BlackBoard Interface - JoystickInterface
4  *
5  * Templated created: Thu Oct 12 10:49:19 2006
6  * Copyright 2008 Tim Niemueller
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <interfaces/JoystickInterface.h>
25 
26 #include <core/exceptions/software.h>
27 
28 #include <cstring>
29 #include <cstdlib>
30 
31 namespace fawkes {
32 
33 /** @class JoystickInterface <interfaces/JoystickInterface.h>
34  * JoystickInterface Fawkes BlackBoard Interface.
35  *
36  This interface provides access to a joystick. It provides up to
37  five axes, where each has a X and a Y value between -1.0 and 1.0.
38  Up to 32 buttons are support via an uint32 bit field.
39 
40  * @ingroup FawkesInterfaces
41  */
42 
43 
44 /** BUTTON_1 constant */
45 const uint32_t JoystickInterface::BUTTON_1 = 1u;
46 /** BUTTON_2 constant */
47 const uint32_t JoystickInterface::BUTTON_2 = 2u;
48 /** BUTTON_3 constant */
49 const uint32_t JoystickInterface::BUTTON_3 = 4u;
50 /** BUTTON_4 constant */
51 const uint32_t JoystickInterface::BUTTON_4 = 8u;
52 /** BUTTON_5 constant */
53 const uint32_t JoystickInterface::BUTTON_5 = 16u;
54 /** BUTTON_6 constant */
55 const uint32_t JoystickInterface::BUTTON_6 = 32u;
56 /** BUTTON_7 constant */
57 const uint32_t JoystickInterface::BUTTON_7 = 64u;
58 /** BUTTON_8 constant */
59 const uint32_t JoystickInterface::BUTTON_8 = 128u;
60 /** BUTTON_9 constant */
61 const uint32_t JoystickInterface::BUTTON_9 = 256u;
62 /** BUTTON_10 constant */
63 const uint32_t JoystickInterface::BUTTON_10 = 512u;
64 /** BUTTON_11 constant */
65 const uint32_t JoystickInterface::BUTTON_11 = 1024u;
66 /** BUTTON_12 constant */
67 const uint32_t JoystickInterface::BUTTON_12 = 2048u;
68 /** BUTTON_13 constant */
69 const uint32_t JoystickInterface::BUTTON_13 = 4096u;
70 /** BUTTON_14 constant */
71 const uint32_t JoystickInterface::BUTTON_14 = 8192u;
72 /** BUTTON_15 constant */
73 const uint32_t JoystickInterface::BUTTON_15 = 16384u;
74 /** BUTTON_16 constant */
75 const uint32_t JoystickInterface::BUTTON_16 = 32768u;
76 /** BUTTON_17 constant */
77 const uint32_t JoystickInterface::BUTTON_17 = 65536u;
78 /** BUTTON_18 constant */
79 const uint32_t JoystickInterface::BUTTON_18 = 131072u;
80 /** BUTTON_19 constant */
81 const uint32_t JoystickInterface::BUTTON_19 = 262144u;
82 /** BUTTON_20 constant */
83 const uint32_t JoystickInterface::BUTTON_20 = 524288u;
84 /** BUTTON_21 constant */
85 const uint32_t JoystickInterface::BUTTON_21 = 1048576u;
86 /** BUTTON_22 constant */
87 const uint32_t JoystickInterface::BUTTON_22 = 2097152u;
88 /** BUTTON_23 constant */
89 const uint32_t JoystickInterface::BUTTON_23 = 4194304u;
90 /** BUTTON_24 constant */
91 const uint32_t JoystickInterface::BUTTON_24 = 8388608u;
92 /** BUTTON_25 constant */
93 const uint32_t JoystickInterface::BUTTON_25 = 16777216u;
94 /** BUTTON_26 constant */
95 const uint32_t JoystickInterface::BUTTON_26 = 33554432u;
96 /** BUTTON_27 constant */
97 const uint32_t JoystickInterface::BUTTON_27 = 67108864u;
98 /** BUTTON_28 constant */
99 const uint32_t JoystickInterface::BUTTON_28 = 134217728u;
100 /** BUTTON_29 constant */
101 const uint32_t JoystickInterface::BUTTON_29 = 268435456u;
102 /** BUTTON_30 constant */
103 const uint32_t JoystickInterface::BUTTON_30 = 536870912u;
104 /** BUTTON_31 constant */
105 const uint32_t JoystickInterface::BUTTON_31 = 1073741824u;
106 /** BUTTON_32 constant */
107 const uint32_t JoystickInterface::BUTTON_32 = 2147483648u;
108 /** JFF_RUMBLE constant */
109 const uint8_t JoystickInterface::JFF_RUMBLE = 1;
110 /** JFF_PERIODIC constant */
111 const uint8_t JoystickInterface::JFF_PERIODIC = 2;
112 /** JFF_RAMP constant */
113 const uint8_t JoystickInterface::JFF_RAMP = 4;
114 /** JFF_SPRING constant */
115 const uint8_t JoystickInterface::JFF_SPRING = 8;
116 /** JFF_FRICTION constant */
117 const uint8_t JoystickInterface::JFF_FRICTION = 16;
118 /** JFF_DAMPER constant */
119 const uint8_t JoystickInterface::JFF_DAMPER = 32;
120 /** JFF_INERTIA constant */
121 const uint8_t JoystickInterface::JFF_INERTIA = 64;
122 /** JFF_CONSTANT constant */
123 const uint8_t JoystickInterface::JFF_CONSTANT = 128;
124 
125 /** Constructor */
126 JoystickInterface::JoystickInterface() : Interface()
127 {
128  data_size = sizeof(JoystickInterface_data_t);
129  data_ptr = malloc(data_size);
130  data = (JoystickInterface_data_t *)data_ptr;
131  data_ts = (interface_data_ts_t *)data_ptr;
132  memset(data_ptr, 0, data_size);
133  add_fieldinfo(IFT_BYTE, "num_axes", 1, &data->num_axes);
134  add_fieldinfo(IFT_BYTE, "num_buttons", 1, &data->num_buttons);
135  add_fieldinfo(IFT_BYTE, "supported_ff_effects", 1, &data->supported_ff_effects);
136  add_fieldinfo(IFT_UINT32, "pressed_buttons", 1, &data->pressed_buttons);
137  add_fieldinfo(IFT_FLOAT, "axis", 8, &data->axis);
138  add_fieldinfo(IFT_UINT8, "ff_effects", 1, &data->ff_effects);
139  add_messageinfo("StartRumbleMessage");
140  add_messageinfo("StopRumbleMessage");
141  add_messageinfo("StopAllMessage");
142  unsigned char tmp_hash[] = {0xeb, 0x7c, 0xd1, 0x1c, 0xae, 0xa, 0x37, 0x45, 0x5c, 0xa, 0x5e, 0xda, 0x5e, 0x17, 0xdd, 0x42};
143  set_hash(tmp_hash);
144 }
145 
146 /** Destructor */
147 JoystickInterface::~JoystickInterface()
148 {
149  free(data_ptr);
150 }
151 /** Convert Direction constant to string.
152  * @param value value to convert to string
153  * @return constant value as string.
154  */
155 const char *
157 {
158  switch (value) {
159  case DIRECTION_DOWN: return "DIRECTION_DOWN";
160  case DIRECTION_LEFT: return "DIRECTION_LEFT";
161  case DIRECTION_UP: return "DIRECTION_UP";
162  case DIRECTION_RIGHT: return "DIRECTION_RIGHT";
163  default: return "UNKNOWN";
164  }
165 }
166 /* Methods */
167 /** Get num_axes value.
168  *
169  The number of axes of this joystick
170 
171  * @return num_axes value
172  */
173 uint8_t
175 {
176  return data->num_axes;
177 }
178 
179 /** Get maximum length of num_axes value.
180  * @return length of num_axes value, can be length of the array or number of
181  * maximum number of characters for a string
182  */
183 size_t
185 {
186  return 1;
187 }
188 
189 /** Set num_axes value.
190  *
191  The number of axes of this joystick
192 
193  * @param new_num_axes new num_axes value
194  */
195 void
196 JoystickInterface::set_num_axes(const uint8_t new_num_axes)
197 {
198  data->num_axes = new_num_axes;
199  data_changed = true;
200 }
201 
202 /** Get num_buttons value.
203  *
204  The number of buttons of this joystick.
205 
206  * @return num_buttons value
207  */
208 uint8_t
210 {
211  return data->num_buttons;
212 }
213 
214 /** Get maximum length of num_buttons value.
215  * @return length of num_buttons value, can be length of the array or number of
216  * maximum number of characters for a string
217  */
218 size_t
220 {
221  return 1;
222 }
223 
224 /** Set num_buttons value.
225  *
226  The number of buttons of this joystick.
227 
228  * @param new_num_buttons new num_buttons value
229  */
230 void
231 JoystickInterface::set_num_buttons(const uint8_t new_num_buttons)
232 {
233  data->num_buttons = new_num_buttons;
234  data_changed = true;
235 }
236 
237 /** Get supported_ff_effects value.
238  *
239  Bit field indicating available force-feedback effects.
240 
241  * @return supported_ff_effects value
242  */
243 uint8_t
245 {
246  return data->supported_ff_effects;
247 }
248 
249 /** Get maximum length of supported_ff_effects value.
250  * @return length of supported_ff_effects value, can be length of the array or number of
251  * maximum number of characters for a string
252  */
253 size_t
255 {
256  return 1;
257 }
258 
259 /** Set supported_ff_effects value.
260  *
261  Bit field indicating available force-feedback effects.
262 
263  * @param new_supported_ff_effects new supported_ff_effects value
264  */
265 void
266 JoystickInterface::set_supported_ff_effects(const uint8_t new_supported_ff_effects)
267 {
268  data->supported_ff_effects = new_supported_ff_effects;
269  data_changed = true;
270 }
271 
272 /** Get pressed_buttons value.
273  *
274  A bit field of enabled buttons. For each currently clicked button the
275  corresponding bit is set to 1. Use the BUTTON_* constants for bit-wise
276  comparisons.
277 
278  * @return pressed_buttons value
279  */
280 uint32_t
282 {
283  return data->pressed_buttons;
284 }
285 
286 /** Get maximum length of pressed_buttons value.
287  * @return length of pressed_buttons value, can be length of the array or number of
288  * maximum number of characters for a string
289  */
290 size_t
292 {
293  return 1;
294 }
295 
296 /** Set pressed_buttons value.
297  *
298  A bit field of enabled buttons. For each currently clicked button the
299  corresponding bit is set to 1. Use the BUTTON_* constants for bit-wise
300  comparisons.
301 
302  * @param new_pressed_buttons new pressed_buttons value
303  */
304 void
305 JoystickInterface::set_pressed_buttons(const uint32_t new_pressed_buttons)
306 {
307  data->pressed_buttons = new_pressed_buttons;
308  data_changed = true;
309 }
310 
311 /** Get axis value.
312  * Values of axes.
313  * @return axis value
314  */
315 float *
317 {
318  return data->axis;
319 }
320 
321 /** Get axis value at given index.
322  * Values of axes.
323  * @param index index of value
324  * @return axis value
325  * @exception Exception thrown if index is out of bounds
326  */
327 float
328 JoystickInterface::axis(unsigned int index) const
329 {
330  if (index > 8) {
331  throw Exception("Index value %u out of bounds (0..8)", index);
332  }
333  return data->axis[index];
334 }
335 
336 /** Get maximum length of axis value.
337  * @return length of axis value, can be length of the array or number of
338  * maximum number of characters for a string
339  */
340 size_t
342 {
343  return 8;
344 }
345 
346 /** Set axis value.
347  * Values of axes.
348  * @param new_axis new axis value
349  */
350 void
351 JoystickInterface::set_axis(const float * new_axis)
352 {
353  memcpy(data->axis, new_axis, sizeof(float) * 8);
354  data_changed = true;
355 }
356 
357 /** Set axis value at given index.
358  * Values of axes.
359  * @param new_axis new axis value
360  * @param index index for of the value
361  */
362 void
363 JoystickInterface::set_axis(unsigned int index, const float new_axis)
364 {
365  if (index > 8) {
366  throw Exception("Index value %u out of bounds (0..8)", index);
367  }
368  data->axis[index] = new_axis;
369  data_changed = true;
370 }
371 /** Get ff_effects value.
372  *
373  Currently running effects. Either 0 if no effect is running, or a bit-wise
374  ored field of the JFF constants.
375 
376  * @return ff_effects value
377  */
378 uint8_t
380 {
381  return data->ff_effects;
382 }
383 
384 /** Get maximum length of ff_effects value.
385  * @return length of ff_effects value, can be length of the array or number of
386  * maximum number of characters for a string
387  */
388 size_t
390 {
391  return 1;
392 }
393 
394 /** Set ff_effects value.
395  *
396  Currently running effects. Either 0 if no effect is running, or a bit-wise
397  ored field of the JFF constants.
398 
399  * @param new_ff_effects new ff_effects value
400  */
401 void
402 JoystickInterface::set_ff_effects(const uint8_t new_ff_effects)
403 {
404  data->ff_effects = new_ff_effects;
405  data_changed = true;
406 }
407 
408 /* =========== message create =========== */
409 Message *
410 JoystickInterface::create_message(const char *type) const
411 {
412  if ( strncmp("StartRumbleMessage", type, __INTERFACE_MESSAGE_TYPE_SIZE) == 0 ) {
413  return new StartRumbleMessage();
414  } else if ( strncmp("StopRumbleMessage", type, __INTERFACE_MESSAGE_TYPE_SIZE) == 0 ) {
415  return new StopRumbleMessage();
416  } else if ( strncmp("StopAllMessage", type, __INTERFACE_MESSAGE_TYPE_SIZE) == 0 ) {
417  return new StopAllMessage();
418  } else {
419  throw UnknownTypeException("The given type '%s' does not match any known "
420  "message type for this interface type.", type);
421  }
422 }
423 
424 
425 /** Copy values from other interface.
426  * @param other other interface to copy values from
427  */
428 void
430 {
431  const JoystickInterface *oi = dynamic_cast<const JoystickInterface *>(other);
432  if (oi == NULL) {
433  throw TypeMismatchException("Can only copy values from interface of same type (%s vs. %s)",
434  type(), other->type());
435  }
436  memcpy(data, oi->data, sizeof(JoystickInterface_data_t));
437 }
438 
439 const char *
440 JoystickInterface::enum_tostring(const char *enumtype, int val) const
441 {
442  if (strcmp(enumtype, "Direction") == 0) {
443  return tostring_Direction((Direction)val);
444  }
445  throw UnknownTypeException("Unknown enum type %s", enumtype);
446 }
447 
448 /* =========== messages =========== */
449 /** @class JoystickInterface::StartRumbleMessage <interfaces/JoystickInterface.h>
450  * StartRumbleMessage Fawkes BlackBoard Interface Message.
451  *
452 
453  */
454 
455 
456 /** Constructor with initial values.
457  * @param ini_length initial value for length
458  * @param ini_delay initial value for delay
459  * @param ini_direction initial value for direction
460  * @param ini_strong_magnitude initial value for strong_magnitude
461  * @param ini_weak_magnitude initial value for weak_magnitude
462  */
463 JoystickInterface::StartRumbleMessage::StartRumbleMessage(const uint16_t ini_length, const uint16_t ini_delay, const Direction ini_direction, const uint16_t ini_strong_magnitude, const uint16_t ini_weak_magnitude) : Message("StartRumbleMessage")
464 {
465  data_size = sizeof(StartRumbleMessage_data_t);
466  data_ptr = malloc(data_size);
467  memset(data_ptr, 0, data_size);
468  data = (StartRumbleMessage_data_t *)data_ptr;
470  data->length = ini_length;
471  data->delay = ini_delay;
472  data->direction = ini_direction;
473  data->strong_magnitude = ini_strong_magnitude;
474  data->weak_magnitude = ini_weak_magnitude;
475  add_fieldinfo(IFT_UINT16, "length", 1, &data->length);
476  add_fieldinfo(IFT_UINT16, "delay", 1, &data->delay);
477  add_fieldinfo(IFT_ENUM, "direction", 1, &data->direction, "Direction");
478  add_fieldinfo(IFT_UINT16, "strong_magnitude", 1, &data->strong_magnitude);
479  add_fieldinfo(IFT_UINT16, "weak_magnitude", 1, &data->weak_magnitude);
480 }
481 /** Constructor */
483 {
484  data_size = sizeof(StartRumbleMessage_data_t);
485  data_ptr = malloc(data_size);
486  memset(data_ptr, 0, data_size);
487  data = (StartRumbleMessage_data_t *)data_ptr;
489  add_fieldinfo(IFT_UINT16, "length", 1, &data->length);
490  add_fieldinfo(IFT_UINT16, "delay", 1, &data->delay);
491  add_fieldinfo(IFT_ENUM, "direction", 1, &data->direction, "Direction");
492  add_fieldinfo(IFT_UINT16, "strong_magnitude", 1, &data->strong_magnitude);
493  add_fieldinfo(IFT_UINT16, "weak_magnitude", 1, &data->weak_magnitude);
494 }
495 
496 /** Destructor */
498 {
499  free(data_ptr);
500 }
501 
502 /** Copy constructor.
503  * @param m message to copy from
504  */
506 {
507  data_size = m->data_size;
508  data_ptr = malloc(data_size);
509  memcpy(data_ptr, m->data_ptr, data_size);
510  data = (StartRumbleMessage_data_t *)data_ptr;
512 }
513 
514 /* Methods */
515 /** Get length value.
516  * Effect length in ms.
517  Setting to 0 will make the effect to play continuously until stopped.
518 
519  * @return length value
520  */
521 uint16_t
523 {
524  return data->length;
525 }
526 
527 /** Get maximum length of length value.
528  * @return length of length value, can be length of the array or number of
529  * maximum number of characters for a string
530  */
531 size_t
533 {
534  return 1;
535 }
536 
537 /** Set length value.
538  * Effect length in ms.
539  Setting to 0 will make the effect to play continuously until stopped.
540 
541  * @param new_length new length value
542  */
543 void
545 {
546  data->length = new_length;
547 }
548 
549 /** Get delay value.
550  * Delay before effect starts in ms.
551  * @return delay value
552  */
553 uint16_t
555 {
556  return data->delay;
557 }
558 
559 /** Get maximum length of delay value.
560  * @return length of delay value, can be length of the array or number of
561  * maximum number of characters for a string
562  */
563 size_t
565 {
566  return 1;
567 }
568 
569 /** Set delay value.
570  * Delay before effect starts in ms.
571  * @param new_delay new delay value
572  */
573 void
575 {
576  data->delay = new_delay;
577 }
578 
579 /** Get direction value.
580  * Direction of effect
581  * @return direction value
582  */
585 {
586  return (JoystickInterface::Direction)data->direction;
587 }
588 
589 /** Get maximum length of direction value.
590  * @return length of direction value, can be length of the array or number of
591  * maximum number of characters for a string
592  */
593 size_t
595 {
596  return 1;
597 }
598 
599 /** Set direction value.
600  * Direction of effect
601  * @param new_direction new direction value
602  */
603 void
605 {
606  data->direction = new_direction;
607 }
608 
609 /** Get strong_magnitude value.
610  * Magnitude of heavy motor.
611  * @return strong_magnitude value
612  */
613 uint16_t
615 {
616  return data->strong_magnitude;
617 }
618 
619 /** Get maximum length of strong_magnitude value.
620  * @return length of strong_magnitude value, can be length of the array or number of
621  * maximum number of characters for a string
622  */
623 size_t
625 {
626  return 1;
627 }
628 
629 /** Set strong_magnitude value.
630  * Magnitude of heavy motor.
631  * @param new_strong_magnitude new strong_magnitude value
632  */
633 void
635 {
636  data->strong_magnitude = new_strong_magnitude;
637 }
638 
639 /** Get weak_magnitude value.
640  * Magnitude of light motor.
641  * @return weak_magnitude value
642  */
643 uint16_t
645 {
646  return data->weak_magnitude;
647 }
648 
649 /** Get maximum length of weak_magnitude value.
650  * @return length of weak_magnitude value, can be length of the array or number of
651  * maximum number of characters for a string
652  */
653 size_t
655 {
656  return 1;
657 }
658 
659 /** Set weak_magnitude value.
660  * Magnitude of light motor.
661  * @param new_weak_magnitude new weak_magnitude value
662  */
663 void
665 {
666  data->weak_magnitude = new_weak_magnitude;
667 }
668 
669 /** Clone this message.
670  * Produces a message of the same type as this message and copies the
671  * data to the new message.
672  * @return clone of this message
673  */
674 Message *
676 {
677  return new JoystickInterface::StartRumbleMessage(this);
678 }
679 /** @class JoystickInterface::StopRumbleMessage <interfaces/JoystickInterface.h>
680  * StopRumbleMessage Fawkes BlackBoard Interface Message.
681  *
682 
683  */
684 
685 
686 /** Constructor */
688 {
689  data_size = sizeof(StopRumbleMessage_data_t);
690  data_ptr = malloc(data_size);
691  memset(data_ptr, 0, data_size);
692  data = (StopRumbleMessage_data_t *)data_ptr;
694 }
695 
696 /** Destructor */
698 {
699  free(data_ptr);
700 }
701 
702 /** Copy constructor.
703  * @param m message to copy from
704  */
706 {
707  data_size = m->data_size;
708  data_ptr = malloc(data_size);
709  memcpy(data_ptr, m->data_ptr, data_size);
710  data = (StopRumbleMessage_data_t *)data_ptr;
712 }
713 
714 /* Methods */
715 /** Clone this message.
716  * Produces a message of the same type as this message and copies the
717  * data to the new message.
718  * @return clone of this message
719  */
720 Message *
722 {
723  return new JoystickInterface::StopRumbleMessage(this);
724 }
725 /** @class JoystickInterface::StopAllMessage <interfaces/JoystickInterface.h>
726  * StopAllMessage Fawkes BlackBoard Interface Message.
727  *
728 
729  */
730 
731 
732 /** Constructor */
734 {
735  data_size = sizeof(StopAllMessage_data_t);
736  data_ptr = malloc(data_size);
737  memset(data_ptr, 0, data_size);
738  data = (StopAllMessage_data_t *)data_ptr;
740 }
741 
742 /** Destructor */
744 {
745  free(data_ptr);
746 }
747 
748 /** Copy constructor.
749  * @param m message to copy from
750  */
752 {
753  data_size = m->data_size;
754  data_ptr = malloc(data_size);
755  memcpy(data_ptr, m->data_ptr, data_size);
756  data = (StopAllMessage_data_t *)data_ptr;
758 }
759 
760 /* Methods */
761 /** Clone this message.
762  * Produces a message of the same type as this message and copies the
763  * data to the new message.
764  * @return clone of this message
765  */
766 Message *
768 {
769  return new JoystickInterface::StopAllMessage(this);
770 }
771 /** Check if message is valid and can be enqueued.
772  * @param message Message to check
773  * @return true if the message is valid, false otherwise.
774  */
775 bool
777 {
778  const StartRumbleMessage *m0 = dynamic_cast<const StartRumbleMessage *>(message);
779  if ( m0 != NULL ) {
780  return true;
781  }
782  const StopRumbleMessage *m1 = dynamic_cast<const StopRumbleMessage *>(message);
783  if ( m1 != NULL ) {
784  return true;
785  }
786  const StopAllMessage *m2 = dynamic_cast<const StopAllMessage *>(message);
787  if ( m2 != NULL ) {
788  return true;
789  }
790  return false;
791 }
792 
793 /// @cond INTERNALS
794 EXPORT_INTERFACE(JoystickInterface)
795 /// @endcond
796 
797 
798 } // end namespace fawkes