Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

device_name param ignored ROS2 #199

Open
Achllle opened this issue Feb 15, 2021 · 1 comment
Open

device_name param ignored ROS2 #199

Achllle opened this issue Feb 15, 2021 · 1 comment

Comments

@Achllle
Copy link

Achllle commented Feb 15, 2021

I'm using an xbox360 located at /dev/input/js0 / /dev/input/event0 on my machine on ROS2 Foxy. I specified these parameters as

            parameters=[
                {"device_name": "'/dev/input/js0"},
                {"device_id": 2}
            ],

I noticed that when device_id is set incorrectly but device_name is correct, the joystick isn't found. Vice versa when device_name is set incorrectly but device_id is set correctly` the joystick is found.

The documentation states

The joystick name to use. This can be useful when multiple different joysticks are attached. If both device_name and device_id are specified, device_name takes precedence.

@tigressine
Copy link

I was having problems with Joy also and came across your issue. I think I discovered the bug in the handleJoyDeviceAdded function.

Here's the code snippet for reference:

void Joy::handleJoyDeviceAdded(const SDL_Event & e)
{
  if (!dev_name_.empty()) {
    int num_joysticks = SDL_NumJoysticks();
    if (num_joysticks < 0) {
      RCLCPP_WARN(get_logger(), "Failed to get the number of joysticks: %s", SDL_GetError());
      return;
    }
    for (int i = 0; i < num_joysticks; ++i) {
      const char * name = SDL_JoystickNameForIndex(i);
      if (name == nullptr) {
        RCLCPP_WARN(get_logger(), "Could not get joystick name: %s", SDL_GetError());
        continue;
      }
      if (std::string(name) == dev_name_) {
        // We found it!
        dev_id_ = i;
        break;
      }
    }
  }

  if (e.jdevice.which != dev_id_) {
    return;
  }

  ...

Say you set device_name to /some/fake/device and you set device_id to 0 (and there is a valid 0 device on your machine). When the joy_node is created, it will set dev_name_ to be /some/fake/device and dev_id_ to be 0.

Now comes this function. This function (I assume) is called whenever a new device is added (like at the beginning of the node running). It checks if dev_name_ is empty: it is not. Then it iterates over all of the joysticks (let's assume a few are connected). None of the joysticks match dev_name_ so we never update dev_id_ (the if (std::string(name) == dev_name_) { line). This means dev_id_ is still 0! So if (e.jdevice.which != dev_id_) { will presumably pass because dev_id_ is a valid device ID.

This function needs a way to return early if the dev_name_ is never found.

Specs: Pop!_OS 20.04, ROS Foxy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants