21 constexpr
double actionsExecutionTime = 1.0;
34 yCInfo(SDLJOYPAD) <<
"parameters:";
36 yCInfo(SDLJOYPAD) <<
"UseAllJoypadAsOne - set it to 1 to have all the connected joypad as one";
37 yCInfo(SDLJOYPAD) <<
"DefaultJoystickNumber - select the id of the joypad to use if there are more than one joypad and UseAllJoypadAsOne is set to 0";
38 yCInfo(SDLJOYPAD) <<
"stick - the number of stick to configure. a stick is simply a wrapping of 2 or more axes so for every stick";
39 yCInfo(SDLJOYPAD) <<
" a group named STICK*ID* containing the stick's parameters is searched. ";
41 yCInfo(SDLJOYPAD) <<
"stick groups parameters:";
42 yCInfo(SDLJOYPAD) <<
"axes - axes count for this stick";
43 yCInfo(SDLJOYPAD) <<
"axis[ID]_id - axis id for current stick related axis";
44 yCInfo(SDLJOYPAD) <<
"invert_axis_[ID] - invert the current axis";
45 yCInfo(SDLJOYPAD) <<
"deadZone - set the deadzone for this stick";
53 if (SDL_InitSubSystem( SDL_INIT_JOYSTICK ) < 0 )
55 yCError(SDLJOYPAD,
"Unable to initialize Joystick: %s", SDL_GetError());
60 joystick_num = SDL_NumJoysticks();
63 if (joystick_num == 0)
65 yCError(SDLJOYPAD,
"No joysticks found");
68 else if (joystick_num == 1)
71 yCInfo(SDLJOYPAD,
"One joystick found");
72 yCInfo(SDLJOYPAD,
"Using joystick: %s", SDL_JoystickName(joy_id));
76 yCInfo(SDLJOYPAD,
"More than one joystick found:");
77 for (
size_t i = 0; i < joystick_num; i++)
79 yCInfo(SDLJOYPAD) << i <<
":" << SDL_JoystickName(i);
82 if(!rf.check(
"UseAllJoypadAsOne"))
84 if(rf.find(
"UseAllJoypadAsOne").asBool())
87 if (rf.check(
"DefaultJoystickNumber"))
89 joy_id = rf.find(
"DefaultJoystickNumber").asInt32();
90 yCInfo(SDLJOYPAD,
"Multiple joysticks found, using #%d, as specified in the configuration options", joy_id);
94 yCWarning(SDLJOYPAD,
"No default joystick specified in the configuration options");
95 yCWarning(SDLJOYPAD,
"Which joystick you want to use? (choose number)");
107 yCError(SDLJOYPAD) <<
"Missing UseAllJoypadAsOne parameter";
114 for(
size_t i = 0; i < joystick_num; ++i)
116 m_device.push_back(SDL_JoystickOpen(i));
121 m_device.push_back(SDL_JoystickOpen(joy_id));
124 for(
size_t i = 0; i < m_device.size(); ++i)
126 if ( m_device[i] ==
nullptr )
128 yCError(SDLJOYPAD) <<
"Could not open joystick with id" << i;
133 m_axisCount += SDL_JoystickNumAxes(m_device[i]);
134 m_ballCount += SDL_JoystickNumBalls(m_device[i]);
135 m_hatCount += SDL_JoystickNumHats(m_device[i]);
136 m_buttonCount += SDL_JoystickNumButtons(m_device[i]);
139 if(parseActions(rf, &actionCount))
143 if(SDL_JoystickEventState(SDL_ENABLE) < 0)
145 yCError(SDLJOYPAD) <<
"SDLJoypad:" << SDL_GetError();
148 yCInfo(SDLJOYPAD) <<
"Actions successfully parsed and linked to the joypad";
153 yCError(SDLJOYPAD) <<
"Error while parsing actions";
157 if(!parseStickInfo(rf)){
return false;}
165 yCError(SDLJOYPAD) <<
"Missing 'sticks' parameter or not an integer";
169 for(
unsigned int i = 0; i < m_axisCount; i++)
171 m_axes.push_back(
true);
175 for(
unsigned int i = 0; i < m_stickCount; i++)
177 std::string stickName;
183 if(!cfg.
check(stickName))
185 yCError(SDLJOYPAD) <<
"Missing" << stickName <<
"group in configuration";
191 if(0 == stickParams.
size())
193 yCError(SDLJOYPAD) <<
"Group" << stickName <<
"is empty";
199 yCError(SDLJOYPAD) <<
"Missing 'axes' count in" << stickName <<
"group or not an integer";
205 for(
int j = 0; j < axesCount; j++)
207 std::string axisName, invertName;
208 unsigned int axis_id;
214 yCError(SDLJOYPAD) <<
"Missing" << axisName <<
"param in" << stickName <<
"group or not an integer.";
218 axis_id = (
unsigned int)stickParams.
find(axisName).
asInt32();
219 if(axis_id > m_axisCount - 1)
221 yCError(SDLJOYPAD) <<
"Axis id out of bound";
225 if(!stickParams.
check(invertName) || !stickParams.
find(invertName).
isBool())
227 yCError(SDLJOYPAD) <<
"Missing" << invertName <<
"param in" << stickName <<
"group or not an bool.";
231 currentStick.
axes_ids.push_back(axis_id);
233 m_axes[axis_id] =
false;
238 yCError(SDLJOYPAD) <<
"Missing deadZone param in" << stickName <<
"group or not an double.";
243 m_sticks.push_back(currentStick);
255 axes_count = m_axisCount;
261 button_count = m_buttonCount;
267 trackball_count = m_ballCount;
273 hat_count = m_hatCount;
279 touch_count = m_touchCount;
285 stick_count = m_stickCount;
291 if(stick_id > m_sticks.size()-1)
293 yCError(SDLJOYPAD) <<
"SDL_Joypad: stick_id out of bounds when calling 'getStickDoF'' method";
302 if(button_id > m_buttonCount - 1){
yCError(SDLJOYPAD) <<
"Button id out of bound!";
return false;}
305 for(i = 0; i < m_device.size(); ++i)
307 unsigned int localCount = SDL_JoystickNumButtons(m_device[i]);
308 if(button_id > localCount - 1)
310 button_id -= localCount;
317 value = float(SDL_JoystickGetButton(m_device[i], button_id));
318 if(value > 0.5 && m_actions.find(button_id) != m_actions.end() &&
yarp::os::Time::now() - m_actionTimestamp > actionsExecutionTime)
320 executeAction(button_id);
326 bool SDLJoypad::getPureAxis(
unsigned int axis_id,
double& value)
328 if(axis_id > m_axisCount - 1){
yCError(SDLJOYPAD) <<
"Axis id out of bound!";
return false;}
331 for(i = 0; i < m_device.size(); ++i)
333 unsigned int localCount;
334 localCount = SDL_JoystickNumAxes(m_device[i]);
335 if(axis_id > localCount - 1)
337 axis_id -= localCount;
345 value = 2 * ((float(SDL_JoystickGetAxis(m_device[i], axis_id)) - (-32.768)) / 0xffff);
351 if(axis_id > m_axisCount - 1){
yCError(SDLJOYPAD) <<
"Axis id out of bound!";
return false;}
354 return getPureAxis(axis_id, value);
367 if (stick_id > m_stickCount - 1){
yCError(SDLJOYPAD) <<
"Stick id out of bound!";
return false;}
370 stick& stk = m_sticks[stick_id];
373 for(
size_t i = 0; i < stk.
axes_ids.size(); i++)
375 if(!getRawAxis(stk.
axes_ids[i], val)) {
return false;}
379 if (coordinate_mode == JypCtrlcoord_POLAR)
383 yCError(SDLJOYPAD) <<
"Polar coordinate system is supported only for bidimensional stick at the moment";
386 value =
Vector3(sqrt(value[0] * value[0] + value[1] * value[1]), atan2(value[0], value[1]));
398 if(hat_id > m_hatCount - 1){
yCError(SDLJOYPAD) <<
"Axis id out of bound!";
return false;}
401 for(i = 0; i < m_device.size(); ++i)
403 unsigned int localCount = SDL_JoystickNumHats(m_device[i]);
404 if(hat_id > localCount - 1)
406 hat_id -= localCount;
414 value = SDL_JoystickGetHat(m_device[i], hat_id);
420 if(trackball_id > m_ballCount - 1){
yCError(SDLJOYPAD) <<
"Trackball id out of bound!";
return false;}
424 for(i = 0; i < m_device.size(); ++i)
426 unsigned int localCount = SDL_JoystickNumBalls(m_device[i]);
427 if(trackball_id > localCount - 1)
429 trackball_id -= localCount;
436 if(SDL_JoystickGetBall(m_device[i], trackball_id, &x, &y) == -1)
438 yCError(SDLJOYPAD) <<
"SDL_JoystickGetBall returned error";
448 void SDLJoypad::updateJoypad()
450 SDL_JoystickUpdate();
yarp::sig::Vector Vector3(const double &x, const double &y)
SDLJoypad: Device that reads inputs of Joypads compatible with the SDL library.
bool getRawAxisCount(unsigned int &axis_count) override
bool getRawButtonCount(unsigned int &button_count) override
bool getRawTouchSurfaceCount(unsigned int &touch_count) override
bool getRawStickDoF(unsigned int stick_id, unsigned int &DoF) override
bool getRawHat(unsigned int hat_id, unsigned char &value) override
bool getRawTrackballCount(unsigned int &trackball_count) override
bool close() override
Close the DeviceDriver.
bool getRawButton(unsigned int button_id, float &value) override
bool getRawAxis(unsigned int axis_id, double &value) override
bool getRawStickCount(unsigned int &stick_count) override
bool getRawHatCount(unsigned int &hat_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
JoypadCtrl_coordinateMode
A simple collection of objects that can be described and transmitted in a portable way.
size_type size() const
Gets the number of elements in the bottle.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
A base class for nested structures that can be searched.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
virtual bool isBool() const
Checks if value is a boolean.
virtual bool asBool() const
Get boolean value.
virtual std::int32_t asInt32() const
Get 32-bit integer value.
virtual bool isFloat64() const
Checks if value is a 64-bit floating point number.
virtual bool isInt32() const
Checks if value is a 32-bit integer.
void resize(size_t size) override
Resize the vector.
void push_back(const T &elem)
Push a new element in the vector: size is changed.
#define yCInfo(component,...)
#define yCError(component,...)
#define yCWarning(component,...)
#define YARP_LOG_COMPONENT(name,...)
std::string to_string(IntegerType x)
An interface for the device drivers.
double now()
Return the current time in seconds, relative to an arbitrary starting point.
An interface to the operating system, including Port based communication.
The main, catch-all namespace for YARP.
std::vector< unsigned int > axes_ids
std::vector< int > direction