Set Up a Generic Gamepad for ROS Teleoperation

ROS Noetic

This article describes the process of adding a gamepad controller to a complex ROS control network to allow a robot’s intuitive and/or low-latency teleoperation. The set-up uses three packages provided by the ROS community; the joy driver, the twist multiplexor, and the twist joy teleop packages.

This is a standard pattern used in many ROS robots around the world. See an example in the sphero_rvr_ros source

Multiple Inputs

By using multiplexed command velocity signals, this approach allows a hierarchy of controls from different sources including a navigation system or remote desktop keyboard.

Steps

1. Select a gamepad with a supported Linux driver

Some good examples come from Logitech

2. Create a <robot>_contollers package or similar to store the config and launch files

If your robot software packages are named with jackobot, then the package might be jackobot_controllers

3. Add the joy and joy-twist, and twist-mux packages as dependencies

<depend>joy</depend>
<depend>teleop_twist_joy</depend>
<depend>twist_mux</depend>

4. Decide on a multiplexed cmd_vel topic namespace

For example:

If nav uses /nav/cmd_vel, then joystick could be /joy/cmd_vel

Add this to the twist_mux config file with the joystick at a higher priority than the nav command topic

5. Create a config file for the joystick and button inputs

axis_linear: 1 # LS vert
scale_linear: 0.4
scale_linear_turbo: 0.7
axis_angular: 3 # RS hori
scale_angular: 6.0
scale_angular_turbo: 6.0
enable_button: 4 # LB
enable_turbo_button: 5 # RB

6. Create a launch file and include the config and namespace remapping

<?xml version="1.0"?>
<launch>
    <arg name="joy_dev" default="/dev/input/js0" />
    <arg name="teleop_joy_config" default="$(find sphero_rvr_controllers)config/joy_config.yaml" />
    <arg name="twist_mux_config"  default="$(find sphero_rvr_controllers)config/twist_mux.yaml"/>

    <!-- joy driver -->
    <node pkg="joy" type="joy_node" name="joy_node">
        <param name="dev" value="$(arg joy_dev)" />
        <param name="deadzone" value="0.3" />
        <param name="autorepeat_rate" value="20" />
    </node>

    <!-- joy teleop -->
    <node pkg="teleop_twist_joy" name="teleop_twist_joy" type="teleop_node">
        <remap from="cmd_vel" to="/joy_teleop/cmd_vel" />
        <rosparam command="load" file="$(arg teleop_joy_config)" />
    </node>

    <!-- twist mux -->
    <node pkg="twist_mux" type="twist_mux" name="twist_mux" output="screen">
        <remap from="cmd_vel_out" to="/controller/tracks/cmd_vel" />
        <rosparam file="$(arg twist_mux_config)"  command="load"/>
    </node>
</launch>

7. Optionally: set a device rule for the joystick device connection

TBC