GamepadUnit.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package RobotAPI::ArmarXObjects::GamepadUnit
17  * @author Simon Ottenhaus ( simon dot ottenhaus at kit dot edu )
18  * @date 2017
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "GamepadUnit.h"
24 
28 #include <linux/joystick.h>
29 
30 using namespace armarx;
31 
33 {
35  offeringTopic(getProperty<std::string>("GamepadTopicName").getValue());
36  deviceName = getProperty<std::string>("GamepadDeviceName").getValue();
37  deviceEventName = getProperty<std::string>("GamepadForceFeedbackName").getValue();
38  readTask = new RunningTask<GamepadUnit>(this, &GamepadUnit::run, "GamepadUnit");
39 }
40 
42 {
44  topicPrx = getTopic<GamepadUnitListenerPrx>(getProperty<std::string>("GamepadTopicName").getValue());
46  sendTask = new SimplePeriodicTask<>([&]
47  {
49  std::unique_lock lock(mutex);
50  if (!js.opened())
51  {
52  return;
53  }
55  if (!dataTimestamp)
56  {
57  ARMARX_INFO << deactivateSpam(1) << "dataTimestamp is null, waiting for value";
58  return;
59  }
60  ARMARX_CHECK_NOT_NULL(dataTimestamp);
61  const IceUtil::Time age = IceUtil::Time::now() - dataTimestamp->toTime();
62  if (age.toMilliSeconds() < getProperty<int>("PublishTimeout").getValue())
63  {
65  ARMARX_CHECK_NOT_NULL(topicPrx) << "Topic proxy must not be null.";
66  topicPrx->reportGamepadState(deviceName, js.name, data, dataTimestamp);
67  }
68  else
69  {
71  ARMARX_INFO << deactivateSpam(100000, std::to_string(dataTimestamp->getTimestamp())) << "No new signal from gamepad for " << age.toMilliSecondsDouble() << " milliseconds. Not sending data. Timeout: " << getProperty<int>("PublishTimeout").getValue() << " ms";
72  }
73  }, 30);
74 
75  sendTask->start();
78 }
79 
80 void GamepadUnit::vibrate(const ::Ice::Current&)
81 {
82  ARMARX_INFO << "vibration!";
83  js.executeEffect();
84 }
85 
87 {
88  if (js.open(deviceName, deviceEventName))
89  {
90 
92  ARMARX_INFO << "opened a gamepad named " << js.name << " with " << js.numberOfAxis << " axis and " << js.numberOfButtons << " buttons.";
93  if (js.numberOfAxis == 8 && js.numberOfButtons == 11)
94  {
96  readTask->start();
97  }
98  else
99  {
100  ARMARX_TRACE;
101  ARMARX_WARNING << "this is not our trusty logitech gamepad.";
102  js.close();
103  return false;
104  }
105  }
106  else
107  {
108  ARMARX_TRACE;
109  ARMARX_WARNING << "Could not open gamepad device " << deviceName;
110  js.close();
111  return false;
112  }
113  return true;
114 }
115 
116 void GamepadUnit::run()
117 {
118  ARMARX_TRACE;
119  while (readTask->isRunning())
120  {
121  ARMARX_TRACE;
122  if (!js.pollEvent())
123  {
124  ARMARX_TRACE;
125  ARMARX_WARNING << "failed to read gamepad data - trying to reconnect";
126  js.close();
127  sleep(1);
128  while (readTask->isRunning() && !openGamepadConnection())
129  {
130  sleep(1);
131  }
132  }
133  ARMARX_TRACE;
134  std::unique_lock lock(mutex);
135  IceUtil::Time now = IceUtil::Time::now();
136  dataTimestamp = new TimestampVariant(now);
137 
138  //mapping found with command line tool jstest <device file>
139 
140  float axisFactor = 1.0f / 32768.f;
141 
142  data.leftStickY = js.axis[0] * axisFactor;
143  data.leftStickX = js.axis[1] * axisFactor;
144  data.rightStickX = js.axis[3] * axisFactor;
145  data.rightStickY = js.axis[4] * axisFactor;
146  data.dPadX = js.axis[7] * axisFactor;
147  data.dPadY = js.axis[6] * axisFactor;
148  data.leftTrigger = js.axis[2] * axisFactor;
149  data.rightTrigger = js.axis[5] * axisFactor;
150  ARMARX_TRACE;
151 
152  data.leftButton = js.buttonsPressed[4];
153  data.rightButton = js.buttonsPressed[5];
154  data.backButton = js.buttonsPressed[6];
155  data.startButton = js.buttonsPressed[7];
156  data.xButton = js.buttonsPressed[2];
157  data.yButton = js.buttonsPressed[3];
158  data.aButton = js.buttonsPressed[0];
159  data.bButton = js.buttonsPressed[1];
160  data.theMiddleButton = js.buttonsPressed[8];
161  data.leftStickButton = js.buttonsPressed[9];
162  data.rightStickButton = js.buttonsPressed[10];
163  ARMARX_TRACE;
164 
165  ARMARX_VERBOSE << "left x (integer): " << js.axis[0] << " left x (float): " << data.leftStickX << " right trigger: " << data.rightTrigger;
166 
167  //usleep(1000); // 10ms
168  }
169 }
170 
171 
173 {
174  ARMARX_TRACE;
175  if (sendTask)
176  {
177  ARMARX_TRACE;
178  sendTask->stop();
179  }
180  if (readTask)
181  {
182  ARMARX_TRACE;
183  readTask->stop();
184  }
185 }
186 
187 
189 {
190 
191 }
192 
194 {
197 }
armarx::Joystick::open
bool open(std::string const &deviceName, std::string const &deviceEventName)
Definition: Joystick.h:55
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::GamepadUnit::onDisconnectComponent
void onDisconnectComponent() override
Definition: GamepadUnit.cpp:172
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
trace.h
armarx::TimestampVariant
Definition: TimestampVariant.h:54
armarx::Joystick::numberOfButtons
int numberOfButtons
Definition: Joystick.h:51
armarx::Joystick::name
std::string name
Definition: Joystick.h:52
armarx::RunningTask
Definition: ArmarXMultipleObjectsScheduler.h:35
armarx::GamepadUnit::onExitComponent
void onExitComponent() override
Definition: GamepadUnit.cpp:188
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:69
armarx::GamepadUnit::vibrate
void vibrate(const ::Ice::Current &=::Ice::emptyCurrent) override
Definition: GamepadUnit.cpp:80
armarx::Joystick::executeEffect
void executeEffect(int gain=100, const int nTimes=1)
Definition: Joystick.h:122
TimestampVariant.h
armarx::Joystick::buttonsPressed
std::vector< bool > buttonsPressed
Definition: Joystick.h:49
armarx::Joystick::axis
std::vector< int16_t > axis
Definition: Joystick.h:48
armarx::Joystick::close
void close()
Definition: Joystick.h:276
armarx::GamepadUnit::onConnectComponent
void onConnectComponent() override
Definition: GamepadUnit.cpp:41
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
armarx::GamepadUnit::onInitComponent
void onInitComponent() override
Definition: GamepadUnit.cpp:32
GamepadUnit.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::ManagedIceObject::offeringTopic
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
Definition: ManagedIceObject.cpp:290
armarx::Joystick::opened
bool opened() const
Definition: Joystick.h:93
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::Joystick::pollEvent
bool pollEvent()
Definition: Joystick.h:99
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:92
armarx::GamepadUnit::openGamepadConnection
bool openGamepadConnection()
Definition: GamepadUnit.cpp:86
Logging.h
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:34
armarx::GamepadUnit::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: GamepadUnit.cpp:193
armarx::GamepadUnitPropertyDefinitions
Definition: GamepadUnit.h:45
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::SimplePeriodicTask
Usage:
Definition: ApplicationNetworkStats.h:32
armarx::Joystick::numberOfAxis
int numberOfAxis
Definition: Joystick.h:50