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 
25 #include "acquisition_thread.h"
26 #include "force_feedback.h"
27 #include "sensor_thread.h"
28 
29 #include <interfaces/JoystickInterface.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 /** Constructor.
41  * @param aqt JoystickAcquisitionThread to get data from
42  * @param senst sensor thread to share joystick interface with
43  */
45 : Thread("JoystickActThread", Thread::OPMODE_WAITFORWAKEUP),
47 {
48  aqt_ = aqt;
49  senst_ = senst;
50 }
51 
52 void
54 {
55  joystick_if_ = senst_->joystick_interface();
56  msgproc_ = new MessageProcessor(aqt_, joystick_if_);
57 }
58 
59 void
61 {
62  delete msgproc_;
63 }
64 
65 void
67 {
68  msgproc_->process();
69 }
70 
71 /** @class JoystickActThread::MessageProcessor "act_thread.h"
72  * Process incoming messages.
73  * Internal utility class.
74  * @author Tim Niemueller
75  */
76 
77 /** Constructor.
78  * @param aqt acqusition thread to intsruct
79  * @param joystick_if interface to listen on for messages
80  */
82  JoystickInterface * joystick_if)
83 {
84  aqt_ = aqt;
85  joystick_if_ = joystick_if;
86  joystick_connected_ = false;
87 }
88 
89 /** Process a single message.
90  * @param msg message to process
91  */
92 void
94 {
95  JoystickForceFeedback *ff = aqt_->ff();
96 
97  if (!ff)
98  return;
99 
100  if (dynamic_cast<JoystickInterface::StartRumbleMessage *>(msg) != NULL) {
102  dynamic_cast<JoystickInterface::StartRumbleMessage *>(msg);
103 
104  ff->rumble(srm->strong_magnitude(),
105  srm->weak_magnitude(),
107  srm->length(),
108  srm->delay());
109 
110  uint8_t e = joystick_if_->ff_effects() | JoystickInterface::JFF_RUMBLE;
111  joystick_if_->set_ff_effects(e);
112  joystick_if_->write();
113 
114  } else if (dynamic_cast<JoystickInterface::StopRumbleMessage *>(msg) != NULL) {
115  ff->stop_rumble();
116  uint8_t e = joystick_if_->ff_effects() & ~JoystickInterface::JFF_RUMBLE;
117  joystick_if_->set_ff_effects(e);
118  joystick_if_->write();
119 
120  } else if (dynamic_cast<JoystickInterface::StopAllMessage *>(msg) != NULL) {
121  ff->stop_all();
122  joystick_if_->set_ff_effects(0);
123  joystick_if_->write();
124  }
125 }
126 
127 /** Process message currently in the queue. */
128 void
130 {
131  JoystickForceFeedback *ff = aqt_->ff();
132 
133  if (ff == NULL) {
134  joystick_if_->msgq_flush();
135  if (joystick_connected_) {
136  joystick_if_->set_supported_ff_effects(0);
137  joystick_if_->write();
138  joystick_connected_ = false;
139  }
140  } else if (!joystick_connected_) {
141  uint8_t effects = 0;
142  if (ff->can_rumble()) {
143  effects |= JoystickInterface::JFF_RUMBLE;
144  }
145  if (ff->can_periodic()) {
146  effects |= JoystickInterface::JFF_PERIODIC;
147  }
148  if (ff->can_ramp()) {
149  effects |= JoystickInterface::JFF_RAMP;
150  }
151  if (ff->can_spring()) {
152  effects |= JoystickInterface::JFF_SPRING;
153  }
154  if (ff->can_friction()) {
155  effects |= JoystickInterface::JFF_FRICTION;
156  }
157  if (ff->can_damper()) {
158  effects |= JoystickInterface::JFF_DAMPER;
159  }
160  if (ff->can_inertia()) {
161  effects |= JoystickInterface::JFF_INERTIA;
162  }
163  if (ff->can_constant()) {
164  effects |= JoystickInterface::JFF_CONSTANT;
165  }
166  joystick_if_->set_supported_ff_effects(effects);
167  joystick_if_->write();
168  joystick_connected_ = true;
169  }
170 
171  while (!joystick_if_->msgq_empty()) {
172  if (!joystick_connected_) {
173  joystick_if_->msgq_flush();
174  break;
175  }
176 
177  process_message(joystick_if_->msgq_first());
178 
179  joystick_if_->msgq_pop();
180  }
181 }
Joystick acqusition thread for Linux joystick API.
JoystickForceFeedback * ff() const
Access force feedback of joystick.
Process incoming messages.
Definition: act_thread.h:47
void process_message(fawkes::Message *msg)
Process a single message.
Definition: act_thread.cpp:93
void process()
Process message currently in the queue.
Definition: act_thread.cpp:129
MessageProcessor(JoystickAcquisitionThread *aqt, fawkes::JoystickInterface *joystick_if)
Constructor.
Definition: act_thread.cpp:81
virtual void finalize()
Finalize the thread.
Definition: act_thread.cpp:60
virtual void loop()
Code to execute in the thread.
Definition: act_thread.cpp:66
JoystickActThread(JoystickAcquisitionThread *aqt, JoystickSensorThread *senst)
Constructor.
Definition: act_thread.cpp:44
virtual void init()
Initialize the thread.
Definition: act_thread.cpp:53
Cause force feedback on a joystick.
bool can_spring()
Check if spring effect is supported.
bool can_inertia()
Check if inertia effect is supported.
bool can_ramp()
Check if ramp effect is supported.
Direction
Direction of the effect.
bool can_friction()
Check if friction effect is supported.
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_rumble()
Check if rumbling effect is supported.
bool can_periodic()
Check if periodic effect is supported.
bool can_damper()
Check if damper effect is supported.
void stop_all()
Stop all current effects.
bool can_constant()
Check if constant effect is supported.
void stop_rumble()
Stop rumbling.
Joystick sensor thread.
Definition: sensor_thread.h:43
fawkes::JoystickInterface * joystick_interface() const
Get joystick interface.
Definition: sensor_thread.h:54
Thread aspect to use blocked timing.
void msgq_pop()
Erase first message from queue.
Definition: interface.cpp:1215
Message * msgq_first()
Get the first message from the message queue.
Definition: interface.cpp:1200
void write()
Write from local copy into BlackBoard memory.
Definition: interface.cpp:501
bool msgq_empty()
Check if queue is empty.
Definition: interface.cpp:1062
void msgq_flush()
Flush all messages.
Definition: interface.cpp:1079
StartRumbleMessage Fawkes BlackBoard Interface Message.
uint16_t length() const
Get length value.
uint16_t strong_magnitude() const
Get strong_magnitude value.
uint16_t weak_magnitude() const
Get weak_magnitude value.
Direction direction() const
Get direction value.
StopAllMessage Fawkes BlackBoard Interface Message.
StopRumbleMessage Fawkes BlackBoard Interface Message.
JoystickInterface Fawkes BlackBoard Interface.
uint8_t ff_effects() const
Get ff_effects value.
void set_supported_ff_effects(const uint8_t new_supported_ff_effects)
Set supported_ff_effects value.
void set_ff_effects(const uint8_t new_ff_effects)
Set ff_effects value.
Base class for all messages passed through interfaces in Fawkes BlackBoard.
Definition: message.h:44
Thread class encapsulation of pthreads.
Definition: thread.h:46
Fawkes library namespace.