YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
JoypadControlClient.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
8#include <yarp/os/LogStream.h>
9#include <tuple>
10
11using namespace yarp::dev;
12using namespace yarp::sig;
13using namespace yarp::os;
14
15namespace {
16YARP_LOG_COMPONENT(JOYPADCONTROLCLIENT, "yarp.device.JoypadControlClient")
17}
18
20{
21 m_ports.push_back(&m_buttonsPort );
22 m_ports.push_back(&m_axisPort );
23 m_ports.push_back(&m_stickPort );
24 m_ports.push_back(&m_trackballPort);
25 m_ports.push_back(&m_touchPort );
26 m_ports.push_back(&m_hatsPort );
27 watchdog.m_ports = m_ports;
28}
29
30bool JoypadControlClient::getJoypadInfo()
31{
32 unsigned int count;
33 bool temp;
34
35 temp = m_rpc_only;
36 m_rpc_only = true;
37 std::vector<std::tuple<int, JoypadControl::LoopablePort*, std::string> > vocabs_ports;
38 vocabs_ports.emplace_back(VOCAB_BUTTON, &m_buttonsPort, "/buttons");
39 vocabs_ports.emplace_back(VOCAB_AXIS, &m_axisPort, "/axis");
40 vocabs_ports.emplace_back(VOCAB_STICK, &m_stickPort, "/stick");
41 vocabs_ports.emplace_back(VOCAB_TRACKBALL, &m_trackballPort, "/trackball");
42 vocabs_ports.emplace_back(VOCAB_TOUCH, &m_touchPort, "/touch");
43 vocabs_ports.emplace_back(VOCAB_HAT, &m_hatsPort, "/hat");
44
45 for(auto vocab_port : vocabs_ports)
46 {
47 if (!getCount(std::get<0>(vocab_port), count)) {
48 return false;
49 }
50 if(count)
51 {
52 std::string source;
53 std::string destination;
54 std::string portname = m_local + std::get<2>(vocab_port) + ":i";
55 std::get<1>(vocab_port)->valid = true;
56 std::get<1>(vocab_port)->count = count;
57
58 if(std::get<0>(vocab_port) == VOCAB_STICK)
59 {
60 for(unsigned int i = 0; i < count; i++)
61 {
62 unsigned int dofCount;
63 if(!getStickDoF(i, dofCount))
64 {
65 yCError(JOYPADCONTROLCLIENT) << "Unable to get sticks DoF";
66 return false;
67 }
68 m_stickDof.push_back(dofCount);
69 }
70 }
71
72 yCInfo(JOYPADCONTROLCLIENT) << "Opening" << portname;
73
74 if(!std::get<1>(vocab_port)->contactable->open(portname))
75 {
76 yCError(JOYPADCONTROLCLIENT) << "Unable to open" << portname << "port";
77 return false;
78 }
79
80 source = m_remote + std::get<2>(vocab_port) + ":o";
81 destination = m_local + std::get<2>(vocab_port) + ":i";
82 if(!yarp::os::NetworkBase::connect(source.c_str(), destination.c_str(), "udp"))
83 {
84 yCError(JOYPADCONTROLCLIENT) << "Unable to connect" << source << "with" << destination;
85 return false;
86 }
87
88 std::get<1>(vocab_port)->useCallback();
89 }
90 }
91 m_rpc_only = temp;
92 return true;
93}
94
96{
97 if (!parseParams(config)) { return false; }
98
99 if(!m_rpcPort.open(m_local + "/rpc:o"))
100 {
101 yCError(JOYPADCONTROLCLIENT) << "Unable to open rpc port.";
102 return false;
103 }
104 yCInfo(JOYPADCONTROLCLIENT) << "rpc port opened. starting the handshake";
105
106 if(!yarp::os::NetworkBase::connect(m_local + "/rpc:o", m_remote + "/rpc:i"))
107 {
108 yCError(JOYPADCONTROLCLIENT) << "Handshake failed. unable to connect to remote port" << m_remote + "/rpc:i";
109 return false;
110 }
111
112 yCInfo(JOYPADCONTROLCLIENT) << "Handshake succeeded! retrieving info";
113
114 if(!getJoypadInfo())
115 {
116 yCError(JOYPADCONTROLCLIENT) << "Unable to get joypad info.";
117 return false;
118 }
119
120 watchdog.start();
121
122 return true;
123}
124
126{
127 for (auto port : m_ports)
128 {
129 if (port->count)
130 {
131 port->onTimeout(0.5);
132 }
133 }
134}
135
136bool JoypadControlClient::getCount(const int& vocab_toget, unsigned int& value)
137{
138 if(!m_rpc_only)
139 {
140 switch(vocab_toget)
141 {
142 case VOCAB_BUTTON:
143 value = m_buttonsPort.count;
144 return true;
145
146 case VOCAB_AXIS:
147
148 value = m_axisPort.count;
149 return true;
150
151 case VOCAB_TRACKBALL:
152 value = m_trackballPort.count;
153 return true;
154
155 case VOCAB_TOUCH:
156
157 value = m_touchPort.count;
158 return true;
159
160 case VOCAB_STICK:
161
162 value = m_stickPort.count;
163 return true;
164
165 case VOCAB_HAT:
166
167 value = m_hatsPort.count;
168 return true;
169
170 default:
171 break;
172 }
173 }
174
175 Bottle cmd, response;
180 m_rpcPort.write(cmd, response);
181 if(response.get(0).asVocab32() == VOCAB_OK && response.get(1).isInt32())
182 {
183 value = response.get(1).asInt32();
184 return true;
185 }
186 else
187 {
188 return false;
189 }
190}
191
193{
194 return getCount(VOCAB_BUTTON, button_count);
195}
196
198{
199 return getCount(VOCAB_AXIS, axis_count);
200}
201
206
208{
209 return getCount(VOCAB_HAT, Hat_count);
210}
211
213{
214 return getCount(VOCAB_TOUCH, touch_count);
215}
216
218{
219 return getCount(VOCAB_STICK, stick_count);
220}
221
222bool JoypadControlClient::getRawStickDoF(unsigned int stick_id, unsigned int& DoF)
223{
224 Bottle cmd, response;
229 cmd.addInt32(stick_id);
230 m_rpcPort.write(cmd, response);
231 if(response.get(0).asVocab32() == VOCAB_OK && response.get(1).isInt32())
232 {
233 DoF = response.get(1).asInt32();
234 return true;
235 }
236 else
237 {
238 return false;
239 }
240}
241
242bool JoypadControlClient::getRawButton(unsigned int button_id, float& value)
243{
244 if(m_rpc_only)
245 {
246 Bottle cmd, response;
247
252 cmd.addInt32(button_id);
253 m_rpcPort.write(cmd, response);
254 if(response.get(0).asVocab32() == VOCAB_OK && response.get(1).isFloat64())
255 {
256 value = response.get(1).asFloat64();
257 return true;
258 }
259 else
260 {
261 yCError(JOYPADCONTROLCLIENT) << "GetButton() error. VOCAB_FAILED";
262 return false;
263 }
264 }
265 else
266 {
267 std::lock_guard<std::mutex> l(m_buttonsPort.mutex);
268 if(button_id < m_buttonsPort.storage.size())
269 {
270 value = m_buttonsPort.storage[button_id];
271 return true;
272 }
273 else
274 {
275 yCError(JOYPADCONTROLCLIENT) << "GetButton() error. button_id out of bound";
276 return false;
277 }
278 }
279}
280
282{
283 value.clear();
284 if(m_rpc_only)
285 {
286 Bottle cmd, response;
287
293 m_rpcPort.write(cmd, response);
294 if(response.get(0).asVocab32() == VOCAB_OK && response.get(1).isFloat64() && response.get(2).isFloat64())
295 {
296 value.push_back(response.get(1).asFloat64());
297 value.push_back(response.get(2).asFloat64());
298 return true;
299 }
300 else
301 {
302 return false;
303 }
304 }
305 else
306 {
307 std::lock_guard<std::mutex> l(m_trackballPort.mutex);
308 if(trackball_id < m_trackballPort.storage.size() / 2)
309 {
310 value.push_back(m_trackballPort.storage[trackball_id * 2]);
311 value.push_back(m_trackballPort.storage[trackball_id * 2 + 1]);
312 return true;
313 }
314 else
315 {
316 return false;
317 }
318 }
319}
320
321bool JoypadControlClient::getRawHat(unsigned int hat_id, unsigned char& value)
322{
323 if(m_rpc_only)
324 {
325 Bottle cmd, response;
326
331 cmd.addInt32(hat_id);
332 m_rpcPort.write(cmd, response);
333 if(response.get(0).asVocab32() == VOCAB_OK && response.get(1).isInt32())
334 {
335 value = response.get(1).asInt32();
336 return true;
337 }
338 else
339 {
340 return false;
341 }
342 }
343 else
344 {
345 std::lock_guard<std::mutex> l(m_hatsPort.mutex);
346 if(hat_id < m_hatsPort.storage.size())
347 {
348 value = m_hatsPort.storage[hat_id];
349 return true;
350 }
351 else
352 {
353 return false;
354 }
355 }
356}
357
358bool JoypadControlClient::getRawAxis(unsigned int axis_id, double& value)
359{
360 if(m_rpc_only)
361 {
362 Bottle cmd, response;
363
368 cmd.addInt32(axis_id);
369 m_rpcPort.write(cmd, response);
370 if(response.get(0).asVocab32() == VOCAB_OK && response.get(1).isFloat64())
371 {
372 value = response.get(1).asFloat64();
373 return true;
374 }
375 else
376 {
377 yCError(JOYPADCONTROLCLIENT) << "GetAxis() error. VOCAB_FAILED";
378 return false;
379 }
380 }
381 else
382 {
383 std::lock_guard<std::mutex> l(m_axisPort.mutex);
384 if(axis_id < m_axisPort.storage.size())
385 {
386 value = m_axisPort.storage[axis_id];
387 return true;
388 }
389 else
390 {
391 yCError(JOYPADCONTROLCLIENT) << "GetAxis() error. Axis_id out of bound";
392 return false;
393 }
394 }
395}
396
398{
399 value.clear();
401 {
402 Bottle cmd, response;
403 int dof, coordmode;
404
410 cmd.addInt32(stick_id);
411 m_rpcPort.write(cmd, response);
412
413 if(response.get(0).asVocab32() == VOCAB_OK && response.get(1).isInt32())
414 {
415 dof = response.get(1).asInt32();
416 }
417 else
418 {
419 return false;
420 }
426 cmd.addInt32(stick_id);
427 m_rpcPort.write(cmd, response);
428 if(response.get(0).asVocab32() == VOCAB_OK)
429 {
430 for(int i = 0; i < dof; i++)
431 {
432 if(response.get(i).isFloat64())
433 {
434 value.push_back(response.get(i).asFloat64());
435 }
436 else
437 {
438 return false;
439 }
440 }
441 return true;
442 }
443 else
444 {
445 return false;
446 }
447 }
448 else
449 {
450 std::lock_guard<std::mutex> l(m_stickPort.mutex);
451 int offset = 0;
452
453 unsigned int i;
454 if(getStickCount(i), stick_id >= i)
455 {
456 yCError(JOYPADCONTROLCLIENT) << "GetStick() error. Stick_id out of bound";
457 return false;
458 }
459 for(size_t j = 0; j < stick_id; j++)
460 {
461 offset += m_stickDof[j];
462 }
463
464 for(size_t i = 0; i < m_stickDof[stick_id]; ++i)
465 {
466 value.push_back(m_stickPort.storage[offset + i]);
467 }
468
469 return true;
470 }
471}
472
474{
475 value.clear();
476 if(m_rpc_only)
477 {
478 Bottle cmd, response;
479
484 cmd.addInt32(touch_id);
485 m_rpcPort.write(cmd, response);
486 if(response.get(0).asVocab32() == VOCAB_OK && response.get(1).isFloat64() && response.get(2).isFloat64())
487 {
488 value.push_back(response.get(1).asFloat64());
489 value.push_back(response.get(2).asFloat64());
490 return true;
491 }
492 else
493 {
494 return false;
495 }
496 }
497 else
498 {
499 std::lock_guard<std::mutex> l(m_touchPort.mutex);
500 if(touch_id < m_touchPort.storage.size()/2)
501 {
502 value.push_back(m_touchPort.storage[touch_id * 2]);
503 value.push_back(m_touchPort.storage[touch_id * 2 + 1]);
504 return true;
505 }
506 else
507 {
508 return false;
509 }
510 }
511}
512
514{
515
516 std::vector<JoypadControl::LoopablePort*> portv;
517 portv.push_back(&m_buttonsPort);
518 portv.push_back(&m_axisPort);
519 portv.push_back(&m_hatsPort);
520 portv.push_back(&m_touchPort);
521 portv.push_back(&m_trackballPort);
522 portv.push_back(&m_stickPort);
523
524 for(auto p : portv)
525 {
526 p->contactable->interrupt();
527 p->contactable->close();
528 }
529
530 m_rpcPort.close();
531 return true;
532}
constexpr yarp::conf::vocab32_t VOCAB_OK
constexpr yarp::conf::vocab32_t VOCAB_GET
constexpr yarp::conf::vocab32_t VOCAB_VALUE
constexpr yarp::conf::vocab32_t VOCAB_COUNT
constexpr yarp::conf::vocab32_t VOCAB_BUTTON
constexpr yarp::conf::vocab32_t VOCAB_IJOYPADCTRL
constexpr yarp::conf::vocab32_t VOCAB_TOUCH
constexpr yarp::conf::vocab32_t VOCAB_HAT
constexpr yarp::conf::vocab32_t VOCAB_TRACKBALL
constexpr yarp::conf::vocab32_t VOCAB_CARTESIAN
constexpr yarp::conf::vocab32_t VOCAB_STICKDOF
constexpr yarp::conf::vocab32_t VOCAB_AXIS
constexpr yarp::conf::vocab32_t VOCAB_POLAR
constexpr yarp::conf::vocab32_t VOCAB_STICK
bool parseParams(const yarp::os::Searchable &config) override
Parse the DeviceDriver parameters.
bool getRawAxisCount(unsigned int &axis_count) override
bool getRawHatCount(unsigned int &Hat_count) override
bool getRawButtonCount(unsigned int &button_count) override
bool getRawTrackballCount(unsigned int &Trackball_count) override
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
bool getRawButton(unsigned int button_id, float &value) override
bool getRawHat(unsigned int hat_id, unsigned char &value) override
bool getRawStickDoF(unsigned int stick_id, unsigned int &DoF) override
bool close() override
Close the DeviceDriver.
bool getRawStickCount(unsigned int &stick_count) override
bool getRawStick(unsigned int stick_id, yarp::sig::Vector &value, JoypadCtrl_coordinateMode coordinate_mode) override
bool getRawTrackball(unsigned int trackball_id, yarp::sig::Vector &value) override
bool getRawTouch(unsigned int touch_id, yarp::sig::Vector &value) override
bool getRawTouchSurfaceCount(unsigned int &touch_count) override
bool getRawAxis(unsigned int axis_id, double &value) override
void run() override
Loop function.
std::vector< JoypadControl::LoopablePort * > m_ports
bool getStickDoF(unsigned int stick_id, unsigned int &DoF) override final
Get the Degree Of Freedom count for desired stick.
bool getStickCount(unsigned int &stick_count) override final
Get the number of the sticks.
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
void addVocab32(yarp::conf::vocab32_t x)
Places a vocabulary item in the bottle, at the end of the list.
Definition Bottle.cpp:164
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition Bottle.cpp:246
void addInt32(std::int32_t x)
Places a 32-bit integer in the bottle, at the end of the list.
Definition Bottle.cpp:140
A mini-server for performing network communication in the background.
void close() override
Stop port activity.
void interrupt() override
Interrupt any current reads or writes attached to the port.
void useCallback(TypedReaderCallback< T > &callback) override
Set an object whose onRead method will be called when data is available.
static bool connect(const std::string &src, const std::string &dest, const std::string &carrier="", bool quiet=true)
Request that an output port connect to an input port.
Definition Network.cpp:682
bool start()
Call this to start the thread.
bool write(const PortWriter &writer, const PortWriter *callback=nullptr) const override
Write an object to the port.
Definition Port.cpp:436
void close() override
Stop port activity.
Definition Port.cpp:363
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
Definition Port.cpp:79
A base class for nested structures that can be searched.
Definition Searchable.h:31
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
Definition Value.cpp:222
virtual yarp::conf::vocab32_t asVocab32() const
Get vocabulary identifier as an integer.
Definition Value.cpp:228
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition Value.cpp:204
virtual bool isFloat64() const
Checks if value is a 64-bit floating point number.
Definition Value.cpp:150
virtual bool isInt32() const
Checks if value is a 32-bit integer.
Definition Value.cpp:132
void push_back(const T &elem)
Push a new element in the vector: size is changed.
Definition Vector.h:268
#define yCInfo(component,...)
#define yCError(component,...)
#define YARP_LOG_COMPONENT(name,...)
For streams capable of holding different kinds of content, check what they actually have.
An interface to the operating system, including Port based communication.