Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
act_thread.cpp
1 
2 /***************************************************************************
3  * act_thread.cpp - Joystick thread to execute force feedback
4  *
5  * Created: Mon Feb 07 21:29:22 2011
6  * Copyright 2006-2011 Tim Niemueller [www.niemueller.de]
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.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "act_thread.h"
24 #include "sensor_thread.h"
25 #include "acquisition_thread.h"
26 
27 #include <interfaces/JoystickInterface.h>
28 
29 #include "force_feedback.h"
30 
31 using namespace fawkes;
32 
33 /** @class JoystickActThread "act_thread.h"
34  * Joystick force feedback actuation thread.
35  * This thread integrates into the Fawkes main loop at the act hook and
36  * executes force feedback commands.
37  * @author Tim Niemueller
38  */
39 
40 
41 /** Constructor.
42  * @param aqt JoystickAcquisitionThread to get data from
43  * @param senst sensor thread to share joystick interface with
44  */
46  JoystickSensorThread *senst)
47  : Thread("JoystickActThread", Thread::OPMODE_WAITFORWAKEUP),
49 {
50  __aqt = aqt;
51  __senst = senst;
52 }
53 
54 
55 void
57 {
58  __joystick_if = __senst->joystick_interface();
59  __msgproc = new MessageProcessor(__aqt, __joystick_if);
60 }
61 
62 
63 void
65 {
66  delete __msgproc;
67 }
68 
69 
70 void
72 {
73  __msgproc->process();
74 }
75 
76 
77 /** @class JoystickActThread::MessageProcessor "act_thread.h"
78  * Process incoming messages.
79  * Internal utility class.
80  * @author Tim Niemueller
81  */
82 
83 /** Constructor.
84  * @param aqt acqusition thread to intsruct
85  * @param joystick_if interface to listen on for messages
86  */
88  JoystickInterface *joystick_if)
89 {
90  __aqt = aqt;
91  __joystick_if = joystick_if;
92  __joystick_connected = false;
93 }
94 
95 /** Process a single message.
96  * @param msg message to process
97  */
98 void
100 {
101  JoystickForceFeedback *ff = __aqt->ff();
102 
103  if (! ff) return;
104 
105  if (dynamic_cast<JoystickInterface::StartRumbleMessage *>(msg) != NULL) {
107  dynamic_cast<JoystickInterface::StartRumbleMessage *>(msg);
108 
109  ff->rumble(srm->strong_magnitude(), srm->weak_magnitude(),
111  srm->length(), srm->delay());
112 
113  uint8_t e = __joystick_if->ff_effects() | JoystickInterface::JFF_RUMBLE;
114  __joystick_if->set_ff_effects(e);
115  __joystick_if->write();
116 
117  }
118  else if (dynamic_cast<JoystickInterface::StopRumbleMessage *>(msg) != NULL)
119  {
120  ff->stop_rumble();
121  uint8_t e = __joystick_if->ff_effects() & ~JoystickInterface::JFF_RUMBLE;
122  __joystick_if->set_ff_effects(e);
123  __joystick_if->write();
124 
125  }
126  else if (dynamic_cast<JoystickInterface::StopAllMessage *>(msg) != NULL)
127  {
128  ff->stop_all();
129  __joystick_if->set_ff_effects(0);
130  __joystick_if->write();
131  }
132 }
133 
134 
135 /** Process message currently in the queue. */
136 void
138 {
139  JoystickForceFeedback *ff = __aqt->ff();
140 
141  if (ff == NULL) {
142  __joystick_if->msgq_flush();
143  if (__joystick_connected) {
144  __joystick_if->set_supported_ff_effects(0);
145  __joystick_if->write();
146  __joystick_connected = false;
147  }
148  } else if (! __joystick_connected) {
149  uint8_t effects = 0;
150  if (ff->can_rumble()) {
151  effects |= JoystickInterface::JFF_RUMBLE;
152  }
153  if (ff->can_periodic()) {
154  effects |= JoystickInterface::JFF_PERIODIC;
155  }
156  if (ff->can_ramp()) {
157  effects |= JoystickInterface::JFF_RAMP;
158  }
159  if (ff->can_spring()) {
160  effects |= JoystickInterface::JFF_SPRING;
161  }
162  if (ff->can_friction()) {
163  effects |= JoystickInterface::JFF_FRICTION;
164  }
165  if (ff->can_damper()) {
166  effects |= JoystickInterface::JFF_DAMPER;
167  }
168  if (ff->can_inertia()) {
169  effects |= JoystickInterface::JFF_INERTIA;
170  }
171  if (ff->can_constant()) {
172  effects |= JoystickInterface::JFF_CONSTANT;
173  }
174  __joystick_if->set_supported_ff_effects(effects);
175  __joystick_if->write();
176  __joystick_connected = true;
177  }
178 
179  while (! __joystick_if->msgq_empty() ) {
180 
181  if (! __joystick_connected) {
182  __joystick_if->msgq_flush();
183  break;
184  }
185 
186  process_message(__joystick_if->msgq_first());
187 
188  __joystick_if->msgq_pop();
189  }
190 }