35 constexpr
double actionsExecutionTime = 1.0;
48 yCInfo(SDLJOYPAD) <<
"parameters:";
50 yCInfo(SDLJOYPAD) <<
"UseAllJoypadAsOne - set it to 1 to have all the connected joypad as one";
51 yCInfo(SDLJOYPAD) <<
"DefaultJoystickNumber - select the id of the joypad to use if there are more than one joypad and UseAllJoypadAsOne is set to 0";
52 yCInfo(SDLJOYPAD) <<
"stick - the number of stick to configure. a stick is simply a wrapping of 2 or more axes so for every stick";
53 yCInfo(SDLJOYPAD) <<
" a group named STICK*ID* containing the stick's parameters is searched. ";
55 yCInfo(SDLJOYPAD) <<
"stick groups parameters:";
56 yCInfo(SDLJOYPAD) <<
"axes - axes count for this stick";
57 yCInfo(SDLJOYPAD) <<
"axis[ID]_id - axis id for current stick related axis";
58 yCInfo(SDLJOYPAD) <<
"invert_axis_[ID] - invert the current axis";
59 yCInfo(SDLJOYPAD) <<
"deadZone - set the deadzone for this stick";
67 if (SDL_InitSubSystem( SDL_INIT_JOYSTICK ) < 0 )
69 yCError(SDLJOYPAD,
"Unable to initialize Joystick: %s", SDL_GetError());
74 joystick_num = SDL_NumJoysticks();
77 if (joystick_num == 0)
79 yCError(SDLJOYPAD,
"No joysticks found");
82 else if (joystick_num == 1)
85 yCInfo(SDLJOYPAD,
"One joystick found");
86 yCInfo(SDLJOYPAD,
"Using joystick: %s", SDL_JoystickName(joy_id));
90 yCInfo(SDLJOYPAD,
"More than one joystick found:");
91 for (
size_t i = 0; i < joystick_num; i++)
93 yCInfo(SDLJOYPAD) << i <<
":" << SDL_JoystickName(i);
96 if(!rf.check(
"UseAllJoypadAsOne"))
98 if(rf.find(
"UseAllJoypadAsOne").asBool())
101 if (rf.check(
"DefaultJoystickNumber"))
103 joy_id = rf.find(
"DefaultJoystickNumber").asInt32();
104 yCInfo(SDLJOYPAD,
"Multiple joysticks found, using #%d, as specified in the configuration options", joy_id);
108 yCWarning(SDLJOYPAD,
"No default joystick specified in the configuration options");
109 yCWarning(SDLJOYPAD,
"Which joystick you want to use? (choose number)");
121 yCError(SDLJOYPAD) <<
"Missing UseAllJoypadAsOne parameter";
128 for(
size_t i = 0; i < joystick_num; ++i)
130 m_device.push_back(SDL_JoystickOpen(i));
135 m_device.push_back(SDL_JoystickOpen(joy_id));
138 for(
size_t i = 0; i < m_device.size(); ++i)
140 if ( m_device[i] ==
nullptr )
142 yCError(SDLJOYPAD) <<
"Could not open joystick with id" << i;
147 m_axisCount += SDL_JoystickNumAxes(m_device[i]);
148 m_ballCount += SDL_JoystickNumBalls(m_device[i]);
149 m_hatCount += SDL_JoystickNumHats(m_device[i]);
150 m_buttonCount += SDL_JoystickNumButtons(m_device[i]);
153 if(parseActions(rf, &actionCount))
157 if(SDL_JoystickEventState(SDL_ENABLE) < 0)
159 yCError(SDLJOYPAD) <<
"SDLJoypad:" << SDL_GetError();
162 yCInfo(SDLJOYPAD) <<
"Actions successfully parsed and linked to the joypad";
167 yCError(SDLJOYPAD) <<
"Error while parsing actions";
171 if(!parseStickInfo(rf)){
return false;}
179 yCError(SDLJOYPAD) <<
"Missing 'sticks' parameter or not an integer";
183 for(
unsigned int i = 0; i < m_axisCount; i++)
185 m_axes.push_back(
true);
189 for(
unsigned int i = 0; i < m_stickCount; i++)
195 stickName =
"STICK"+std::to_string(i);
197 if(!cfg.
check(stickName))
199 yCError(SDLJOYPAD) <<
"Missing" << stickName <<
"group in configuration";
205 if(0 == stickParams.
size())
207 yCError(SDLJOYPAD) <<
"Group" << stickName <<
"is empty";
213 yCError(SDLJOYPAD) <<
"Missing 'axes' count in" << stickName <<
"group or not an integer";
219 for(
int j = 0; j < axesCount; j++)
221 string axisName, invertName;
222 unsigned int axis_id;
223 axisName =
"axis" + std::to_string(j) +
"_id";
224 invertName =
"invert_axis_" + std::to_string(j);
228 yCError(SDLJOYPAD) <<
"Missing" << axisName <<
"param in" << stickName <<
"group or not an integer.";
232 axis_id = (
unsigned int)stickParams.
find(axisName).
asInt32();
233 if(axis_id > m_axisCount - 1)
235 yCError(SDLJOYPAD) <<
"Axis id out of bound";
239 if(!stickParams.
check(invertName) || !stickParams.
find(invertName).
isBool())
241 yCError(SDLJOYPAD) <<
"Missing" << invertName <<
"param in" << stickName <<
"group or not an bool.";
245 currentStick.
axes_ids.push_back(axis_id);
247 m_axes[axis_id] =
false;
252 yCError(SDLJOYPAD) <<
"Missing deadZone param in" << stickName <<
"group or not an double.";
257 m_sticks.push_back(currentStick);
269 axes_count = m_axisCount;
275 button_count = m_buttonCount;
281 trackball_count = m_ballCount;
287 hat_count = m_hatCount;
293 touch_count = m_touchCount;
299 stick_count = m_stickCount;
305 if(stick_id > m_sticks.size()-1)
307 yCError(SDLJOYPAD) <<
"SDL_Joypad: stick_id out of bounds when calling 'getStickDoF'' method";
316 if(button_id > m_buttonCount - 1){
yCError(SDLJOYPAD) <<
"Button id out of bound!";
return false;}
319 for(i = 0; i < m_device.size(); ++i)
321 unsigned int localCount = SDL_JoystickNumButtons(m_device[i]);
322 if(button_id > localCount - 1)
324 button_id -= localCount;
331 value = float(SDL_JoystickGetButton(m_device[i], button_id));
332 if(value > 0.5 && m_actions.find(button_id) != m_actions.end() &&
yarp::os::Time::now() - m_actionTimestamp > actionsExecutionTime)
334 executeAction(button_id);
340 bool SDLJoypad::getPureAxis(
unsigned int axis_id,
double& value)
342 if(axis_id > m_axisCount - 1){
yCError(SDLJOYPAD) <<
"Axis id out of bound!";
return false;}
345 for(i = 0; i < m_device.size(); ++i)
347 unsigned int localCount;
348 localCount = SDL_JoystickNumAxes(m_device[i]);
349 if(axis_id > localCount - 1)
351 axis_id -= localCount;
359 value = 2 * ((float(SDL_JoystickGetAxis(m_device[i], axis_id)) - (-32.768)) / 0xffff);
365 if(axis_id > m_axisCount - 1){
yCError(SDLJOYPAD) <<
"Axis id out of bound!";
return false;}
368 return getPureAxis(axis_id, value);
381 if (stick_id > m_stickCount - 1){
yCError(SDLJOYPAD) <<
"Stick id out of bound!";
return false;}
384 stick& stk = m_sticks[stick_id];
387 for(
size_t i = 0; i < stk.
axes_ids.size(); i++)
389 if(!getRawAxis(stk.
axes_ids[i], val)) {
return false;}
393 if (coordinate_mode == JypCtrlcoord_POLAR)
397 yCError(SDLJOYPAD) <<
"Polar coordinate system is supported only for bidimensional stick at the moment";
400 value =
Vector3(sqrt(value[0] * value[0] + value[1] * value[1]), atan2(value[0], value[1]));
412 if(hat_id > m_hatCount - 1){
yCError(SDLJOYPAD) <<
"Axis id out of bound!";
return false;}
415 for(i = 0; i < m_device.size(); ++i)
417 unsigned int localCount = SDL_JoystickNumHats(m_device[i]);
418 if(hat_id > localCount - 1)
420 hat_id -= localCount;
428 value = SDL_JoystickGetHat(m_device[i], hat_id);
434 if(trackball_id > m_ballCount - 1){
yCError(SDLJOYPAD) <<
"Trackball id out of bound!";
return false;}
438 for(i = 0; i < m_device.size(); ++i)
440 unsigned int localCount = SDL_JoystickNumBalls(m_device[i]);
441 if(trackball_id > localCount - 1)
443 trackball_id -= localCount;
450 if(SDL_JoystickGetBall(m_device[i], trackball_id, &x, &y) == -1)
452 yCError(SDLJOYPAD) <<
"SDL_JoystickGetBall returned error";
462 void SDLJoypad::updateJoypad()
464 SDL_JoystickUpdate();
yarp::sig::Vector Vector3(const double &x, const double &y)
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,...)
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