Fawkes API  Fawkes Development Version
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 }
virtual void init()
Initialize the thread.
Definition: act_thread.cpp:56
uint16_t weak_magnitude() const
Get weak_magnitude value.
Base class for all messages passed through interfaces in Fawkes BlackBoard.
Definition: message.h:44
bool msgq_empty()
Check if queue is empty.
Definition: interface.cpp:1048
fawkes::JoystickInterface * joystick_interface() const
Get joystick interface.
Definition: sensor_thread.h:54
JoystickInterface Fawkes BlackBoard Interface.
bool can_ramp()
Check if ramp effect is supported.
Process incoming messages.
Definition: act_thread.h:47
Fawkes library namespace.
bool can_friction()
Check if friction effect is supported.
virtual void finalize()
Finalize the thread.
Definition: act_thread.cpp:64
MessageProcessor(JoystickAcquisitionThread *aqt, fawkes::JoystickInterface *joystick_if)
Constructor.
Definition: act_thread.cpp:87
uint16_t length() const
Get length value.
Thread class encapsulation of pthreads.
Definition: thread.h:42
void write()
Write from local copy into BlackBoard memory.
Definition: interface.cpp:500
Joystick acqusition thread for Linux joystick API.
void stop_rumble()
Stop rumbling.
Joystick sensor thread.
Definition: sensor_thread.h:38
void stop_all()
Stop all current effects.
void rumble(uint16_t strong_magnitude, uint16_t weak_magnitude, Direction direction=DIRECTION_DOWN, uint16_t length=0, uint16_t delay=0)
Rumble the joystick.
bool can_constant()
Check if constant effect is supported.
bool can_periodic()
Check if periodic effect is supported.
JoystickForceFeedback * ff() const
Access force feedback of joystick.
Thread aspect to use blocked timing.
void msgq_pop()
Erase first message from queue.
Definition: interface.cpp:1193
Cause force feedback on a joystick.
Message * msgq_first()
Get the first message from the message queue.
Definition: interface.cpp:1180
Direction
Direction of the effect.
virtual void loop()
Code to execute in the thread.
Definition: act_thread.cpp:71
bool can_damper()
Check if damper effect is supported.
uint16_t strong_magnitude() const
Get strong_magnitude value.
uint8_t ff_effects() const
Get ff_effects value.
bool can_spring()
Check if spring effect is supported.
StartRumbleMessage Fawkes BlackBoard Interface Message.
void set_supported_ff_effects(const uint8_t new_supported_ff_effects)
Set supported_ff_effects value.
Direction direction() const
Get direction value.
bool can_rumble()
Check if rumbling effect is supported.
void msgq_flush()
Flush all messages.
Definition: interface.cpp:1064
void set_ff_effects(const uint8_t new_ff_effects)
Set ff_effects value.
void process_message(fawkes::Message *msg)
Process a single message.
Definition: act_thread.cpp:99
bool can_inertia()
Check if inertia effect is supported.
JoystickActThread(JoystickAcquisitionThread *aqt, JoystickSensorThread *senst)
Constructor.
Definition: act_thread.cpp:45
void process()
Process message currently in the queue.
Definition: act_thread.cpp:137